Documents the root cause of the bf-40i loss (claude-sonnet PTY fallback
in resolve_adapter), the consequences, and the mitigations (atomic label,
NEEDLE fixes bf-14w/bf-2wi).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
All module-level deliverables for phases 1-11 are committed. Checked all
[ ] boxes to [x], added a Status section summarizing what is done vs.
pending (main() orchestration, E2E tests, billing verification, CI release),
and noted that the Phase 11 install.sh end-to-end download test is blocked
on a release binary (which requires main() completion first).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
G-1 (HIGH): Argo param syntax fixed in build-musl — {{}} not $()
G-2 (HIGH): SIGTERM row in signal table now includes 'SIGTERM child (per HR-8 mirror)'
G-3 (HIGH): Phase 11 now includes deferred install.sh end-to-end download test
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
G-1: claude_version claim narrowed — appears only in json/stream-json error, not text
G-2: claude_version runtime source specified — run binary once pre-fork, cache result
G-3: TRUST_DISMISSED idle-wait upper bound documented — wall-clock timeout is the only exit
G-4: keeper write-end fd close-before-waitpid added to all non-Stop exit paths
G-5: hook ordering claim softened to "likely first (unverified per OQ-1)"; OQ-1 expanded
G-6: ANSI stripping in last_assistant_message fallback extended to stream-json mode
G-7: parent fd 0 close after prompt read specified in PTY Spawner §3
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Critical:
- G-1: HR-8 vs Signal Handling contradiction resolved — SIGINT handler now sends SIGINT (not SIGTERM) to child
High:
- G-2: Event Loop timer is not a timerfd; Instant::elapsed() with poll() timeout parameter instead
- G-3: Signal handler safety specified: AtomicBool, kill(2), self-pipe to wake blocked poll()
- G-4: NEEDLE invoke_template now includes --no-inherit-hooks; AS-3 pass criterion now achievable
- G-5: Error output per format: text→stderr only; json→stdout JSON; stream-json→final error line
Medium:
- G-6: Child resets SIGINT+SIGTERM to SIG_DFL before execvp (signal handler inheritance)
- G-7: "weekly schedule" claim removed; version-compat tests run on every push (CI already covers it)
- G-8: needle-transform-claude defined as NEEDLE's built-in transform for claude JSON output
- G-9: Integration tests use --claude-binary <path-to-mock_claude> via CARGO_MANIFEST_DIR
- G-10: XTVERSION probe accepts both ESC[>q and ESC[>0q (parameterized form)
- G-11: Install Script renumbered 1-8 with clean integers (removed decimal 2.5/3.5 steps)
- G-12: T-6 threat (PATH hijack) added to threat model
Low:
- G-13: Config path respects $XDG_CONFIG_HOME when set
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Addresses all MISSING/PARTIAL items from the plan review:
- Glossary, Non-Goals, Hard Requirements, What It Is Not, Scope Lock
- Acceptance scenarios (AS-1 through AS-6) with pass/fail criteria
- Module layout (src/ file tree), state machine diagrams, concurrency model
- Cross-cutting concerns: error propagation, signals, temp dir, log boundary
- Tech stack rationale column on crate table
- Edge case catalog (EC-1..12), anti-patterns, invariants (INV-1..8)
- Proof obligations (PO-1..6) with named recovery per assumption
- Phase entry/exit criteria and LOC estimates for all 11 phases
- Conformance harness + definition of done + all-gates policy in Testing
- Security section: threat model (T-1..5), untrusted input policy, supply chain
- Performance section: budgets, benchmark contract, CI size gate
- Operations section: migration plan, semver stance, rollout/rollback, doctor command
- Risk register (R-1..7) with likelihood/impact/mitigation
- ADRs (ADR-001..003) for the three churn-magnet decisions
- Open Questions updated with phase dependencies and resolution deadlines
- Phase 6 renamed from duplicate "Hook installer" to "Stop poller"
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>