Two more false-positive patterns the previous heuristics missed:
1. Command-catalog maps in cobra_commands_test.go:
"beads": {"harvest", "lint", "verify"}
"corpus": {"fitness"}
A grouped-by-parent regex now recognizes these.
2. Go handler naming convention `run<Title><Case>` (e.g. runConfigModels,
runOvernightSetup). Tests frequently call handlers directly rather than
dispatching through cobra. A runXxx probe closes the gap.
Effect: uncovered count drops from 13 → 8. Remaining 8 (`beads audit`,
`beads cluster`, `flywheel compare`, `overnight curator compact|diagnose|
enqueue|event|status`) are genuinely uncovered — their run* handlers exist
in source but are not exercised from any test.
`ao doctor health` was reporting "heal.sh timed out after 30s" on cold
checkouts where `heal.sh --strict` legitimately takes ~60s to walk the
full skills tree. The false-positive warning masked real integrity
regressions and pushed operators toward ignoring doctor output.
Raise the default timeout to 120s (enough margin over observed 45-75s
runs) and add an `AO_DOCTOR_HEAL_TIMEOUT` env override for slower hosts.
The timeout helper is an unexported pure function with tests covering
default, valid override, and invalid/garbage override (falls back to
default — never zero).
The parity gate was missing test coverage that exists in real unit tests
because its detection relied only on literal "ao <cmd>" string matches.
Add two fallbacks:
1. Dedicated test-file heuristic (`<cmd>_test.go`, `<cmd>_*_test.go` with
spaces/hyphens mapped to underscores). Picks up handoff, harvest,
retrieval-bench, overnight setup, rpi serve.
2. Go executeCommand/SetArgs heuristic for multi-word commands: matches
`"scenario", "list"` split across comma-separated string args. Picks up
scenario list, scenario validate.
Use `find` instead of `ls` for the file-existence probe so the script no
longer trips over `set -euo pipefail` when a glob matches nothing.
Effect: uncovered-command count drops from 20 → 13 with zero new tests
needed; remaining 13 are genuinely uncovered (beads subcommands, overnight
curator subcommands, config models, corpus fitness, flywheel compare).
The fixture repo at mktemp inherits the operator's global git config. On hosts
where commit.gpgsign=true with a signing program that requires real keys
(e.g. gpg.ssh.program=/tmp/code-sign used by managed workstations), the
fixture commit fails and the whole skill lint suite fails.
Set commit.gpgsign=false and tag.gpgsign=false inside the fixture so the
test works regardless of global signing configuration.
CI installs Mike Farah's Go yq (supports `-o json`), but many Linux distros
ship the kislyuk Python yq (jq wrapper that emits JSON by default). The
previous `yq -o json '.'` call aborted on the Python variant and printed
"invalid YAML frontmatter" for every skill, masking real schema errors.
Detect the variant once via `yq --help` and route through a shared
`yq_to_json` helper so both variants produce identical JSON input to the
jsonschema/jq validators.
Effect: `scripts/validate-skill-schema.sh` now reports 69/69 PASS on hosts
with the Python yq instead of 0/69 FAIL; CI behavior on the Go yq is
unchanged.
Commit 8e0da39d "Remove lowercase docs index" removed docs/index.md,
but mkdocs.yml's `nav:` still points to `Home: index.md`. With
`mkdocs build --strict` the missing-nav-target warning becomes fatal,
breaking Pages deploys since 2026-04-21.
docs/INDEX.md (uppercase) is a contributor TOC and is not interchangeable
with the styled landing page. Restoring the 237-line landing from
8e0da39d^ fixes the strict build without touching the TOC.
Inventory of 92 .agents/ directories across WSL + /mnt/c + /mnt/d
with content-hash dedup. Found 1,642 artifact files (59% unique,
41% duplicates) and flagged platform-lab double-checkout, 510K
AppleDouble phantoms on /mnt/d/archive/mac-extract, and stale ao
binary (v2.26.1 pre-harvest-command).
- .agents/harvest/cross-disk-2026-04-19T19-52-54.json: Python walker catalog
- .agents/harvest/latest.md: human report
- .agents/plans/2026-04-19-cross-disk-harvest-cleanup.md: 6-task execution plan (T1-T6)
Wave 1 already executed this session: ao rebuilt to v2.37.2+ with Go 1.26.2,
AppleDouble metadata purged, platform-lab consolidated to ~/dev/personal.
Wave 2+ (ao harvest --min-confidence 0.9 promotion) also executed — +125
items to ~/.agents/learnings/.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Add tests for pure helpers in cli/cmd/ao/knowledge_*.go that were
previously untested. Covers parsing, formatting, and classification
helpers without touching real filesystems or external commands.
https://claude.ai/code/session_01EMusoGMSUSbtPqkotJy3U7
The 2026-04-22 nightly-dream-cycle learning
(.agents/learnings/2026-04-22-close-loop-citation-gate-deadlock.md) lists
three corrective actions for the chicken-and-egg promotion deadlock that
silently zeroed throughput for weeks:
1. Split admission gates by path — DONE (b69a00f)
2. Parameterize shared helpers (requireCitations bool) — DONE (b69a00f)
3. Fail loudly if ingested > 0 && promoted == 0 — this commit
Prior to this commit, scripts/nightly-dream-cycle.sh reported both numbers
in the summary but never asserted their relationship, so the deadlock
surfaced only in downstream metrics (sigma=0, escape_velocity=false) —
exactly the "quietly posting another zero-throughput status issue" pattern
the learning warns against.
Changes:
- scripts/check-dream-throughput.sh (new): standalone gate consuming
'ao flywheel close-loop --json'. Exits 1 on the deadlock pattern
(added > 0 && promoted == 0), 0 on healthy / no-op, 2 on bad input.
Uses the same pattern as the sibling check-compile-*.sh gates.
- scripts/nightly-dream-cycle.sh: invokes the gate after the summary
artifacts are written (so uploads still succeed) and exits non-zero
when a stall is detected. NIGHTLY_DREAM_STRICT=0 downgrades to warn
for diagnostic runs. The summary.json grows a
close_loop.throughput_stalled bool; the summary.md renders a banner
above the stage table when the stall fires, so the auto-filed
"Nightly dream cycle status" issue leads with it.
- tests/scripts/check-dream-throughput.bats (new): 8 cases covering
healthy, empty-run, deadlock, missing input, no-arg, non-integer
input, and missing keys.
Verified locally against all 8 cases via direct bash invocation
(bats is not available in this environment); shell syntax validated
with 'bash -n' on both scripts.
check-go-absolute-complexity.sh exited 2 with a manual-install hint when
gocyclo was missing, which surfaced go-complexity-ceiling (weight=6) as a
FAIL on any machine whose PATH did not already have gocyclo even though
the repo's code was clean.
Auto-install gocyclo into GOBIN (or $GOPATH/bin) when 'go' is available,
then retry. Provide GOCYCLO_NO_AUTOINSTALL=1 as an opt-out for CI (which
already pre-installs gocyclo in validate.yml) and for offline runs.
Fitness (post-cycle2 -> post-cycle3):
go-complexity-ceiling (w=6): fail -> pass
Verified:
rm /root/go/bin/gocyclo; ao goals measure --goal go-complexity-ceiling
-> auto-install + pass
GOCYCLO_NO_AUTOINSTALL=1 bash scripts/check-go-absolute-complexity.sh
-> exits 2 with install hint (CI-compatible)
https://claude.ai/code/session_015RK27PGX79MsGU5XUhBxkr
compile-freshness and compile-no-oscillation both require .agents/defrag/
latest.json, a local-only artifact that is .gitignored. On machines that
run Dream but not a manual `ao defrag`, both gates fail with "not found"
even though Dream has just written a fresh defrag preview at
.agents/overnight/<run>/defrag/latest.json with the same JSON shape.
- check-compile-health.sh: when the canonical path is missing and
COMPILE_OUTPUT_DIR is unset, fall back to the freshest overnight
preview. CI paths (which set COMPILE_OUTPUT_DIR) remain strict.
- scripts/check-compile-oscillation.sh: new helper that mirrors the
freshness gate's fallback and runs the oscillating-goals jq filter.
- GOALS.md: replace the inline compile-no-oscillation bash with a call to
the new script so the fallback applies there too.
Fitness (post-cycle1 -> post-cycle2):
compile-freshness (w=4): fail -> pass
compile-no-oscillation (w=4): fail -> pass
Verified:
ao goals measure --goal compile-freshness -> pass
ao goals measure --goal compile-no-oscillation -> pass
ao goals validate -> valid: true
heal.sh --strict -> clean
https://claude.ai/code/session_015RK27PGX79MsGU5XUhBxkr
The flywheel-proof gate regressed after b69a00f4 (fix(flywheel): unblock
close-loop auto-promotion). close-loop now auto-promotes candidates in the
same call, so the Phase 2 assertion "pool candidate exists in pool/pending
after ingest" fired after the candidate had already moved to promoted. This
broke the downstream cite -> promote exercise in Phase 3.
Split the test's staged view: Phase 2 exercises ingest in isolation (via
ao pool ingest --json, a flat {added: N} shape) so the candidate stays in
pool/pending. Phase 3 is unchanged and still exercises the citation ->
close-loop -> promoted artifact path.
Fitness: flywheel-proof (weight=7) pass -> fail -> pass (restored).
Verified locally: bash tests/e2e/proof-run.sh -> 20 checks PASS.
https://claude.ai/code/session_015RK27PGX79MsGU5XUhBxkr
Addresses a batch of documentation improvements identified in a full-docs
audit. The goal is to reduce newcomer friction from dead links and missing
canonical references, and to give skill/plugin authors explicit pages for
hooks, schemas, and version migration that were previously implied only by
source code.
Navigation fixes:
- docs/INDEX.md and docs/newcomer-guide.md pointed to the wrong path for
the CLI reference (cli/commands.md vs. the real cli/docs/COMMANDS.md).
Replace with the canonical github URL so both mkdocs and raw-GitHub
readers land on the file.
- INDEX.md Getting Started section now opens with a "pick your path"
router so evaluators, installers, contributors, and upgraders don't
have to triangulate across three overlapping entry points.
- Link docs/getting-started/index.md from INDEX.md (was previously
orphaned) and add an "Install verification" block pointing at ao doctor.
New pages:
- docs/HOOKS.md: user-facing orientation covering lifecycle events,
install/uninstall, customization env vars, and common failure modes,
pointing to cli/docs/HOOKS.md for the deep technical reference.
- docs/SCHEMAS.md: catalog of every JSON Schema under schemas/ and
lib/schemas/, grouped by manifest vs. runtime artifact vs. internal
contract, with validation commands.
- docs/UPGRADING.md: action-required version migration guide. Seeds
Unreleased (2.38.x) and 2.37.x sections covering strict delegation,
--no-lifecycle -> --no-scaffold rename, Olympus bridge removal,
swarm-evidence schema enforcement, and pre-mortem gate tightening.
Reference quality:
- GLOSSARY.md: 11 new terms (.agents/, MEMORY.md, Compact/PreCompact,
Compile, Context Window, Discovery, Dream/Overnight Run alias,
Flywheel Health, Harvest, Holdout, RPI Phase, Session Lifecycle).
- troubleshooting.md: three new failure-mode sections (pre-mortem gate,
go-test-precommit block, context-window compaction recovery).
- CONTRIBUTING.md: escalates the sync-skill-counts.sh requirement from
an easily-missed sentence to a bold callout with CI-failure rationale.
mkdocs.yml: registers the three new pages in nav so they're reachable
from the published site and pass strict build.
Validation:
- tests/docs/validate-links.sh: 1553 links checked, 0 broken.
- tests/docs/validate-doc-release.sh: PASS.
- scripts/docs-build.sh --check: new docs introduce 0 warnings (the
single remaining preexisting warning about index.md is out of scope).
Close the skills/skills-codex ecosystem gaps surfaced by the recent audit:
- docs/SKILLS.md now lists all 69 skills. Added an "Additional Skills" table
covering the 21 previously undocumented entries (autodev, bootstrap, compile,
deps, design, discovery, goals, grafana-platform-dashboard, harvest, perf,
push, readme, red-team, refactor, reverse-engineer-rpi, review, scaffold,
scenario, security, security-suite, test). Removed stale `/knowledge` router
alias and nonexistent `extract` internal-table row.
- Added `scripts/validate.sh` behavioral contracts to the 16 skills that lacked
one (autodev, bootstrap, deps, design, discovery, dream, harvest, llm-wiki,
perf, red-team, refactor, review, scaffold, scenario, test, validation).
Each encodes skill-specific assertions beyond the frontmatter check. Coverage:
53/69 -> 69/69.
- Fixed `scripts/check-codex-parity-drift.sh` which was a silent no-op: it
passed a non-existent --check flag to audit-codex-parity.py, swallowed the
argparse error via `|| true`, then grep'd for strings the audit never emits.
Now uses the exit code + JSON output and correctly fails on drift.
- Added `scripts/check-skill-size.sh` (warn>500, fail>800 lines) to flag
oversized SKILL.md files that should decompose into references/*.md. Current
state: 6 warnings (crank/implement/post-mortem/release/swarm/vibe), 0 fails.
Hygiene sweep: heal.sh --strict clean, codex parity audit clean, 69/69
validators green, size-lint reports no failures.
https://claude.ai/code/session_014AgjT36REb94fjL7sxrnFf
Register cobra flag completions so `ao <cmd> --<flag> <TAB>` surfaces
the valid enumerated values instead of falling back to file completion:
- ao --output: json, table, yaml
- ao seed --template: generic, go-cli, python-lib, rust-cli, web-app
- ao goals init --template: same set (derived from lifecycle.ValidTemplates)
- ao inject --format: json, markdown
- ao inject --session-type: brainstorm, career, debug, implement, research
The seed/goals-init template lists are derived from lifecycle.ValidTemplates
so completion stays in lockstep with validation. L2 integration tests
exercise the registered cobra completion functions directly and assert the
exact value set + ShellCompDirectiveNoFileComp directive.
https://claude.ai/code/session_01KvJRtiQRZY38PVxNZ7S6Rm
Nightly dream cycle (issue #117) reported 43 candidates ingested with zero
auto-promoted, indexed, or citation-rewarded every night, yielding sigma=0,
rho=0, escape_velocity=false. Loop-dominance also reported "B1" dominant
even when r1=b1=0.
Three linked fixes:
1. checkPromotionCriteria demanded >=2 citations for every candidate. The
function is shared between the manual pool batch-promote path (where
citation signal is the right gate) and the automated flywheel close-loop
path (where scoring tier already established signal). Fresh candidates
cannot be cited before they surface, so the gate was a deadlock: nothing
promoted -> nothing indexed -> nothing cited -> nothing promoted. Add a
requireCitations parameter; batch-promote passes true (preserved
behavior), close-loop passes false.
2. computeLoopDominance defaulted Dominant to "B1" and only flipped to "R1"
when r1 > b1, so an all-zero or tied state lied about which loop was
winning. Use a switch that reports "none" when neither strictly dominates.
3. Add a learning capturing the chicken-and-egg-gate pattern, which also
closes the "performance" query gap in retrieval-bench (was 0 hits, now 1;
live-retrieval coverage: 90% -> 100%).
End-to-end verification with scripts/nightly-dream-cycle.sh:
auto_promote.promoted: 0 -> 46
store.indexed: 0 -> 46
loop_dominance: "B1" -> "none"
retrieval coverage: 0.90 -> 1.00
https://claude.ai/code/session_01SJeBFbtnMJMbUgwZPx4xqg
Dream's findings-router round-tripped the final line through a JSON parse
and re-emit during tonight's overnight run (nightly/2026-04-21). The
differences are purely cosmetic:
- `<name>` encoded as <name> (equivalent Unicode escape)
- null-valued claimed_by / claimed_at keys dropped (outer record keeps
the same fields, so the null entries were redundant)
No item consumed-state changes; the sweep from commit ae84b8bf against the
"Skill() -> $skill notation" item is intentionally left for the next
Dream pass to reconcile via its resolution-detector sweep.
https://claude.ai/code/session_01TZeRkm97SrPchDwPsD41rd
The worker guard's bulk-staging block lowercased the command before matching
`*git add -a*`, which could match `-a` + `-u` clusters or (more subtly) any
text starting with `-a` after `git add `. Legitimate selective patterns like
`git add -u` (update-only) happened to slip past only because `-u` doesn't
contain `-a`, but the intent was already murky.
Split the patterns:
- commit/push/--all/. match against the lowercased command (subcommand
names can reasonably be case-insensitive in alias contexts)
- `-A` is checked against the raw command, so only the uppercase bulk flag
trips the block
Adds four regression tests: `-A` still blocks, `--all` still blocks,
selective `-u` is allowed, filenames containing `-a` are allowed.
Embedded hook copy resynced via `make sync-hooks`.
https://claude.ai/code/session_01TZeRkm97SrPchDwPsD41rd
Unblocks CI on this PR. Both were pre-existing drift on main:
- cli/embedded/.../test-pyramid.md: re-ran `cd cli && make sync-hooks`
to match source under skills/standards/references/. Fixes the
embedded-sync and go-build `Verify embedded hooks in sync` gates.
- skills-codex/{crank,quickstart,standards}/.agentops-generated.json
and skills-codex/.agentops-manifest.json: re-ran
`scripts/regen-codex-hashes.sh`. Fixes the codex-runtime-sections
`Validate Codex generated artifacts` gate.
https://claude.ai/code/session_01W5b6kSdX9wEDgXfVGCXTZa
The vertical `│` and corner `┘` on the "Better next session" loop sat
at column 70, one past "Gates" (which ends at column 69). The diagram
visually hung off the right edge.
Moved both to column 69 so the loop closes directly under the "s" of
"Gates". Rebalanced the horizontal fill (22 `─` before text, 21 after)
to preserve loop text centering.
Per council review on the doctrine-backlinks PR: "Each factor maps
to concrete tooling" overclaims. The mapping isn't 1:1 and isn't
shown in the README, so the sentence relies on the doctrine site
to clarify — which invites a skeptic to spot-check and fail.
Softens to "The AgentOps product implements these principles through
skills, the ao CLI, and local bookkeeping in .agents/" — accurate
without making a specific mapping claim the README can't defend.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Closes a discoverability gap: stargazers who land on this repo had no
link to the 12-factor doctrine that explains why AgentOps is shaped
the way it is. Two additions:
- Top quick-nav row gains Doctrine -> 12factoragentops.com link
- New "The 12-Factor Doctrine" section near the end with a tier table
(Foundation, Flow, Knowledge, Scale) and links to the site
Keeps the README product-first; doctrine framing is a feature of
AgentOps, not a parallel brand.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Previous landing was too abstract ("operational layer") and buried the
skills behind a catalog link. Rewrite to:
## docs/index.md
- Open with the concrete problem: "Coding agents don't do their own
bookkeeping" → session 15 rediscovers session 1's lessons without
AgentOps
- Add "The primary use case" section with the 4-layer table (bookkeeping,
validation, primitives, flows) and the flywheel diagram
- Add "See It Work" section with actual terminal examples of /council
and /rpi so readers see what the system does, not just what it is
- Add "The headline skills" table with 9 skills + "use it when" framing
(matches README.md)
- Add "Advanced: Day Loop and Night Loop" explaining /evolve and /dream
- Tabbed install blocks for Claude Code / Codex / OpenCode + ao CLI
## docs/_hooks/gen_skill_pages.py — skills/index.md generator
- Replace generic "Featured Workflows" with the same 9-skill headline
table + use-case framing (consistent with landing and README)
- Reorganize complete catalog into 8 family groups (Validation, Flows,
Bookkeeping, Session, Product, Utility, Platform, PR workflow) so
readers can navigate 69 skills by purpose instead of alphabet
- "Related references" card block moved to the bottom
Both pages now answer "what is this and which skills do I try first"
before linking to the exhaustive catalog.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
doc-release-gate was failing because skills/rpi/SKILL.md and siblings link
to .agents/learnings/2026-04-19-orchestrator-compression-anti-pattern.md
which lived only in a local gitignored dir. Force-add the file (other
learnings in .agents/learnings/ are force-added too).
codex-runtime-sections was failing because skills-codex/shared/SKILL.md
was edited in 2385dbd4 to link the strict-delegation contract but the
manifest hash wasn't regenerated. Run scripts/regen-codex-hashes.sh.
Also force-add .agents/learnings/2026-04-19-quick-strict-delegation-70min-meta-change.md
(referenced from the 2026-04-19 post-mortem report; same ignored-dir issue).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
## doc-release-gate (link validation)
- tests/docs/validate-links.sh: fix canonical-path assignment bug where
inline `|| fallback` never fires if the outer $() assignment itself
does not fail. Rewrite as explicit if-else so mkdocs-generated paths
(docs/skills/*.md, docs/cli/*.md) resolve correctly in CI environments
where those directories don't exist on disk.
## skill-lint + skill-integrity + go-build (TestSkillContract_ReferencesLinkedInSKILLMD)
- Add strict-delegation-contract.md link to skills/shared/SKILL.md and
skills-codex/shared/SKILL.md Reference Documents sections (heal.sh
--strict requires every references/*.md to be linked in its SKILL.md).
- Extend tests/skills/lint-skills.sh regex to support ../shared/references/
paths in addition to skills/<name>/references/ — matches heal.sh behavior.
## markdownlint
- Disable MD030 (list-marker-space) in .markdownlint.json. Material theme
grid-cards syntax uses 3 spaces after `-` which is standard for multi-line
items; markdownlint default of 1 space conflicts. 61 violations → 0.
## contract-compatibility-gate + smoke-test (next-work parity)
- .agents/rpi/next-work.jsonl: fix invalid enum values for the
2026-04-19-rpi-dag-hardening entry. Type "enhancement" → "process-improvement",
source values normalized to valid enum (council-finding, retro-learning,
backlog-processing).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
## 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>