mirror of
https://github.com/boshu2/agentops.git
synced 2026-09-14 15:08:13 +08:00
2821992965
Plan rev 2 post-mortem queued 10 follow-up issues; this commit lands
Wave 1 (9 independent issues, parallel workers, zero file conflicts).
Wave 2 (Issue 5 wiring INGEST to real entry points) follows in the
next commit.
Wave 1 issues:
Issue 1 — harvest.WalkOptions.SkipGlobalHub + 2 consumers:
- harvest/walker.go adds the flag, guards the ~/.agents/ auto-include
- corpus/fitness.go opts in so corpus.Compute is hermetic (V8 fix)
- overnight/ingest.go opts in for Dream's private-lane harvest
- 2 new tests: TestDiscoverRigs_SkipGlobalHub_OmitsHome,
TestCompute_Hermetic_DespitePopulatedHome
Issue 2 — forge.RunMinePass in-process entry point:
- NEW cli/internal/forge/runmine.go (272 LOC): pure-extraction
consumer-side entry (mines already-forged sessions, distinct from
cobra's producer-side transcript path).
- cli/cmd/ao/forge.go: thin adapter (+18 LOC); cobra RunE untouched
- 6 new L1 tests in cli/internal/forge/runmine_test.go
Issue 3 — mine.Run in-process entry point:
- cli/internal/mine/mine.go: 134 → 587 LOC (pure extract of git,
agents, code sources; Option B dependency-injection for events
source which depends on cmd/ao internals)
- cli/cmd/ao/mine.go: 580 → 292 LOC (-288), becomes a thin adapter
with type aliases preserving byte-identical cmd/ao shape
- 14 new L1 tests in cli/internal/mine/mine_test.go
Issue 4 — provenance.Audit in-process entry point:
- cli/internal/provenance/provenance.go: +146 LOC adding Audit,
AuditReport, parseLearningFrontmatter, parseLearningDate
- cli/cmd/ao/rpi_phased_provenance.go: thin adapter (+12 LOC)
- 2 new L1 tests
Issue 6 — iterationID sanitization (V9/S1/S2):
- checkpoint.go: sanitizeIterationID helper rejecting /, \, .., empty,
non-printable, whitespace. Called from NewCheckpoint.
- recovery.go: same check in RecoverFromCrash after TrimPrefix extract.
- findings_router.go: findingFilenameRe post-match validated via
time.Parse("2006-01-02") so f-9999-99-99-001.md is rejected.
- 3 new L1 tests
Issue 7 — Stage-order recording hook + test (V6):
- reduce.go: package-level reduceStageRecorder var + call from each
of the 7 REDUCE stages' run closures (nil by default in production).
- stages_test.go: TestRunReduce_FullStageOrder_Enforced asserts the
exact seven-stage order via reflect.DeepEqual.
Issue 8 — Post-commit metadata re-verification (V7):
- checkpoint.go: VerifyMetadataRoundTripPostCommit walks cp.PrevDir
(pre-REDUCE baseline) vs cp.LiveDir (post-Commit live tree),
legitimately-deleted files skipped, strips flagged.
- loop.go: call added AFTER cp.Commit() succeeds, ratchet-forward
(logs a finding, does not unwind). logPostCommitFinding helper
writes to .agents/findings/f-<date>-postcommit-iter-<N>.md
which intentionally does NOT match findingFilenameRe so the
router skips it and it surfaces as a morning-report WARN only.
- overnight_e2e_test.go: TestRunLoop_PostCommitMetadataCheck_LogsFinding
simulates a strip, asserts the finding file is written with the
correct name.
Issue 9 — Package-level TestMain for HOME isolation:
- NEW cli/internal/overnight/overnight_testmain_test.go: TestMain
runs for every test in the package, sets HOME to a temp dir,
pre-creates .agents/learnings so harvest.Promote has a target.
Belt-and-suspenders backup to per-test t.Setenv("HOME", ...) guards.
Issue 10 — check-home-isolation.sh CI gate + pre-push wiring:
- NEW scripts/check-home-isolation.sh: grep-based gate catching Go
test files that reference harvest.*/RunIngest(/harvest.Promote
without t.Setenv("HOME", ...) or a package-level TestMain guard.
Kill switch: CHECK_HOME_ISOLATION_DISABLED=1.
- scripts/pre-push-gate.sh: new check 3b wired after the existing
Go-file section, gated on needs_check go.
- Immediately caught cli/cmd/ao/flywheel_e2e_test.go — fixed inline
with per-test t.Setenv("HOME", t.TempDir()) on all 5 TestFlywheelE2E_*
functions. Defense-in-depth; the tests already used t.TempDir for
promoteDir, so the fix is belt-and-suspenders not a latent bug fix.
Issue 11 — skills-codex parity pass (dream, harvest, evolve):
- skills-codex/dream/SKILL.md: added "Compounding Loop (v2)" section,
3 new $dream start examples, iteration sub-summary output bullet,
"Delineation vs $evolve" table — matching the parent-slice updates
to skills/dream/SKILL.md.
- skills-codex/harvest/SKILL.md: added nightly-usage blockquote.
- skills-codex/evolve/SKILL.md: added "Delineation vs $dream" table
before ## Flags.
- regen-codex-hashes.sh run post-edit to update .agentops-generated
checksums.
Key finding (follow-up bead worth filing):
- scripts/audit-codex-parity.sh reports green even when entire
sections are missing from skills-codex. It catches hash drift
but not semantic content drift. Manual grep was needed to detect
Wave 5 parent-slice updates missing from the codex copies. Tighten
the audit to flag missing headings/sections that exist in
skills/<name>/ but not skills-codex/<name>/.
Gates:
- go build ./... OK
- go vet ./... OK
- go test ./internal/overnight/... ./internal/corpus/... \
./internal/harvest/... ./internal/forge/... \
./internal/mine/... ./internal/provenance/... OK
- go test ./cmd/ao/ (full suite, 183s) OK
- scripts/check-home-isolation.sh PASS
- heal.sh --strict clean
- scripts/regen-codex-hashes.sh 3 skills updated
Parent refs:
- .agents/plans/2026-04-09-dream-followups.md
- .agents/council/2026-04-09-pre-mortem-dream-followups.md
- .agents/plans/2026-04-09-dream-nightly-compounder.md (parent plan)
- .agents/rpi/phase-2-summary-2026-04-09-crank.md (follow-up source)
- .agents/rpi/phase-3-summary-2026-04-09-dream-nightly-compounder.md
106 lines
3.6 KiB
Bash
Executable File
106 lines
3.6 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
#
|
|
# check-home-isolation.sh
|
|
#
|
|
# Warn-then-fail CI gate: any Go test file in cli/ that references
|
|
# harvest.Promote, harvest.DiscoverRigs, RunIngest, or any code path
|
|
# that transitively writes to $HOME/.agents/learnings MUST also
|
|
# isolate HOME via t.Setenv("HOME", ...) or a package-level TestMain.
|
|
#
|
|
# Without this guard, tests silently poison the operator's real
|
|
# global hub on every run. This exact bug was caught during Phase 3
|
|
# validation of the Dream nightly compounder on 2026-04-09 — 150
|
|
# synthetic fixture files leaked into ~/.agents/learnings/learning/
|
|
# and had to be manually deleted.
|
|
#
|
|
# Kill switch: set CHECK_HOME_ISOLATION_DISABLED=1 to bypass locally.
|
|
#
|
|
# Exit codes:
|
|
# 0 = pass (zero offending test files)
|
|
# 1 = fail (one or more offending test files)
|
|
# 2 = script error (bad invocation, missing cli/ dir)
|
|
|
|
set -euo pipefail
|
|
|
|
if [[ "${CHECK_HOME_ISOLATION_DISABLED:-}" == "1" ]]; then
|
|
echo "check-home-isolation: disabled via CHECK_HOME_ISOLATION_DISABLED=1"
|
|
exit 0
|
|
fi
|
|
|
|
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
CLI_DIR="${REPO_ROOT}/cli"
|
|
|
|
if [[ ! -d "$CLI_DIR" ]]; then
|
|
echo "check-home-isolation: cli/ not found at ${CLI_DIR}" >&2
|
|
exit 2
|
|
fi
|
|
|
|
# Patterns that indicate a test path might write to the global hub.
|
|
TRIGGER_PATTERN='harvest\.Promote|harvest\.DiscoverRigs|RunIngest\('
|
|
|
|
# Patterns that indicate the test file isolates HOME.
|
|
# Either a per-test t.Setenv("HOME", ...) OR a package-level TestMain
|
|
# that sets HOME counts as isolation.
|
|
HOME_ISOLATION_PATTERN='t\.Setenv\("HOME"|os\.Setenv\("HOME"'
|
|
|
|
# Additionally, if a test file lives in a package that has a
|
|
# TestMain isolation (e.g., cli/internal/overnight/overnight_testmain_test.go),
|
|
# tests in that package inherit the TestMain guarantee and don't
|
|
# need per-test calls.
|
|
#
|
|
# Detect this by checking each test file's parent directory for any
|
|
# file named "*testmain*_test.go" that contains TestMain + Setenv HOME.
|
|
|
|
failed=0
|
|
offending_files=()
|
|
|
|
while IFS= read -r file; do
|
|
# Skip if no trigger pattern in this file.
|
|
if ! grep -qE "$TRIGGER_PATTERN" "$file" 2>/dev/null; then
|
|
continue
|
|
fi
|
|
|
|
# Per-file isolation present? Pass.
|
|
if grep -qE "$HOME_ISOLATION_PATTERN" "$file" 2>/dev/null; then
|
|
continue
|
|
fi
|
|
|
|
# Package-level TestMain with HOME isolation? Walk the package dir.
|
|
pkg_dir="$(dirname "$file")"
|
|
testmain_isolated=0
|
|
for tm in "$pkg_dir"/*testmain*_test.go; do
|
|
[[ -f "$tm" ]] || continue
|
|
if grep -q "TestMain" "$tm" 2>/dev/null && \
|
|
grep -qE "$HOME_ISOLATION_PATTERN" "$tm" 2>/dev/null; then
|
|
testmain_isolated=1
|
|
break
|
|
fi
|
|
done
|
|
if [[ $testmain_isolated -eq 1 ]]; then
|
|
continue
|
|
fi
|
|
|
|
# Neither per-file nor package-level isolation — fail this file.
|
|
offending_files+=("$file")
|
|
failed=$((failed + 1))
|
|
done < <(find "$CLI_DIR" -name "*_test.go" -type f 2>/dev/null)
|
|
|
|
if [[ $failed -gt 0 ]]; then
|
|
echo "check-home-isolation: FAIL ($failed file(s) use harvest.* without HOME isolation)" >&2
|
|
echo "" >&2
|
|
for f in "${offending_files[@]}"; do
|
|
echo " $f" >&2
|
|
done
|
|
echo "" >&2
|
|
echo "Fix: add 't.Setenv(\"HOME\", t.TempDir())' at the top of each test function," >&2
|
|
echo "or add a package-level TestMain that sets HOME before m.Run()." >&2
|
|
echo "" >&2
|
|
echo "Background: Phase 3 validation of the Dream nightly compounder caught this" >&2
|
|
echo "exact bug. Tests that call harvest.Promote or RunIngest without isolation" >&2
|
|
echo "write to ~/.agents/learnings/ for real, poisoning the operator's corpus." >&2
|
|
exit 1
|
|
fi
|
|
|
|
echo "check-home-isolation: PASS (no test files missing HOME isolation)"
|
|
exit 0
|