Reasoning bank entries: reasoning-bank-read.sh --summary
AUTHORITATIVE CHECK SOURCE: All actively-evaluated checks live here in Step 3.
core/config/verification-checklist.md is a comprehensive reference catalog
(2000+ items) but is too large to load in one context window. When adding new
checks for new features, add them HERE, not in the checklist file.
The checklist file remains useful for per-section deep dives via targeted reads.
4-Tier Architecture evidence checks (Section 4T)
Check: world/.initialized exists (init-world.sh ran successfully)
Check: world/program.md is non-empty (The Program — shared purpose defined)
Check: <agent>/.initialized exists (init-agent.sh ran successfully)
Check: agents/<agent>/self.md is non-empty (agent identity defined)
Check: $MIND_AGENT env var is set and matches agent directory name
Check: meta/spark-questions.jsonl exists (moved from old mind/ to meta/)
Check: meta/skill-quality.yaml exists (moved from old mind/ to meta/)
Check: meta/evolution-log.jsonl exists (moved from old mind/ to meta/)
Check: Knowledge tree lives in world/knowledge/tree/ (collective, not per-agent)
Check: Experience records live in agents/<agent>/experience.jsonl (per-agent, not world/)
Check: core/scripts/_paths.py exports WORLD_DIR, AGENT_DIR, META_DIR
Check: core/scripts/_platform.sh has WORLD_DIR="$(cygpath -m "$WORLD_DIR")" (Windows path fix)
Check: No mind/ directory exists (fully migrated to 4-tier)
Stray world/ or meta/ at repo root means a script wrote a literal
path instead of resolving via local-paths.conf (the canonical
external paths). 2026-05-07 cleanup found a 16-day-stale world/
at repo root alongside the 9.2MB OneDrive canonical — silent
divergence, no error surfaced. Bare-string world/foo paths
collapse to ./world/foo when _paths.sh isn't sourced; the .gitignore
/world/ and /meta/ entries hide the divergence from git status.
Bash (no-stray-roots): test ! -d world && test ! -d meta && echo "PASS: world/ and meta/ not at repo root" || echo "FAIL: stray world/ or meta/ at repo root — script wrote without resolving via _paths.sh; canonical paths are in agents//local-paths.conf"
Context-budget zone anchoring (Section CB — rb-313, guard-301)
These checks keep the zone=distance-to-autocompact invariant stable over time.
If any fails, see agents/alpha/journal/2026/04/2026-04-19.md "Rebase context-budget zones".
Check: core/scripts/context-budget-status.py classify_zone takes pct_to_autocompact (NOT used_pct) — grep def classify_zone.pct_to_autocompact must match
Check: core/scripts/context-budget-status.py reads CLAUDE_CODE_AUTO_COMPACT_WINDOW and CLAUDE_AUTOCOMPACT_PCT_OVERRIDE from env (not hardcoded)
Check: core/scripts/context-budget-status.py writes env_seen, effective_window, autocompact_pct, autocompact_token_limit, headroom_tokens, pct_to_autocompact fields into budget JSON
Check: agents/<agent>/session/context-budget.json contains env_seen key (proves statusLine subprocess inherited env vars)
Check: core/scripts/context-budget-banner.sh exists and emits the exact shape CTX: raw N% | of-autocompact N% | zone WORD | headroom N tokens | env W/P | updated TS
Bash: grep -qE 'CTX: raw .*of-autocompact.*zone.*headroom.*env.*updated' core/scripts/context-budget-banner.sh && echo "PASS: banner.sh source emits 6-field shape" || echo "FAIL: banner shape regressed in source" — static check on banner.sh source (runs in non-session context where no context-budget.json exists yet; context-citation-audit.sh's banner_re check on line 70 validates the regex-level audit-regex compatibility)
Check: core/scripts/context-citation-audit.sh exists; its banner_re matches banner.sh's print format (zone field captured)
Check: core/scripts/context-citation-audit.sh splits journal blocks on ^#+\s (not ^#\s) so both # and ## heading styles work
Check: No hardcoded numeric zone thresholds in core/config/obligation-schema.yaml, core/config/conventions/compact-recovery.md, core/config/conventions/working-memory.md, core/scripts/reasoning-snapshot.py — all reference the script as source of truth. Grep 65%\|used_pct >= 65\|>=65% across these files must return empty.
Check: guard-301 exists and is active (reasoning-bank.py guard read --id guard-301 returns a record)
Check: rb-313 exists and is active (reasoning-bank.py rb read --id rb-313 returns a record)
Check: core/scripts/abbreviated-obligation-audit.py emits claim_banner_zone in its per-claim audit record
Check: core/scripts/context-budget-status.py module docstring contains the pq-034 design-intent note — prevents future maintainers from "correcting" an intentionally small effective_window. Grep the script for pq-034 must match.
Schema-scope / enforcement-scope alignment (rb-315, guard-303)
These two invariants state scope as "per session" / "per claim" — the
implementation must iterate at the promised granularity, else the
threshold silently never fires / the audit falsely credits claims.
Check: core/scripts/obligation-audit.py counts session_false_claims from obligation-audit.jsonl records
Check: core/scripts/context-citation-audit.sh scopes banner search per-OBLIGATION (neighborhood bounded by next claim's start), not per-block. Grep the script for matches[i + 1].start() must match.
Agent resolution: MIND_AGENT env var is the ONLY mechanism (Section 4T continued)
No fallback files, no .active-agent global, no .latest-session-id.
Check: core/scripts/_paths.py _resolve_agent_name reads only os.environ.get("MIND_AGENT")
Check: core/scripts/_paths.sh resolves AGENT_NAME="${MIND_AGENT:-}" (one line, no fallbacks)
Bash: MIND_AGENT=test-agent source core/scripts/_paths.sh && echo "$AGENT_NAME" → verify prints "test-agent"
Inlined-_APD drift detection (rb-1092, g-115-983)
AGENTS_PARENT_DIR is inlined at 5 sites for latency/import-cycle reasons
(see CLAUDE.md "Agent-dir Resolution" table). Drift between any inlined
copy and core/scripts/_paths.sh AGENTS_PARENT_DIR silently re-routes the
affected helper to the wrong root: session-state-get.sh would return
UNINITIALIZED for an existing agent (canonical rb-1092 incident), which
would route /start to the UNINITIALIZED branch and clobber a working
agent's state. The /start Step 1.5 drift-warning probe (skill: start)
catches this at entry; this check catches it on the verify-learning
cadence so drift is surfaced even when no /start re-entry happens.
Bash (inlined-_APD-drift): canonical=$(grep -E '^AGENTS_PARENT_DIR=' core/scripts/_paths.sh | head -1 | sed -E 's/^AGENTS_PARENT_DIR=//;s/^"//;s/"$//') && fail=0 && for f in core/scripts/session-state-get.sh core/scripts/session-mode-get.sh core/scripts/session-signal-exists.sh core/scripts/cleanup-stale-bindings.sh; do v=$(grep -E '^_APD=' "$f" | head -1 | sed -E 's/^_APD=//;s/^"//;s/"$//'); if [ "$v" != "$canonical" ]; then echo "FAIL: $f _APD=$v != _paths.sh AGENTS_PARENT_DIR=$canonical"; fail=1; fi; done && py=$(grep -E '^_AGENTS_PARENT_DIR' core/scripts/_wake_signals.py | head -1 | sed -E 's/^_AGENTS_PARENT_DIR[[:space:]]=[[:space:]]"([^"])"./\1/') && if [ "$py" != "$canonical" ]; then echo "FAIL: core/scripts/_wake_signals.py _AGENTS_PARENT_DIR=$py != _paths.sh AGENTS_PARENT_DIR=$canonical"; fail=1; fi && [ "$fail" = 0 ] && echo "PASS: all 5 inlined _APD/_AGENTS_PARENT_DIR sites match _paths.sh canonical "$canonical"" || true
Wrapper-test daemon stale-code isolation (commit 5cce91b8; g-115-1328)
In-process pytest wrapper daemons freeze git_head_sha at import; a commit
landing mid-run trips rt_check_staleness -> one-shot auto-restart, which
corrupts wrapper stdout (JSONDecodeError) — the ~70-failure incident
(2026-06-02). conftest.py pre-sets RT_STALENESS_WARNED=1 to short-circuit
_runtime.sh:169 before the restart arms. Guard against silent removal.
Full narrative: tree node daemon-lifecycle-windows "Test-Side Mirror".
Bash (conftest-staleness-isolation): grep -q 'RT_STALENESS_WARNED' mind_api/tests/conftest.py && echo "PASS: conftest.py sets RT_STALENESS_WARNED (wrapper-test daemon stale-code isolation, commit 5cce91b8)" || echo "FAIL: RT_STALENESS_WARNED missing from mind_api/tests/conftest.py — the 74-failure wrapper-test daemon-staleness fix was removed (see g-115-1328, tree: daemon-lifecycle-windows)"
infra-streak test-suite board-post hermeticity (g-115-2641; g-249-30 leak)
infra-streak-notify.sh --notify emits a coordination-board breadcrumb. The
test suite neutralizes that live post ONLY via a suite-wide default
export INFRA_STREAK_BOARD_STUB=<tmp jsonl> (test-infra-streak-dedup.sh:49):
when set, the wrapper reads/writes that local JSONL (L396-397) instead of the
real board (L399 board-read.sh / L449 board-post.sh). Every case inherits the
export; cases 9/9b override with their own stub. Drop the suite-wide export
(or add a --notify case that shadows it with an unset) and the suite posts REAL
breadcrumbs with live episode keys to the append-only coordination channel —
observed live 2026-07-18 (2 messages, marked read). Guard against silent removal.
Bash (infra-streak-board-stub-hermeticity): grep -qE '^[[:space:]]*export INFRA_STREAK_BOARD_STUB=' core/scripts/tests/test-infra-streak-dedup.sh && echo "PASS: test-infra-streak-dedup.sh retains its suite-wide 'export INFRA_STREAK_BOARD_STUB=' default — every case inherits the local-JSONL stub, so the suite never reads or posts the REAL coordination board" || echo "FAIL: test-infra-streak-dedup.sh lost the suite-wide 'export INFRA_STREAK_BOARD_STUB=' default — infra-streak-notify.sh's --notify path falls to the live board-read.sh / board-post.sh branch, leaking real coordination breadcrumbs with live episode keys (observed 2026-07-18, 2 msgs; g-115-2641 / g-249-30)"
drain-temp Phase 1.5 TEMP_DIR dangerous-rm guard (g-115-1876, g-115-1877;
helper-form update 2026-07-13 merge). The Phase 1.5 ephemera purge MUST route
through the canonical guarded helper core/scripts/temp-drain-purge.sh —
never a hand-rolled inline find ... -delete / rm on an interpolated
TEMP_DIR. If _paths.sh fails to export AGENT_DIR, an inline TEMP_DIR
collapses to "/temp" or "" and the delete reads to Claude Code's permission
layer as a dangerous-rm, HANGING an autonomous agent on the approval prompt
(no user to answer — 46+ min hang, g-115-1876). Pin BOTH halves: the SKILL.md
routes through the helper, and the helper retains its REFUSED guard block
(AGENT_DIR/PROJECT_ROOT/TEMP_DIR assertions + under-root + basename==temp).
Bash (drain-temp-purge-helper-routed): grep -qF 'temp-drain-purge.sh' .claude/skills/drain-temp/SKILL.md && ! grep -qE 'find "$TEMP_DIR".*-delete' .claude/skills/drain-temp/SKILL.md && echo "PASS: drain-temp Phase 1.5 purge routes through the canonical guarded helper temp-drain-purge.sh (no inline find -delete)" || echo "FAIL: drain-temp/SKILL.md no longer routes Phase 1.5 purge through temp-drain-purge.sh (or re-introduced an inline find -delete) — the autonomous-agent dangerous-rm hang guard is bypassed (g-115-1876/g-115-1877)"
Bash (drain-temp-purge-helper-guarded): grep -qF 'REFUSED — AGENT_DIR empty/unset' core/scripts/temp-drain-purge.sh && grep -qF 'REFUSED — TEMP_DIR empty' core/scripts/temp-drain-purge.sh && echo "PASS: temp-drain-purge.sh retains its REFUSED guard block (empty/unset path assertions before any deletion)" || echo "FAIL: temp-drain-purge.sh lost its REFUSED guard assertions — the destructive purge is no longer runtime-guarded against an empty/collapsed TEMP_DIR (g-115-1876/g-115-1877)"
Generated-Checklist Verify Step (Section GCV — g-306-03 / BRD Gap 15, 2026-06-12)
aspirations-verify Q1.5 generates a 5-10 item yes/no checklist from the goal
and logs UNCOVERED gaps (failing items the goal's own verification never
declared) to meta/missing-verification-criteria.jsonl for later goal-template
improvement. Evidence: TICKing All the Boxes (2410.03608). Conservative
escalation — covered-criterion failures fail Q1; uncovered failures only log
(low-risk additive step). These checks pin the step + its companion logger.
Bash (gcv-step-present): grep -q 'Q1.5 GENERATED CHECKLIST' .claude/skills/aspirations-verify/SKILL.md && echo "PASS: aspirations-verify has the Q1.5 generated-checklist step (BRD Gap 15)" || echo "FAIL: aspirations-verify SKILL.md lost the Q1.5 GENERATED CHECKLIST step (g-306-03 regressed)"
Bash (gcv-logger-wired): grep -q 'missing-criteria-log.sh' .claude/skills/aspirations-verify/SKILL.md && echo "PASS: Q1.5 wires missing-criteria-log.sh for uncovered-gap recording" || echo "FAIL: aspirations-verify Q1.5 no longer calls missing-criteria-log.sh — uncovered checklist gaps go unrecorded (g-306-03)"
Bash (gcv-logger-exists): test -f core/scripts/missing-criteria-log.sh && test -f core/scripts/missing-criteria-log.py && git ls-files --error-unmatch core/scripts/missing-criteria-log.py >/dev/null 2>&1 && echo "PASS: missing-criteria-log.{sh,py} exist + git-tracked" || echo "FAIL: missing-criteria-log companion script missing/untracked (g-306-03 lost-deliverable class; restore + git add)"
Bash (gcv-digest-ref): grep -q 'Q1.5 GENERATED CHECKLIST' core/config/iteration-close-digest.md && echo "PASS: iteration-close-digest § VERIFY references Q1.5" || echo "FAIL: iteration-close-digest.md § VERIFY lost the Q1.5 item (g-306-03)"
Bash (gcv-regression-test): test -f core/scripts/tests/test_missing_criteria_log.py && git ls-files --error-unmatch core/scripts/tests/test_missing_criteria_log.py >/dev/null 2>&1 && N=$(py -3 -m pytest core/scripts/tests/test_missing_criteria_log.py -o addopts= 2>&1 | grep -oE '[0-9]+ passed' | grep -oE '[0-9]+' | head -1) && [ -n "$N" ] && [ "$N" -ge 10 ] && echo "PASS: missing-criteria-log regression test exists + git-tracked + $N cases passing (>=10)" || echo "FAIL: missing-criteria-log regression test missing/untracked OR <10 passing (g-306-03; restore test + git add, or if the appender contract changed update the test + this check)"
state-update-audit run-all exit-code partition (g-115-1945). main() exits 1
ONLY on HARD_FAIL_FLAGS (parse/crash/missing-input); soft/transient flags
(impk_snapshot_failed = an own-cloud write_conflict surviving g-115-1871's
daemon retry) and positive/informational flags (above_mean/below_mean/
backpressure findings) exit 0. Regression class: a revert to
exit(1 if flags else 0) re-fires the spurious "state-update-audit.sh
failed (non-fatal)" WARN in iteration-close on nearly every deep close while
the audit's core compute succeeded. NB: the fix is PRODUCER-side (this .py),
NOT a consumer-side audit_rc -eq 1 branch in iteration-close.sh.
Bash (audit-exit-hardfail-partition): grep -q 'HARD_FAIL_FLAGS' core/scripts/state-update-audit.py && grep -q '_has_hard_failure' core/scripts/state-update-audit.py && echo "PASS: state-update-audit.py run-all partitions HARD_FAIL_FLAGS from soft/informational flags (g-115-1945 — exit 1 only on parse/crash/missing-input, not on transient impk_snapshot_failed or positive above_mean)" || echo "FAIL: state-update-audit.py lost the HARD_FAIL_FLAGS/_has_hard_failure exit-partition — main() likely reverted to 'exit(1 if flags else 0)', re-firing the spurious 'state-update-audit.sh failed (non-fatal)' WARN in iteration-close on every soft/transient/positive flag (g-115-1945 regressed)"
Fresh-eyes board-read read-state filter (g-115-2486 / g-115-2490). Both
fresh-eyes rituals count self_evolution/self-drift board findings; without
--unread-only an ACTIONED (marked-read) signal re-counts every review within
its window, re-inflating self_evolution_signals_count as net-divergent
residue (the stale-signal treadmill g-115-2486 fixed for fresh-eyes-review
Phase 2.3b and g-115-2490 for fresh-eyes-program Phase 2.6b).
Bash (fresh-eyes-unread-only): grep -qE 'board-read.sh --channel findings.--unread-only' .claude/skills/fresh-eyes-review/SKILL.md && grep -qE 'board-read.sh --channel findings.--unread-only' .claude/skills/fresh-eyes-program/SKILL.md && echo "PASS: both fresh-eyes-review (Phase 2.3b) and fresh-eyes-program (Phase 2.6b) self_evolution board-read calls carry --unread-only, so actioned/marked-read board signals stop re-counting as net-divergent residue every review (g-115-2486/g-115-2490)" || echo "FAIL: a fresh-eyes board-read self_evolution call lost --unread-only — actioned board signals re-count every review within the window, re-inflating self_evolution_signals_count (g-115-2486/g-115-2490 regressed)"
Gap-16 never-summarize-summaries verifier (g-306-01, guard-745). The
consolidate-source-verify.sh fail-loud guard stops aspirations-consolidate
from regenerating any summary level FROM a prior summary file (GSD 2.0 /
BRD Gap 16). These checks pin the script, its fail-loud + raw-pass
behavior, the consolidate Step 0.6 wiring, and the guardrail. Synthetic
paths only — the verifier is a pure path/name classifier (the files need
not exist).
Bash (gap16-verifier-exists): test -f core/scripts/consolidate-source-verify.sh && git ls-files --error-unmatch core/scripts/consolidate-source-verify.sh >/dev/null 2>&1 && echo "PASS: consolidate-source-verify.sh exists + git-tracked" || echo "FAIL: consolidate-source-verify.sh missing/untracked (g-306-01 lost-deliverable class; restore + git add)"
Bash (gap16-fail-loud): bash core/scripts/consolidate-source-verify.sh "smoke/handoff.yaml" >/dev/null 2>&1; [ $? -eq 1 ] && echo "PASS: verifier fails loud (exit 1) on a summary artifact — Gap-16 fail-loud path exercised" || echo "FAIL: consolidate-source-verify.sh did NOT exit 1 on a summary path — fail-loud path broken (g-306-01)"
Bash (gap16-raw-passes): bash core/scripts/consolidate-source-verify.sh "smoke/experience.jsonl" >/dev/null 2>&1; [ $? -eq 0 ] && echo "PASS: verifier passes (exit 0) a raw source — no false positive" || echo "FAIL: consolidate-source-verify.sh wrongly rejected a raw source path (g-306-01)"
Bash (gap16-consolidate-wired): grep -q 'consolidate-source-verify.sh' .claude/skills/aspirations-consolidate/SKILL.md && echo "PASS: aspirations-consolidate Step 0.6 wires the Gap-16 verifier" || echo "FAIL: aspirations-consolidate lost the Step 0.6 source-integrity verifier (g-306-01 regressed)"
Bash (gap16-guardrail): bash core/scripts/guardrails-read.sh --category framework-patterns 2>/dev/null | grep -q 'guard-745' && echo "PASS: guard-745 (never-summarize-summaries) registered" || echo "FAIL: guard-745 missing from guardrails (g-306-01 deliverable 1)"
Gate D Step 5e outside the trivial_mode skip region (g-115-1414, GATE-INTEGRITY).
Lightweight mode (g-305-15) added an IF-trivial_mode SKIP region around Phase-4
retrieval (Steps 1-5d) in BOTH core/config/execute-protocol-digest.md and
.claude/skills/aspirations-execute/SKILL.md. INVARIANT: Step 5e (Gate D) MUST
stay OUTSIDE that region and always run; the classifier never reads/infers the
arm. Both files position the sentinel line "Step 5e ALWAYS RUNS — NEVER gated by
trivial_mode" immediately BEFORE the "Step 5e: Gate D commons-pattern injection"
section header. The two checks below pin that line-order in each file (structure-
agnostic): if a future edit pulls Step 5e into the skip region, the sentinel
disappears or moves after the header → FAIL. If the marker wording is
deliberately reworded, update the grep pattern here in lockstep.
Bash (gate-d-5e-outside-skip-digest): F=core/config/execute-protocol-digest.md; S=$(grep -nE 'Step 5e ALWAYS RUNS' "$F" | head -1 | cut -d: -f1); H=$(grep -nE 'Step 5e: Gate D commons-pattern injection' "$F" | head -1 | cut -d: -f1); { [ -n "$S" ] && [ -n "$H" ] && [ "$S" -lt "$H" ]; } && echo "PASS: execute-protocol-digest.md positions 'Step 5e ALWAYS RUNS' (L$S) before the Step 5e Gate D section (L$H) — Step 5e is outside the trivial_mode skip region (g-115-1414)" || echo "FAIL: execute-protocol-digest.md no longer positions the 'Step 5e ALWAYS RUNS — never gated by trivial_mode' sentinel before the Step 5e Gate D section — Step 5e may have been pulled into the g-305-15 trivial_mode skip region (GATE-INTEGRITY regression, g-115-1414)"
Bash (gate-d-5e-outside-skip-skill): F=.claude/skills/aspirations-execute/SKILL.md; S=$(grep -nE 'Step 5e ALWAYS RUNS' "$F" | head -1 | cut -d: -f1); H=$(grep -nE 'Step 5e: Gate D commons-pattern injection' "$F" | head -1 | cut -d: -f1); { [ -n "$S" ] && [ -n "$H" ] && [ "$S" -lt "$H" ]; } && echo "PASS: aspirations-execute/SKILL.md positions 'Step 5e ALWAYS RUNS' (L$S) before the Step 5e Gate D section (L$H) — Step 5e is outside the trivial_mode skip region (g-115-1414)" || echo "FAIL: aspirations-execute/SKILL.md no longer positions the 'Step 5e ALWAYS RUNS — never gated by trivial_mode' sentinel before the Step 5e Gate D section — Step 5e may have been pulled into the g-305-15 trivial_mode skip region (GATE-INTEGRITY regression, g-115-1414)"
Bash (consult-gate-digest-parity): grep -qF 'pre-apply-consult-gate.sh' .claude/skills/aspirations-execute/SKILL.md && grep -qF 'pre-apply-consult-gate.sh' core/config/execute-protocol-digest.md && echo "PASS: pre-apply-consult-gate.sh is wired in BOTH aspirations-execute/SKILL.md AND execute-protocol-digest.md — the digest IS the post-compaction hot path, so a Phase-4 pre-edit gate present in only one silently never fires there (g-115-2203)" || echo "FAIL: pre-apply-consult-gate.sh is missing from execute-protocol-digest.md OR aspirations-execute/SKILL.md — a Phase-4 pre-edit gate present in only one silently never fires on the hot path (the digest is loaded on post-compaction re-reads, NOT the full SKILL.md; g-115-2203). Every Phase-4 pre-edit gate MUST live in BOTH files — assert the mechanism, not the case (rb-3452)"
Micro-hypothesis resolves_when/consumer + auto-settle wiring (g-303-34, g-115-1665).
g-303-34 made resolves_when + consumer REQUIRED at the micro-hyp filing sites and
added the Step 1.5 auto-settle CONSUMER, fixing the dominant micro-hyp failure
(zeta audit g-303-14: 71% never-resolve, 0% consumed). These are behavior-changing
pseudocode edits a future edit could silently drop. The three checks pin: (1) the
aspirations-spark sq-016 filing JSON still carries BOTH fields, (2) the reflect-on-
outcome Step 1.5 consumer header still exists, (3) the sq-016 RB block still stamps
source_horizon: micro (rb-876 first-principles attribution-gap fix). If the wording
is deliberately reworded, update the grep pattern here in lockstep.
Bash (microhyp-spark-resolves-consumer): F=.claude/skills/aspirations-spark/SKILL.md; grep -qE '"source_step":"sq-016"."resolves_when"' "$F" && grep -qE '"source_step":"sq-016"."consumer"' "$F" && echo "PASS: aspirations-spark sq-016 micro-hyp filing JSON carries both resolves_when and consumer (g-303-34 non-resolution/no-consumer fix)" || echo "FAIL: aspirations-spark sq-016 micro-hyp filing lost resolves_when and/or consumer -- the g-303-34 REQUIRED-fields fix regressed (71%-never-settle / 0%-consumed failure mode returns)"
Bash (microhyp-autosettle-header): grep -q 'Auto-Settle Unresolved Micro-Hypotheses' .claude/skills/reflect-on-outcome/SKILL.md && echo "PASS: reflect-on-outcome has the Step 1.5 Auto-Settle Unresolved Micro-Hypotheses consumer (g-303-34)" || echo "FAIL: reflect-on-outcome lost the Step 1.5 Auto-Settle Unresolved Micro-Hypotheses step -- resolves_when is filed but never consumed (g-303-34 regressed)"
Bash (microhyp-spark-source-horizon): grep -q 'source_horizon: micro' .claude/skills/aspirations-spark/SKILL.md && echo "PASS: aspirations-spark sq-016 RB block stamps source_horizon: micro (g-303-34 / rb-876 first-principles-spark attribution-gap fix)" || echo "FAIL: aspirations-spark sq-016 RB block lost the source_horizon: micro stamp -- first-principles micro-horizon RB origin no longer traceable (g-303-34 / rb-876 regressed)"
_world_config Mode G overlay loader (rb-1100, guard-590, Phase 2.5.D)
When _world_config.py used the pre-relocation root/agent/local-paths.conf
path (Mode G), it silently fell through to PROJECT_ROOT/world (nonexistent
in canonical layout) and returned None. load_world_config swallowed the
None as a dict(default) fallback, causing 25 routing-table-empty failures
for ~3 weeks until pytest collection collision surfaced the regression.
These two checks catch the same drift class at verify-learning cadence:
(1) _resolve_world_dir() returns non-None Path for a bound agent
(2) capability-routing overlay loads non-empty title_prefix_routes
rb-1100 calls this "silent safe-default degradation = sync-invariant audit missed a site".
Check: core/scripts/_world_config.py _resolve_world_dir() returns non-None Path for a bound agent (Mode G regression — Phase 2.5.D missed sync site)
Bash (world-config-resolves): MIND_AGENT=alpha py -3 -c "import sys; sys.path.insert(0, 'core/scripts'); from _world_config import _resolve_world_dir; p = _resolve_world_dir(); assert p is not None, 'FAIL: _resolve_world_dir() returned None (Mode G regression — silently falls through to PROJECT_ROOT/world)'; print(f'PASS: _world_config._resolve_world_dir() returned {p}')"
Check: core/scripts/_world_config.py load_world_config('capability-routing') returns non-empty title_prefix_routes (overlay file load works end-to-end)
Bash (capability-routing-non-empty): MIND_AGENT=alpha py -3 -c "import sys; sys.path.insert(0, 'core/scripts'); from _world_config import load_world_config; cfg = load_world_config('capability-routing'); routes = cfg.get('title_prefix_routes', {}) if cfg else {}; assert len(routes) > 0, 'FAIL: title_prefix_routes is empty — overlay loader silently degraded (rb-1100)'; print(f'PASS: capability-routing overlay loaded {len(routes)} title_prefix_routes')"
Hardcoded AGENTS_PARENT_DIR literal audit (g-115-1009, source: exp-encode-
session-2026-05-20-world-config-mode-g). Static-pattern companion to the
Mode G dynamic checks above. Inlined-_APD-drift guards the 5 documented
sync sites; the Mode G checks above probe runtime behavior of one loader;
THIS check guards completeness across the WHOLE Python tree — any Python
file silently doing PROJECT_ROOT / "agents" instead of routing through
agents_root() is a latent Phase-2.5.D regression that neither sibling
catches. Canonical example was context-budget-status.py:80, fixed in
g-115-1009 Part 1. Extracts canonical value from _paths.py dynamically
(not hardcoded "agents") so future AGENTS_PARENT_DIR relocations don't
re-introduce a false-pass when the literal-name changes.
Bash (hardcoded-APD-literal): canonical=$(grep -E '^AGENTS_PARENT_DIR\s*=' core/scripts/_paths.py | head -1 | sed -E 's/.=\s"([^"])"./\1/') && hits=$(grep -rEn "\bPROJECT_ROOT\s*/\s*"${canonical}"" core/scripts/.py mind_api/src/.py 2>/dev/null | grep -v '_paths.py' || true) && if [ -n "$hits" ]; then echo "FAIL: hardcoded PROJECT_ROOT / "${canonical}" outside _paths.py — use agents_root() helper"; echo "$hits"; else echo "PASS: no hardcoded PROJECT_ROOT / "${canonical}" outside _paths.py canonical declaration"; fi
Evolution-stub finalize gate: producer<->consumer wiring (g-115-2180).
The rb-428 sentinel family only works when BOTH halves are live: a producer
with no consumer leaves an orphaned sentinel (the g-115-1521 failure class),
and a consumer with no producer is dead code. This gate closes guard-380's
broken promise — measured 2026-07-14, only 11 of 65 MATERIAL Self edits ever
reached the user and 22 EXPIRED unnotified, because nothing PROMPTED the
evolution-complete.sh call before evolution-stub-expiry.py honestly buried
the stub at 24h. If any of the three legs below is silently removed, material
agent-identity changes go dark again and NOTHING else in the system notices.
Asserts all three: (1) the producer script exists, (2) iteration-close.sh
actually CALLS it (registered != invoked — the exact trap of g-115-2176),
(3) aspirations-precheck consumes the sentinel it sets. No line anchors (rb-682).
Bash (evolution-finalize-gate-wiring): prod=core/scripts/evolution-stub-pending-check.sh; miss=""; [ -f "$prod" ] || miss="$miss producer-script-absent"; grep -q "evolution-stub-pending-check.sh" core/scripts/iteration-close.sh 2>/dev/null || miss="$miss not-called-from-iteration-close"; grep -q "force_evolution_finalize" "$prod" 2>/dev/null || miss="$miss producer-does-not-set-sentinel"; grep -q "force_evolution_finalize" .claude/skills/aspirations-precheck/SKILL.md 2>/dev/null || miss="$miss no-precheck-consumer"; if [ -n "$miss" ]; then echo "FAIL: evolution-finalize gate wiring broken —$miss (material Self edits will expire unnotified, guard-380)"; else echo "PASS: evolution-finalize gate wired end-to-end (producer exists, called from iteration-close, sets force_evolution_finalize, consumed by aspirations-precheck Phase 0-pre2.5)"; fi
Operator-offload-gate wiring: dual-site + slot-map + registry + override-flag
(g-115-2151, gate landed 2026-07-13). The gate is wired across 4 files that can
silently drift apart: a refactor of aspirations_write.py could drop one of the
two _operator_offload_eval call sites — the g-115-1405 depth-1 partial-wiring-
loss class, invisible until recurring goals slip through unfiled. Asserts all
four legs: (1) exactly 2 _operator_offload_eval( call sites in aspirations_write.py,
(2) the override_offload->operator-offload-gate SLOT_TO_GATE_ID mapping in
_override_helpers.py, (3) the gate id in gates.yaml, (4) the --override-offload
flag in aspirations-add-goal.sh. No line anchors (rb-682).
Bash (operator-offload-gate-wiring): f=mind_api/src/endpoints/aspirations_write.py; miss=""; sites=$(grep -c "_operator_offload_eval(" "$f" 2>/dev/null || echo 0); sites=${sites:-0}; [ "$sites" -eq 2 ] || miss="$miss aspirations_write-call-sites=$sites(want-2)"; grep -qE 'override_offload.*operator-offload-gate' core/scripts/_override_helpers.py 2>/dev/null || miss="$miss no-SLOT_TO_GATE_ID-mapping"; grep -q "id: operator-offload-gate" core/config/gates.yaml 2>/dev/null || miss="$miss no-gates.yaml-registry-id"; grep -q "override-offload" core/scripts/aspirations-add-goal.sh 2>/dev/null || miss="$miss no-override-offload-flag"; if [ -n "$miss" ]; then echo "FAIL: operator-offload-gate wiring drifted —$miss (partial wiring loss is invisible until recurring goals silently slip through unfiled — g-115-1405 depth-1 class; gate landed 2026-07-13, g-115-2151)"; else echo "PASS: operator-offload-gate wired end-to-end (2 _operator_offload_eval call sites in aspirations_write.py, override_offload SLOT_TO_GATE_ID mapping, gates.yaml registry id, --override-offload flag)"; fi
Pre-apply-consult DRIFT gate: framework_edited wiring in iteration-close.sh
(g-115-2661, source g-115-2655). The g-115-2655 fix made pre-apply-consult-
drift-gate.py gate the drift streak on framework_edited — whether the deep
close ACTUALLY edited a framework file, derived from the goal's OWN commit via
git log --grep=$GOAL_ID — so read-only framework diagnostics (tree scans,
gate audits) stop false-firing the streak. The gate DEFAULTS framework_edited=true
(backward-compat / fail-safe), so if iteration-close.sh do_learning_gate stops
computing _fw_edited OR stops passing --framework-edited, the gate SILENTLY
reverts to the pre-fix behavior and re-fires on read-only diagnostics. Invisible
because the g-115-2655 unit tests exercise decide()/the CLI GIVEN the flag, never
the bash git-grep + flag-threading seam (the sq-019 integration gap). This grep
is that wiring regression guard. No line anchors (rb-682) — assert the four
unique-to-this-feature tokens (var + git-grep + gate + flag), not the case.
Bash (drift-gate-framework-edited-wiring): f=core/scripts/iteration-close.sh; miss=""; grep -qF '_fw_edited' "$f" || miss="$miss no-_fw_edited-computation"; grep -qF -- '--grep="$GOAL_ID"' "$f" || miss="$miss no-git-log--grep-GOAL_ID"; grep -qF 'pre-apply-consult-drift-gate.py' "$f" || miss="$miss drift-gate-not-called"; grep -qF -- '--framework-edited' "$f" || miss="$miss --framework-edited-not-passed"; if [ -n "$miss" ]; then echo "FAIL: iteration-close.sh do_learning_gate lost the g-115-2655 framework_edited wiring —$miss (pre-apply-consult-drift-gate.py defaults framework_edited=true, so the drift streak SILENTLY re-fires on read-only framework diagnostics; the g-115-2655 unit tests cover decide()/the CLI GIVEN the flag, NOT the bash git-grep+flag seam — g-115-2661)"; else echo "PASS: iteration-close.sh do_learning_gate computes _fw_edited via git log --grep=$GOAL_ID AND passes --framework-edited to pre-apply-consult-drift-gate.py — the g-115-2655 read-only-diagnostic false-fire fix stays wired (g-115-2661)"; fi
pr_merged predicate CODE+DOC pairing (g-115-2597, source: g-115-2593 which shipped the
pr_merged structured-precondition type). test_predicate_pr_merged.py guards BEHAVIOR, but
the CODE<->DOC pairing has no guard: deleting/renaming the convention section leaves the
behavior tests green while the slug-gotcha doc (repo = the REMOTE owner/name from
git remote get-url origin, NOT the local directory name — the two diverged on first
live use) silently vanishes for future precondition authors. Asserts BOTH legs;
backtick-tolerant doc pattern, no line anchors (rb-682).
Bash (pr-merged-code-doc-pairing): grep -qE '"pr_merged"[[:space:]]:[[:space:]]_eval_pr_merged' core/scripts/predicate.py && grep -qE '^### .?pr_merged' core/config/conventions/preconditions.md && echo "PASS: pr_merged predicate CODE+DOC pairing intact (PREDICATE_TYPES registration in predicate.py + ### pr_merged section in preconditions.md)" || echo "FAIL: pr_merged CODE+DOC pairing broken — registration without doc, or doc without registration; the repo-slug gotcha (repo = REMOTE owner/name from git remote get-url, not the local dir) silently vanishes for precondition authors (g-115-2597 / g-115-2593)"
Skill-discovery invocation-source glob-routing (g-115-1405, source: g-115-1403
skill-discovery 13-flagged audit). Sibling to hardcoded-APD-literal above but
for the GLOB surface: skill-discovery's journal + execution-diary invocation
sources MUST sweep agents_root()/ctx.paths.agents_root.glob("*/...") (DEPTH 2,
post-Phase-2.5.D), NEVER PROJECT_ROOT.glob("*/...") at DEPTH 1 — depth-1 matches
0 files under agents//, silently zeroing 2 of 4 invocation sources for
EVERY skill and inflating silently_undertriggering (the under-logging defense
built by g-115-879/rb-314/g-115-798 is itself broken). Empirically 2026-06-11:
legacy '/journal.jsonl' matched 0; 'agents//journal.jsonl' matched 6.
Asserts BOTH absence of the depth-1 bug pattern AND presence of the 4 correct
agents_root() globs (2 CLI + 2 daemon) — no brittle line anchors (rb-682,
tree node verify-learning-citation-drift). Quote-agnostic.
Bash (skill-discovery-glob-routing): bug=$(grep -nE "(PROJECT_ROOT|project_root|ctx.paths.project_root).glob(['"]*/(journal.jsonl|session/execution-diary.jsonl)['"])" core/scripts/skill-discovery.py mind_api/src/endpoints/skill_discovery.py 2>/dev/null || true); ok_cli=$(grep -cE "agents_root().glob(['"]*/(journal.jsonl|session/execution-diary.jsonl)['"])" core/scripts/skill-discovery.py 2>/dev/null || true); ok_daemon=$(grep -cE "ctx.paths.agents_root.glob(['"]*/(journal.jsonl|session/execution-diary.jsonl)['"])" mind_api/src/endpoints/skill_discovery.py 2>/dev/null || true); ok_cli=${ok_cli:-0}; ok_daemon=${ok_daemon:-0}; if [ -n "$bug" ]; then echo "FAIL: depth-1 PROJECT_ROOT.glob('*/...') invocation-source residue (agents/ relocation zeroes journal+diary sources for all skills)"; echo "$bug"; elif [ "$ok_cli" -lt 2 ] || [ "$ok_daemon" -lt 2 ]; then echo "FAIL: expected agents_root() journal+diary globs missing (cli=$ok_cli/2 daemon=$ok_daemon/2)"; else echo "PASS: skill-discovery invocation-source globs route through agents_root()/ctx.paths.agents_root (cli=$ok_cli daemon=$ok_daemon, no depth-1 residue)"; fi
Skill-coinvocation-discovery ledger glob-routing (g-304-24, sibling to
skill-discovery-glob-routing above). skill-coinvocation-discovery.py mines the
cross-agent ledger via base.glob("*/skill-invocations.jsonl") where base defaults
to agents_root() (DEPTH 2, post-Phase-2.5.D) — NEVER a depth-1 PROJECT_ROOT.glob
("*/...") which matches 0 files under agents// and silently zeroes every
co-invocation candidate. This consumer is invisible to the three CLAUDE.md audit
greps (constant/literal/.parent), so the CLAUDE.md cross-agent glob consumers
table row + this regression guard are its only audit surface. Asserts absence of
the depth-1 bug AND presence of the agents_root()-routed ledger glob.
Quote-agnostic, no brittle line anchors (rb-682).
Bash (skill-coinvocation-glob-routing): bug=$(grep -nE "(PROJECT_ROOT|project_root).glob(['"]*/skill-invocations.jsonl['"])" core/scripts/skill-coinvocation-discovery.py 2>/dev/null || true); ok_glob=$(grep -cE ".glob(['"]*/skill-invocations.jsonl['"])" core/scripts/skill-coinvocation-discovery.py 2>/dev/null || true); ok_root=$(grep -cE "agents_root()" core/scripts/skill-coinvocation-discovery.py 2>/dev/null || true); ok_glob=${ok_glob:-0}; ok_root=${ok_root:-0}; if [ -n "$bug" ]; then echo "FAIL: depth-1 PROJECT_ROOT.glob('*/skill-invocations.jsonl') residue (agents/ relocation zeroes all co-invocation candidates)"; echo "$bug"; elif [ "$ok_glob" -lt 1 ] || [ "$ok_root" -lt 1 ]; then echo "FAIL: expected agents_root()-routed skill-invocations glob missing (glob=$ok_glob root=$ok_root)"; else echo "PASS: skill-coinvocation-discovery ledger glob routes through agents_root() (glob=$ok_glob root=$ok_root, no depth-1 residue)"; fi
WM-writer fsync-before-rename guard (wm-writer-fsync, g-001-44). A bare
write_text()/write + os.replace() survives a crash in metadata only: NTFS
journals the rename while the data blocks stay unflushed, so the renamed
file can come back as all-0x00 (canonical: charlie session d600a945 WM,
8140 null bytes after a 60+ min autocompact hang). The working-memory
writer cluster MUST fsync before its atomic rename — wm.py write_yaml
inline, the CAS consumers (recurring-loop-state-mutate.py,
loop-state-bump-counters.py, dry-idle-tick.py) via
_fileops.durable_write_text — and wm.py read_yaml must carry the all-null
detective. Ratchet half: count fsync-less rename sites across
core/scripts/*.py and compare against meta/audit-baselines.yaml
(wm-fsync-rename-sites) — INCREASE = regression (new writer authored
without fsync), decrease = ratchet the baseline down.
Bash (wm-writer-fsync): miss=""; grep -q "os.fsync" core/scripts/wm.py || miss="$miss wm.py"; grep -q "durable_write_text" core/scripts/_fileops.py || miss="$miss _fileops.py"; for f in recurring-loop-state-mutate loop-state-bump-counters dry-idle-tick; do grep -q "durable_write_text" "core/scripts/$f.py" || miss="$miss $f.py"; done; grep -q "os.fsync" mind_api/src/endpoints/wm_write.py || miss="$miss wm_write.py(daemon-LIVE)"; grep -q 'strip(b.\x00' core/scripts/wm.py || miss="$miss read_yaml-detective"; grep -q 'strip(b.\x00' mind_api/src/endpoints/wm_write.py || miss="$miss daemon-read-detective"; if [ -n "$miss" ]; then echo "FAIL: WM-writer fsync/detective coverage missing:$miss (g-001-44 / g-001-49)"; else total=0; for f in $(grep -rlE "os.replace(|tmp.replace(" core/scripts/*.py mind_api/src 2>/dev/null | grep -vE "tests|pycache"); do grep -qE "os.fsync|durable_write_text" "$f" || total=$((total+1)); done; echo "PASS: WM-writer cluster (CLI + daemon-LIVE) fsyncs before rename + all-null detectives present (fsync-less rename FILES elsewhere incl. mind_api: $total — compare meta/audit-baselines.yaml wm-fsync-rename-sites; increase = regression)"; fi
Evolve gate-eval raw-append resurrection guard (g-115-1974, source: g-115-1971).
aspirations-evolve/SKILL.md Gate Retirement Evaluation step 1 must journal the
evaluator recommendation via the daemon-routed evolution-log-append.sh — NEVER
via a raw shell append (>> or tee -a) to meta/gate-eval-recommendations.jsonl.
Under own-cloud the mirror sweep is PUSH-ONLY, so a raw append to a governed
shared meta JSONL is box-local, last-pusher-wins on S3, and stranded on
concurrent divergence — only backend-routed writes (locked_append_jsonl / daemon
wrappers) are fleet-shared (guard-996, rb-3105). The recs file is a FROZEN
legacy artifact (4 records, all 2026-05-01; zero code readers). Asserts BOTH
absence of the raw-append resurrection AND presence of the daemon-routed
gate-eval-recommendation event line. Order/quote-agnostic, no brittle line
anchors (rb-682).
Bash (evolve-gate-eval-raw-append-guard): bug=$(grep -nE "(>>|tee -a).*gate-eval-recommendations" .claude/skills/aspirations-evolve/SKILL.md 2>/dev/null || true); ok=$(grep -cE "gate-eval-recommendation.*evolution-log-append.sh|evolution-log-append.sh.*gate-eval-recommendation" .claude/skills/aspirations-evolve/SKILL.md 2>/dev/null || true); ok=${ok:-0}; if [ -n "$bug" ]; then echo "FAIL: raw shell append to gate-eval-recommendations.jsonl resurrected in aspirations-evolve/SKILL.md (own-cloud divergence trap — box-local write, push-only mirror; guard-996/g-115-1971)"; echo "$bug"; elif [ "$ok" -lt 1 ]; then echo "FAIL: expected daemon-routed gate-eval-recommendation lineage line (evolution-log-append.sh) missing from aspirations-evolve/SKILL.md Gate Retirement step"; else echo "PASS: evolve gate-eval lineage routes through evolution-log-append.sh (daemon, fleet-shared); no raw >>/tee -a append to gate-eval-recommendations.jsonl"; fi
Team-state sibling-row backend overlay guard (g-115-1980, source: g-115-1979
fleet-wide last_active split-brain). _team_state.load_rows() MUST overlay the
storage backend's view of the rows dir — under own-cloud the mirror sweep is
PUSH-ONLY, so sibling shards written on other boxes never land locally and a
local-only iterdir composes clone-era fossils for every partner (alpha
misreported the fleet dormant 2026-07-11). Asserts BOTH the overlay plumbing
(_backend_rows + list_dir + force_fresh) AND that load_rows still merges it
(the overlay call inside load_rows). Read-side twin of the raw-append guard
above; guard-998/rb-3117 carry the pattern. Quote-agnostic, no brittle line
anchors (rb-682).
Bash (team-state-backend-overlay-guard): f=core/scripts/_team_state.py; has_helper=$(grep -c "def _backend_rows" "$f" 2>/dev/null || true); has_list=$(grep -c "list_dir" "$f" 2>/dev/null || true); has_fresh=$(grep -c "force_fresh=True" "$f" 2>/dev/null || true); wired=$(grep -c "_backend_rows(world_dir)" "$f" 2>/dev/null || true); has_helper=${has_helper:-0}; has_list=${has_list:-0}; has_fresh=${has_fresh:-0}; wired=${wired:-0}; if [ "$has_helper" -lt 1 ] || [ "$has_list" -lt 1 ] || [ "$has_fresh" -lt 1 ]; then echo "FAIL: _team_state.py backend row overlay missing (helper=$has_helper list_dir=$has_list force_fresh=$has_fresh) — local-only iterdir composes clone-era sibling fossils under push-only own-cloud mirror (g-115-1979 split-brain regression)"; elif [ "$wired" -lt 2 ]; then echo "FAIL: _backend_rows exists but not wired into both load_rows AND row_agent_names (wired=$wired/2) — compose or roster falls back to local-only discovery"; else echo "PASS: _team_state.py sibling rows route through the storage backend (_backend_rows overlay wired into load_rows + row_agent_names, force_fresh reads)"; fi
Skill-freshness-report integration smoke (Section SFR — g-115-1552, source: g-304-14
sq-018). Sibling to the two skill-telemetry checks above, but a RUN/smoke check (not a
glob-routing grep): skill-freshness-report.py is a standalone Layer-5d report
cross-referencing each .claude/skills/*/SKILL.md mtime against its last cross-agent
skill-invocations.jsonl invocation, splitting skills into stale_modified / fresh_stable
/ never_invoked_in_window cohorts. The 16 hermetic tests (test_skill_freshness_report.py)
cover its cohort logic on synthetic fixtures but NEVER run it against the real repo, so a
_paths import change, a real-data edge case, or a SKILL.md front-matter shape change would
crash the live report while the unit tests stay green. This smoke check runs it against the
real SKILL.md mtimes + real cross-agent ledger and asserts BOTH exit 0 AND the two ALERT
cohort keys (stale_modified, fresh_stable) are present in the JSON. No brittle line anchors.
Bash (skill-freshness-report-smoke): out=$(py -3 core/scripts/skill-freshness-report.py --output json 2>/dev/null); rc=$?; echo "$out" | py -3 -c "import sys,json; d=json.load(sys.stdin); sys.exit(0 if all(k in d for k in ('stale_modified','fresh_stable')) else 1)"; krc=$?; if [ "$rc" = 0 ] && [ "$krc" = 0 ]; then echo "PASS: skill-freshness-report.py --output json runs (exit 0) and emits stale_modified + fresh_stable cohorts"; else echo "FAIL: skill-freshness-report.py smoke check (exit=$rc keys_present_rc=$krc) — g-304-14 Layer-5d standalone report broken; check _paths import drift, real-data edge case, or SKILL.md front-matter shape change (regression class the 16 hermetic tests miss)"; fi
Tree-read --summary projection field-carry (Section TSP — g-115-1409, source: g-115-1408
strategic-scan-S2-silently-dead incident). Mirror-sync invariant for a SECOND projection
surface (sibling to skill-discovery-glob-routing above): the --summary node projection is
built in TWO mirrored places — core/scripts/tree.py (read --summary CLI) and
mind_api/src/world/tree_read.py (daemon /v1/tree/read summary). Both MUST emit
last_updated + article_count per node; dropping either field in either path silently
zeroes strategic-scan S2a (stale-node) + S2b (thin-node) knowledge-frontier detection
(g-115-1408 found S2 dead for exactly this reason — the fields existed on every node but
the projection omitted them). Asserts the projection-dict literal ("": node.get(""))
carries BOTH keys in BOTH files — quote-agnostic, no brittle line anchors (rb-682, tree
node verify-learning-citation-drift).
Bash (tree-summary-projection-fields): fail=0; for f in core/scripts/tree.py mind_api/src/world/tree_read.py; do for k in last_updated article_count; do grep -qE "["']${k}["'][[:space:]]*:[[:space:]]node.get([[:space:]]["']${k}["']" "$f" || { echo "FAIL: $f --summary projection missing '${k}' key (strategic-scan S2a/S2b go dead — g-115-1408/g-115-1409)"; fail=1; }; done; done; [ "$fail" = 0 ] && echo "PASS: tree-read --summary projection carries last_updated + article_count in both paths (tree.py CLI + tree_read.py daemon)" || true
── Evolution-capture resolver-tier + relocation-drift checks (Section ECR — g-115-1993, sq-018 batch) ──
Three regression guards for framework fixes landed 2026-07-11 whose common
failure mode is a SILENT zero: the writer keeps running, no error, but its
per-agent capture drops to nothing after an agents/ relocation or a hand-sync
drift between two copies. All three mirror the skill-discovery-glob-routing /
skill-coinvocation-glob-routing style above: assert the CORRECT routing marker
is present (no brittle line anchors, rb-682), so a future edit that re-drifts
trips the check instead of silently zeroing capture.
(1) evolution-git-sweep agent_self relocation classifier (g-115-1405 drift class;
live-fixed 2026-07-11 commit 973f9d52 after ~6wk of silent agent_self zero). The
sweep classifies self.md commits into the agent_self stream across BOTH layout eras:
the legacy 2-part form (parts[1]=='self.md', pre-relocation, kept deliberately since git
HISTORY has pre-relocation commits) AND the relocated form whose depth derives from _agents_root(). A
2-part-only regression silently zeroes agent_self backfill on relocated boxes.
Asserts the relocated-era classifier (_agents_root().relative_to(PROJECT_ROOT) +
parts[-1] == "self.md") is present. Quote-agnostic, no brittle line anchors.
Bash (evolution-git-sweep-agent-self-relocation): ok_reloc=$(grep -cE "_agents_root().relative_to(PROJECT_ROOT)" core/scripts/evolution-git-sweep.py 2>/dev/null || echo 0); ok_selfmd=$(grep -cE "parts[-1] == ["']self.md["']" core/scripts/evolution-git-sweep.py 2>/dev/null || echo 0); if [ "$ok_reloc" -lt 1 ] || [ "$ok_selfmd" -lt 1 ]; then echo "FAIL: evolution-git-sweep.py relocated-era agent_self classifier missing (reloc=$ok_reloc selfmd=$ok_selfmd) — a 2-part-only form silently zeroes agent_self self.md backfill on relocated boxes (g-115-1405; live-fixed 2026-07-11 commit 973f9d52 after ~6wk silent zero)"; else echo "PASS: evolution-git-sweep.py agent_self classifier derives depth from _agents_root().relative_to(PROJECT_ROOT) with parts[-1]=='self.md' (reloc=$ok_reloc selfmd=$ok_selfmd) — both layout eras classified"; fi
(2) evolution-prepare + evolution-record resolve_agent marker-cache sync (g-115-1960).
Both scripts carry a HAND-SYNCED copy of resolve_agent() whose last resolution tier
reads the per-SID bash-inject marker (core/logs/bash-inject-resolved/) so a
binding-reaped session still resolves its agent. The two copies are not import-shared;
editing ONE to drop the marker tier silently re-introduces per-session evolution-capture
death after binding reap. Asserts BOTH files still carry the bash-inject-resolved tier.
Bash (evolution-resolve-agent-marker-sync): fail=0; for f in core/scripts/evolution-prepare.py core/scripts/evolution-record.py; do grep -qE "bash-inject-resolved" "$f" 2>/dev/null || { echo "FAIL: $f resolve_agent missing the bash-inject-resolved marker-cache tier — the two hand-synced resolve_agent copies drifted; a binding-reaped session loses agent resolution and per-session evolution capture dies silently (g-115-1960)"; fail=1; }; done; [ "$fail" = 0 ] && echo "PASS: both evolution-prepare.py + evolution-record.py resolve_agent carry the bash-inject-resolved marker-cache tier (hand-synced copies in sync, g-115-1960)" || true
(3) daemon utilization endpoint agents_root routing (mirrors skill-coinvocation-
glob-routing above; the LAST ⚠ LATENT project_root/"agents" hardcode in the CLAUDE.md
cross-agent glob-consumer table, fixed 2026-07-11). The cross-agent */local-paths.conf
enumeration MUST route via ctx.paths.agents_root (DEPTH 2) — a project_root/"agents"
re-drift zeroes sibling enumeration. The bug pattern excludes comment lines (the fix's
own history comment legitimately names the old hardcode). Asserts the ctx.paths.agents_root
glob is present AND no LIVE hardcode residue.
Bash (utilization-agents-root-routing): bug=$(grep -nE "(project_root|PROJECT_ROOT|ctx.paths.project_root)[[:space:]]/[[:space:]]["']agents["']" mind_api/src/endpoints/utilization.py 2>/dev/null | grep -vE '^[0-9]+:[[:space:]]*#' || true); ok_root=$(grep -cE "ctx.paths.agents_root" mind_api/src/endpoints/utilization.py 2>/dev/null || echo 0); ok_glob=$(grep -cE "agents_root.glob(['"]*/local-paths.conf['"])" mind_api/src/endpoints/utilization.py 2>/dev/null || echo 0); if [ -n "$bug" ]; then echo "FAIL: utilization.py LIVE hardcoded project_root/"agents" residue (depth-1 latent regression — the last one fixed 2026-07-11; re-drift zeroes cross-agent local-paths enumeration)"; echo "$bug"; elif [ "$ok_root" -lt 1 ] || [ "$ok_glob" -lt 1 ]; then echo "FAIL: utilization.py agents_root routing missing (root=$ok_root glob=$ok_glob) — cross-agent /local-paths.conf enumeration must route via ctx.paths.agents_root"; else echo "PASS: utilization.py cross-agent enumeration routes via ctx.paths.agents_root.glob('/local-paths.conf') (root=$ok_root glob=$ok_glob, no live hardcoded-agents residue)"; fi
── Deploy-verification framework surface (Section DVS — g-115-2701, sq-018 batch, 2026-07-19) ──
Two regression guards for the per-push deploy-verification stack's FRAMEWORK
half — the surface that ships in every world via the promotion cycle. (The
DOMAIN half — this deployment's world/conventions/post-execution.md Step 2.4
mandate + guard-119 — is guarded in world/verification-checklist.md, which
only loads for a deployment that HAS a CI/deploy pipeline, so those checks
never false-fail in a fresh world.) Failure mode is a SILENT gap: the helper
is deleted/renamed, or a template rewrite drops the seed, and nothing errors —
pushes just stop being verified. Marker-style asserts, no brittle line anchors
(rb-682 idiom, mirrors Section ECR above).
(1) The canonical per-push deploy-verification helper exists and parses. It is
the probe guard-119 + the post-execution convention both name; deleting or
breaking it silently disables deploy verification everywhere.
Bash (deploy-verify-helper-present): if [ -f core/scripts/deploy-verify.sh ] && bash -n core/scripts/deploy-verify.sh 2>/dev/null; then echo "PASS: core/scripts/deploy-verify.sh present and parses (canonical per-push deploy-verification helper)"; else echo "FAIL: core/scripts/deploy-verify.sh missing or has a syntax error — the canonical deploy-verification probe named by the post-execution convention is gone; pushes are no longer verified (g-115-2701)"; fi
(2) The framework post-execution TEMPLATE carries the 2b.2 post-push deploy-
verification gate — the seed that gives every NEW world deploy verification. A
template rewrite that drops it means fresh worlds ship with no gate (the
live-world overlay would then be the only copy, defeating the promotion cycle).
Bash (deploy-verify-template-gate): if grep -q "2b.2" core/config/templates/post-execution-default.md 2>/dev/null && grep -qi "deploy verification" core/config/templates/post-execution-default.md 2>/dev/null; then echo "PASS: post-execution-default.md carries the 2b.2 post-push deploy-verification gate (template twin seeds new worlds, g-115-2689)"; else echo "FAIL: core/config/templates/post-execution-default.md missing the 2b.2 post-push deploy-verification gate — a template rewrite dropped the seed that gives every NEW world deploy verification (g-115-2689/g-115-2701)"; fi
(3) The deploy-detect-hook.sh CAPTURE hook stays registered as an ACTIVE
PostToolUse[Bash] hook in .claude/settings.json (g-115-2688-a). It records
every deploy-triggering push into the pending-deploys hard gate; if a future
settings.json edit drops the registration the hook goes silent and the whole
gate fails OPEN with no error — the exact silent-gap failure mode the DVS
header warns about, one layer up (capture vs verify). JSON-PARSE not bare grep
so a stray _comment mention of the script cannot satisfy the check (guard-1099);
asserts BOTH the script exists AND the registration is live (a registered-but-
deleted hook would fail at hook runtime with no verify-learning signal).
Bash (deploy-detect-hook-registered): py -3 -c "import json,sys,os; s=json.load(open('.claude/settings.json',encoding='utf-8')); reg=[h for b in s.get('hooks',{}).get('PostToolUse',[]) if b.get('matcher')=='Bash' for h in b.get('hooks',[]) if 'deploy-detect-hook.sh' in h.get('command','')]; ok=bool(reg) and os.path.isfile('core/scripts/deploy-detect-hook.sh'); (print('PASS: deploy-detect-hook.sh present AND registered as an active PostToolUse[Bash] hook (CAPTURE half of the pending-deploys gate, g-115-2688-a)') if ok else (print('FAIL: deploy-detect-hook.sh missing OR not registered as a PostToolUse[Bash] hook in .claude/settings.json — the pending-deploys CAPTURE half is silent; deploy-triggering pushes stop being recorded and the hard gate fails open with no signal (g-115-2704)') or sys.exit(1)))"
(4) The pending-deploys-gate.sh RESOLVE half stays wired into iteration-close.sh
at BOTH seams (g-115-2688-a/b). SG-a: the --goal form in do_verify resolves the
CLOSING goal's deploy obligations. SG-b: the all-sweep form (no --goal) in
productivity-check re-probes every REMAINING pending entry. Together with check (3)
(the CAPTURE hook) they are the two halves of the pending-deploys hard gate: (3)
RECORDS deploy-triggering pushes, (4) RESOLVES them. A refactor that drops either
seam makes the RESOLVE half silent — deploy obligations stop being resolved with no
error (the same fail-open class check (3) guards for capture). FILE-READ + per-call-
line discrimination (not bare grep) so a comment mention cannot satisfy it AND both
DISTINCT seam shapes (with/without --goal) are asserted present (guard-1099).
Bash (pending-deploys-gate-wired): py -3 -c "import os,sys; lines=list(open('core/scripts/iteration-close.sh',encoding='utf-8')); calls=[l for l in lines if 'pending-deploys-gate.sh' in l and not l.lstrip().startswith('#')]; sg_a=any('--goal' in l for l in calls); sg_b=any('--goal' not in l for l in calls); ok=os.path.isfile('core/scripts/pending-deploys-gate.sh') and len(calls)>=2 and sg_a and sg_b; (print('PASS: pending-deploys-gate.sh present AND wired into iteration-close.sh at BOTH seams — SG-a (--goal closing-goal resolve, g-115-2688-a) + SG-b (all-sweep re-probe, no --goal, g-115-2688-b): the RESOLVE half of the pending-deploys gate') if ok else (print('FAIL: pending-deploys-gate.sh missing OR not wired at both iteration-close.sh seams (SG-a --goal resolve + SG-b all-sweep re-probe) — a refactor dropped a seam; the pending-deploys RESOLVE half goes silent and deploy obligations stop being resolved with no signal (g-115-2707)') or sys.exit(1)))"
Bash-agent-inject hook evidence checks (Section 4T continued)
The PreToolUse[Bash] hook auto-injects MIND_AGENT from .active-agent- so
the LLM no longer needs to prefix every Bash call manually.
Check: core/scripts/bash-agent-inject.sh and core/scripts/bash-agent-inject.py exist
Check: .claude/settings.json has a PreToolUse hook with matcher: "Bash" pointing at bash-agent-inject.sh
Check: .claude/settings.json has NO FileChanged hook for .active-agent-* (retired stanza) and core/scripts/set-active-agent-env.sh has been deleted
Bash (hook-works): bash core/scripts/session-state-get.sh → verify output is RUNNING/IDLE/NO_AGENT for the currently-bound agent (if binding exists). A literal "NO_AGENT" output while .active-agent-<current-SID> contains a valid agent name means the hook is not wired up or not stamping correctly.
Check: core/scripts/bash-agent-inject.sh sources both _paths.sh and _platform.sh (without _platform.sh, MSYS may hand python3 a /c/... path it cannot open — same rule as guard-051 applies)
Bash (no-fallback-chain): grep -E '||\s*(py|python)( |$)' core/scripts/*.sh → verify returns empty (no hook script uses python3||py||python fallback; single source of truth via _paths.sh shim)
(python-form-consistency check RETIRED 2026-07-11, vl-2026-07-10 batch run.
It asserted "inside .sh wrappers use python3 — never py -3", enshrining the
2026-04-23 python3-only sweep end-state (rb-471). That doctrine was
superseded: core/config/conventions/python-invocation.md now calls py -3
"bedrock", and ~140 .sh call sites use it deliberately with rb-370/guard-335
justification comments — including 5-line exec py -3 thin shims that never
source _paths.sh, and py-3-first-python3-fallback chains like
aspirations-precheck-budget-meter.sh now_ms(). The check would flag every
one of them. python3-inside-.sh remains PERMITTED (convention rule 3), so
neither form is a violation; there is nothing left to assert. The sibling
no-fallback-chain check above still guards the hook scripts' single-source
rule, which is the part that still matters.)
Bash (fail-open): echo 'not json' | bash core/scripts/bash-agent-inject.sh; echo "exit=$?" → verify exit=0 and empty stdout (malformed stdin must not block Bash tool)
Bash (override-preserved): echo '{"session_id":"test","tool_input":{"command":"MIND_AGENT=alpha pwd"}}' | bash core/scripts/bash-agent-inject.sh → verify empty stdout (explicit MIND_AGENT= at command boundary must skip injection so cross-agent probes work)
Bash-inject diagnostic surface (rb-514, 2026-04-25)
When binding resolution returns no agent AND no explicit MIND_AGENT= override,
the hook surfaces the silent-no-injection failure class via a greppable artifact.
Without this surface, NO_AGENT sessions made silent no-op Bash calls invisible —
the diagnostic turns the silent failure class into one that grep can find.
Check: core/scripts/bash-agent-inject.py defines _log_binding_miss_once — grep for def _log_binding_miss_once must match
2026-05-19 (plan v1 step 0.13-0.14): both writers relocated from PROJECT_ROOT/
to core/logs/ (already-gitignored telemetry sink hosting watchdog logs).
Check confirms the writers point at the canonical sink, not the legacy root paths.
Bash (writer-sink): grep -q '"core" / "logs"' core/scripts/bash-agent-inject.py && grep -q 'logs_dir / "bash-inject-sentinels"' core/scripts/bash-agent-inject.py && grep -q 'logs_dir / "bash-inject-misses.jsonl"' core/scripts/bash-agent-inject.py && echo "PASS: writers point at core/logs/" || echo "FAIL: writers still target PROJECT_ROOT — relocation regressed"
Bash (helper-invoked): grep -qE '_log_binding_miss_once(sid' core/scripts/bash-agent-inject.py && echo "PASS: helper invoked from main()" || echo "FAIL: helper defined but not called"
Bash-inject miss-rate surfacing (g-115-897, paired Apply of g-115-795)
Operational mitigation for the architecturally-locked hook miss modes
(timeout fail-open + no-binding). The injector cannot be made more
robust without violating the PreToolUse fail-open contract OR
_paths.py's "one path, no fallbacks" design, so this check surfaces
the rate of misses instead of trying to prevent them. Tunable thresholds:
MISS_THRESHOLD_ADVISORY=5 (default), MISS_THRESHOLD_ALERT=20, MISS_WINDOW_HOURS=24.
Check: core/scripts/bash-inject-misses-recent.sh exists and is executable
Bash (miss-rate): bash core/scripts/bash-inject-misses-recent.sh → verify JSON output containing verdict field; report the verdict (clean PASS / advisory WARN / alert FAIL) — alert verdict means >=20 misses in 24h, suggests a session-binding misconfiguration worth investigating
Schema-on-error CLI tool conformance (Section SOE — rb-512, 2026-04-25)
RETIRED in H2 Wave 2 (2026-05-15): reasoning-bank.py CLI was gutted —
RB_ADD_SCHEMA_TEXT, GUARD_ADD_SCHEMA_TEXT, argparse, --schema flag, and
all CLI subcommands removed. The record contract now lives in
mind_api/src/store_registry.py + mind_api/src/endpoints/store.py.
journal.py was previously retired in H2 Wave 1 (2026-05-15).
No stdin-JSON CLI tools with the rb-512 pattern remain.
Section SOE checks are no longer applicable — all stores route through
the daemon generic store endpoint.
Session Manifest Integrity (Section SMI — asp-248, 2026-04-23)
Guards against the Phase -1.5 drift pattern: pseudocode that carries a
hardcoded allowlist parallel to an authoritative config file. Single
source of truth is core/config/session-manifest.yaml. Scripts consume
the manifest; pseudocode must call scripts, not inline the list.
Check: core/config/session-manifest.yaml contains a top-level files: list (authoritative)
Bash (no-parallel-allowlist): grep -nE '^\s*(WHITELISTED|VALID_SESSION_FILES|SESSION_FILE_ALLOWLIST)\s*=\s*[([]' .claude/skills/boot/SKILL.md .claude/skills/start/SKILL.md .claude/skills/stop/SKILL.md core/scripts/*.sh → verify returns empty (no pseudocode or script carries a hardcoded parallel list; manifest is single source of truth — guard-426)
Orphan ratchet (g-254-04, 2026-04-26): Replaces the previous hardcoded count<=2
threshold which silently passed because session-desync-check.sh emits JSON warnings,
not '[info] orphan:' lines, so the grep matched zero. The ratchet invokes
session-manifest-orphan-ratchet.sh which subprocess-spawns session_snapshot.py,
counts orphans[], compares to meta/audit-baselines.yaml session_manifest_orphans.baseline,
and emits a verdict (seeded/stable/ratcheted/regressed). The ratchet is ADVISORY by
default (exit 0 always) — set VERIFY_LEARNING_ORPHAN_HARD_GATE=1 to make regression
exit non-zero. The baseline auto-seeds on first run and ratchets DOWN on monotonic
improvement, mirroring learning-routing-ratchet.py's pattern.
Bash (orphan-ratchet): bash core/scripts/session-manifest-orphan-ratchet.sh --json | py -3 -c "import json,sys; d=json.load(sys.stdin); v=d.get('verdict'); ok = v in ('seeded','stable','ratcheted'); print(f"{'PASS' if ok else 'FAIL'}: orphan-ratchet verdict={v} current={d['current']} baseline={d['baseline']}")" → PASS unless verdict=regressed (current count exceeds baseline; either register the new orphan in core/config/session-manifest.yaml or file a Maintain goal to remove it)
Check: meta/audit-baselines.yaml has a session_manifest_orphans entry with baseline + history (created on first ratchet run; auto-ratchets down as orphans get registered/removed)
Check: .claude/skills/boot/SKILL.md Phase -1.5 calls session-desync-check.sh (advisory, does NOT delete) — NOT a for F in a b c; do rm -f ...; done loop. Grep Phase -1.5 for rm -f must return empty.
Pair-consumer entry-type coverage (Section SMI continued — g-115-416, 2026-05-08)
session-manifest.yaml entries fall into 3 entry-type combinations: regular file
(default), glob:true, type:dir. Both consumers (session_snapshot.py main()
and session-manifest-clear.sh inline-Python) MUST have a handler branch for
each type present in the manifest. guard-477 was the LLM-side enforcement;
session-manifest-coverage-audit.sh catches the same drift mechanically.
Bash (pair-consumer-coverage): bash core/scripts/session-manifest-coverage-audit.sh → must exit 0 and print "PASS: every distinct entry-type" (FAIL means a consumer dropped a branch while manifest still has entries of that type, or manifest introduced a new type with no consumer wiring)
Third-consumer entry-type coverage — session-manifest-write-gate.py (g-115-861, 2026-05-17)
session-manifest-coverage-audit.sh above scopes the pair: session_snapshot.py main()
and session-manifest-clear.sh inline-Python. session-manifest-write-gate.py is the
THIRD consumer (g-115-840 added the type:dir dispatch block). This check pins the
gate's dispatch contract independently — if a new type:* value lands in the manifest
without a corresponding entry_type == "" branch in the write-gate, dir-type
writes fall back silently to the unregistered-dispatch path. Distinct from the
9-case test suite at mind_api/tests/test_session_manifest_write_gate.py (those
verify behavior; this is a structural-completeness pin).
Bash (write-gate-type-coverage): MISS=$(grep -hE "^[[:space:]]+type:[[:space:]]+\w+" core/config/session-manifest.yaml | sed -E "s/^[[:space:]]+type:[[:space:]]+//; s/[[:space:]]+$//" | sort -u | grep -vE "^(file|)$" | while read t; do grep -qE "entry_type[[:space:]]==[[:space:]]"$t"" core/scripts/session-manifest-write-gate.py 2>/dev/null || echo "$t"; done); if [ -z "$MISS" ]; then echo "PASS: session-manifest-write-gate.py has dispatch branch for every distinct manifest type"; else echo "FAIL: session-manifest-write-gate.py missing dispatch for type(s): $MISS"; fi
Agent Watchdog lifecycle (Section MON — 2026-05-12)
Per-agent observability probes invoked as a periodic tick from
iteration-close.sh productivity-check. agent-watchdog.py hosts a Probe
registry (running-sid, heartbeat, background-job, stop-hook-block) with
state persisted across ticks in agents//session/watchdog-prev-state.json.
The earlier daemon model was retired because nohup+disown didn't
reliably detach on Git Bash for Windows — see file's top-level docstring
for the rationale. The invariants below catch the most likely drift
modes: missing script, missing manifest entry, missing iteration-close
tick wiring, retired daemon files lingering.
Check: core/scripts/agent-watchdog.py exists and contains the build_probes(ctx) registry call
Check: core/scripts/agent-watchdog.sh exists (wrapper sources _paths.sh and execs python — used for ad-hoc human inspection)
Check: Retired files DO NOT exist: core/scripts/watchdog-start.sh, core/scripts/watchdog-stop.sh, core/scripts/watchdog-status.sh, core/scripts/_watchdog_lifecycle.py, core/scripts/running-sid-watcher.py, core/scripts/running-sid-watcher.sh, core/logs/running-sid-watcher.jsonl (all superseded by agent-watchdog --tick — keeping daemon-era artifacts is the regression this section guards against)
Bash (retired-watcher-gone): test ! -f core/scripts/running-sid-watcher.py && test ! -f core/scripts/running-sid-watcher.sh && test ! -f core/logs/running-sid-watcher.jsonl && echo "PASS: retired running-sid-watcher files absent" || echo "FAIL: superseded running-sid-watcher artifact lingering — agent-watchdog replaces it"
Bash (retired-daemon-scripts-gone): test ! -f core/scripts/watchdog-start.sh && test ! -f core/scripts/watchdog-stop.sh && test ! -f core/scripts/watchdog-status.sh && test ! -f core/scripts/_watchdog_lifecycle.py && echo "PASS: retired watchdog daemon scripts absent" || echo "FAIL: daemon-era watchdog scripts still present — agent-watchdog --tick replaces them"
Bash (manifest-watchdog-entry): grep -qE "^\s+- file: watchdog-prev-state.json\s*$" core/config/session-manifest.yaml && echo "PASS: manifest registers watchdog-prev-state.json" || echo "FAIL: session-manifest.yaml missing watchdog-prev-state.json entry"
Bash (manifest-watchdog-cleanup): ! grep -qE "^\s+- file: watchdog.(pid|log)\s*$" core/config/session-manifest.yaml && echo "PASS: manifest no longer references retired watchdog.pid/log" || echo "FAIL: session-manifest.yaml still references retired daemon files"
Bash (iteration-close-wires-tick): grep -q "agent-watchdog.py.*--tick" core/scripts/iteration-close.sh && echo "PASS: iteration-close.sh invokes agent-watchdog.py --tick" || echo "FAIL: iteration-close.sh does not invoke the watchdog tick"
Bash (no-start-spawn): ! grep -q "watchdog-start.sh" .claude/skills/start/SKILL.md && echo "PASS: /start no longer spawns a watchdog daemon" || echo "FAIL: /start still references retired watchdog-start.sh"
Bash (no-stop-kill): ! grep -q "watchdog-stop.sh" .claude/skills/aspirations-graceful-stop/SKILL.md && echo "PASS: graceful-stop no longer kills a watchdog daemon" || echo "FAIL: aspirations-graceful-stop still references retired watchdog-stop.sh"
Bash (no-recovery-stop): ! grep -q "watchdog-stop.sh" core/scripts/recovery-gate.sh && echo "PASS: recovery-gate.sh no longer references retired watchdog-stop.sh" || echo "FAIL: recovery-gate.sh still references retired watchdog-stop.sh"
Bash (tick-smoketest): LOG=core/logs/watchdog-alpha.jsonl; BEFORE=$(wc -l < "$LOG" 2>/dev/null | tr -d ' ' || echo 0); STATE=agents/alpha/session/watchdog-prev-state.json; touch agents/alpha/session/running-session-id 2>/dev/null; MIND_AGENT=alpha py -3 core/scripts/agent-watchdog.py --tick >/dev/null 2>&1; AFTER=$(wc -l < "$LOG" 2>/dev/null | tr -d ' ' || echo 0); test -f "$STATE" && echo "PASS: tick wrote state file" || echo "FAIL: tick did not write $STATE"
Bash (tick-emits-on-transition): MIND_AGENT=alpha py -3 core/scripts/agent-watchdog.py --tick >/dev/null 2>&1; LOG=core/logs/watchdog-alpha.jsonl; BEFORE=$(wc -l < "$LOG" 2>/dev/null | tr -d ' ' || echo 0); touch agents/alpha/session/running-session-id 2>/dev/null; MIND_AGENT=alpha py -3 core/scripts/agent-watchdog.py --tick >/dev/null 2>&1; AFTER=$(wc -l < "$LOG" 2>/dev/null | tr -d ' ' || echo 0); test "$AFTER" -gt "$BEFORE" && echo "PASS: tick emitted transition event on mtime change (before=$BEFORE after=$AFTER)" || echo "FAIL: tick did not detect mtime transition"
Cross-Agent Attribution Deliverable Integrity (Section CAA — g-115-774, 2026-05-15)
g-115-741 found g-115-714's deliverables (_cross_agent_attribution_filter.py +
its test) missing from disk AND never git-committed despite g-115-714
deep-closing. post-state-update-gate.sh:122 fail-open meant cross-agent
attribution silently no-op'd ~37h with no surfaced error. This guards the
lost-deliverable regression class: a deep-closed goal whose code artifact
never reached disk/git. Distinct from the 25d6520 over-deletion tail
(compiled-but-never-committed pre-cutover) and from the goal-selector
import-smoke check (g-115-768 sibling). Asserts the deliverable exists,
is git-tracked, and its >=5 attribution tests still pass.
Pytest idiom (g-115-1182): -o addopts= ... 2>&1, NOT -q ... 2>/dev/null.
This repo's pytest.ini sets addopts=-q; a second explicit -q double-quiets
pytest and suppresses the "N passed" summary line, so the grep returns empty
→ false FAIL. -o addopts= overrides the .ini default (restores summary);
2>&1 captures it regardless of stream. (Was the broken -q | grep passed
idiom until g-115-1182 fixed it here + in sibling Section ATF below.)
Bash (cross-agent-attribution-deliverable): test -f core/scripts/_cross_agent_attribution_filter.py && git ls-files --error-unmatch core/scripts/_cross_agent_attribution_filter.py >/dev/null 2>&1 && N=$(py -3 -m pytest core/scripts/tests/test_post_state_update_attribution.py -o addopts= 2>&1 | grep -oE '[0-9]+ passed' | grep -oE '[0-9]+' | head -1) && [ -n "$N" ] && [ "$N" -ge 5 ] && echo "PASS: _cross_agent_attribution_filter.py exists + git-tracked + $N attribution tests passing (>=5)" || echo "FAIL: cross-agent attribution deliverable regression - _cross_agent_attribution_filter.py missing/untracked OR test_post_state_update_attribution.py <5 passing (g-115-714 lost-deliverable class; restore file + git add + ensure >=5 tests)"
Attribution-Filter in_flight-null Robustness (Section ATF — g-115-1182, 2026-05-26)
g-115-1154 confirmed team-state-clear-in-flight runs in iteration-close.sh
do_verify Step 3 (g-284-06) BEFORE post-state-update-gate fires the filter in
do_state_update Step 8.78 — so self.in_flight=null (self_claimed_at=0) is the
NORMAL filter-time state, not an edge case. Under that state Source 3
(pre-claim-mtime) is disabled by its self_claimed_at>0 guard; only Sources 1
(concurrent-partner) and 2 (partner uncommitted-log) survive as fallbacks. This
guards that the in_flight-null contract stays pinned: a regression test asserts
Sources 1+2 STILL drop partner files and documents the Source 3 fail-open gap
(tracked by g-115-1154 / g-115-1178 / g-115-1180). NOT a Source 4 fallback —
the sq-018 spark proposed one but it contradicts the filter's fail-open
philosophy and is not the chosen fix layer. Sibling to Section CAA.
NOTE on the pytest idiom: this repo's pytest.ini sets addopts = -q, so a
second explicit -q double-quiets pytest and SUPPRESSES the "N passed"