## What
Refreshes the committed
`docs/releases/flywheel-compounding-snapshot.json` (was 2026-05-26, **9
days old**). `check-flywheel-compounding-snapshot.sh` hard-FAILs when
the snapshot exceeds `AGENTOPS_FLYWHEEL_SNAPSHOT_MAX_DAYS=14` → it would
have gone **stale-red on main ~2026-06-09**. Nothing auto-refreshes it
(manual-only, per the gate's own fix hint), so a refresh PR is the
mechanism.
## Not metric-gaming
Regenerated from the live corpus (711 artifacts, 250 citations this
period). Values stay **honest** — still below escape velocity
(`sigma_rho` 0.002→0.0057, status **DECAYING**).
`escape_velocity_compounding=false` is **non-blocking by design** ("an
action signal, not a structural CI failure"); only the 14-day staleness
check blocks. This refresh only resets the staleness clock.
## ag-qtm9 investigation (parent bead correction)
The parent P1's premise is **inaccurate**: citations *are* recorded
(`.agents/ao/citations.jsonl`, 3776 entries); `sigma_rho` is
low-but-nonzero, not 0. The flywheel is genuinely below escape velocity
(`sigma=0.029` retrieval coverage) — **real corpus health, not a code
bug**. ag-qtm9 stays open as a corpus-health/strategy item (not a quick
code fix); this PR carves off the bounded snapshot-freshness half.
## Gotcha documented
Generated from the **main checkout** — a fresh git worktree has an empty
local `.agents/` corpus, which yields a degenerate `sigma_rho=0`
snapshot.
## Verification
- `check-flywheel-compounding-snapshot.sh` → **PASS** (0d old)
- Scope: only the snapshot JSON; rebased onto current `origin/main`
Closes-scenario: ag-omcw#refresh-snapshot
Bounded-context: BC1-Corpus
Evidence: docs/releases/flywheel-compounding-snapshot.json
Squash merge PR #546. Local evidence: doc-release, smoke, snapshot gate, pre-push Bats, snapshot Bats, structural gates, and pre-push --fast passed. PR GitHub Actions were blocked in runner setup by GitHub codeload/action download failures before repository code executed. Snapshot records current corpus as DECAYING rather than preserving stale compounding evidence.
Makes release-notes scope mechanical per tier so a release can never
again under-scope its notes and burn the re-mining churn (root cause of
the v3.0.x rewrites).
- **Scope rule + tiers** in the standard (+ codex twin): notes = git
range since the previous release (a major = the whole major), with a
major/minor/hotfix table.
- **Coverage gate** in validate-release-notes.sh: maps the diff to
product areas, FAILS if a heavily-touched area (>=3 files) is
undocumented. Wired into release.yml via --since. It immediately caught
a real gap (v3.0.1 missing the Codex area — fixed here).
- **scaffold-release-notes.sh**: mines the range into a tier-correct
draft so notes start comprehensive.
- 6 new bats (14 total), shellcheck clean, codex parity green. v3.0.1
notes verified to PASS coverage over the real v2.41.1..v3.0.1 diff.
Closes-scenario: ag-nc9#tiers-coverage-gate
Bounded-context: BC5-Runtime
Evidence: scripts/validate-release-notes.sh
v3.0.1 is the 3.0 GA/Latest page, so it must tell the entire
v2.41.1->v3.0 transformation (~320 commits, ~138K/133K lines), not a
patch-framed summary. Earlier passes captured a fraction (the rip +
3.0.1 fixes) and dropped whole capabilities — ao doctor, the expanded
goals/evolve surface, hex ports, the BDD/gates layer, the reference Gas
City, the consolidation, the docs reconciliation. Mined the full delta
and rewrote the curated notes to cover every touched product area,
conforming to the standard (validate-release-notes.sh passes). v3.0.0
keeps its narrower .0 notes.
Bounded-context: BC5-Runtime
Evidence: docs/releases/2026-05-25-v3.0.1-notes.md
v3.0.1 is the recommended cut, so its release page should carry the full
3.0 story rather than just the patch delta. Fold the 3.0.0 major content
(Highlights theme, Breaking Changes, full At-a-Glance + Product Areas)
into the v3.0.1 curated notes, with the 3.0.1 release-engineering fixes
merged into the Install and Eval/Validation areas. v3.0.0 keeps its own
standalone notes. Conforms to the standard (validate-release-notes.sh
passes).
Bounded-context: BC5-Runtime
Evidence: docs/releases/2026-05-25-v3.0.1-notes.md
Fixes two compounding misses on the v3.0.x release notes and makes the
failure mechanically impossible.
**Root cause:** extract-release-notes.sh silently fell back to dumping
the raw CHANGELOG when no curated docs/releases/*-notes.md existed — so
3.0.0/3.0.1 shipped raw dumps, and the curated notes I then wrote did
not follow skills/release/references/release-notes.md (invented
headings, bold-lead-in bullets instead of action labels). The template
also had no major-release variant.
**Standard (template + codex twin):** add a major-release (X.0.0)
variant — required ## Breaking Changes section + migration link;
document the hard gate.
**Conform:** rewrite both 3.0.x curated notes to the standard (major
shape for 3.0.0 w/ Breaking Changes + canonical taxonomy + action
labels; patch shape for 3.0.1).
**Enforce:** scripts/validate-release-notes.sh (existence + sections +
taxonomy + action labels + Breaking-Changes-for-major) + 8 bats cases;
wired as a hard gate in release.yml before notes extraction;
extract-release-notes.sh now fails instead of silently dumping raw
CHANGELOG.
Local: both notes PASS the validator, 8/8 bats, shellcheck clean, codex
parity passes.
Closes-scenario: ag-d0f#release-notes-standard
Bounded-context: BC5-Runtime
Evidence: scripts/validate-release-notes.sh
Audit finding: extract-release-notes.sh builds the GitHub release body
from a curated docs/releases/<date>-v<ver>-notes.md (Highlights /
Upgrade Notes / Product Areas / See Also) and tucks the raw CHANGELOG
into a collapsed <details>. v3.0.0 and v3.0.1 shipped WITHOUT that file,
so the script silently fell back to dumping the raw CHANGELOG — the
published pages did not follow the curated format.
Adds both curated files: major-release style for 3.0.0 (At a Glance +
Product Areas + The Rip breaking section), patch style for 3.0.1
(matches v2.41.1). Verified both regenerate with curated highlights +
collapsed full-changelog. Published v3.0.0/v3.0.1 release bodies updated
to match.
Bounded-context: BC5-Runtime
Evidence: scripts/extract-release-notes.sh
Rescope PRACTICE.md into PRACTICE-REGISTRY.md: it now owns only the
practice-slug lineage registry, not product positioning or CDLC doctrine.
Update all references (schema, validate-practice-citations.sh, bats test,
architecture-terms.md, documentation-index.md, aggregate.go comment).
Introduce the Context Density Rule as a canonical domain concept: every
high-value context token carries intent, boundary, evidence, decision,
constraint, or next action. New domain entry context-density-rule.md (+
codex mirror). Thread the BDD/Gherkin + DDD + Hexagonal + TDD narrow waist
through cdlc.md, README.md, PRODUCT.md, GOALS.md, and the rpi/domain/
post-mortem skills. Sync codex artifacts.
Three required-job failures caught by `gh run list` per the cycle-48
tightened quality protocol (operator-asked, "how are you going to
enforce quality"):
1. **markdownlint** (cycle 46+) — MD004 ul-style violation in
docs/releases/v2.39.0-claims/all-claims-evidence-map.md:52. A `+`
bullet at column 3 was being interpreted as a nested list using
plus-style; rewrote prose to use "with" instead.
2. **validate-three-gap-supergate** (cycle 42+) — compile-health child
failed every CI run since the supergate landed because it requires
.agents/defrag/latest.json which doesn't exist on greenfield CI
runners (the nightly workflow generates it via `ao defrag` into a
tmpdir + COMPILE_OUTPUT_DIR env). Sibling gates (council-coverage,
flywheel-proof) already SKIP under similar conditions; compile-
health now does too: if neither AGENTS_DIR/defrag/latest.json nor
AGENTS_DIR/overnight/*/defrag/latest.json exists AND
COMPILE_OUTPUT_DIR is unset, SKIP with "enforced by nightly
workflow" message. The nightly workflow remains the canonical
enforcer.
3. **registry-check** (cycle 45) — registry.json stale because cycle
45 added 4 new skills/evolve/references/*.md files without
regenerating. `bash scripts/generate-registry.sh` regenerated;
counts now reflect current state (77 skills, 43 hooks, 4 stores,
14 job types, 63 evals, 148 CLI commands).
Verification:
- markdownlint docs/releases/v2.39.0-claims/*.md — clean.
- bash scripts/check-three-gap-supergate.sh --gap=all — PASS locally.
- AGENTS_DIR=/tmp/no-such-dir bash scripts/check-three-gap-supergate.sh
--gap=durable-learning — PASS with SKIP message for compile-health
(simulates CI greenfield).
- bash scripts/generate-registry.sh --check — "OK: registry.json is up
to date".
Out of scope:
- agentops-contract-canaries cycle-45 failure (aggregate=0.9549) — same
fingerprint as the soc-l4yt closed-flake; doesn't reproduce on cycle
46/47 CI runs or in local 5/5 bats. Not addressed here.
- security-toolchain-gate (advisory; exit 3 with 0 missing tools) —
pre-existing, not introduced by this branch.
First strong-verification follow-up against the 2026-05-11 evolution
roadmap-drain harvest (medium-severity item: "promote highest-visibility
claims to PG4-strong evidence files, starting with TRUST-FACTORY-FIVE-
STEP-PRIMITIVE, 9 refs").
Adds docs/releases/v2.39.0-claims/trust-factory-five-step-primitive.md
following the autonomous-flywheel.md template:
- Per-step evidence ledger for all 5 trust-factory steps (identity,
reproducibility, evaluation, evidence, recovery).
- Each step maps to named repo surfaces under cli/, .agents/,
skills/, scripts/, or docs/contracts/.
- Each step names at least one verification gate that fires on drift
(check-retrieval-quality-ratchet, check-wiring-closure,
check-three-gap-supergate --gap=all, check-flywheel-compounding,
check-flywheel-proof, check-flywheel-compounding-snapshot,
check-corpus-freshness).
- Verification map table summarizes step → gate(s).
- Anti-claim disclaims invention, continuous measurement, and
AgentOps-exclusivity of the primitive.
Promotion record:
- all-claims-evidence-map.md: entry promoted from "partial (pointer)"
to "verified (PG4)" with surface + gates inline + link to the new
evidence file.
- README.md in the same directory grows a new "High-visibility PG4
promotions (additional)" table; the existing 5 README-scope rows
stay in place.
- factory-claim-ledger.example.json row remains at
evidence_status=partial in this commit; the contract validator
will accept promotion to "verified" once the row's evidence_artifacts
list points to the new file (separate ledger-row update follow-up).
This closes 1 of N high-visibility claims from the medium-severity
PG4-strong-verify follow-up. The next-work entry remains unconsumed;
4-9 additional candidates exist in the A1 audit
(.agents/research/2026-05-11-aop-claim-evidence-map.md).
Validation:
- pre-push --fast: green, no PRE_PUSH_SKIP_EVAL override needed.
- No `Pass N: FAILED|BLOCKED` structural markers in gate output.
Closes 25 P2/P3 AOP-CLAIM verify beads from the A1 audit follow-up
queue (cycle 35).
Why
- The A1 audit (bead soc-waod, cycle 20) classified 30 AOP-CLAIM
markers; 5 were closed via PG4 (cycle 30) with dedicated per-claim
evidence files under docs/releases/v2.39.0-claims/. The remaining
25 cover PRODUCT, GOALS, BRIEF, ASSURANCE, COMP, CONTRACT, DOCS,
WIKI, SOFTWARE-FACTORY, and TRUST-FACTORY scopes — each was a
separate verify bead in the queue.
- Each of these claims has natural evidence already in the repo
(factory contracts, dream-cycle script, competitive docs, etc.).
Spawning 25 standalone evidence files mirrors PG4 but produces
diminishing-marginal-value when most claims share their evidence
with existing surfaces.
What
- docs/releases/v2.39.0-claims/all-claims-evidence-map.md (NEW):
comprehensive evidence map for all 25 non-README claims. Each
entry names (a) the claim location, (b) the repo surface that
demonstrates it, (c) the verification gate (or "doc-only" / "not
gated" where honest), (d) the bead it closes.
- docs/releases/v2.39.0-claims/README.md: cross-link to the new
evidence map.
Two strength levels are now explicit:
- **PG4 strength** (5 README claims): dedicated per-claim evidence
file. Strongest evidence form.
- **All-claims-map strength** (25 non-README claims): pointer entry
in the batch map. Promotes the A1 classification from
`unverified` to `partial` (declared-pointer-evidenced).
Promotion path: any of the 25 that wants full `verified` status
follows the PG4 pattern — dedicated evidence file + CI-blocking
gate that fails on drift.
Verification
- pre-push --fast: PASS
Companion: A1 audit soc-waod (closed cycle 20), PG4 soc-dec2.4
(cycle 30).
Closes soc-dec2.2 — PG2 (3.0 PMF scenario exported evidence).
Why
- PRODUCT.md/README make a 3.0 PMF claim with no public proof.
The soc-m6v5.8 epic specified the scenario shape; PG2 is the
exported-evidence checkpoint that public launch claims gate on.
What
- docs/releases/v3.0/pmf-scenario.md (NEW): single-day autonomous
/evolve drain record. Names the scenario (one-day roadmap drain),
control path (manual-selection baseline), this run's
instrumentation (11 P1 closures, 11 commits, 41-bead queue, 5
insight tags), exported artifacts (cycle ledger + daily learning
+ research docs + the 14 directive-implementation surfaces), and
the friction modes the loop caught. Explicit anti-claims so the
record does not overpromise (no throughput numbers vs other
tools, no A/B vs human-in-loop, no generalizability claim).
- docs/documentation-index.md: cataloged the new record under
release artifacts.
The record self-evidences: every directive-implementation row
links to a commit SHA, and every artifact path is checked in.
Companion beads: soc-m6v5.8 (parent scenario spec), soc-dec2.4
(PG4 README claim manifest), soc-p1ac.1 (LC1 learning-capture
protocol used to produce the durable record).
Closes soc-dec2.4 — PG4 (Public launch claims need exported proof
under docs/releases/).
Why
- All 5 AOP-CLAIM-README-* markers were narrative-only — pointing
nowhere a public reader could verify them. The A1 audit (bead
soc-waod, cycle 20) had already classified them as unverified;
PG4 is the public-evidence output layer.
- Local .agents/ notes are gitignored, so they cannot back claims
made on the public surface.
What
- docs/releases/v2.39.0-claims/README.md (NEW): manifest mapping
each AOP-CLAIM-README-* marker → evidence file + verification
gate.
- docs/releases/v2.39.0-claims/factory-context.md (NEW): backs
AOP-CLAIM-README-FACTORY-CONTEXT.
- docs/releases/v2.39.0-claims/competitive-memory.md (NEW): backs
AOP-CLAIM-README-COMPETITIVE-MEMORY.
- docs/releases/v2.39.0-claims/first-validated.md (NEW): backs
AOP-CLAIM-README-FIRST-VALIDATED (links to PG1 journey test).
- docs/releases/v2.39.0-claims/evolve-autonomous.md (NEW): backs
AOP-CLAIM-README-EVOLVE-AUTONOMOUS (links to cycle history +
LC1 work).
- docs/releases/v2.39.0-claims/autonomous-flywheel.md (NEW): backs
AOP-CLAIM-README-AUTONOMOUS-FLYWHEEL (links to G1 snapshot gate +
live σρ=0.0488 vs δ/100=0.0274).
- docs/documentation-index.md: cataloged the manifest per the
contracts-must-be-catalogued rule.
- tests/install/test-five-minute-journey.sh: shellcheck fixes
(SC2164 cd-fallback, SC2155 separate declare/assign).
Each evidence file names the repo surface backing the claim plus
the verification gate that protects it from drift. The pattern
generalizes to other public surfaces (PRODUCT.md, landing pages) —
file under docs/releases/<version>-claims/<claim-id>.md.
Companion: A1 audit (soc-waod) — discovery layer; this is the
output layer for the 5 README-scope claims.
Closes soc-45sg.1 — G1 (Make flywheel-compounding CI-blocking via
corpus-state snapshot).
Why
- The live flywheel-compounding gate (`bash scripts/check-flywheel-
compounding.sh`) computes σρδ from the current corpus on demand.
Multi-session activity is required to move it; CI runners have a
cold corpus and would always fail. Result: the gate sat in the
Roadmap column, not enforcing.
- The fix is the snapshot pattern. An operator captures a corpus-
state evidence file when their local corpus IS compounding, commits
it under docs/releases/, and CI validates the artifact without
re-running the multi-session computation.
What
- scripts/snapshot-flywheel-compounding.sh (NEW, operator command):
runs `ao flywheel status --json` and wraps it in a snapshot envelope
with recorded_at, git_sha, git_branch. Writes to
docs/releases/flywheel-compounding-snapshot.json (tracked path).
- scripts/check-flywheel-compounding-snapshot.sh (NEW, CI gate):
reads the snapshot, fails on missing / stale (>14d default) /
escape_velocity_compounding != true. Honors AGENTOPS_FLYWHEEL_
SNAPSHOT_SKIP=1 operator override.
- docs/releases/flywheel-compounding-snapshot.json (NEW, seed):
initial snapshot at HEAD 800b5165, compounding=true, σρ=0.0488,
δ=2.742, recorded 2026-05-11T21:48:44Z.
- GOALS.md: new gate row flywheel-compounding-snapshot, weight 5.
Three-Gap proof-surface table: moved into Currently enforcing
column for Gap 2 (durable learning); live `flywheel-compounding`
stays in Roadmap as the higher-fidelity but unattainable-in-CI
reference. Closes the bead's "gate moves from Roadmap to Currently
enforcing column" acceptance.
- .github/workflows/validate.yml: new validate-flywheel-compounding-
snapshot job. Registered in summary.needs[] + summary echo per
validate-ci-policy-parity contract (54 jobs, 7 non-blocking).
- scripts/pre-push-gate.sh: new always-on check 22h.
- AGENTS.md: CI Jobs row for validate-flywheel-compounding-snapshot.
- tests/scripts/pre-push-gate.bats: stub for the new gate script.
Verification
- snapshot script: produced snapshot at recorded_at=2026-05-11T21:48:44Z,
compounding=true.
- gate: PASS (0d old, compounding=true, threshold 14d). SKIP path
honored via env override.
- validate-ci-policy-parity.sh: PASS (54 jobs).
- bats 51/51 ok.
- pre-push --fast (PRE_PUSH_SKIP_EVAL=1 for soc-l4yt canary flake):
both passes green with "ok flywheel-compounding snapshot".
Operator runbook: when the live gate is green (`bash scripts/check-
flywheel-compounding.sh` passes), refresh the snapshot:
bash scripts/snapshot-flywheel-compounding.sh
git add docs/releases/flywheel-compounding-snapshot.json
git commit -m "chore(flywheel): refresh compounding snapshot"
The snapshot is good for 14 days before CI starts failing.
Companion bead: D11 (soc-ymph.11) which shipped ao corpus
snapshot/restore — pattern reuse: tracked durable JSON evidence
artifact + structural CI gate.
* docs(mkdocs): fix 5 anchor mismatches + 1 unresolvable relative link (soc-2yx9)
mkdocs slugify collapses em-dash spacing in headings to a single hyphen, so
'## A — B' produces id="a-b", not 'a--b'. Five doc cross-references encoded
the visual double-dash and were silently flagged INFO by `mkdocs build --strict`.
Fixes (slugs verified against built site/ HTML):
- docs/GLOSSARY.md → how-it-works.md#ralph-wiggum-pattern-fresh-context-every-wave
- docs/cdlc.md (×2) → the-science.md#part-6-the-convergence-cdlc-as-the-unifying-spine
- docs/context-lifecycle.md (×2) → #the-knowledge-ledger-session-to-session-flow
- docs/releases/2026-03-21-v2.28.0-notes.md → ../CHANGELOG.md#2280-2026-03-21
Plus one structural fix:
- docs/documentation-index.md → ../evals/workbench/ replaced with the
github.com URL pattern used by every other extra-docs link in this file.
evals/ lives outside docs_dir so mkdocs cannot resolve relative links there.
Acceptance: zero INFO/WARN/ERROR mentioning these 5 files in
`mkdocs build --strict`. Pre-existing INFO lines on templates/ and L*-*/
README directory links are out of scope (research §U4 / pre-mortem L3).
Closes soc-2yx9 from epic soc-xlw8.
* fix(goals): anchor cwd to GOALS.md repo root for `ao goals measure` (soc-crzz)
Reproduction: from /tmp, `ao goals measure --file <abs>/GOALS.md` returned
21/22 fails with "bash: scripts/check-*.sh: No such file or directory".
Goal Check strings are relative paths; bash inherited the caller's cwd.
Fix: at RunMeasure entry, derive the repo root from the absolute GoalsFile
path and chdir to it for the duration of the measurement; restore the prior
cwd via deferred no-op-safe restorer (`withGoalFileCwd`). When GoalsFile is
not inside a git repo, the helper returns a no-op so today's behavior is
preserved outside repos.
Also expose `Paths.RepoRoot` from cli/internal/paths so future callers can
detect the resolved repo top without re-shelling git. The field is empty
when the resolver was given a directory not inside a repo, mirroring
`git rev-parse --show-toplevel` semantics.
Smoke (post-fix): `cd /tmp && ao goals measure --file <abs>/GOALS.md --json`
returns 22/22 pass, zero "No such file" errors.
Tests:
- TestRunMeasure_RelativeScripts_FromExternalCwd exercises the bug path
end-to-end (fake git repo + relative-script goal + chdir to outside).
- TestWithGoalFileCwd_NoRepoFallback verifies the no-repo no-op.
- TestWithGoalFileCwd_EmptyPath verifies the empty-input no-op.
Per pre-mortem H1 (.agents/council/2026-05-07-pre-mortem-drain-open-next-work-items.md).
Closes soc-crzz from epic soc-xlw8.
* feat(eval): add stdout_contains_auto_detect ratchet for live test counts (soc-bvhn)
Two eval pins drifted silently when tests were added:
- evals/agentops-core/hook-lifecycle-behavior.json "Total: 226"
- evals/agentops-core/pre-push-gate-governance.json "1..51"
The 226-pin only counted tests/hooks/test-hooks.sh and missed the 86-test
test-hooks.bats suite entirely; the 1..51-pin was a manually-bumped
plan line (commit bd104270 was 50→51 after PR #263 added a test).
Replace both with a new expectation type stdout_contains_auto_detect that:
1. Re-executes a source-of-truth command (e.g. `bash tests/hooks/test-hooks.sh`)
2. Captures a regex group from its combined stdout+stderr
3. Verifies the case stdout contains the FULL match (drift = fail loud)
4. Honors tolerance_pct (default 0; strict-by-default)
5. Pre-checks the command's binary on PATH so missing `bats` etc. fails
with an explicit "not found on PATH" message instead of regex miss
6. Inherits the case's cwd / suite-dir + timeout policy
Drift surfaces a `BUMP the pinned value to "Total: N"` one-liner so the
operator can react in one edit. Migrated both pins to use the new type.
Pre-mortem M3 (.agents/council/2026-05-07-pre-mortem-drain-open-next-work-items.md)
patch is enforced indirectly: validExpectationType registers the new kind,
and the parser rejects empty command/pattern at load time.
Tests: 8 new in expectations_auto_detect_test.go covering pass-on-match,
fail-loud-on-drift, missing-binary-fails-loud, pattern-no-match, the
bats `1..N` plan-line shape, missing-command rejection, tolerance allowing
numeric drift, and registry membership.
Closes soc-bvhn from epic soc-xlw8.
* feat(reconcile): observation-log aggregator unblocks Wave 1E (soc-ejq2)
Wave 1E (soc-f42z9) of the Reconciliation Engine epic cannot promote the
factory-claim-ledger validator from advisory to blocking until ≥20 advisory
runs are aggregated to .agents/reconcile/observation-log.jsonl. The CI job
(`factory-claim-ledger-strict (advisory)` at validate.yml:450-565) already
emits per-run observation JSON as a workflow artifact; nothing aggregated
them. This builds the missing pull-mode aggregator.
scripts/aggregate-observation-log.sh:
1. `gh run list --workflow validate.yml ...` for recent runs
2. `gh run download <run-id> -n factory-claim-ledger-observation` per run
(silently skips runs that predate the advisory job)
3. Schema-validates EVERY observation BEFORE dedup (pre-mortem M3 patch:
`jq unique_by(.run_id)` silently collapses null-key entries — we reject
malformed observations up front with `jq -e all(.run_id and ...)`)
4. Dedups on run_id, atomic write to .agents/reconcile/observation-log.jsonl
5. Backfills merged_anyway and ledger_updated:
- pr_number=null (push-to-main): both false. Push-to-main observations
satisfy the no-silent-merge criterion by definition.
- else: `gh pr view` for state + `git log` for ledger-touch detection
Empty-output case (no runs yet): produces valid empty JSONL, exits 0.
Idempotent: re-running does not duplicate; verified by L2 test.
Skeleton .agents/reconcile/promotion-decision.md (gitignored, not in repo)
seeded by the script for operator to fill in false-positive baseline.
L1+L2 fixture-driven tests (9/9 pass): empty-input, dedup, schema rejection
of null run_id, push-to-main backfill semantics, --dry-run no-write,
idempotent byte-identical re-runs.
Adds `reconcile` to docs/contracts/agents-write-surfaces.md (prose table
and BEGIN/END allowlist) — required for `check-agents-write-surfaces.sh`
to pass after the new write surface lands.
NOT in scope (deferred to follow-up issues):
- Scheduled .github/workflows/aggregate-observations.yml workflow
- Operator-filled promotion-decision.md baseline
- Wave 1E gate flip itself (soc-f42z9)
Per pre-mortem M3 (.agents/council/2026-05-07-pre-mortem-drain-open-next-work-items.md).
Closes soc-ejq2 from epic soc-xlw8.
* feat(crank): wire CI-policy parity gate into wave acceptance (soc-il9k)
Prevents recurrence of c587b361-style manual fixes. Wave 1C of soc-e4ulx
added factory-claim-ledger-strict (advisory) to .github/workflows/validate.yml
without updating AGENTS.md or `summary.needs:`. Codex-team caught and fixed
the drift manually. This PR formalizes that recovery as a conditional
crank wave-acceptance gate, so the next wave that touches workflow YAML
fails loud at acceptance instead of slipping through.
Insertion (canonical and codex-mirrored):
- skills/crank/SKILL.md Step 5.5: new "CI-Policy Parity Gate (conditional)"
sub-section pointing to the worked example.
- skills/crank/references/wave-patterns.md: appended worked example with
drift→fix transcript referencing commit c587b361.
- skills/swarm/references/local-mode.md (worker prompt template): added
section 4 to CONDITIONAL PREFLIGHT CHECKS so workers run the gate
proactively, not only at acceptance.
- skills-codex/* parity copies + regenerated codex hashes.
Trigger (narrow grep — yaml workflow files only):
if git diff --name-only HEAD~1 -- | grep -qE '^\.github/workflows/.*\.ya?ml$'; then
bash scripts/validate-ci-policy-parity.sh || exit 1
fi
CODEOWNERS-only or markdown-only changes do not trip the gate. The
validator (scripts/validate-ci-policy-parity.sh, 186 LOC, unchanged) is a
read-only dependency.
Golden fixture tests/integration/test-ci-policy-parity-wave-gate.sh
(9/9 pass): SKILL doc presence, trigger-pattern shape, worked-example
linkage, worker-template wiring, codex parity, validator presence,
drifted-fixture exits 1, aligned-fixture exits 0, live-repo PASS.
Per planning rule finding-2026-05-07-ci-parity-as-wave-acceptance — this
PR IS the formalization of that rule (self-referential by design).
Closes soc-il9k from epic soc-xlw8.
* feat(reconcile): thesis-stability gate + Wave 0 snapshot (soc-mt50)
Gates the Reconciliation Engine arc transition from Wave 1 to Wave 2
(soc-r3y8b) by diffing current README/PRODUCT/GOALS hero sections against
the snapshot frozen at Wave 0 close (commit ab479e26 — "docs(positioning):
wiki-framing sweep across all surface docs (soc-9xn0)").
scripts/check-thesis-stability.sh:
Hero extractor anchored to '^## ' (with trailing space) per pre-mortem M2
patch — code-fence-safe, excludes the H2 boundary line itself:
awk 'NR==1, /^## / {if (!/^## /) print}' <file>
Per-file diff against the snapshot's fenced ```...``` block. Operator
decides accept/re-brainstorm/incidental on FAIL.
Exit codes: 0 = no drift, 1 = drift (operator decision required), 2 =
precondition error (snapshot missing, source files missing, or snapshot
carries a literal `^<!-- WAVE_0_TODO -->$` line — anchored regex prevents
prose mentions of the marker from triggering the precondition gate, per
pre-mortem L6).
--json mode emits {verdict, drifted, decision_template} for tooling.
Snapshot artifact (.agents/reconcile/wave-0-thesis-snapshot.md):
Frozen verbatim hero blocks for README.md / PRODUCT.md / GOALS.md at
closure SHA ab479e26. Header documents extraction contract + regen path.
Decision template (.agents/reconcile/thesis-stability-decision.md):
Operator-fillable record. Three explicit options (accept / re-brainstorm
/ incidental). Re-validation matrix for Waves 2-4 acceptance criteria
on accept-drift path.
.gitignore:
Adds the snapshot + decision-template paths to the .agents/ allowlist
alongside existing exceptions (rpi/next-work.jsonl, nightly/, evolve/,
goals/, findings/registry.jsonl). observation-log.jsonl and
promotion-decision.md remain runtime state (generated by aggregator and
operator fill-in respectively) and stay ignored.
Smoke (run during implementation):
- bash scripts/check-thesis-stability.sh → exit 0 (no drift today)
- bash scripts/check-thesis-stability.sh --help → usage emitted, exit 0
- inject SMOKE-DRIFT into README hero, re-run → exit 1 with diff
- revert, re-run → exit 0
Per pre-mortem M2 + L6 (.agents/council/2026-05-07-pre-mortem-drain-open-next-work-items.md).
Closes soc-mt50 from epic soc-xlw8.
* ci(reconcile): allowlist thesis-stability snapshot + decision artifacts (soc-mt50 follow-up)
PR-E (06f416e1) added two static contract artifacts under .agents/reconcile/
that need to be tracked: wave-0-thesis-snapshot.md (frozen at Wave 0 SHA
ab479e26) and thesis-stability-decision.md (operator-fillable template).
The .gitignore exception alone is not sufficient — scripts/check-no-tracked-agents.sh
maintains a narrow audit-truth allowlist of paths under .agents/ that may
be tracked. Without an allowlist update, the pre-push-gate's "tracked
.agents state" check fails on these two new files.
Extends ALLOWED_PATHS_REGEX and ALLOWED_REINCLUDES_REGEX to include the
two reconcile paths. observation-log.jsonl + promotion-decision.md
intentionally remain runtime state (generated by the aggregator and
operator fill-in respectively) and are NOT added to the allowlist.
Updates the file's header comment to document the new reconcile entry
in the audit-truth allowlist surface.
Acceptance:
- bash scripts/check-no-tracked-agents.sh → "no disallowed tracked repo-root .agents state"
- bash scripts/pre-push-gate.sh --fast → exit 0 (46 skipped, 0 failed)
Per CLAUDE.md "All exceptions require a coordinated update of .gitignore +
this allowlist + CLAUDE.md/PROGRAM.md guidance." (Reconciliation Engine
arc context covered in PR-E commit message.)
* chore(rpi): mark soc-9xn0 + soc-e4ulx next-work entries consumed (soc-ot2m)
Closes the housekeeping tail of epic soc-xlw8. Both unconsumed entries in
.agents/rpi/next-work.jsonl flip to consumed=true, claim_status=consumed,
consumed_by=soc-xlw8, consumed_at=2026-05-08T09:30:00-04:00.
Mapping (10 raw items → 7 work units → 6 PRs; U1 already resolved by
Wave 1A pre-session, no PR needed):
U2 BATS count audit gap → PR-C f75201f5 (soc-bvhn)
U3 ao goals measure cwd → PR-B 04e585e8 (soc-crzz)
U4 mkdocs link rot + anchors → PR-A cf584671 (soc-2yx9)
U5 observation-log aggregator → PR-D af681e9c (soc-ejq2)
U6 thesis-stability gate → PR-E 06f416e1 (+93e4cf05)
U7 CI-policy parity in crank → PR-F a2fb6a2f (soc-il9k)
Closure note (gitignored, local provenance):
.agents/rpi/closure-2026-05-07-next-work-items.md
Also adds .agents/findings/registry.jsonl with three reusable findings
generated during this session (the file was untracked due to .agents/
gitignore precedence; the audit-truth allowlist already permits it):
- finding-2026-05-07-mkdocs-slug-observed-not-asserted
- finding-2026-05-07-sed-range-includes-boundary-line
- finding-2026-05-07-jq-unique-by-collapses-null-keys
Acceptance:
- bash scripts/validate-next-work-contract-parity.sh → exit 0
- jq -c . < .agents/rpi/next-work.jsonl → valid JSONL, 2 entries
- bash scripts/check-no-tracked-agents.sh → no disallowed paths
- bash scripts/pre-push-gate.sh --fast → exit 0 (46 skipped)
Per pre-mortem L5 (.agents/council/2026-05-07-pre-mortem-drain-open-next-work-items.md):
the validator was already passing pre-PR (the phase-2-summary's claim of
broken parity was stale). Acceptance is steady-state ("validator continues
to exit 0 after marking entries consumed"), not transition.
Closes soc-ot2m and epic soc-xlw8.
* chore(reconcile): record Wave 1E promotion-decision baseline (Option B defer)
Filled .agents/reconcile/promotion-decision.md from skeleton with computed
baseline from observation-log.jsonl: 3 obs / 0 fail / 2 PRs / vacuous FP
rate. Sample 3 < 20 threshold and PRs 2 < 3 threshold do not justify
promotion to blocking; first-day post-aggregator data is also clustered
within ~4h. Selected Option B (defer/extend sampling) with explicit
re-evaluation trigger documented (>=20 runs, >=3 PRs, >=1 fail).
validate.yml gate stays advisory (continue-on-error: true intact). No
behavior change to CI. Re-evaluation tracked under bd soc-nsuq, which
blocks Wave 1E parent soc-f42z9.
Audit-truth allowlist extended in both .gitignore and
scripts/check-no-tracked-agents.sh to track the decision artifact, mirroring
the thesis-stability-decision.md allowlist pattern from 93e4cf05. The
promotion-decision is committed input to the Wave 1E gate-flip workflow,
not runtime state.
Refs: soc-xlw8 (RPI follow-up), soc-f42z9 (Wave 1E parent), soc-nsuq
(re-evaluation), soc-ejq2 (aggregator that produced the baseline).
## Docs site — boshu2.github.io/agentops
- Replace Jekyll minima with MkDocs Material (slate dark palette default)
- Landing hero scoped to .landing-hero (no gradient bleed on inner pages)
- Section landings (getting-started, architecture, reference, contracts, levels) with narrative ledes
- Generate skill catalog + per-skill pages from skills/*/SKILL.md at build
- Generate CLI reference from cli/docs/ at build (fails build on missing source)
- Fix every internal link via one-shot migration (scripts/migrations/2026-04-19-fix-docs-links.py)
- Wire mkdocs build --strict into pre-push gate (Check 25a)
- Replace .github/workflows/pages.yml with .github/workflows/docs.yml (actions/deploy-pages)
- README + docs/CONTRIBUTING updated with docs-build toolchain on-ramp
- tests/docs/validate-links.sh patched to understand mkdocs-generated paths
## RPI orchestrator strict-delegation contract
- Strict sub-skill delegation is now the default for /rpi, /discovery, /validation. No --full flag — always on.
- Canonical contract in skills/shared/references/strict-delegation-contract.md (plus Codex mirror)
- Forged learning with detection phrases + corrective actions (ao-inject-ready)
- Rename --no-lifecycle -> --no-scaffold in /discovery (Claude + Codex) with deprecation alias through v2.40.0
- Harden inline-work hotspots with orchestrator-owned markers in /crank STEPS 3a.3, 6.5, 8.7 + Inline Work Policy footer
- Flag consistency: --auto and --interactive scopes documented; --complexity syntax formalized
- CHANGELOG [Unreleased] documents + scaffolds; runtime hook enforcement explicitly deferred
## fix(hooks): go-test-precommit skips when no Go files staged
- Previously ran go vet + go build unconditionally, blocking non-Go commits when Go toolchain was missing or at a different version
- Now checks staged diff and exits cleanly if no *.go or go.{mod,sum,work} files are staged
- Applied to both hooks/ (source) and cli/embedded/hooks/ (synced)
Provenance: full RPI lifecycle with strict delegation at every phase boundary (Phase 1 Skill(discovery) -> Phase 2 Skill(crank) -> Phase 3 Skill(validation) -> Skill(vibe), Skill(post-mortem), Skill(retro)).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Rename the athena skill to compile — a descriptive name that communicates
what it actually does. Extend with Karpathy's LLM Knowledge Bases architecture:
- New compile phase: LLM reads raw .agents/ artifacts and produces interlinked
markdown wiki at .agents/compiled/ with index.md, log.md, backlinks
- New lint phase: detects contradictions, orphan pages, stale claims, coverage gaps
- Pluggable compute backend via AGENTOPS_COMPILE_RUNTIME (ollama|claude|openai)
- Hash-based incremental compilation (only recompile changed sources)
- compile.sh engine with security fixes (no shell injection, path traversal guard)
- Full rename across 93 files: skills, docs, CLI, tests, hooks, scripts, codex
Existing Mine → Grow → Defrag cycle preserved as phases within the larger
compile workflow. No vector DB — compiled wiki IS the retrieval layer.