fix(ooda): liveness-verify worker_present to close fail-open reasoner bug (#4631) - #4644
Conversation
rysweet
left a comment
There was a problem hiding this comment.
Step 17b — Comprehensive Code Review
Verdict: ✅ Approve (zero blocking findings). Independently re-verified below, not rubber-stamped.
Scope reviewed (true merge diff, not the misleading two-dot view)
gh pr diff renders +755 / −2184 across 19 files, which looks alarming. That is a two-dot artifact: this branch is 1 ahead / 4 behind main, so gh shows main's newer content as apparent deletions. The actual three-dot merge diff (main...HEAD) is +688 / −2 across 7 files — exactly the single commit dd76dbe3c. git merge-tree --write-tree reports a clean merge, 0 conflict markers (mergeable: MERGEABLE). No unintended reverts of no_progress.rs / gates.rs / deleted docs will occur on merge.
Checklist
- Code quality & standards ✅ — Single-site change at
cycle.rs. Presence read is nowcontains_key(goal_id) && find_live_engineer_for_goal(&simard_state_root(), goal_id).is_some(). Cheap→expensive short-circuit preserves the IO-free fast path for the common "no claim" case. Mirrors the #4437 / #4574 / #4608 fail-close hardening exactly (Approach B), adds no new public API, no newSIMARD_*_SECSthreshold, noprint!/println!/dbg!, structured-tracing discipline intact. - Logic correctness ✅ — Verified symbol resolution end-to-end:
find_live_engineer_for_goal(&Path, &str) -> Option<PathBuf>atadvance_goal/spawn.rs:806, re-exported viaadvance_goal/mod.rs:41;simard_state_root()re-exported fromcrate::goal_curation. Call site types (&PathBuf → &Path,&str,.is_some()) all line up. Fail-closed direction is correct:None(dead or unreadable/IO-error) →worker_present = false→ existingstale_claim_secsreclaim re-engages. Never fabricates a live worker. - Edge cases ✅ — Dead PID, recycled-PID (start-time guard inherited from the helper), missing sentinel, and
read_dirIO error all resolve to "not present" (safe). Genuinely-live workers unchanged (no over-correction). - Test coverage ✅ — Three hermetic,
#[serial(cognitive_memory)]tests over real allocated worktrees + live claim sentinels: (1) leaked/dead-PID →!worker_presentandstale_claim_secs.is_some()(the TDD driver that fails pre-fix); (2) live engineer →worker_present+ no stale signal (over-correction guard); (3) no map entry → short-circuit absent. Env-var mutation is scoped/restored via a Drop guard;gitfixtures run with a scrubbed env. Respects the #4571/#4575 de-flake precedent. - No TODOs / stubs / swallowed exceptions / unimplemented ✅ — Grep of added lines is clean; no
unwrap/expectin production code (only in test fixtures, appropriately).
Independent verification performed
cargo test --locked --lib tests_worker_present_liveness→ 3 passed, 0 failed (clean 1m compile, no warnings surfaced).- CI: coverage, cargo-audit/deny/vet, npm-audit, scripts-tests, GitGuardian pass; pre-commit pending (must go green before merge).
Non-blocking observations (no action required)
- Quadratic scan — N claim-holding goals each scan the full worktrees root (~N entries) per cycle. Already documented in the new API-reference
#costnote and bounded by concurrent-engineer admission limits. Approach A (in-process claim check) remains a non-breaking future optimization if profiling ever flags it. - Branch is 4 commits behind
main— merge is clean, so not required, but a rebase would makegh pr difflegible for human reviewers.
Conclusion: Correct, minimal, well-tested fix that closes the #4631 fail-open leak by mirroring the already-reviewed fail-close liveness verifier. Scope guard honored (no changes to subordinate.rs reap selection, reaper, or resource-admission). Ready to merge once pre-commit is green.
Step 17c — Security Review (MANDATORY)Verdict: ✅ Approve — net security improvement, zero new vulnerabilities. Independently analyzed against the true 3-dot merge diff ( Security requirements — all met
Notes (non-blocking)
Conclusion: No secrets exposed, no injection or traversal vectors, no new attack surface. The change is a defense-in-depth hardening that eliminates a fail-open reclaim gap. Approved from a security standpoint. |
Step 17d — Philosophy Guardian ReviewVerdict: ✅ COMPLIANT — approved against all four principles. Assessed on the true 3-dot merge diff (+688/−2, 7 files), not the misleading 2-dot Philosophy compliance checklist
Notes
No remediation items. Change is minimal, verified, and philosophy-compliant. |
… bug (#4631) gather_per_goal_cycle_ctx computed worker_present from bare engineer_worktrees map membership. A leaked/orphaned entry (engineer SIGKILLed, OOM, host reboot, daemon crash-reload) read as "present … alive" forever, so the goal never re-spawned and never populated stale_claim_secs — silently wedging. Gate the presence read on a verified-live engineer via the existing find_live_engineer_for_goal helper (PID + starttime, mirroring the #4608/#4574 fail-close hardening). contains_key is retained as a short-circuit so the filesystem scan only runs for goals that hold a claim. Dead/leaked claims now read false and the existing stale_claim_secs reclaim path re-engages. Additive, non-breaking; genuinely-live workers unchanged (fail-closed on dead/unreadable claims). Adds hermetic, serial-safe regression tests (leaked -> absent+reclaimable, live -> present, no-entry -> short-circuit) and docs for the liveness-verified worker-presence contract. Closes #4631 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
dd76dbe to
f97437f
Compare
Step 18b — Review Feedback Implementation SummaryAll three mandatory reviews (Code 17b, Security 17c, Philosophy 17d) returned ✅ Approve/Compliant with zero blocking findings. Actions taken per the Step 18a action plan:
Net result
Scope guard intact — no speculative edits. Ready to merge once the re-triggered |
📊 Coverage Summary
Coverage data from CI run. Test files matching |
Summary
Fixes a fail-open bug in the per-goal OODA reasoner.
gather_per_goal_cycle_ctxcomputed
worker_presentfrom bareengineer_worktreesmap membership, so aleaked/orphaned claim entry (engineer SIGKILLed, OOM, host reboot, daemon
crash-reload) read as "present … alive" forever — the goal never re-spawned and
never populated
stale_claim_secs, silently wedging.The presence read is now gated on a verified-live engineer via the existing
find_live_engineer_for_goalhelper (PID + starttime), mirroring the #4608 /#4574 fail-close hardening.
contains_keyis retained as a short-circuit sothe filesystem scan only runs for goals that actually hold a claim. Dead/leaked
claims now read
falseand the existingstale_claim_secsreclaim pathre-engages automatically.
Additive and non-breaking: genuinely-live workers are unchanged, and the read
stays fail-closed on dead/unreadable claims.
Changes
src/ooda_loop/cycle.rs— single-site liveness gate onworker_presentat
gather_per_goal_cycle_ctx; adds hermetic, serial-safe regression tests(leaked → absent+reclaimable, live → present, no-entry → short-circuit).
docs/concepts/worker-presence-liveness-verification.md,docs/concepts/engineer-claim-liveness-lease.md,docs/reference/worker-presence-liveness-api.md,docs/reference/ooda-per-goal-cycle-api.md,docs/fail-open-audit.md,mkdocs.yml.Issue
Closes #4631