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>
Documents build commands, test structure, module map, key invariants,
and bead workflow for AI coding agents working in this repo.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
bf-4r6 (Write AGENTS.md) was blocked on bf-40i (Wire main()), but
documentation writing does not require main() to be functional.
Removing this dependency makes bf-4r6 ready for a worker to claim.
bf-52c's dependency on bf-40i remains correct — binary E2E tests
genuinely require a working binary.
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>
Verified claude-print-ci WorkflowTemplate is present in iad-ci and
shows Synced status in ArgoCD app argo-workflows-ns-iad-ci. Overall
app is OutOfSync/Degraded due to pre-existing unrelated pdftract and
ExternalSecret issues.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
WorkflowTemplate/claude-print-ci shows Sync: Synced in ArgoCD app
argo-workflows-ns-iad-ci, and is present in iad-ci cluster (created
2026-06-10T06:09:14Z). Overall app is OutOfSync due to pre-existing
unrelated pdftract/ExternalSecret issues outside this bead's scope.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Copied claude-print.yaml to ~/.config/needle/adapters/ and confirmed
needle test-agent returns Status: READY with stdin input and
needle-transform-claude transform.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
install.sh was created in Phase 9 (commit 50b2132). Verified it passes
bash -n, covers x86_64/aarch64 musl targets, installs with -m 755 to
~/.local/bin, and runs claude-print --check post-install.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Confirms the --check subcommand (src/check.rs) is fully implemented:
openpty probe, mkfifo probe, optional mock_claude PTY round-trip,
exits 0 on success with diagnostic table, exits 2 on any FAIL.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
All 13 emitter unit tests pass on re-verification. Implementation was
already complete from prior run; this run confirms correctness and
commits the bead close state.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds emitter.rs with three output format handlers and stream-json reader thread,
ClaudePrintError enum with exit codes and JSON subtypes to error.rs,
and 13 unit tests in tests/emitter.rs covering all plan requirements.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Implements src/transcript.rs: lenient JSONL parsing, message.id dedup
with usage-fingerprint fallback, text extraction from ContentBlock arrays,
40×50ms retry loop for Stop-before-JSONL races (PO-5), and last_assistant_message
fallback. All 18 tests in tests/transcript.rs pass; AS-6 verified with
MOCK_DELAY_JSONL=100.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Phase 6 Stop Poller was implemented in 59e170e and verified complete.
Both integration tests (test_stop_hook_fires, test_missing_transcript_path_derived) pass.
Compaction removed duplicate in-progress entry for bf-64s.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
All Phase 6 implementation was committed in prior sessions (59e170e).
Both completion criteria tests pass: test_stop_hook_fires and
test_missing_transcript_path_derived.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
All tests pass including test_stop_hook_fires and
test_missing_transcript_path_derived. Implementation complete in 59e170e.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Verifies test_stop_hook_fires and test_missing_transcript_path_derived pass;
documents the FIFO open race resolution (OQ-4) and path derivation algorithm.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add src/poller.rs with FIFO O_NONBLOCK open (read-end + keeper write-end),
Stop hook JSON payload parsing, transcript path derivation via cwd slug,
and StopInfo resolution. Wire poller into EventLoop via add_fifo_fd() which
was already present in event_loop.rs from Phase 3.
Update mock-claude to emit proper JSON Stop payloads (with and without
transcript_path via MOCK_OMIT_TRANSCRIPT_PATH=1) and update the pty_integration
assertion to match.
Tests test_stop_hook_fires and test_missing_transcript_path_derived both pass.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
All open beads are transitively blocked waiting on bf-64s (Phase 6, in_progress).
No configuration error — sequential dependency chain is working as designed.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Prompts exceeding INLINE_PROMPT_MAX (32 KB) are written to a NamedTempFile
and a shell $(< path) read command is injected via bracketed paste instead
of the raw bytes, avoiding PTY pipe-buffer saturation.
Adds four unit tests: threshold boundary (inline), threshold+1 (file relay),
temp-file content verification, and end-to-end state-machine coverage.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Implementation was already present from bf-54m. make_prompt_payload()
wraps the startup prompt in ESC[200~ / ESC[201~\r; injection fires after
the post-dismiss idle gap. All 41 tests pass confirming correct behavior.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
After trust-dismiss fires, the post-dismiss wait is now an idle-gap:
injection fires only after idle_gap_ms of uninterrupted silence.
Any PTY output chunk resets the gap via last_output_at, preventing
premature injection during TUI redraws after the dismiss CR.
- Rename POST_DISMISS_IDLE_MS → DEFAULT_POST_DISMISS_IDLE_MS (pub const)
- Add idle_gap_ms field to StartupSeq; expose via with_idle_gap() ctor
- TrustDismissed timer now uses last_output_at instead of trust_dismiss_at
- Reset last_output_at when entering TrustDismissed via idle-fallback path
- Add three unit tests: resets on output, fires after silence, no double-fire
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Implements StartupSeq with scan_line() that detects 2+ trust keywords
("trust", "Allow", "continue", "folder", "permission", "proceed") on a
PTY output line and returns CR to dismiss the dialog. Includes idle
fallback (0.8 s after 200+ bytes) and hard timeout (45 s / <200 bytes →
HardTimeout). Phase 2 injects the prompt via bracketed paste after a
2 s post-dismiss idle.
11 test_trust_dialog_* integration tests cover keyword match, threshold,
case sensitivity, chunk-boundary assembly, one-shot dismiss, and CR- vs
LF-terminated lines. 12 unit tests in startup::tests cover scan_line
and feed() in isolation.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
All 9 terminal unit tests pass. TerminalEmu in terminal.rs handles
DA1/DA2/DSR/XTVERSION/WinSize probes with dedup bitmask and split-chunk
accumulation.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>