## What
The 3.3 GC pack flow becomes Gas City's native human door, drivable by
humans and agents alike (operator decision). Five commits:
1. **a903c23f8** `feat(gc)`: Mayor prompt rewritten observe-only →
**shepherd** — polls external rigs' ready step beads and dispatches each
via `gc sling <gc.run_target> <bead> --nudge`. Never claims, never
authors, never closes.
2. **e58aeb5cb** `feat(gc)`: `invoke.sh mayor start|status|tell` — the
agent control surface over native primitives (`gc session wake`, `gc
session list --json`, `gc mail send --notify`; mail chosen over
sling-text to avoid v1.3.5's inline-text auto-create). Mayor is now a
`mode=always` standing session.
3. **bd8c34df6** `docs(gc)`: README — two doors (human attaches, agent
drives via mail), heartbeat propulsion, #4586 context.
4. **2b6ffe9cf** `feat(gc)`: `skills/using-gc` rewritten as the
mayor-orchestration skill (drive loop, bead-ids-only doctrine, GC
liveness truth stack with both codex wedge classes, stall protocol) +
all regenerated projections.
5. **362f4af79** `fix(gc)` (cross-family review: 1 BLOCKER + 5 MAJORs,
all fixed): **shepherd-heartbeat order** (native `gc order`, 3m cooldown
— mode=always keeps the Mayor resident but nothing re-prompts it; the
order is the liveness engine); HQ filtered from rig enumeration; stall
recovery = `session wake` (re-sling documented as a no-op for routed
beads); `mayor status` tri-state fail-closed; mail authority limited to
dispatch/status with bodies treated as untrusted data (pause/resume
dropped — stateless under fresh wake); test stubs reject non-allowlisted
verbs.
## Why
On v1.3.5, demand-driven worker spawning never fires for rig-routed work
(upstream gastownhall/gascity#4586, ours, with a stock-pack no-LLM
repro). Shepherd-dispatch by a standing Mayor is both the
v1.3.5-functional propulsion path AND the stock-GC operating pattern
(their mayor prompt: create → sling bead-id → monitor) — so this flow
survives the upstream fix rather than fighting it. Intent stays
caller-owned: drivers hand the Mayor bead IDs, never prose work.
## Verification
- `tests.python.test_gc33_thin_pack`: 34 passed (2 integration-gated
skips)
- `shellcheck -S warning` + `bash -n` clean; `scripts/regen-all.sh
--check`: all 11 projections current
- Every gc primitive verified against v1.3.5 source (cmd_mail.go,
cmd_session_wake.go, cmd_sling.go, cmd_rig.go, decode_sessions.go,
orderdiscovery)
- Codex adversarial review round: all findings fixed
- **Not yet proven live**: heartbeat-order discovery/scheduling,
mode=always residency, wake-based recovery, end-to-end propulsion — the
live canary follows this merge.
## Why
Verified against GC v1.3.5 source + docs: the stock Mayor **dispatches
and never claims** (mayor.md prompt, swarm example, reference
mayor-dispatch.sh); the blessed single-bead intake is `gc sling
<rig>/<agent> <bead> --on <formula>`, with claims happening rig-scoped —
the byte-for-byte unchanged-safe path on v1.3.5. Our pack inverted this
by slinging to the city-scoped `agentops.mayor`, which is exactly (and
only) the shape that hits the v1.3.5 cross-store claim defect. This
aligns intake with the official pattern: the loop works on official
v1.3.5 binaries, beads stay rig-homed and git-synced.
## What
1. **4f31a35e6** `fix(gc)`: `invoke.sh feed` slings to
`<rig>/agentops.plan-reviewer --on agentops-experiment` with rig-scoped
role vars; new `invoke.sh create` writes the work bead into the rig
store via the pinned bd against the managed Dolt server; Mayor demoted
to optional observe-only coordinator (explicit do-not-claim); refiner
rework path re-pointed off the Mayor. Static proof: zero
`agentops.mayor` routing left; the only executable sling targets the rig
role.
2. **e766d05a5** `docs(gc)`: README default flow = create → feed →
observe → refine → teardown on the official pattern; cross-store claim
bug demoted to "not exercised by the default flow"; preview label +
promotion criteria unchanged.
3. **ae7664496** `fix(gc)` (from cross-family review — 1 BLOCKER + 4
MAJORs, all fixed): executable provenance anchored to the pack's own
lock/receipt chain instead of the mutable marker; re-bootstrap now
detects stale toolchain paths/digests; feed verifies the bead exists
exactly before sling (v1.3.5 `gc sling` auto-creates a task from unknown
text — a typo would have dispatched garbage); Mayor observe surface uses
`gc rig list` + per-rig `gc bd --rig N ready/blocked` (bare city reads
miss rig work); test stubs record exact argv under space-containing
paths, guards proven to bite.
## Verification
- `tests.python.test_gc33_thin_pack`: 23 run, OK (2 integration skips —
need booted city)
- `shellcheck -S warning deploy/gc/*.sh`: clean; `bash -n` all scripts
- Codex adversarial review round: all findings fixed
- **Not yet proven live**: the full booted-city flow (`--nudge` wake,
formula execution, refine landing). That is the immediate next phase — a
dogfood run sending the RPI human-summary bead through a real city on
official v1.3.5.
## What
Three commits executing the official-artifacts-only GC pack release
path:
1. **c07d10d66** `fix(gc)`: `materialize-toolchain.sh` now downloads the
official gastownhall/gascity v1.3.5 and steveyegge/beads v1.1.0 release
archives instead of compiling from source. Fail-closed verification
chain: lock-pinned sha256 of the official checksums asset → archive
sha256 against the verified checksums file → installed binary must
report the locked version/commit. Users need curl+tar+shasum; no
git/make/compiler. Offline test mode via `AGENTOPS_GC_ARCHIVE_CACHE`
with the identical verification path.
2. **95e83f8d8** `docs(gc)`: README labels the pack **preview** and
discloses the two v1.3.5 upstream defects: the default automated
feed→claim loop fails deterministically (city-scoped Mayor claims a
rig-fed bead against the city store → `bead not found`; fixed upstream
in a135117945e2/3fa9bb38e916, arrives at the next official release) and
the rare tmux teardown hang (upstream PR gastownhall/gascity#3985).
Preview → supported after the next official pin bump, deterministic
qualification, and one clean canary.
3. **0318a2429** `test(gc)`: negative tests proving the binary
version/commit binding fails closed (added after cross-family review
found the guard untested; verified the tests fail when the guard is
neutered).
## Verification
- `python3 -m unittest tests.python.test_gc33_thin_pack`: 17 tests, 15
pass + 2 integration skips (need materialized GC_BIN)
- Live network run: downloaded, checksum-verified, and version-bound
both official binaries (gc 1.3.5 @ 8ffc009d…, bd 1.1.0 @ 8e4e59d39…)
- `shellcheck -S warning deploy/gc/*.sh` clean
- Cross-family (Codex) adversarial review: 1 MAJOR found → fixed in
commit 3; no fail-open findings in the verification chain
## Scope
`deploy/gc/materialize-toolchain.sh`, `deploy/gc/README.md`,
`tests/python/test_gc33_thin_pack.py` only. No fork artifacts, no lock
change — pin stays official v1.3.5.
## Outcome
Repairs the single lifecycle boundary exposed by the first post-merge
AgentOps Gas City canary.
- Exports the exact marker/toolchain-bound `GC_BIN` from bootstrap,
invoke, and teardown before official GC behavior.
- Uses official `gc stop --force`, then stops the private supervisor.
- Waits up to the declared timeout for processes scoped to the exact
canonical city root to drain.
- Reports the exact remaining process rows on timeout.
No GC/BD fork change, role/formula/model change, new daemon, or
live-city repair is included.
## Evidence
- Focused regressions: 2/2 passed.
- ShellCheck warning severity: passed.
- Thin-pack gate against pinned GC: 11 tests passed, 2 expected skips.
- Exact pinned native integration: 11/11 passed in 115.638s.
- Subject manifest:
`3d9a7816ed6807f843fd805e0462a16ff9589eb9a3a0b572da4d4039d5ed319a`.
- Fresh Sol-high verdict: PASS,
`230bd8e56d29bcf926ef772b749d1fb9c1f7550a92ccb6f6653630ddfdad1c4c`.
- Validated candidate head: `fe5a1248fa9eaa97aa6bc97f86d551c5bdbbd66c`.
## Release boundary
Hosted CI and one wholly fresh terminal mixed-provider canary remain
required after this repair merges. There will be no third canary or
in-city repair loop.
## Outcome
Ships AgentOps 3.3 as a thin native Gas City pack and removes the
accidental second orchestration control plane.
- Removes the custom GC delivery command/package, packet/schema family,
feeder/program engine, reducer/order, reliability registry, Beads
capability mirror, and fork-baseline runtime checks (about 29k deleted
lines).
- Retains six bounded adapters for pinned toolchain materialization,
clean bootstrap, native sling/status/doctor invocation, bead-isolated
worktrees, moving-main PR delivery, and teardown.
- Uses official Gas City and Beads behavior as the state owners, with
required OTEL configuration.
- Preserves Fable Mayor/Refiner, Sol-high planning and fresh validation,
Terra-high default implementation, Opus-medium overflow, and
support-only Luna.
- Supports automatic Refiner merge after hosted CI or a manual-review
toggle without locking `main`.
## Evidence
- Exact official GC: `8ffc009ded781a2ada2077f3a29bd712b2def0bf`
- Exact official BD: `8e4e59d39f3459a43cf21a3236a13eca4dd874f7`
- Full pinned native boundary: 9/9 passed in 114.047s
- Exact source-bead route replay: passed in 98.051s
- Release replay: manifest integrity, thin tests and both pack lints,
generated projections, contract compatibility, Bats contract,
ShellCheck, test-removal ratchet, and `go test ./...` all passed
- Fresh independent semantic verdict: PASS (Sol-high)
- Exact delivered head: `e805f0e26ce21c2eae9e720f57fff2a705f3185b`
- Subject manifest:
`8554d065076f70d0e639ca353409d2a75dca7ac01e4cb65cb4a118e98c0770fc`
- Verdict:
`3f89376b675de854832f38b46ccfa7ad7ca54079ffde578769c33e1f118c68c1`
## Release boundary
After this PR merges, the release qualification runs one fresh mixed
Terra/Opus canary from merged `main`, with at most one external repair
and one terminal retry. No live city repairs itself.
The only known local fast-gate exception is `workflow.install-drift`:
the installed workflow symlink resolves to the separate dirty primary
checkout, outside this candidate. All candidate-owned gates passed.
## Summary
- keep the city dispatcher and non-primary rig dispatchers suspended
- activate exactly the selected primary rig dispatcher
- seal Formula control records to that dispatcher before admission and
fail closed on malformed or foreign bindings
- verify the effective official GC agent inventory during bootstrap
## Evidence
- fresh Sol-high pre-delivery binding verdict: PASS
- candidate diff digest:
c7362c701f417e259194b97572734aed18ebc022f17abcd907681926f9db6fc2
- Python workflow tests: 18/18
- bootstrap Bats: 30/30
- GC executor gate: PASS
- full local release gate: PASS
- two fresh official GC v1.3.5 / BD v1.1.0 zero-model qualifications:
PASS
## Residual
Stable GC teardown sometimes leaves its private tmux session after gc
stop. Qualification cleanup was scoped and reached zero processes; this
upstream-owned residual is disclosed and is not changed here. The
post-merge mixed-provider canary remains a separate release gate.
## Summary
- bind Formula cook to concrete targets derived from the digest-bound
native rig
- decode Gas City v1.3.5's exact relative Ralph-attempt refs into
canonical AgentOps workflow keys
- fail closed on root, control, source-spec, attempt, route, replay, and
custom factory-binding drift
- retain official GC v1.3.5 and Beads v1.1.0 unchanged
## Why
The fifth release canary correctly stopped before model launch because
`rig/agentops.plan-reviewer` was not a valid Formula target. Exact
official qualification then exposed a second AgentOps assumption: stable
GC persists top-level Ralph attempt refs as `mayor.iteration.1`,
`plan.iteration.1`, `implement.iteration.1`, and `validate.iteration.1`,
while AgentOps had expected formula-qualified values.
This change supplies sealed concrete routes to the pinned stable release
and uses explicit one-to-one persisted-to-canonical maps. It does not
patch or depend on an unreleased Gas City/Beads fork.
## Evidence
- candidate: `21cbd7693819ae047d4ce3da4f95ef9453e2e80a`
- tree: `ede2b444217be5c8e2aa19bf5af81d231b70b360`
- official GC: `8ffc009ded781a2ada2077f3a29bd712b2def0bf` (v1.3.5)
- official BD: `8e4e59d39f3459a43cf21a3236a13eca4dd874f7` (v1.1.0)
- two fresh configured-not-started roots passed independently:
- route-fixture-g: build `rfg-bq0`, Terra `rfg-plb`, Opus `rfg-cio`
- route-fixture-h: build `rfh-eez`, Terra `rfh-86h`, Opus `rfh-jgc`
- both roots had zero sessions, zero running agents, clean Git, and
clean managed teardown
- fresh Sol-high binding verdict: PASS; file SHA-256
`0c9b14bcd0f04d782f67f815c029b267224a554a445c5d2a25feadac881d2e10`
## Checks
- `bash scripts/check-gc-executor.sh`
- 41 packet tests
- 41 GC 3.3 tests
- 4 projection tests
- 35 bootstrap Bats tests
- static contract PASS
- `bash scripts/ci-local-release.sh`
- LOCAL CI PASS in 89s
- race, security, SBOM, release binary, smoke, install, and contract
gates passed
- advisory readiness is 7 only because HIL is intentionally deferred to
the one post-merge mixed-provider canary
## Delivery boundary
The final required-telemetry mixed-provider canary will run once from
merged `main`. These stopped and qualification-only roots will not be
replayed.
## Summary
- bind the GC 3.3 bead-native workflow: Fable Mayor, fresh Sol-high plan
and validation, Terra-high default or Opus-medium overflow
implementation, Luna support-only
- add the bounded one-shot graph feeder, strict packet/worktree
identity, semantic terminalization, and model-free protected delivery
sweep
- make official Gas City v1.3.5 plus Beads v1.1.0 bootstrap repeatable,
disable unstable event propulsion/hooks, and prove quiescent teardown
## Reliability boundaries
- no Gas City self-repair loop, daemon, private scheduler, model
fallback, or main mutex
- semantic completion is independent of delivery; protected
PR/CI/rebase/merge is deterministic and moving-main aware
- event hooks are disabled because 3.3 uses explicit program admission
and cooldown delivery; native controller bead observation remains active
## Evidence
- full local release CI PASS at
.agents/releases/local-ci/20260722T113355Z
- two pristine standalone-clone cycles with official GC v1.3.5 8ffc009d
and BD v1.1.0 8e4e59d: repeat bootstrap, exact rig Dolt context, absent
event hooks, bounded events, enabled sealed delivery, and delayed
zero-process teardown
- fresh independent Sol-high pre-delivery binding PASS over exact head
e8c1253b40
- binding verdict SHA-256:
4f8d81811cd5b2eb35159c98159db2f8917d3ef54167f3c0d59d8378de14b2d1
## Tracker
Beads: age-gc-scope-failclosed-release-gktia.2
The one bounded mixed-provider live canary remains a post-merge release
gate; this PR does not claim final 3.3 release readiness before that
proof.
## Summary
- replace the unreachable Python factory lifecycle with an optional
typed Go delivery reducer
- make Beads the delivery lifecycle authority with deterministic
moving-main successor epochs
- add native Git/worktree, PR, hosted-check, auto-merge, landing, and
cold-replay boundaries
- retire obsolete v1 role/factory schemas and preserve the pinned
historical capability harness
## Validation
- fresh Sol-high PASS over exact 43-path manifest
ec6a2a4bf0b180782411b1ae4afd4a2ad8384129ff037ce8c119480317626b02
- go test ./...
- go test -race ./internal/gcadapter/delivery
- go vet ./...
- scripts/check-gc-executor.sh
- GC 3.3 schema, migration, provenance, factory-doctor, and bootstrap
gates
Bead: age-gc-scope-failclosed-release-gktia.1
## Outcome
Adds the bounded GC33-6 delivery slice outside core ao: a separately
built crash-only reducer, strict admission certificate binding,
immutable handoff and branch/PR receipts, native graph.v2 formulas,
one-step disabled Order glue, and one centralized stock claim wrapper.
Semantic bead: ag-agentops-33-gc-refinery-4km81.7 (closed after
independent validation).
Binding PASS:
d3ac5a566e0f5197814e2dbcf04d0540849f58636ed8bb49a0faca7d6af94639 over
manifest
155a089b4b461bda61a7f1ad1987c66f5755ac7c5628aa648e70740be2580a5a.
## Verification
- Full cli Go suite: PASS (2,887 tests)
- Focused race-enabled reducer suite: PASS
- GC factory/executor Python contracts: PASS
- Full executor gate: PASS (123 Python + 25 Bats)
- Exact official GC v1.3.5 pack lint and no-start discovery: PASS
- Cold replay: exactly one delivery, branch, and PR; six emitted
artifacts validate against shipped schemas
- Production Go surface: 922 lines, under 3,000 tripwire
## Boundaries
No ao command, core port, default install, live city, real
Git/forge/CI/merge adapter, daemon, scheduler, or factory.py import.
Real adapters and delivery completion remain GC33-7.
Bead: ag-agentops-33-gc-refinery-4km81.5\n\nThis delivers the GC33-4
deterministic proof kernel without starting Gas City or adding a second
agentic loop.\n\nWhat changed:\n- width-two per-bead lease and candidate
isolation, with overlap serialization and no main/global mutex\n- exact
candidate Git/worktree/index auditing and bounded PGID-scoped process
receipts\n- Draft 2020-12 typed delivery/ambiguity publication with
exhaustive construction-state routing\n- composed six-role native
query/sling firewall executed by factory doctor\n- fake-store-derived
loss, duplicate, expiry, and replay evidence\n- live Fable remains
closed pending supported confinement and GC33-11\n\nFresh Sol-high
binding evidence:\n- exact subject manifest:
9ec940be7b528fe9ed2181830d2261424af1865c2c4b9793d7f2c68158845790\n-
verdict.v2:
ef985788f1b28c66397a28e55e57cbaac620a51bdfad745812bcfe141df847f9\n- 8 of
8 criteria PASS, zero findings\n\nLocal gates:\n- 67 focused Python
tests\n- 25 of 25 bootstrap Bats cases\n- factory doctor\n- Python and
shell syntax\n- diff hygiene
## Outcome
Defines the GC 3.3 factory as one semantic intelligence loop with
deterministic delivery:
- Fable Mayor plus a bounded, nonbinding ambiguity adviser
- Sol-high for plan binding and fresh exact-subject validation
- Terra-high as the default writer and Opus 4.8 medium as explicit
overflow/repair
- Luna dormant and unroutable until later qualification
- no model-driven delivery-policy/refinery loop
- native GC sling/claim/scale-from-zero semantics retained
- exact provider/model/reasoning/fallback runtime attestation
- legacy composed program/refinery entry points and opposite-provider
lifecycle roles removed
Controller dispatch to the Fable adviser stays fail-closed until GC33-4
proves process/filesystem isolation. This does not claim that manual
operator sling to the named on-demand target is impossible.
## Evidence
Fresh Sol-high `verdict.v2`: PASS
(`bb31806fc5e0714363a9e539121ee7aa19231431fb04ddfee1fce8376b57d272`)
over subject manifest
`119b7a6db2380af47d87a24aced60d96858dd9e413a54dc640376e27767e8d1e` (52
paths, 18 deletions).
- focused acceptance: 124 tests PASS
- projection owner: 4 tests PASS
- bootstrap fixtures: 25 Bats tests PASS
- complete GC static contract: PASS
- factory/executor doctors: PASS
- generated projection check: PASS
- exact official GC v1.3.5 and Beads v1.1.0 provenance replay: PASS
- `git diff --check`: PASS
No city, model session, supervisor, tmux session, Dolt server, or canary
was started for this pre-canary bead.
## Summary
- freeze the dueled AgentOps 3.3 Gas City architecture and separate the
3.3.1 observability/tuning plan
- add the GC33-0 machine-readable inventory, strict cleanup admission,
Git audit, fork provenance, and known-error ownership contracts
- mirror the Gas City fork main to exact official upstream and retain
only the open upstream contribution branch
- keep the suspended v17 city and all ambiguous external state untouched
## Evidence
- 33 focused reliability tests pass
- Ruff and git diff checks pass
- inventory digest:
26f0ef04ae80fcb5a39bb2564ffcb8e69573d187cfef75a49f79f36850fb0b04
- known-error registry: 23 entries, digest
6faadb254fb29ed6a1024ef7de577be5bc9200e7269835e9a5690245629ccf4f
- fork manifest digest:
de00833a7df3a8086a37d2d60e8c27f2bbd3e71acfbde1d4d2695072facb9008
- fresh Sol/high binding verdict: PASS, digest
052b84cbb2ddc42a9832bc9f95eaa915627c142f5493f0ae4317d91e9ef7784f
The full Gas City local suite was intentionally not replayed after its
exact official-main tree produced unrelated environment/timing failures;
the tested subject and digest-bound reuse are recorded explicitly in
deploy/gc/fork-baseline.json.
## Summary
- pin and materialize an exact colocated Gas City and official Beads
toolchain without editing installed binaries
- add deterministic isolated bootstrap, recovery, teardown, exact
workspace binding, and tracked .gitignore preservation
- add bead-native Mayor, plan review, isolated Codex/Claude workers,
binding Validators, rejection-to-Mayor rescope, fenced Refinery,
integration validation, qualification, and protected PR delivery
- make the local quick release gate deterministic after CLI cleanup
## Validation
- fresh GC-managed Codex Sol verdict: PASS (verdict
d1a1e03808b4605e49cc97423c7570b04d581c9ee1fad9aa8f1daf6e72d6f0ef)
- focused GC executor/factory/projection suite: PASS (32 packet + 77
factory + 4 projection + 21 bootstrap tests, plus doctors and static
contracts)
- teardown suite: 7/7 PASS
- local-ci-fast: PASS
- exact v16 mixed-provider live canary: Terra and Opus 4.8 workers in
parallel, opposite-family candidate validators, Opus Refiner, Sol
integration validator, all lifecycle beads closed, clean managed
teardown
## Scope
The follow-on Fable 5 Mayor/Refiner, Sol-every-bead validation, and Luna
support-worker topology is deliberately not part of this historical v16
baseline; it will build on this foundation in a separate bead program.
## Summary
- add a bead-native Gas City factory pack with Mayor, fresh plan review,
Codex/Claude Worker and Validator pools, and a fenced Refiner
- make the bead graph the sole work/lifecycle authority; JSON artifacts
are digest-bound evidence only
- isolate each experiment in its own branch, worktree, Git index, and
lease, then admit exact PASSed candidates to Refinery
- make lease, verdict, rejection, successor, assembly, reassembly, PR
landing, and partial closure transitions crash-replayable
- enforce fresh-worker rescope after FAIL/NOT_PROVEN and an atomic
max-attempt HOLD
- encode the operating contract, live canary, role archaeology, and Bun
Rust-port lessons in AgentOps docs
## Validation
- live GC canary: Claude Worker -> Codex Validator -> Claude integration
Validator -> Codex Refiner -> PR #916 -> landed
`b80a752aad3843af66160b08a823aaed57e07169`
- `./scripts/check-gc-executor.sh`: 20 packet tests, 29 factory tests, 4
projection tests, and 8 bootstrap Bats tests PASS
- both GC packs lint PASS
- Ruff, ShellCheck, Python compile, and generated projection checks PASS
- branch-built `ao gate check --fast`: 13/13 PASS
- branch-built `ao gate check --full`: 66/66 PASS
- independent fresh-context audit of exact head
`1b18cf663ece790a12cd840f6eed2856852c552f`: PASS
## Contract
The unit of work is the bead. The pack defines roles, prompts, commands,
and policy; it does not own a parallel pack/JSON lifecycle. A rejected
experiment must be terminal and closed before any Mayor rescope or
successor reduction can proceed.
- post-mortem + handoff: optional 'ms outcome <skill> --success|--failure'
closing step (conditional on command -v ms; graceful skip, no hard dep) +
mirrored to skills-codex twins (parity_required) with regen'd hashes.
- scripts/ms-adoption-probe.py: read-only probe counting ms-search vs
hand-grep events over ~/.claude/projects transcripts; unit test with a
real-transcript-derived fixture; baseline committed to docs/evals/.
Bandit finding (consume-don't-build): ms outcome rows are WRITE-ONLY w.r.t.
ranking; recorded as an upstream feature note.
## Summary
Adds a `--probe "<phrase>"` mode to
`skills/skill-builder/scripts/scan_descriptions.py` that ranks every
skill against a lexical trigger phrase **deterministically** (no live
model, byte-stable output). Introduces an optional `trigger_probes:`
skill-frontmatter field so a skill can self-declare phrases it must rank
#1 for; the probe asserts the declaring skill wins its own phrases
against the corpus.
Epic: ag-czzf.
**INFORMATIONAL-only tooling — not a blocking gate.** The probe is a
self-check authors can run; no CI gate is wired to it.
## Changes
- `skills/skill-builder/scripts/scan_descriptions.py` — `--probe` ranker
+ `trigger_probes` parser (flow + block YAML forms).
- `schemas/skill-frontmatter.v2.schema.json` — optional `trigger_probes`
array field.
- `tests/scripts/scan-descriptions-probe.bats` — 4 scenarios (rank-#1,
determinism, demotion-on-mutation, usage-error exit codes).
## Validation
- New bats suite: 4/4 pass.
- `scripts/pre-push-gate.sh` reds are pre-existing main-red
(context-packet-ab canary + its downstream pre-push-gate-governance
nested bats), not caused by this diff; CI is changed-files-scoped.
Closes-scenario: ag-7led#trigger-probe
Bounded-context: BC2-Validation
Evidence: skills/skill-builder/scripts/scan_descriptions.py
---------
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
## What
RPI cycle on **mining how AgentOps makes skills** (bead `ag-vb3q`),
using the external `meta_skill` best-practices doc as the scoring lens
(methodology only — no Rust `ms` build).
**Research:** codebase-archaeology over the 83-skill corpus + the skill
factory
(`skill-builder`/`skill-auditor`/`heal-skill`/`converter`/`forge`,
`SKILL-TIERS`, `score_agentops_skill.py`, CI gates). The corpus is
structurally excellent: **100% frontmatter conformance, 100% Codex
parity, ~94% references usage**.
**The one finding that matters:** skill selection is pure LLM reasoning
over the `description` field, yet **73 of 81 skills (90%) carry no
trigger marker**. The auditor *has* the checks
(`description-has-triggers`, `trigger-clarity`) but they were downgraded
**FAIL→WARN**, so the gap accumulated silently — a textbook
doctrine-vs-enforcement drift.
## This PR (Implement)
- **`references/skill-authoring-standard.md`** — clean-room distillation
of the external standard, cross-walked to AgentOps's *actual* enforced
rules (best-practice → gate → severity table).
- **`scripts/scan_descriptions.py`** — corpus-wide trigger scanner that
mirrors `audit.sh`'s exact three-form detection (so it never contradicts
the per-skill auditor) and adds the prioritized remediation backlog + a
suggested `Triggers:` stub the auditor never produced. `--json` robot
mode, `--strict` exit code.
- **`tests/python/test_scan_descriptions.py`** — 11 behavioral tests
(all three forms, suggestion quality, CLI exit codes, live-corpus
smoke).
- **`skill-builder/SKILL.md`** — "Corpus authoring health" section +
reference link (194/250 lines).
- Regenerated `registry.json`; patched `catalog.json` reference count.
## Plan (follow-on beads filed)
- `ag-okfu` — add trigger markers to the 73 flagged skills (wave by
tier; acceptance = scanner `--strict` exits 0)
- `ag-cx7d` — ratchet `trigger-clarity`/`description-has-triggers`
WARN→FAIL once the corpus is clean (blocked by `ag-okfu`)
- `ag-mm6q` — fix `generate-skill-catalog.sh` BSD-awk incompatibility
## Evidence
\`\`\`
python3 skills/skill-builder/scripts/scan_descriptions.py skills #
scanned 81, missing 73 (90%)
python3 -m unittest tests.python.test_scan_descriptions # 11 ok
bash scripts/check-registry-drift.sh # PASS — no drift
bash scripts/validate-context-map-drift.sh # exit 0
heal --strict skills/skill-builder # All clean
\`\`\`
Closes-scenario: ag-vb3q#authoring-standard-trigger-scan
Bounded-context: BC4-Factory
Evidence: .agents/audits/meta-skill-archaeology.md