Commit Graph

34 Commits

Author SHA1 Message Date
Bo 5644f2ba71 fix(gates): fail closed on ratchet collection failure and pin first-parent head scope
Repairs the two fresh-Sol ADR-0016 review findings. Turns the RED witnesses
recorded in the previous commit green without touching the governed regex, the
growth guard, the allowlist, or scripts/.skill-python-grandfather.

1. check-skill-python-ratchet.sh no longer swallows the collector contract.

scripts/lib/ratchet.sh gives every chosen collection command an explicit
"|| return 2" because the gate runs in a shell with no ambient strict mode. The
caller then discarded exactly that: ratchet_changed_files_status ... 2>/dev/null
|| true turned a dead Git read into an EMPTY changed set, the governed loop ran
zero times, and the gate printed its green banner over a diff nobody read.
Measured before this change, with a diff-tree shim over a tree carrying a real
unpinned violation: "PASS: skill-python ratchet" / exit 0. The rc is now
preserved and the gate exits 2, with stderr no longer sent to /dev/null so the
library's own reason survives.

2. head scope now HAS the first-parent semantics it declared.

git diff-tree -m --first-parent does not mean "diff only against parent 1":
-m splits a merge into one diff block PER PARENT and emits them all, while
--first-parent constrains history traversal rather than which parent blocks
print. The parent-2 block lists every path already settled on the first-parent
line, so a merge commit re-attributed long-landed files to itself. Sol measured
this on the live integration lineage: at 88c2692f2 the old form emitted 14
governed rows, 12 from the second-parent block, none introduced by that merge.

Head collection becomes one owner, ratchet__head_diff, doing an explicit
two-tree HEAD^1..HEAD diff, with the --root empty-tree diff kept for root
commits (HEAD^1 does not resolve there, and a root commit's contents are exactly
what it introduced). An unreadable parent list fails closed at rc 2 rather than
returning an empty set. The helper replaces all SIX open-coded copies of the old
command -- head scope plus the upstream-without-upstream and auto fallbacks, in
both the name-only and name-status collectors -- so the same defect cannot
survive in a path nobody looked at. diff-tree is retained (not git diff) to
preserve the existing rename-detection posture; only ref selection changes.

The lib header no longer claims -m --first-parent means first-parent.

Verification:
  - tests/scripts/check-skill-python-ratchet.bats  15/15 (N7, N8 were RED)
  - tests/scripts/ratchet-lib.bats                 41/41 (merge case was RED)
  - all six other ratchet-lib consumer suites: unchanged from base
  - go test ./internal/gates/...                   ok (negative-witness closure)
  - shellcheck -S warning on both changed scripts: clean
  - git diff --check: clean
  - live gate sweep over all eight consumers, run identically at the unmodified
    base 0ba51a5f6 and here: byte-identical results. The one pre-existing
    failure (check-atomic-write-ratchet stale-entry rc=1, and its bats case 13)
    reproduces at base with real history and is NOT caused by this change.

Refs: /tmp/agentops-adr0016-go-promotion-review-sol.md (REQUEST_CHANGES,
"Two ratchet corrections are still required"); ADR-0016 section 3.
2026-07-27 23:52:16 -04:00
Bo 56190722e6 fix(gates): atomic-write ratchet fails closed on scan-helper death — no silent PASS (#946)
## Root cause (CI flake, run 29785505667 attempt 1, PR #944)

The bats test `adding only the temp-signal half to a file with an
EXISTING rename still trips` failed once on ubuntu with the ratchet
printing a clean `PASS … grandfathered=0` where the fixture
deterministically trips. Diagnosed by analysis per the test-isolation
discipline (not repro-chasing):

- bats errexit proves every fixture `git commit` succeeded; the fixture
repo is fully isolated.
- `grandfathered=0` in the PASS line fingerprints the run as in-fixture
(real repo = 4).
- Zero stderr in the captured output rules out every loud failure
handler.

What remains: **three silent paths where a scan helper (grep/awk/git)
dying under 4-way-parallel runner load reads as "no finding"** — the
gate then certifies an unchecked diff:

1. `file_trips`: strip/grep failure returned 1 ("does not trip") → file
silently skipped.
2. Detector loop read from `< <(ratchet_changed_files | sort)` — a
collector rc 2 inside process substitution is discarded, certifying an
EMPTY change set (the exact fail-open the ratchet-lib header warns
about).
3. `ratchet_added_hunk_matches`: helper death propagated as arbitrary
nonzero, swallowed by `|| continue`.

## Fix

- `file_trips` is tri-state (0 trips / 1 no / 2 refuse-to-certify,
loud); signal greps read full input (no `-q` early-exit) so pipefail can
never surface a SIGPIPE'd printf as a phantom failure on large files.
- Changed files are collected into a variable under pipefail with an
explicit `exit 2` handler.
- `ratchet_added_hunk_matches` maps fallback-grep/awk death to loud rc 2
(0/1 unchanged; existing `|| continue` consumers skip on 2 exactly as
before, now loudly).
- `compute_grandfather_set` aborts `--regenerate` on helper failure —
never a truncated grandfather list.

## Pinned

Dying-awk PATH-shim tests at gate and lib level: helper death is rc 2
"refusing to certify", never PASS. Same fail-closed class as the
pawl-refuted empty-stream certify (2026-07-10).

## Validation

- 58/58 in `check-atomic-write-ratchet.bats` + `ratchet-lib.bats` on
fresh origin/main
- All six ratchet-lib consumer gate suites green
- `shellcheck -S warning` clean; real-repo gate PASS (grandfathered=4);
`--regenerate` byte-identical
- 65 repetitions of the formerly-flaky test green

Residual: the external kill source is unprovable from one occurrence; a
recurrence now exits 2 naming the failed helper + file instead of
printing PASS.
2026-07-20 19:47:19 -04:00
Bo 81e6380510 feat(cli): wire ao eval — the Learn seat's measurement surface (#921)
Registers the fully-built-but-never-wired eval module into the CLI spine
and repairs its one real instrument bug. Three commits, RPI-shaped: wire
+ fix, drift guards + docs, fixture counts.

## What
- **`ao eval` joins the spine** (cmd/ao/eval_composition.go):
deterministic suite runs, run-record
compare/baseline/scorecard/coverage, locked Tasks, holdout scenarios,
suite A/B verdicts with power-derived n-required, and the holdout-safe
Outcomes projection. This is the operating contract's *Learn* seat — a
read/measure consumer of evidence. It reports numbers and owns no retry,
scheduling, promotion, or lifecycle authority. The retired Aliases/Bench
seats stay nil and their subcommands are omitted.
- **Instrument bug fixed**: both scenario-ab arms were corpus-denied at
runtime — the with-gold treatment was only a prompt injection through
the retired `ao lookup`, so the A/B silently guaranteed a zero delta.
Treatment is now environment-shaped: the with-gold arm runs with the
corpus readable, the control arm stays sandbox-confined (the fail-closed
empty-deny guard is untouched), and judges are always corpus-denied.
- **Schema drift guards**: a run record persisted by the production
writer must validate against eval-run.v1.schema.json (and the minimal
suite against eval-suite.v1.schema.json) — closing the same silent-fork
class the verdict.v2 golden corpus closed.
- **Hermetic test builds hardened**: keep the real HOME's Go caches
(TestMain isolation was forcing module re-downloads) and skip VCS
stamping.
- docs/architecture/go-cli.md gains the eval section; MIGRATION.md notes
`ao eval`'s return; COMMANDS.md, cli-surface, and surface counts
regenerated; new leaves carry honest allowlist reasons; new cmd/ao L2
tests drive eval run/compare/help through the full production wiring.

## Evidence
- Full cli suite 2,801 green; race green on cmd/ao + the eval island;
vet clean
- Full-tier gate: 65/66 on the penultimate commit; the single failure
(surface counts) is the final fixture commit, re-verified PASS
standalone — no other check reads those fixtures
- Fresh independent validation (Codex, frozen subject 86022a3c6, clean
tree at start and end): **OVERALL PASS**, 6/6 — including a live
end-to-end `ao eval run` producing a passing run record
- Rubric-relocation decision honored: true holdout rubrics live in the
external measurement register; the repo keeps only leak-guarded
projections
2026-07-18 18:33:46 -04:00
Bo 5d61bf8a3f fix: kill the shared-config gremlin class (hook-safe repo-root, git-env scrubbing, config-hygiene gate) (#922)
Fixes the three gremlins observed 2026-07-18 (bead
age-gate-scripts-worktree-gitdir-p62wo):

1. **Gate scripts broke under hook env from linked worktrees** (#919
regression): new scripts/lib/repo-root.sh (GIT_*-scrubbed resolution,
BASH_SOURCE anchor, worktree-correct) swept across 32 scripts. Proof:
this PR's own push ran the pre-push gates from a linked worktree and
passed.
2. **core.bare=true recurrence**: mechanism proven (leaked GIT_DIR +
no-arg git init --bare rewrites the SHARED config); writer traced with
high confidence to a live Gas City city process (concrete suspect:
gascity cmd_rig_test.go runGitInTest, unscrubbed env + no-arg init
--bare — fork-side fix filed separately). Defense: new
always.git-config-hygiene gate fails fast on core.bare/test identities
with the repair command inline (--self-test proves fail-closed).
3. **Test/test@test.com identity leak**: writer convicted — our own
pre-push chain leaked GIT_DIR into go test, whose helpers wrote the
shared config via git -C (mechanism proven). Cut at both ends:
validate-go-fast scrubs env for children; every test git-helper set-site
scrubs; check-test-isolation gains a WARN-ratchet rule (baseline 3 →
FAIL at 0).

Gates: shellcheck rc=0 across 36 scripts; go build/vet clean;
655+379+149 tests; hygiene self-test; both originally-failing validators
pass under the repro env.
2026-07-18 18:20:16 -04:00
Bo 23c0026500 fix: close v3.3.0 release-audit findings (#915)
## Summary

Closes the findings from the v3.3.0 release-viability audit of main.

**Surface truth (High):** `ao constraint`, `ao goals trace`, `ao session
memory`, and `ao skills edit` are production tombstones but
docs/cli-surface.md documented them as `public-tested`/`covered` (the
test binary keeps constraint live, and the generated doc reflected the
test build). Added `deprecated` allowlist rows, dropped the stale
constraint-subcommand rows, regrouped constraint with its tombstone
peers in the default spine, regenerated both surface projections, and
added `TestCathedralCutTombstonesSurvivePruning` pinning the invariant
that every Cathedral Cut verb keeps an executable tombstone.

**Installer hardening (Medium):** `install-bd.sh` now fails closed when
no published checksum exists for a release asset (explicit `--no-verify`
overrides), and the curl|bash path verifies the fetched
`installer-common.sh` against a pinned SHA-256 before sourcing it
(drift-guarded by a new install-bd.bats test).

**Docs (Medium/Low):** UPGRADING.md no longer links the MIGRATION-3.0.md
file the Cathedral Cut deleted; CHANGELOG 3.3.0 `### Removed` now names
`yield`, `constraint`, and the 3.2 `verify` front door and links the
MIGRATION.md map.

**Gate scripts (Low):** flywheel/provenance gate scripts build `ao` into
`mktemp -d` scratch dirs instead of fixed world-known /tmp paths
(symlink/TOCTOU on shared hosts).

**Bonus (surfaced by the push gate):** `scripts/lib/preamble.sh`
mis-resolved REPO_ROOT under git hook env (GIT_DIR without
GIT_WORK_TREE), which made `go.cli-architecture` refuse every
worktree-origin push touching `cli/cmd/ao/**`. Fixed by scrubbing the
hook-injected discovery env around the rev-parse.

## Validation
- `go build && go vet && go test ./...`: 5,085 tests green,
golangci-lint clean
- `ao gate check --fast`: 27/27 pass, including under simulated hook env
- bats install-bd suite 6/6 incl. new pin drift test; shellcheck clean
on all touched scripts
- markdownlint clean; doc-release gate passes; tombstone exit codes
verified on the built binary
2026-07-17 12:58:47 -04:00
boshu 5bdbb5fd09 refactor: simplify AgentOps loop and harden CLI 2026-07-15 19:17:08 -04:00
boshu e4dbef98f6 Collapse AgentOps install to ao skills link
Retire the 3.x plugin curl/PowerShell installers as tombstones, delete the
plugin-cache helpers, and rewire CI/doctor/conformance onto the canonical
checkout + ao skills link path. Keep install-bd and the opt-in operator scripts.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-15 17:04:55 -04:00
boshu cb2a7ac398 refactor: complete the cathedral cut 2026-07-15 00:21:02 -04:00
boshu 4823077621 refactor: cut AgentOps to a single-pass evidence loop 2026-07-14 22:01:50 -04:00
Bo 1d4c003e05 Cut plan: gate registry diet, legacy bash gate removal, CI collapse, pawl warm-service removal (#906)
## Summary
- **Wave 1** — remove the `always.wiring-closure` meta-gate, demote
`docs.skill-refs` to Full tier, delete 8 orphan scripts.
- **Wave 2** — delete the legacy bash pre-push gate (`pre-push-gate.sh`,
2,279 lines) and its parity machinery; collapse `validate.yml` from 18
jobs to 5.
- **Wave 3** — remove the pawl warm NTM standing service; the cold
review spine (pawl-review / pawl-verdict / pre-push check) is untouched.
- **Wave 4** — gate registry diet: cut 24 doctrine/meta check IDs and
~70 backing scripts/workflows/bats; trim nightly knowledge-cycle job.

Net: gate registry 112 → 83 checks (incl. main's additions), ~24k lines
of scripts/CI/bats deleted. Routine one-file fast gate now runs in ~19s.

## Test plan
- [x] `go build` / `go vet` / gates+goals+ports package tests green
- [x] `ao gate check --fast --scope range:origin/main..HEAD` — 66
passed, 0 failed, 1 skipped (199 changed files)
- [x] `validate-ci-policy-parity.sh` PASS; validate.yml / nightly.yml
parse
- [x] `regen-changed-scope --check` green; registry.json regenerated
- [x] Grepped tree for dangling references to every deleted script/check
ID

Made with [Cursor](https://cursor.com)

---------

Co-authored-by: boshu <241868352+boshu2@users.noreply.github.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-13 14:45:20 -04:00
boshu 9c6a662203 feat(loop): refactor the four-umbrella operating loop
Bead: age-four-umbrella-loop-refactor-xz4ps.1
2026-07-13 06:48:50 -04:00
boshu 0514f82ec3 feat(pawl): present review as the user front door; warm verbs grouped operator-only (age-hk5zg.2)
'ao pawl --help' listed the warm standing-service verbs as flat peers of review,
pushing users toward operator machinery (NTM, projects_base) they cannot run.
Cobra groups now split the surface: review under 'Use the membrane (the front
door — needs no NTM, no setup)', up/down/reap/health/doctor/smoke/route/metrics
under 'Operate the standing warm service (operator-only; requires the NTM swarm
substrate)'. Grouping/labeling only — every verb keeps its name and behavior.
docs/contracts/pawls.md carries the same operator-only note.

Fix swept in: scripts/lib/sku_extract.py's cobra help parser only recognized
'*Commands:' section titles, so EVERY grouped command's subcommands were
invisible to the SKU catalog ('ao goals' was already affected; this change made
'ao pawl' the second victim and surfaced the bug). The parser now enters any
non-reserved column-0 title block and requires the 2+-space name/short gap, so
grouped subcommands resolve precisely (registry.json reflects the corrected
projection for ao goals too). Locked by TestPawlHelpPresentsReviewAsFrontDoor.
2026-07-10 20:44:30 -04:00
boshu c0d12e4004 feat(gates): extract shared shrink-only ratchet lib (age-ratchet-lib-extraction-bv7d.1)
scripts/lib/ratchet.sh: the one implementation of the grandfather/baseline
ratchet mechanics 7 gates hand-roll today — per-consumer parse modes
(raw|cr-strip|strip|trailing-comment), scope-aware changed-file collection
incl. upstream, fail-closed growth guard (comm -13 + intersection authority,
RATCHET_GROWTH_GUARD=off escape for migrated gates), parameterized stale
predicates, generic regenerate (header-fn + LC_ALL=C sorted body), added-hunk
guard with ENVIRON-passed ERE.

tests/scripts/lib/ratchet-difftest.bash: byte-parity differential harness
(stdout, stderr, exit code separately) for the migration slices.

tests/scripts/ratchet-lib.bats: 24 cases — real pinned-shape round-trips per
parse mode, growth rejection, self-allowlist refusal, stale by set-diff and
by predicate, regenerate golden, added-hunk guard, harness smoke.

cli/internal/gates/checks/ratchet_routing_test.go: self-extending FM3 closure —
every check script sourcing the lib must route lib edits via its Match globs.

Pre-mortem: .agents/council/2026-07-10-pre-mortem-ratchet-lib.md (3 rounds).
Lib is FROZEN for the rest of the arc per FM6.

Claude-Session: https://claude.ai/code/session_01RDWPYn4ZS2SyBkcBvAM18u
2026-07-10 19:47:31 -04:00
boshu f7864bff30 feat(frontier): LKG frontier with compensated-ancestry RESOLVED + 5 liveness acceptance tests (age-ekam) 2026-07-10 09:55:16 -04:00
boshu 46c802d7ab fix(pawl): tip-coherence guard + canonical evidence/catch rooting (age-pawl-bead-tip-coherence-wckn, age-pawl-evidence-worktree-loss-np1e)
Two guards for the 2026-07-09 wrong-tree/evidence-loss incident:

wckn: pawl_tip_coherence refuses (exit 3, fix-and-re-run) when the review
target commit cites bead ids sharing the reviewed bead's prefix and none is
the bead or a dotted relative - a verdict can no longer bind a tree that
belongs to a different bead. Positive-mismatch only; PAWL_ALLOW_TIP_MISMATCH=1
opts out. 7 bats.

np1e: evidence transcripts and membrane catches now root at the CANONICAL
checkout (git-common-dir parent) via pawl_evidence_dir/pawl_canonical_root,
so reviews run in disposable land worktrees no longer write artifacts that
die with 'git worktree remove', and ledger evidence_path never dangles.
5 bats. Both libs registered in validate-embedded-sync + embedded copies synced.

Claude-Session: https://claude.ai/code/session_01BkgdP88SiccCSyYdi8GHNa
2026-07-10 09:38:54 -04:00
boshu e7acfd9fa9 refactor(skills): repoint operating-loop CRUD to ao beads exec for bd+br dual-support + trim rpi (age-jgf9)
Dual-support increment 3 (the user-facing completion). AgentOps ships to users
who mostly track with bd; operating-loop skills hardcoded `br`, breaking them.
Repoint bead CRUD (ready/update/close/create/dep/show/list, non-jq) and the
children-extraction pattern to the tracker-agnostic `ao beads exec` (bd-or-br)
across skills/**/SKILL.md + references. In THIS repo (br) there is no behavior
change; the win is bd users.

- children pattern `br show <epic> --json | jq '…parent-child….id'` →
  `ao beads exec children <epic>` (post-mortem closure-integrity-audit + the
  latent invalid `br children` in rpi phase-data-contracts).
- probe blocks re-gated `command -v br` → `command -v ao` (bd users have ao).
- parity_only codex twins refreshed via codex-sync + hashes; bespoke twins are
  hand-maintained (codex-sync skips them by design) and left for a deliberate
  follow-up.
- jq-shape `br … --json | jq '<shape>'` sites left on br (increment 4 will
  normalize the --json shape across trackers).
- rpi/SKILL.md trimmed 280→249 lines (meta-tier ≤250): receipt JSON folded into
  the existing phase-data-contracts.md, rpi_state block compacted, redundant
  Reference-Documents entries dropped.
- snippet validators (ao_snippet_resolve.py lib + validate-skill-body-refs.sh)
  taught that `ao beads exec` is a flag-forwarding passthrough, so tracker flags
  after it are not validated against ao's help.
2026-07-08 17:33:46 -04:00
boshu 74aefa8312 feat(economics): amend-into-#trivial-bind trap guard (age-verification-economics-ebec.11)
Kills the operator-error class that fired ~4x on 2026-07-07, each costing a wasted
review round: after the pawl auto-binds a #trivial provenance commit on the feat, a
'git commit --amend' folds the fix INTO the bind — HEAD becomes a #trivial commit
carrying code, the reviewer's trivial-waiver walk steps PAST it to review the STALE
original feat, and the verdict binds the wrong tree (surfacing only as an opaque
'hidden non-trivial commit' gate failure at push).

scripts/lib/pawl-amend-guard.sh (new, sourceable, unit-tested): pawl_amend_guard
returns 2 when HEAD is a trailing-#trivial commit changing non-provenance files,
printing the diagnosis + the rebuild-don't-amend recovery. Wired EARLY into
pawl-review.sh (scope=head, before the review — where it saves the round) and as a
land-time backstop in pawl-land.sh; embedded pawl bundle + Makefile + embed validator
updated. Safe: provenance-only #trivial binds, plain feats, and mid-subject #trivial
mentions all pass; opt out PAWL_NO_AMEND_GUARD=1. bats 5/5; guard proven to fire on
the trap and stay silent on legitimate binds; race suite green.
2026-07-07 19:10:45 -04:00
boshu 69d5e7c392 feat(economics): pre-flight gate — run the deterministic battery BEFORE the model reviewer (age-verification-economics-ebec.9)
THE bottleneck fix. On 2026-07-07, closing skill-doc changes took 4-7 model-review
rounds each because ~90% of the defects were DETERMINISTIC (format/link/twin/
gate-hint) — but the expensive cross-family verdict was requested BEFORE the local
deterministic checks were green, so the membrane re-discovered them serially, each
round a full re-review + re-land.

scripts/lib/pawl-preflight.sh (new, sourceable, unit-tested): pawl_preflight <scope>
<repo> runs the reviewed repo's deterministic battery before the reviewer and fails
fast (exit 3, same fix-and-re-run disposition as the --smoke/REFUTED path) on a
CONFIRMED-red battery — WITHOUT spending a reviewer round (0 tokens). Command:
PAWL_PREFLIGHT_CMD if set (operator owns exit semantics), else the default
'ao gate check --fast --scope head' (ao resolved AO_BIN -> repo cli/bin/ao -> PATH,
mirroring check-pawl-pre-push.sh). Wired into pawl-review.sh after the HEAD snapshot,
before packet assembly + the meter clock.

SAFETY — pure ACCELERATOR, never a false blocker: a nonzero that cannot be CONFIRMED
as a real gate run (RCE trust-guard, missing/stale ao, build error — distinguished by
the absence of the gate's 'checks —' summary marker) is SKIP-and-proceed, not RED.
Worst case it no-ops and behavior is byte-identical to today (the pre-push gate still
backstops). Disabled for PAWL_UNTRUSTED_REPO=1 (never run a repo's own battery over an
untrusted checkout) and scope != head (no committed HEAD). Opt out: PAWL_NO_PREFLIGHT=1.

Converts the inert prose lesson 'run the battery before the verdict' into MECHANISM
(the skills audit proved prose lessons are inert). bats 9/9; embedded pawl bundle +
Makefile sync + embed-sync validator updated; Go embed test green.
2026-07-07 18:46:27 -04:00
boshu 9a23ba9cc5 refactor(skills): execute the audit retire wave — 8 skills retired/merged, 66 -> 58, spine 15 -> 13 (age-skills-audit-fable-l6ic.12)
Executes the age-e3zk decision (fresh disposition pass: docs/audits/
skills-audit-2026-07-06.md; council 2026-07-06 parked this behind age-p2c7,
which landed as d7f950ca8; operator directive 2026-07-07 authorized finishing
all filed work).

RETIRED: red-team (validate --debate absorbs), perf (frontier-generic, zero
repo bindings), flywheel (ao flywheel status CLI is the surface).
MERGED: eval-outcomes -> validate (--mode=pre-impl --target=scenario),
review -> validate (--mode=pr), compile + curate -> post-mortem (mining half;
mechanical surfaces stay ao compile / ao lookup), recover -> status
(--recover mode; deep playbook preserved at status/references/
recovery-playbook.md; delivers l6ic.7 and the l6ic.13 row reconcile).

Mechanics: ao skills retire x8 (trees incl. images/*/skills, terminal ledger
rows via --into, .agy-plugin review bundle removed); absorption tombstones in
docs/SKILLS.md + SKILL-TIERS.md (56 user-facing + 2 internal = 58, counted);
spine gate re-anchored 15 -> 13 (l6ic.11 minimal consistency: review +
red-team leave; membrane 7 + bookkeeper 6); bespoke twins post-mortem/status
hand-mirrored per AGENTS-CODEX; manifest pruned of orphan twin rows (62 -> 57);
overrides catalog pruned of 8 retired rows; gemini verify core_skills +
claude/codex image manifests updated; retired-subject eval
red-team-adversarial-validation.json removed (not canary-listed).

Gates: spine-integrity 13 PASS; wiring-closure PASS; skill-frontmatter 58/58;
codex manifest+artifacts+parity PASS; regen-check ALL GREEN; SKILL-TIERS also
fixed Opus 4.6 -> 4.8, GOALS.yaml -> GOALS.md, flywheel diagram to CLI truth
(l6ic.6 pre-work). Residual prose mentions in non-gated docs are the l6ic.2
debris sweep's scope.
2026-07-07 11:06:35 -04:00
boshu fe1d8fee8c feat(pawl): patch-id REBOUND verdicts — authorize a byte-identical rebase without a full re-review, gate-green + lineage required (age-rk3r.9)
# Conflicts:
#	skills/catalog.json
2026-07-02 18:24:24 -04:00
boshu 3c4e4d6d54 feat(pawl): source per-repo verify config once at pawl-review entry (age-rk3r.17) 2026-07-02 01:30:44 -04:00
boshu b4c74afd02 feat(pawl): reviewer adapter contract — codex byte-compatible, agy cold, local-mlx eval-only; folds age-iian timeout re-snapshot (age-rk3r.1)
Post-refutation fixes (cross-family pawl caught two defects in the first cut):
- DEFECT 1 (fail-open): the agy/local-mlx genuine-run marker 'VERDICT:' appears in the
  packet itself, so a run that merely cat/echoed the packet classified GENUINE and the
  last-verdict parser could extract a CONFIRMED from echoed diff-context lines. Fixed:
  sentinel-wrapped agy packets (random-nonce boundary lines) + a marker-independent
  packet-line containment check (reviewer_packet_echoed) classify packet echo as ECHO.
- DEFECT 2 (wrong family certified): the verdict write hardcoded --refuter codex:...;
  REVIEWER=agy now certifies the canonical 'gemini' family (roster: agy|google->gemini),
  codex stays byte-identical, local-mlx gets a deliberately off-roster label so an
  opted-in eval verdict can never pass the prod roster check.
2026-07-02 00:23:32 -04:00
boshu dbbcbde1b8 feat(gates): preamble ratchet — new scripts must source the hardened preamble, grandfathered tree only shrinks (age-gate-the-ungated-egwt.10)
Advisory-first rollout, deliberately: shell.preamble-ratchet seeds Blocking:false
for ONE clean cycle on main, then flips Blocking — the same staged pattern the
epic already landed for docs.cli-snippets (egwt.4) and docs.demoted-claims
(egwt.6), recorded in the RepairHint. The backing check itself is fail-closed
(exit 1) on every violation class:

- new/changed top-level scripts/*.sh must source scripts/lib/preamble.sh or
  carry a non-empty '# preamble-exempt: <reason>' (empty reason rejected)
- grandfather authority = base-ref ∩ working snapshot, so appending an entry in
  the same diff grants nothing (both halves fail independently)
- the snapshot is shrink-only vs. its base-ref version; only the initial
  snapshot commit may introduce it
- scripts/lib/** exempt as a class (sourced libs, not entrypoints)

Also folds with_tmpdir (trap-EXIT mktemp cleanup, ~79 re-rolls) and require_cmd
(command -v + install-hint die, ~62 re-rolls) into the preamble; 18 preamble
bats + 10 ratchet bats.
2026-07-01 19:07:52 -04:00
boshu 322d419572 feat(ci): verdict backstop — report-only tip-verdict verification reusing the pre-push waiver (age-wedge-all-in-dyr0.9) 2026-07-01 19:01:41 -04:00
boshu 55186e5460 refactor(scripts): codex-exec lib — one fail-closed hardened runner, migrate all non-pawl callers (age-gate-the-ungated-egwt.8) 2026-07-01 18:39:34 -04:00
boshu b7503b4519 feat(gates): docs.cli-snippets gate — resolve ao commands in live docs against the cobra tree (age-gate-the-ungated-egwt.4) 2026-07-01 18:07:41 -04:00
boshu 38aa215222 feat(gates): extract docs-scope lib — shared live-doc resolution + banner exemption (age-gate-the-ungated-egwt.1) 2026-07-01 17:18:17 -04:00
boshu 0096a050c3 refactor(skills): demote evolve/autodev/acfs to a new experimental tier (age-focus-membrane-bookkeeper-m1wg.21)
Heavy legacy RPI chains with no measured uplift. Add a new `experimental` tier
and demote the three. The tier value is registered at ALL FOUR enum sites — the
authoritative schemas/skill-frontmatter.v1.schema.json (enforced by the blocking
skill.manifests gate), validate-skill-schema.sh, sku_catalog.py, and
generate-registry.sh — plus a Tier Values row in SKILL-TIERS.md. Frontmatter
metadata.tier and the SKILL-TIERS row cell flipped in lockstep for all three.

acfs is demoted, NOT cut: its cut is external (~/acfs) and a deferred operator
one-way-door decision (noted in the disposition ledger). Codex twins refreshed
by regen (not dropped — .18 owns twin cuts). registry drift, manifests schema,
sku-catalog, sync-counts all green; go build + internal tests pass.
2026-07-01 00:08:34 -04:00
boshu 974f351d6f feat(scripts): add scripts/lib/preamble.sh — strict-mode + REPO_ROOT + portable stat/find (age-0dq9.1)
Sourced library centralizing two recurring portability hazards (recon P6a):
the macOS find->bfs shim (-printf support diverges from real /usr/bin/find) and
stat -f %m (BSD) vs stat -c %Y (GNU). Provides strict mode, REPO_ROOT (git
toplevel + non-git fallback), portable_mtime, portable_find (real system find),
newest_by_mtime (global sort, not find-exec-ls), newest_in_dir. Additive only —
callers migrate in P6b (deferred). bats covers the real-find path + proves
portable_find bypasses a broken PATH find; shellcheck -S error clean.

Closes age-0dq9.1
2026-06-25 20:56:17 -04:00
Boden Fuller cf90ec392a feat(skills): consolidate beads 4->2 — retire beads umbrella, fold lifecycle doctrine into beads-br (ag-ez7y6 #beads-consolidate-4to2)
Salvaged the uncommitted work from wt-ag-ez7y6 and completed the 4->2 beads
skill consolidation the salvaged test asserts:

- Fold the "Issue-Lifecycle Discipline" doctrine (live-reads-authoritative,
  scoped-closure-proof, parent-reconciliation, narrow-the-umbrella-issue,
  normalize-stale-queue) from the retired `beads` umbrella into beads-br.
- Retire skills/beads --into beads-br via `ao skills retire` (trees removed,
  ledger row moved to historical: merged-into beads-br).
- Re-target every retired-skill reference: crank/implement/plan/post-mortem/
  refactor frontmatter+deps, SKILL-TIERS rows, docs/SKILLS.md, GLOSSARY link,
  sku_catalog LOOP_MOVES[2], image manifests (counts adjusted).
- Codex twin: mirror the doctrine into skills-codex/beads-br, prune `beads` from
  the codex catalog/manifest, regen hashes (parity gate age-yxl).
- Add cli/cmd/ao/beads_consolidation_test.go (L2 structural invariants). Uses a
  leak-proof repo-root finder (skills/+docs/contracts/) because the shared
  findRepoRoot keys on .agents/, which the cmd/ao suite leaks into the pkg dir.

Fixed an ao-skills-retire bug surfaced here: the historical row was appended at
the end of the `workflows:` section (between historical: and dispositions:)
instead of inside historical:. Corrected manually; full fix tracked separately.

Bounded-context: BC3-Loop
Evidence: cli/cmd/ao/beads_consolidation_test.go

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-16 23:42:28 -04:00
Boden Fuller 692f420ac3 feat(contracts): additive artifact-classification schema + BC6 Orchestration (ag-4akl8 #backfilled-fields)
S0 foundation slice (v4 additive, no-rename — quorum-ratified). Adds the
artifact-classification fields to every active `- skill:` row + workflows entry
and introduces BC6 Orchestration, without renaming the ledger file, the
`- skill:` row key, or the `domain: "BCn Name"` string format.

- skill-dispositions.yaml: backfill kind/runtime_targets/parity_policy/
  capability_class/path/aliases/supersedes on all 71 active rows + 4 workflows;
  re-bin the 6 orchestration skills (ntm/swarm/agent-mail/using-atm/
  vibing-with-ntm/continuity-loop) into BC6.
- bounded-contexts.yaml: add BC6 Orchestration + OrchestrationPort.
- sku_catalog.py: BC6 enum + cli-command-per-BC carve-out (require >=1 active
  artifact per BC; cli coverage only where a BC owns commands).
- generate-registry.sh: emit the new fields (+ derived runtime_reach) and a
  first-class `workflows` surface.
- generate-skill-domain-map.sh / check-bounded-contexts-drift.sh: BC-count
  sites 5->6; both registry docs carry BC6.
- new gate validate-skill-disposition-schema.sh (+ bats) rejects unknown
  kind/capability_class and missing fields, naming the offending row; wired into
  regen-all, pre-push-gate, and the Go gate registry.

Renamed-consumer parsers (resolve-skill-path.sh, skills_retire.go, heal.sh) and
the `- skill:` fixtures are byte-untouched.

Closes-scenario: ag-4akl8#backfilled-fields-preserve-the-skill-count
Bounded-context: BC4-Factory
Evidence: docs/contracts/skill-dispositions.yaml

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-13 13:19:19 -04:00
Boden Fuller 85b7b97b1d fix(scripts): validators resolve skill paths via dispositions ledger (ag-2vz5v)
Shared scripts/lib/resolve-skill-path.sh routes skills/<slug>/ and
skills-codex/<slug>/ paths through the historical: section of
docs/contracts/skill-dispositions.yaml: merged-into rewrites the slug
segment to the target, cut skips visibly (stderr warn), no row / unknown
slug / missing ledger degrade to identity. Exact-slug awk parse (plan does
not match plan-foundry). The 4 validators that hardcoded skill paths
(rpi-contract, lifecycle-guards, cold-start, pre-push-gate) route their
fixed entries through it so folds/cuts auto-retarget instead of needing
hand-repointing. Identity-preserving on the current repo (no historical row
matches any routed active skill): 3 standalone validators byte-identical
before/after; 16 bats incl. 4 validator-integration cases.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-12 23:27:43 -04:00
Bo 092b99dad9 feat(skills): add skill-eval.sh ms-backed quality gate (ag-yzoz #skill-eval) (#726)
## What

Adds `scripts/skill-eval.sh` — a thin gate that runs one skill's
`SKILL.md` through Jeff Emanuel's `ms` (meta_skill) `lint` + `validate`.
The wrapper decides the gate purely on whether a **blocking** `rule_id`
appears (ms's own severity/exit is not trusted):

- Blocking: `no-secrets`, `no-injection`, `safe-paths`,
`required-metadata`, `no-cycle`, `valid-version` → non-zero exit.
- Everything else → annotated only (`::warning::`), never fails.
- `ms` not on PATH (or `MS_BIN` missing) → **loud `::error::` hard-fail
(exit 3)**, never skip-and-pass — a silent skip would recreate the
no-evaluation gap this gate closes.

Planted `skills/_fixtures/{bad,good}-skill/SKILL.md` fixtures +
`tests/scripts/skill-eval.bats` (10 tests) exercise the
bad/good/ms-absent contracts.

## Fixture scoping

`skills/_fixtures/` is non-skill scaffolding (planted fixtures). The
skill-enumerating gates/generators are taught to skip `skills/_*` so the
fixtures never inflate the skill count (stays 82) or fail registry /
schema / wiring / runtime / count gates. Touched enumerators:
`generate-registry`, `validate-skill-schema`, `sync-skill-counts`,
`validate-skill-count`, `generate-skill-catalog`,
`generate-context-map`, `validate-manifests`, `check-wiring-closure`,
`validate-headless-runtime-skills`, `lib/sku_catalog.py`,
`check-alias-collisions`, `run-all`, `test-runtime-opencode-smoke`,
`release-smoke-test`, `smoke-test`, `validate-skill`.

Does **not** touch `validate.yml` — wiring skill-eval.sh into CI is a
separate bead.

Epic: ag-czzf

## Verification

- `bats tests/scripts/skill-eval.bats` → 10/10 pass (ms 0.1.2 on PATH)
- `shellcheck scripts/skill-eval.sh` → clean
- `check-registry-drift`, `validate-skill-schema`, `sync-skill-counts`,
`run-all`, opencode-smoke → all PASS with fixtures present, skill count
= 82 (fixtures excluded)

Closes-scenario: ag-yzoz#skill-eval
Bounded-context: BC2-Validation
Evidence: scripts/skill-eval.sh

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
2026-06-04 16:38:57 -04:00
Bo e90d6d79f9 feat(registry): SKU capability catalog (schema v2) — generated skill×command×BC join (ag-cbm) (#525)
## What

Extends `registry.json` into a **generated SKU capability catalog**
(schema_version 2) — the flagship 3.0 inventory feature. It is a 4th
DERIVED projection (alongside DDD-vocab / Hex-frontmatter /
Gherkin-acceptance), a JOIN of existing sources — **never
hand-authored** (repo bans hand-edited inventory maps). Oracle-validated
design: `.agents/discovery/2026-05-24-capability-inventory-and-gaps.md`.

## Catalog

214 SKU entries: **81 skills + 66 cli-commands + 64 gates + 3
reference-impls**. Each entry: `sku` (stable id), `name`, `type`,
`bounded_context`, `hex_role`, `tier`, `purpose`, `status` (active |
deprecated | planned | alias-of:&lt;sku&gt;), `disposition`, `consumes`,
`produces`, `drives_commands`, `driven_by_skills`.

`registry.json` schema v2 is a strict **superset** of v1 — existing
`summary`/`surfaces`/`cadence_recommendations` consumers (the Go `ao
registry` command) keep working; new
`capabilities`/`capability_summary`/`cli_top_level_commands` blocks are
added.

## The join key — `drives_commands`

Derived from each skill **BODY** (SKILL.md + `references/*`), resolved
against the live cobra tree (`scripts/lib/sku_extract.py`). Stale refs
that resolve to nothing (e.g. the removed `ao schedule`) never become
edges. `driven_by_skills` is the cmd→skill reverse. This closes oracle
gap #1 (no skill↔command linkage anywhere).

## New gate — `validate-sku-catalog-drift`

Three required checks: **(a) drift** (regenerate + diff), **(b) linkage
integrity** (every `drives_commands` edge resolves to a real `ao`
command — closes gaps #1/#2/#3), **(c) coverage** (every BC + every
operating-loop move has an active skill; every BC has a cli-command).
Wired into `validate.yml` + the verdict aggregator.

## Stale refs fixed

`ao schedule` in `skills/crank` + `skills/rpi` best-practices and
`agentopsd` in `skills/swarm` shared-checkout-discipline → reframed to
the hookless / out-of-session (cron-driven `ao rpi`/`ao evolve` via Gas
City) model. Disjoint from PR #524 (which fixed the hooks/inject refs);
rebased on it — `validate-skill-cli-snippets.sh` is now 0.

## Retired

The bogus "163 cli_commands" count (Go-file count, oracle gap #6) → **66
real top-level cobra nodes** from the live tree.

## Gates (all green locally)

registry-check · validate-sku-catalog-drift (3/3) ·
validate-context-map-drift · skill-domain-map-golden ·
bounded-contexts-drift · codex-parity-drift · regen-codex-hashes --check
· contract-compatibility (sku-catalog.md catalogued) · doc-release ·
validate-skill-cli-snippets (0) · skill-frontmatter · heal --strict ·
markdownlint (0) · shellcheck (0 errors) · mkdocs --strict · `go test
./cmd/ao` (9207) · new bats suite (5/5).

Closes-scenario: ag-cbm#sku-catalog
Bounded-context: BC1-Corpus
Evidence: .agents/discovery/2026-05-24-capability-inventory-and-gaps.md
2026-05-24 20:47:04 -04:00