Fixes three onboarding defects that surfaced on 2026-04-15 when running
against a global ~/.agents corpus from a non-git home directory:
1. `ao compile --full` failed in the installed bundle with
"open skills/compile/scripts/compile.sh: file does not exist". The
Makefile's sync-hooks target never copied compile.sh into
cli/embedded/skills/, so the //go:embed all:skills fallback had
nothing to fall back to. Fix: sync-hooks now seeds the script and a
regression test (TestMaterializeCompileScriptFallsBackToEmbedded)
asserts the embedded copy resolves when no local skills/ exists.
2. Headless compile implicitly required OLLAMA_HOST / OPENAI_API_KEY /
ANTHROPIC_API_KEY with no actionable error when none were set, and
ignored a locally installed `claude` CLI. Fix: resolveCompileRuntime
auto-detects the `claude` binary and selects claude-cli runtime (no
API key needed — inherits Claude Code auth). preflightCompileRuntime
fails fast with an actionable error naming the exact env var to set.
compile.sh gains a matching claude-cli backend and a --preflight flag.
3. The headless compiler concatenated all changed files into one LLM
prompt, which is unworkable on 2000+ file corpora. Fix: compile.sh
batches by --batch-size (default 25) and --max-batches (default
unlimited); ao compile propagates both flags.
Onboarding gaps:
- $quickstart now detects a global ~/.agents corpus (GLOBAL_AGENTS=true)
and, when GIT=false + AO=true, surfaces a harvest → compile →
knowledge-activation path instead of only suggesting `git init`.
- Harvest SKILL.md clarifies that promotion writes to ~/.agents/learnings/
(not ~/.agents) and adds a "which skill do I need?" decision table.
- Compile SKILL.md documents the claude-cli runtime and batching flags.
- skills-codex/compile/scripts/compile.sh wrapper now falls back through
multiple candidate paths and finally delegates to `ao compile`, so an
installed bundle without a sibling skills/ checkout still works.
Tests added:
- TestMaterializeCompileScriptFallsBackToEmbedded
- TestResolveCompileRuntime
- TestPreflightCompileRuntimeErrors (5 subtests)
- TestPreflightCompileRuntimeSuccess
- TestCompileScriptOptionsPassesBatchFlags
- TestQuickstartSkillCoversGlobalCorpus (both parity surfaces)
Verification:
cd cli && go vet ./... && go test ./... # all green
bash skills/heal-skill/scripts/heal.sh --strict # clean
bash tests/docs/validate-doc-release.sh # PASS
bash scripts/check-contract-compatibility.sh # 0 failures
bash scripts/regen-codex-hashes.sh # 3 skills rehashed
bash scripts/generate-cli-reference.sh # COMMANDS.md regenerated
Add -shuffle=on to go test in validate.yml and Makefile to detect
test ordering dependencies at CI time.
Fix 5 tests that failed under shuffle:
- TestCobraIndexCheckCommand: add resetCommandState(t)
- TestDoctor_Integration_*: add resetCommandState(t) + env isolation
- TestMaturity_Integration_ScanPendingTransitions: add env isolation
- TestInjectForFlag_NoDeclaration: add env isolation
- TestRunGoals_GoroutineLeak: use goleak.IgnoreCurrent() to avoid
false positives from parallel test subprocess cleanup
Root causes: leaked cobra flag values, missing maturity var resets in
testutil, and missing AGENTOPS_RPI_RUNTIME env var isolation.
Doctor was reporting 3 false warnings after the Codex-native migration:
- Plugin check missed ~/.codex/skills/ (only searched ~/.claude/, ~/.agents/)
- Search index hint referenced old flat "ao store rebuild" command
- Version display showed "vv2.18.2" (double v prefix from ldflags)
Also:
- Add check-doctor-health.sh to ci-local-release.sh Phase 2
- Fix make install to run build first (ensures embedded sync)
- Add formatVersion unit test
Go/clang defaults the Mach-O identifier to `a.out` with ad-hoc signature,
causing syspolicyd to repeatedly scan the binary during hook-driven workflows.
Add post-build codesign step (Identifier=com.12factoragentops.ao) to Makefile
build/install targets and GoReleaser Homebrew post_install.