Commit Graph

27 Commits

Author SHA1 Message Date
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