## 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>
Defines a tracked contract for swarm worker result files living under
.agents/swarm/results/<task>.json. These files were implicitly shaped
but never validated — misshapen packets could silently break crank
result ingestion.
- schemas/swarm-evidence.schema.json: JSON Schema. Required: task,
status, files_changed, notes. Optional: tests, gate, evidence,
before/after counters. additionalProperties=true permits task-specific
extensions.
- scripts/validate-swarm-evidence.sh: jq-based validator accepting a
file or directory. ajv fallback when available. Exit 0 pass, 1 fail.
- docs/contracts/swarm-evidence.md: human-readable contract doc with
example and schema link. Added to docs/INDEX.md catalog.
- scripts/pre-push-gate.sh: new section 26b ('swarm evidence schema')
invokes the validator on every push.
- scripts/check-contract-compatibility.sh: extended ref resolution to
also search schemas/ so docs/contracts/*.md can cite
schemas/*.schema.json without tripping the cataloguing check.
Consumes ag-yhr 'Implement executable swarm evidence schema validation'.
Reorder the Dream RunLoop iteration body so fitness is measured against
the staging tree BEFORE cp.Commit() instead of against the already-mutated
live tree after. Under strict mode, a regression halt now fires before
the live ~/.agents/ is ever touched — external observers never see a
regressed state.
## What changed
Before (Option B):
REDUCE → COMMIT → VerifyMetadataRoundTripPostCommit → MEASURE → DELTA → HALT
On regression: status=halted-on-regression-POST-commit, NO rollback,
live tree already mutated.
After (Option A, this commit):
REDUCE → MEASURE (against cp.StagingDir) → DELTA → HALT (with Rollback)
→ COMMIT → VerifyMetadataRoundTripPostCommit
On strict-mode regression/plateau: cp.Rollback() discards staging,
status=halted-on-regression-PRE-commit, live tree untouched.
## Why the original 395 LOC estimate was inflated
Prior session deferred M8 as a ~395 LOC architectural change requiring
dedicated --complexity=full --mixed council. This session's pre-flight
council validation (3-judge --tdd mode) discovered that the staging
infrastructure already existed in the codebase:
* cp.StagingDir is a full mirror of .agents/ subpaths
(checkpoint.go:194-223)
* REDUCE already writes into cp.StagingDir (reduce.go:186)
* cp.Rollback() is safe at any state (checkpoint.go:345)
* cp.StagingDir/.agents/ is a valid cwd for corpus.Compute — no
signature change needed
The actual fix was a sequencing bug, not missing infrastructure.
Real size: ~300 LOC (code + tests + docs). Real re-plumbing: 1 existing
test (TestRunLoop_RegressionHaltStrict status assertion), well under
the pre-agreed 5-broken-tests abort gate.
## Files
cli/internal/overnight/types.go
+ StatusHaltedOnRegressionPreCommit (new enum value)
+ Validate() + IsCorpusCompounded() switches updated
+ StatusHaltedOnRegressionPostCommit kept for backward compat with
persisted pre-M8 iterations
cli/internal/overnight/loop.go
- Removed old COMMIT block at former loop.go:332-348
- Removed old post-commit metadata check at former 350-360
- Added new MEASURE block at former position, pointing RunMeasure at
cp.StagingDir via a local RunLoopOptions copy
- Added cp.Rollback() to the measure-error branch
- Added cp.Rollback() + StatusHaltedOnRegressionPreCommit to the strict
regression halt branch (and removed writeCommittedButFlaggedMarker,
which was post-commit-specific)
- Added cp.Rollback() + StatusHaltedOnRegressionPreCommit to the strict
plateau halt branch
- Inserted new COMMIT block + post-commit metadata check AFTER the
warn-only rescue path, before the per-iter persist+append
- Warn-only rescue path itself unchanged (tolerated regressions still
commit; that's the whole point of warn-only)
cli/internal/overnight/loop_fitness_injection_test.go
+ TestM8_StrictRegression_HaltsPreCommit (T1 — the core wiring)
+ TestM8_StagingDiscardedOnPreCommitHalt (T2 — proves Rollback fired)
+ TestM8_HappyPath_CommitsNormally (T4 — pass-through not broken)
~ TestRunLoop_RegressionHaltStrict — status assertion updated to
StatusHaltedOnRegressionPreCommit
~ TestRunLoop_WarnOnlyBudgetExhausted — same update; budget-exhausted
fall-through to strict halt now uses PreCommit (consistency invariant)
docs/contracts/dream-run-contract.md
+ Iteration structure now documents 4 stages with Option A sequencing
+ Halt conditions table updated with new iter status values
+ Historical note explains the shift + why PostCommit status is kept
## Test results
* 4 new M8 tests pass
* 2 existing tests updated + pass
* Full overnight package green
* Full cli test suite green (go test ./...)
* Race detector clean (go test -race ./internal/overnight/...)
* go vet clean
* Scope gate: 1 broken existing test (< 5 abort threshold)
## Dream RunLoop Correctness epic status
M1-M7 + M8 + M9 all landed. Epic complete. M9 ratchet upgrade (warn→fail)
still gated on 1-2 clean post-679552ae main runs; na-h61 was the last
deferred item.
Closes: na-h61
Refs: .agents/council/2026-04-11-m8-assumption-validation-consolidated.md
.agents/council/2026-04-11-m8-assumption-validation-judge{1,2}.md
The legacy "rolled-back" string at loop.go carried two fundamentally
different semantics at two producer sites:
loop.go REDUCE pre-commit failure — corpus NOT on disk
loop.go post-commit regression halt — corpus IS on disk
The second was a LIE: the label claimed rollback while cp.Commit()
had already compounded the corpus into the live tree. Operators
reading the morning report saw "rolled-back" and assumed no-op,
when in fact the mutation was permanent.
Fix: introduce a 5-value IterationStatus enum in types.go with
StatusRolledBackPreCommit and StatusHaltedOnRegressionPostCommit
as distinct constants. Update both producer sites. Add a
committed-but-flagged marker file in iteration_store.go that
operators can find via directory listing. Fix the Micro-epic 2
rehydration logic to use IsCorpusCompounded as the baseline
predicate (closing the known-limitation documented at
.agents/council/2026-04-10-pre-mortem-microepic-2-cycle-history.md
#pm-20260410-m2-005).
Ship the Status Precedence Truth Table in docs/contracts/dream-report.md
so the enum semantics are documented, not tribal.
Touches:
- cli/internal/overnight/types.go (IterationStatus enum + Validate + IsCorpusCompounded)
- cli/internal/overnight/loop.go (rename + rehydration predicate update + other status literals)
- cli/internal/overnight/iteration_store.go (marker helpers)
- cli/internal/overnight/overnight_e2e_test.go (predicate update)
- cli/cmd/ao/overnight.go (explicit string() cast at the Steps boundary)
- docs/contracts/dream-report.md (enum + truth table + historical note)
- Test additions: 4 L1 enum + 4 L1 marker + 3 L2 rehydration/hash invariant
The TestRunLoop_LiveTreeHashInvariant test lands the StatusDone case
only; follow-up fixture engineering for the other 4 status values is
tracked in bd issue na-1iv.
Plan: .agents/plans/2026-04-10-microepic-3-status-enum.md
Pre-mortem: .agents/council/2026-04-10-pre-mortem-microepic-3-status-enum.md
Closes known-limitation from .agents/council/2026-04-10-pre-mortem-microepic-2-cycle-history.md
Writes each Dream iteration to <outputDir>/<runID>/iterations/iter-N.json
via atomic CreateTemp -> Sync -> Rename -> fsyncDir, and rehydrates prior
iterations at RunLoop startup so a crashed or MEASURE-failed run resumes
with full history and a correct prevSnapshot baseline.
Fixes the 2026-02-22 evolve-overnight failure mode where a crashed run
silently lost iteration history and restarted from a fresh baseline.
Also fixes the pre-existing IterationID contract drift at loop.go:145:
the documented format at types.go:10 is "<run-id>-iter-<N>" but the
runtime generated just "iter-N". Now matches the documented contract.
Touches:
- cli/internal/overnight/iteration_store{.go,_test.go} (new)
- cli/internal/overnight/loop_testhooks.go (new; test-only fault hook)
- cli/internal/overnight/loop_resume_test.go (new; L2 resume + ID regression)
- cli/internal/overnight/loop.go (persist + rehydrate + ID fix + plateau replay)
- cli/internal/overnight/types.go (add required RunID field)
- cli/internal/overnight/{stages,boundary,overnight_e2e}_test.go (set RunID)
- cli/cmd/ao/overnight.go (wire summary.RunID into RunLoopOptions)
- docs/contracts/dream-report.md, docs/contracts/dream-run-contract.md
- skills/dream/SKILL.md, skills-codex/dream/SKILL.md (+ regen codex hashes)
Prevents direct recurrence of the 115-cycle runaway from 2026-02-22.
Plan: .agents/plans/2026-04-10-microepic-2-cycle-history.md
Pre-mortem: .agents/council/2026-04-10-pre-mortem-microepic-2-cycle-history.md
Dream nightly compounder plan rev 2, Wave 5 (Issues 11, 12, 13)
executed by two parallel workers.
Issue 11 — L2 e2e tests + 150+ learning fixture + frozen v1 reader:
- NEW cli/internal/overnight/fixture/gen_fixture.go: deterministic
fixture generator producing 150 learnings + 20 findings + 5
patterns + 3 knowledge files with realistic metadata distribution
(maturity mix 0.50/0.30/0.15/0.05, source_bead on 60%, utility
0.1-0.9, mtime spanning 180 days). Parked at fixture/ not
testdata/ because Go excludes testdata/ from package resolution.
Two non-obvious tunings: pseudo-random hex bodies avoid dedup
trigram overlap, and pattern[0] embeds all learning filenames to
avoid orphan pruning during REDUCE.
- NEW cli/internal/overnight/overnight_e2e_test.go: three L2 tests
driving INGEST + REDUCE + MEASURE against the full 150-learning
fixture. TestRunLoop_L2_FullIteration_CorpusQualityMoves asserts
catalog build, checkpoint, stage-order, metadata round-trip,
findings routed, next-work.jsonl written, and fitness vector
populated. TestRunLoop_L2_MetadataStripDetected exercises the
pm-005 regression at L2 scale with checkpoint rollback.
TestRunLoop_L2_CompoundFilterCliff_DoesNotSilentlyKillCorpus is
the pm-015 guard: asserts no corpus-quality metric drops by more
than 0.30 between iterations (the "cliff" threshold from
2026-04-02-flywheel-quality-fixes).
- NEW cli/cmd/ao/testdata/v1_reader/summary_v1.go: frozen v1
reader struct snapshot of overnightSummary at 2026-04-09 HEAD.
Only struct definitions, no methods, to prevent drift.
- EXTENDED cli/cmd/ao/overnight_test.go: added
TestRunOvernight_SchemaV2IsV1BackwardCompatible (pm-008 fix).
Constructs a minimal v2 summary, marshals it, unmarshals into
the frozen v1 reader, and asserts every v1 field is populated.
Previous tests untouched.
Issue 12 — Contract v2 bumps:
- docs/contracts/dream-run-contract.md: new v2 iteration-loop
section. Documents INGEST -> REDUCE -> MEASURE, the 5
checkpointed subpaths, 5 halt conditions, 5 anti-goals, 6 new
flags, startup recovery protocol, and the pm-011 concurrency
guard. V1 content + Wave 2's "Retrieval-bench determinism"
subsection preserved.
- docs/contracts/dream-report.md: Schema v2 section documenting
the 4 new top-level fields (iterations, fitness_delta,
plateau_reason, regression_reason) and the IterationSummary
shape (14 fields). Explicit backward-compat guarantee
referencing TestRunOvernight_SchemaV2IsV1BackwardCompatible.
Issue 13 — Skill docs:
- skills/dream/SKILL.md: added Compounding Loop (v2) section with
anti-goals, 3 new /dream start examples, iteration sub-summary
bullet in Output, Delineation vs /evolve table. 207/250 line
budget.
- skills/harvest/SKILL.md: nightly-usage blockquote pointing at
/dream start as the primary nightly driver and noting the
.agents/overnight/run.lock refusal during Dream runs.
- skills/evolve/SKILL.md: Delineation vs /dream section
(identical verbatim table to dream/SKILL.md — must be kept in
sync). Pointer added in See Also.
Verification:
- go build ./... OK
- go vet ./... OK
- go test ./internal/overnight/... all green (e2e + unit)
- go test ./cmd/ao/ all green (incl. schema v2 backward-compat)
- heal.sh --strict clean
- check-contract-compatibility.sh 0 failures / 0 warnings
Follow-up flagged (not blocking): skills-codex/ parity for dream/
harvest/evolve needs a pass of scripts/audit-codex-parity.sh +
regen-codex-hashes.sh to propagate the markdown changes.
Refs: plan Issues 11/12/13, pre-mortem pm-008/011/012/015.
Dream nightly compounder (plan rev 2). Lands Wave 1 skeleton and
Wave 2 parallel components per the file-conflict matrix.
Wave 1 — cli/internal/overnight/ skeleton:
- doc.go with package contract + anti-goals (no code mutation, no
/rpi, no git ops, no symlinks, no swarm)
- types.go with RunLoopOptions and normalize() defaults (2h budget,
6h max, K=2 plateau window, 0.05 regression floor, 512MB checkpoint
cap, 12h stale-lock threshold)
- loop.go with public RunLoop surface (stub for Wave 3 stage drivers)
Wave 2 — independent components (zero file overlap, 6 workers):
- checkpoint.go: two-phase-commit staging overlay with marker-file
crash-recovery protocol. VerifyMetadataRoundTrip computes set-diff
over ALL frontmatter keys (pm-005 fix — no hardcoded allowlist)
- fitness.go / plateau.go: FitnessSnapshot.Delta with per-metric
floors; PlateauState with K=2 minimum (pm-FEAS-08) and noisy-sample
absorption
- findings_router.go: scans .agents/findings/f-*.md, dedups against
next-work.jsonl by finding ID, regex-gates registry.json and
README.md (pm-MISS-06 fix)
- queue.go: evolve pinned-queue format parser
- cli/internal/lifecycle/close_loop.go: extracted from
cli/cmd/ao/flywheel_close_loop.go (pm-001 fix — the original plan
mis-identified feedback_loop.go as a close-loop stub;
feedback_loop.go is untouched). Dependency-injected ExecuteCloseLoop
lets Dream's REDUCE call close-loop in-process. cmd/ao adapter
preserves byte-for-byte stdout compatibility.
- cli/internal/corpus/: new package computing FitnessVector from the
local corpus. Dedicated cli/cmd/ao/corpus.go CLI (pm-002 fix —
corpus-quality stays OUT of the goals Directive subsystem).
- retrieval_bench.go + dream-run-contract.md: documented existing
determinism (pm-012 fix — no --seed flag added, would be dead work).
Tests: 58 new tests across internal/overnight, internal/corpus,
and internal/lifecycle, all L1 unit tests per AI-native test shape.
All passing. 50+ pre-existing close-loop-adjacent cmd/ao tests
preserved unmodified.
Build: go build ./... OK, go vet ./... OK, all three new package
test suites green.
Refs: .agents/plans/2026-04-09-dream-nightly-compounder.md (rev 2),
.agents/council/2026-04-09-pre-mortem-dream-nightly-compounder.md
(attempt 1 FAIL → 15 findings patched → attempt 2 WARN/PROCEED).
From codex/ag-wfo3 (91abb072) with conflict resolution:
- Keep main's proof-backed shouldSkipLegacyFailedEntry (CompletionEvidence check)
- Fix test to match readQueueEntries behavior (returns all non-consumed,
proof filtering is downstream via shouldSkipLegacyFailedEntry)
- next-work.schema.md doc updates
- docs/contracts/codex-skill-api.md: source of truth for Codex runtime
skill structure, frontmatter, discovery paths, multi-agent primitives
- scripts/validate-codex-api-conformance.sh: checks generated codex
skills against actual Codex API (baseline: 12 failures, 124 refs)
- Add contract to docs/INDEX.md
Wave 1 of strict-quality epic (ag-u5t), 4 issues in parallel:
- ag-u5t.1: git-worker-guard.sh blocks git commit/push/add-all for swarm workers
- ag-u5t.2: embedded_parity section in task-validation-gate auto-validates hook sync
- ag-u5t.3: validate-swarm-evidence.sh enforces fail-closed evidence validation
- ag-u5t.5: time_boxed phase result status in RPI phased runner
Also fixes: test harness cwd leak from bare cd in constraint-compiler tests,
adds test coverage for commit-review-gate, intent-echo, research-loop-detector.
173/173 hook tests pass. All Go tests pass. Embedded sync verified.
The headless RPI phase runner duplicated what `ao rpi` already does,
without its ratchet tracking, telemetry, or phased-state integration.
The real value was the test helper improvements and standards doc.
- Add bin/run-rpi-headless.sh: chains RPI phases as separate headless
Claude invocations, each invoking the actual skills (/research, /plan,
/crank, /vibe, /post-mortem) so the full skill chain executes
- Add docs/contracts/headless-invocation-standards.md: documents when to
use --dangerously-skip-permissions (skill chains) vs --allowedTools
(controlled prompts), timeout strategy, and session chaining
- Update test-helpers.sh: add --no-session-persistence, --max-budget-usd,
configurable ALLOWED_TOOLS env var (default: skip-permissions for tests)
- Update release-smoke-test.sh: add --no-session-persistence,
--max-budget-usd, scoped --allowedTools for fast test (no skill exec)
Key insight: skills chain skills — --allowedTools constrains the entire
session including tools used inside skill execution, so skill-invoking
workflows must use --dangerously-skip-permissions with timeout/budget
as the safety rails instead.