From 16bf418396939c04084e01568c1d9cbf64329258 Mon Sep 17 00:00:00 2001 From: jedarden Date: Wed, 10 Jun 2026 20:43:00 -0400 Subject: [PATCH] bf-4eb: Remove overly-conservative dependency blocking bf-4r6 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- .beads/issues.jsonl | 22 ++++------------------ notes/bf-4eb.md | 26 ++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 18 deletions(-) create mode 100644 notes/bf-4eb.md diff --git a/.beads/issues.jsonl b/.beads/issues.jsonl index c9b72de..0a30db8 100644 --- a/.beads/issues.jsonl +++ b/.beads/issues.jsonl @@ -1,18 +1,4 @@ -{"id":"bf-10t","title":"Phase 10: Tests (~500 LOC)","description":"Entry: Phase 8 complete (can run in parallel with Phase 9).\n\nPhase 10 completes the test suite by adding tests NOT already written as part of Phases 2-9 completion criteria. Each prior phase's completion criterion already specifies and runs its own targeted integration tests.\n\nPhase 10 adds the remaining cross-phase and corner-case tests:\n- Version-resilience suite: feed transcript JSONL with extra/unknown fields across all JSONL event types; confirm no panic, correct output\n- Hook inheritance suite: verify user hooks in ~/.claude/settings.json fire alongside the relay hook (OQ-2 resolution validated end-to-end)\n- All MEDIUM/LOW mock scenarios not covered by earlier phases (see Testing section of plan.md for full list)\n- Conformance harness: run claude-print against a real claude binary in a sandboxed invocation and compare output format to claude -p reference\n\nComplete when:\n- cargo test passes with zero failures (all unit + integration tests)\n\nReference: docs/plan/plan.md \u00a7 Phase 10","design":"","acceptance_criteria":"","notes":"","status":"in_progress","priority":1,"issue_type":"task","assignee":"claude-glm-glm47-alpha","created_at":"2026-06-10T03:54:17.744030380Z","updated_at":"2026-06-10T06:05:50.540302877Z","source_repo":".","compaction_level":0,"labels":["deferred","umbrella"],"dependencies":[{"issue_id":"bf-10t","depends_on_id":"bf-2f1","type":"blocks","created_at":"2026-06-10T03:54:31.710642868Z","created_by":"cli","thread_id":""},{"issue_id":"bf-10t","depends_on_id":"bf-3za","type":"blocks","created_at":"2026-06-10T06:07:58.776597159Z","created_by":"cli","thread_id":""}]} -{"id":"bf-168","title":"Add claude-print-ci WorkflowTemplate to declarative-config","description":"Create the claude-print-ci WorkflowTemplate in jedarden/declarative-config at k8s/iad-ci/argo-workflows/.\n\nDeliverables:\n- WorkflowTemplate named claude-print-ci\n- verify step only (build-musl + github-release steps added in Phase 11)\n- Delegates to rust-verify WorkflowTemplate\n- Follows existing patterns in k8s/iad-ci/argo-workflows/\n\nAcceptance criteria:\n- WorkflowTemplate YAML is valid and parseable\n- ArgoCD syncs it without errors\n- Running claude-print-ci with verify step completes successfully via rust-verify delegation","design":"","acceptance_criteria":"","notes":"","status":"in_progress","priority":2,"issue_type":"task","assignee":"claude-code-glm-47-claude-print-bravo","created_at":"2026-06-10T05:42:41.854551786Z","updated_at":"2026-06-10T06:09:32.129526605Z","source_repo":".","compaction_level":0,"labels":["split-child","umbrella"],"dependencies":[{"issue_id":"bf-168","depends_on_id":"bf-3n3","type":"blocks","created_at":"2026-06-10T05:42:54.812631980Z","created_by":"cli","thread_id":""},{"issue_id":"bf-168","depends_on_id":"bf-38f","type":"blocks","created_at":"2026-06-10T06:10:36.151226501Z","created_by":"cli","thread_id":""}]} -{"id":"bf-2f1","title":"Phase 8: Emitter (~120 LOC)","description":"Entry: Phase 7 complete.\n\nImplementation: src/emitter.rs\n- Output format routing: text (plain string to stdout), json (JSON object with result/cost/session_id/claude_version), stream-json (forward raw JSONL lines as written)\n- claude_version: read from child process version string captured at startup\n- Error result objects: exit code mapping (0=success, 1=error, 2=no-response, 3=timeout, 4=input-error)\n- stream-json: reader thread consuming JSONL transcript file via mpsc channel, forward each line to stdout as written\n\nComplete when:\n- All emitter unit tests pass (tests/emitter.rs)\n- AS-1 (text output format) passes: response text emitted to stdout, exit 0\n- AS-2 (json output format) passes: valid JSON object on stdout with result field\n- stream-json output parses as valid JSONL (each line is valid JSON)\n\nReference: docs/plan/plan.md \u00a7 Phase 8","design":"","acceptance_criteria":"","notes":"","status":"closed","priority":1,"issue_type":"task","assignee":"claude-code-glm-47-claude-print-bravo","created_at":"2026-06-10T03:53:59.176338208Z","updated_at":"2026-06-10T05:45:00Z","closed_at":"2026-06-10T05:45:00Z","close_reason":"Completed","source_repo":".","compaction_level":0,"dependencies":[{"issue_id":"bf-2f1","depends_on_id":"bf-64k","type":"blocks","created_at":"2026-06-10T03:54:31.701710128Z","created_by":"cli","thread_id":""}]} -{"id":"bf-360","title":"Implement --check subcommand in claude-print","description":"Add the --check subcommand to src/main.rs or src/check.rs.\n\nDeliverables:\n- openpty probe: confirm openpty syscall succeeds\n- mkfifo probe: confirm mkfifo in /home/coding/.tmp succeeds\n- optional mock_claude PTY round-trip (if mock_claude binary present in PATH)\n- exits 0 on success, prints diagnostic table to stdout\n\nAcceptance criteria:\n- cargo build succeeds with the --check subcommand present\n- Running claude-print --check locally exits 0 and prints a diagnostic table\n- Running claude-print --check on a system missing openpty exits non-zero with clear error","design":"","acceptance_criteria":"","notes":"","status":"closed","priority":2,"issue_type":"task","created_at":"2026-06-10T05:42:25.787304377Z","updated_at":"2026-06-10T05:45:27.270Z","closed_at":"2026-06-10T05:45:27.270Z","close_reason":"Completed","source_repo":".","compaction_level":0,"labels":["split-child"]} -{"id":"bf-38f","title":"Run claude-print-ci verify step and confirm successful completion","description":"Submit a manual workflow run using the claude-print-ci WorkflowTemplate and confirm the verify step completes successfully.\n\nSteps:\n- Submit a Workflow referencing workflowTemplateRef: claude-print-ci to iad-ci argo-workflows namespace\n- Monitor the workflow progress (stream logs while running, check final phase)\n- Confirm the rust-verify delegation completes with Succeeded phase\n\nAcceptance criteria:\n- Workflow reaches Succeeded phase\n- The verify step (fmt + clippy + test) passes without errors\n- Confirms rust-verify delegation works end-to-end","design":"","acceptance_criteria":"","notes":"","status":"open","priority":2,"issue_type":"task","created_at":"2026-06-10T06:10:29.005383291Z","updated_at":"2026-06-10T06:10:29.005383291Z","source_repo":".","compaction_level":0,"labels":["split-child"],"dependencies":[{"issue_id":"bf-38f","depends_on_id":"bf-4km","type":"blocks","created_at":"2026-06-10T06:10:36.137373876Z","created_by":"cli","thread_id":""}]} -{"id":"bf-3n3","title":"Write claude-print.yaml NEEDLE agent config","description":"Create claude-print.yaml NEEDLE agent configuration file for dispatching beads via claude-print instead of claude -p.\n\nDeliverables:\n- input_method: stdin\n- output_transform: needle-transform-claude\n- invoke_template: claude-print --output-format json --model ${MODEL}\n- All required NEEDLE agent config fields populated correctly\n\nAcceptance criteria:\n- NEEDLE accepts the config without validation errors\n- NEEDLE dispatches a test bead using claude-print.yaml\n- AS-3 (agent spec test 3) passes with this config","design":"","acceptance_criteria":"","notes":"","status":"closed","priority":2,"issue_type":"task","assignee":"claude-code-glm-47-claude-print-bravo","created_at":"2026-06-10T05:42:36.202732130Z","updated_at":"2026-06-10T05:52:09.166882664Z","closed_at":"2026-06-10T05:52:09.166882664Z","close_reason":"Completed","source_repo":".","compaction_level":0,"labels":["split-child"],"dependencies":[{"issue_id":"bf-3n3","depends_on_id":"bf-3vj","type":"blocks","created_at":"2026-06-10T05:42:54.798141429Z","created_by":"cli","thread_id":""}]} -{"id":"bf-3pc","title":"Add PTY integration tests: startup and exit-path scenarios","description":"Expand tests/pty_integration.rs with mock-PTY tests for the following scenarios from the plan's integration test table:\n\n- Happy path: exit 0, correct response text, non-zero token counts\n- Trust dialog (standard wording): MOCK_TRUST_DIALOG=1 \u2192 exit 0\n- Trust dialog (alternate wording): MOCK_TRUST_DIALOG=1 MOCK_TRUST_WORDING=alternate \u2192 exit 0\n- No startup output: MOCK_SILENT=1 \u2192 exit 2 after timeout\n- Child exits before Stop: MOCK_EXIT_BEFORE_STOP=1 \u2192 exit 2\n- Stop hook never fires: MOCK_DELAY_STOP=99999 \u2192 exit 124\n- Stop fires before PROMPT_INJECTED: MOCK_STOP_BEFORE_INJECT=1 \u2192 exit 2, is_error=true in output (EC-7)\n\nEach test invokes the compiled claude-print binary with --claude-binary pointing at the mock-claude test fixture. Use std::process::Command to invoke the binary under test.\n\nAcceptance criteria:\n- All 7 tests compile and pass via cargo test\n- Each test asserts the correct exit code\n- Happy path test also asserts non-empty response text in stdout","design":"","acceptance_criteria":"","notes":"","status":"in_progress","priority":2,"issue_type":"task","assignee":"claude-glm-glm47-alpha","created_at":"2026-06-10T06:07:21.833119624Z","updated_at":"2026-06-10T06:08:31.870625620Z","source_repo":".","compaction_level":0,"labels":["split-child"]} -{"id":"bf-3vj","title":"Write install.sh for claude-print binary","description":"Create install.sh that downloads the claude-print release binary from GitHub and installs it to ~/.local/bin/claude-print.\n\nDeliverables:\n- Downloads the correct binary for the current platform from the GitHub releases page\n- Installs to ~/.local/bin/claude-print with executable permissions\n- Runs claude-print --check after install to verify the binary works\n- Script is POSIX-compatible bash\n\nAcceptance criteria:\n- bash -n install.sh passes (syntactically valid)\n- Running install.sh on a clean system installs the binary and exits 0\n- claude-print --check succeeds after install","design":"","acceptance_criteria":"","notes":"","status":"closed","priority":2,"issue_type":"task","created_at":"2026-06-10T05:42:30.633173087Z","updated_at":"2026-06-10T05:47:43.818004Z","closed_at":"2026-06-10T05:47:43.818004Z","source_repo":".","compaction_level":0,"labels":["split-child"],"dependencies":[{"issue_id":"bf-3vj","depends_on_id":"bf-360","type":"blocks","created_at":"2026-06-10T05:42:54.784343802Z","created_by":"cli","thread_id":""}]} -{"id":"bf-3za","title":"Ensure cargo test passes with zero failures for Phase 10","description":"Final integration pass to make all tests pass cleanly:\n\n1. Run cargo test locally (falls back to local cgroup-limited run if no git remote or uncommitted changes)\n2. Fix any compilation errors introduced by the new test files from bf-3pc, bf-4nq, bf-69f\n3. Fix any test failures:\n - Mock-claude binary path resolution\n - Test isolation (no leftover temp dirs, no cross-test contamination)\n - Timeout values appropriate for CI environment\n4. Ensure cargo fmt --check passes on all new test files\n5. Ensure cargo clippy -- -D warnings passes\n\nDepends on: bf-69f\n\nAcceptance criteria:\n- cargo test passes with zero failures (all unit + integration tests)\n- cargo fmt --check passes\n- cargo clippy -- -D warnings passes\n- No leftover claude-print-* dirs in TMPDIR after test run (INV-1)","design":"","acceptance_criteria":"","notes":"","status":"open","priority":2,"issue_type":"task","created_at":"2026-06-10T06:07:51.718915692Z","updated_at":"2026-06-10T06:07:51.718915692Z","source_repo":".","compaction_level":0,"labels":["split-child"],"dependencies":[{"issue_id":"bf-3za","depends_on_id":"bf-69f","type":"blocks","created_at":"2026-06-10T06:07:55.509159267Z","created_by":"cli","thread_id":""}]} -{"id":"bf-42j","title":"Phase 9: NEEDLE Integration (~50 LOC + config)","description":"Entry: Phase 8 complete.\n\nDeliverables:\n1. claude-print.yaml \u2014 NEEDLE agent config for dispatching beads via claude-print instead of claude -p\n - input_method: stdin, output_transform: needle-transform-claude\n - invoke_template: claude-print --output-format json --model ${MODEL}\n2. install.sh \u2014 download release binary from GitHub, install to ~/.local/bin/claude-print, verify --check\n3. claude-print-ci WorkflowTemplate in jedarden/declarative-config (k8s/iad-ci/argo-workflows/)\n - verify step only (build-musl + github-release steps added in Phase 11)\n - delegates to rust-verify WorkflowTemplate\n4. --check subcommand in src/main.rs or src/check.rs\n - openpty probe: confirm openpty syscall succeeds\n - mkfifo probe: confirm mkfifo in /home/coding/.tmp succeeds\n - optional mock_claude PTY round-trip (if mock_claude binary present in PATH)\n - exits 0 on success, prints diagnostic table\n\nComplete when:\n- bash -n install.sh passes (syntactically valid)\n- Manually copying locally-built binary to ~/.local/bin/claude-print and running claude-print --check succeeds\n- NEEDLE dispatches a test bead using claude-print.yaml; AS-3 passes\n- README flags table matches claude-print --help output exactly (verified manually)\n\nReference: docs/plan/plan.md \u00a7 Phase 9","design":"","acceptance_criteria":"","notes":"","status":"in_progress","priority":1,"issue_type":"task","assignee":"claude-code-glm-47-claude-print-bravo","created_at":"2026-06-10T03:54:09.318382701Z","updated_at":"2026-06-10T05:42:08.074835677Z","source_repo":".","compaction_level":0,"labels":["umbrella"],"dependencies":[{"issue_id":"bf-42j","depends_on_id":"bf-2f1","type":"blocks","created_at":"2026-06-10T03:54:31.706113490Z","created_by":"cli","thread_id":""},{"issue_id":"bf-42j","depends_on_id":"bf-168","type":"blocks","created_at":"2026-06-10T05:42:57.601270040Z","created_by":"cli","thread_id":""}]} -{"id":"bf-4km","title":"Confirm ArgoCD syncs claude-print-ci WorkflowTemplate without errors","description":"Verify that ArgoCD successfully syncs the claude-print-ci WorkflowTemplate from declarative-config to iad-ci.\n\nSteps:\n- Check ArgoCD app argo-workflows-ns-iad-ci sync status via the read-only proxy\n- Confirm the sync completed without errors for the claude-print-ci resource\n- If out of sync, wait for auto-sync or trigger a manual sync\n\nAcceptance criteria:\n- ArgoCD reports Synced and Healthy for the argo-workflows-ns-iad-ci app\n- The claude-print-ci WorkflowTemplate is present in iad-ci cluster (kubectl get workflowtemplate claude-print-ci -n argo-workflows)","design":"","acceptance_criteria":"","notes":"","status":"open","priority":2,"issue_type":"task","created_at":"2026-06-10T06:10:23.716877461Z","updated_at":"2026-06-10T06:10:23.716877461Z","source_repo":".","compaction_level":0,"labels":["split-child"],"dependencies":[{"issue_id":"bf-4km","depends_on_id":"bf-5nr","type":"blocks","created_at":"2026-06-10T06:10:36.122633134Z","created_by":"cli","thread_id":""}]} -{"id":"bf-4no","title":"Phase 11: CI (~YAML only)","description":"Entry: Phase 10 complete (and Phase 9 complete for install.sh e2e test).\n\nDeliverables in jedarden/declarative-config (k8s/iad-ci/argo-workflows/claude-print-ci.yaml):\n- Update claude-print-ci WorkflowTemplate stub (from Phase 9) with full steps:\n 1. verify \u2014 delegates to rust-verify WorkflowTemplate (fmt + clippy + test + cargo audit)\n 2. build-musl \u2014 cross-compile x86_64-unknown-linux-musl release binary\n 3. build-mock-claude-musl \u2014 build test-fixtures/mock-claude/ as musl binary\n 4. github-release \u2014 upload claude-print + mock_claude binaries + last-claude-version.txt artifact to GitHub Release\n- Confirm cargo audit runs (either via rust-verify or as explicit step between verify and build-musl)\n- install.sh end-to-end download test: download release artifact from GitHub Release URL, verify install.sh exits 0 and claude-print --check passes\n\nComplete when:\n- CI run on main branch produces release binary at expected GitHub Release URL\n- last-claude-version.txt artifact present in release\n- Binary passes claude-print --check (credential-free) via install.sh\n- install.sh end-to-end download test passes (deferred from Phase 9)\n- AS-1 verified manually before pushing release tag\n\nReference: docs/plan/plan.md \u00a7 Phase 11","design":"","acceptance_criteria":"","notes":"","status":"open","priority":1,"issue_type":"task","created_at":"2026-06-10T03:54:27.444014247Z","updated_at":"2026-06-10T03:54:27.444014247Z","source_repo":".","compaction_level":0,"dependencies":[{"issue_id":"bf-4no","depends_on_id":"bf-10t","type":"blocks","created_at":"2026-06-10T03:54:31.717358160Z","created_by":"cli","thread_id":""},{"issue_id":"bf-4no","depends_on_id":"bf-42j","type":"blocks","created_at":"2026-06-10T03:54:31.725797267Z","created_by":"cli","thread_id":""}]} -{"id":"bf-4nq","title":"Add PTY integration tests: output formats, multi-turn, and missing-data fallbacks","description":"Add PTY-level integration tests (using mock-claude binary) for these scenarios:\n\n- Output format json: parse stdout as JSON, verify all required fields present\n- Output format stream-json: each stdout line parses as valid JSON\n- Multi-turn: MOCK_TURNS=3 \u2192 last turn text returned, 3 turns counted in token sum\n- Transcript race: MOCK_DELAY_JSONL=100 \u2192 retry loop fires, exit 0\n- Missing transcript_path: MOCK_OMIT_TRANSCRIPT_PATH=1 \u2192 path derived, exit 0\n- Missing last_assistant_message: MOCK_OMIT_LAST_MESSAGE=1 \u2192 retry-only path, exit 0\n- Both omitted + delayed JSONL: MOCK_OMIT_LAST_MESSAGE=1 MOCK_DELAY_JSONL=200 \u2192 retries suffice, exit 0\n- Error in transcript: MOCK_IS_ERROR=1 \u2192 exit 1, is_error=true in json output\n- Custom response text: MOCK_RESPONSE=hello \u2192 response field equals 'hello' in json output\n- Large prompt (>32KB): test harness sends 33000-byte stdin \u2192 file relay used, exit 0\n\nDepends on: bf-3pc (startup/exit-path scenarios must be written first so the PTY test helpers are established)\n\nAcceptance criteria:\n- All 10 tests compile and pass via cargo test\n- SIGINT test added: send SIGINT to process after 1s with MOCK_DELAY_STOP=5000, assert exit 130","design":"","acceptance_criteria":"","notes":"","status":"open","priority":2,"issue_type":"task","created_at":"2026-06-10T06:07:32.891979298Z","updated_at":"2026-06-10T06:07:32.891979298Z","source_repo":".","compaction_level":0,"labels":["split-child"],"dependencies":[{"issue_id":"bf-4nq","depends_on_id":"bf-3pc","type":"blocks","created_at":"2026-06-10T06:07:55.483455428Z","created_by":"cli","thread_id":""}]} -{"id":"bf-5bl","title":"Starvation alert: beads invisible to worker","description":"## Starvation Alert\n\nOpen beads exist but Pluck found none \u2014 possible configuration error.\n\n**Workspace:** default\n**Total beads:** 6\n**Open:** 5\n**In-progress:** 1\n**Claimed by:** claude-glm-glm47-alpha\n\nCheck exclude_labels, workspace path, and filter configuration.","design":"","acceptance_criteria":"","notes":"","status":"closed","priority":2,"issue_type":"task","created_at":"2026-06-10T03:57:06.245148475Z","updated_at":"2026-06-10T04:30:00Z","closed_at":"2026-06-10T04:30:00Z","source_repo":".","compaction_level":0,"labels":["starvation-alert"]} -{"id":"bf-5nr","title":"Validate claude-print-ci WorkflowTemplate YAML syntax","description":"Confirm the WorkflowTemplate YAML in declarative-config is syntactically valid.\n\nSteps:\n- Run python3 yaml.safe_load on the workflowtemplate file\n- Run kubectl dry-run apply to confirm Kubernetes accepts it\n\nAcceptance criteria:\n- YAML parses without errors\n- kubectl dry-run returns no errors (workflowtemplate configured/created dry run)","design":"","acceptance_criteria":"","notes":"","status":"closed","priority":2,"issue_type":"task","created_at":"2026-06-10T06:10:14.456325882Z","updated_at":"2026-06-10T06:12:23Z","source_repo":".","compaction_level":0,"labels":["split-child"],"closed_at":"2026-06-10T06:12:23Z"} -{"id":"bf-64k","title":"Phase 7: Transcript Reader (~180 LOC)","description":"Entry: Phase 6 complete. PO-5 acknowledged: retry loop (40\u00d750ms) is the mitigation for Stop-before-JSONL races. Verify retry timing by running test_transcript_race with MOCK_DELAY_JSONL=100 and confirming exit 0.\n\nImplementation: src/transcript.rs\n- JSONL parse with lenient serde (unknown fields tolerated, unknown event types skipped)\n- message.id dedup + usage-fingerprint fallback dedup for events without message.id\n- Text extraction from assistant ContentBlock array (text type only)\n- 40\u00d750ms retry loop with Stop-payload fallback to last_assistant_message after exhausted\n- Path derivation: strip leading /, replace / with -, append session_id from Stop payload\n\nComplete when:\n- All transcript unit tests pass (tests/transcript.rs)\n- test_streaming_dedup_40_retries passes\n- AS-6 (race scenario: Stop fires before JSONL flush) passes with MOCK_DELAY_JSONL=100\n\nReference: docs/plan/plan.md \u00a7 Phase 7","design":"","acceptance_criteria":"","notes":"","status":"closed","priority":1,"issue_type":"task","assignee":"claude-code-glm-47-claude-print-bravo","created_at":"2026-06-10T03:53:52.452812786Z","updated_at":"2026-06-10T05:15:23.394672440Z","closed_at":"2026-06-10T05:15:23.394672440Z","close_reason":"Completed","source_repo":".","compaction_level":0,"dependencies":[{"issue_id":"bf-64k","depends_on_id":"bf-64s","type":"blocks","created_at":"2026-06-10T03:54:31.695602796Z","created_by":"cli","thread_id":""}]} -{"id":"bf-64s","title":"Phase 6: Stop Poller (~80 LOC)","description":"Entry: Phase 5 complete. OQ-2 must be resolved (verify --setting-sources= suppresses standard sources; see PO-2 for fallback). OQ-4 (FIFO open race) validated by test.\n\nImplementation: poller.rs (or extend event_loop.rs)\n- Open FIFO read-end O_NONBLOCK, integrate into poll() loop\n- Parse Stop hook JSON payload (session_id, transcript_path, last_assistant_message)\n- Derive transcript path from session_id + cwd slug if transcript_path absent\n- Signal event loop exit via channel/flag\n\nComplete when:\n- Integration test test_stop_hook_fires passes (mock_claude emits Stop, FIFO received, exit 0)\n- test_missing_transcript_path_derived passes (Stop without transcript_path \u2192 path derived from session_id)\n\nReference: docs/plan/plan.md \u00a7 Phase 6","design":"","acceptance_criteria":"","notes":"","status":"closed","priority":1,"issue_type":"task","assignee":"claude-glm-glm47-alpha","created_at":"2026-06-10T03:53:44.914912586Z","updated_at":"2026-06-10T04:40:12.904790Z","closed_at":"2026-06-10T04:40:12.904790Z","source_repo":".","compaction_level":0} -{"id":"bf-69f","title":"Add PTY integration tests: version resilience and --no-inherit-hooks","description":"Add remaining PTY-level integration tests using mock-claude binary:\n\nVersion-resilience PTY scenarios:\n- Unknown probe emitted: MOCK_UNKNOWN_PROBE=1 \u2192 probe ignored, session completes, exit 0\n- Unknown event type in JSONL: MOCK_UNKNOWN_EVENT_TYPE=1 \u2192 parse succeeds, text extracted, exit 0\n- Unknown usage fields: MOCK_UNKNOWN_USAGE_FIELDS=1 \u2192 ignored, token counts correct, exit 0\n\nHook inheritance scenarios (PTY-level, invoking claude-print binary):\n- --no-inherit-hooks flag: the appropriate --setting-sources argument appears in mock-claude's received argv (either --setting-sources= or --setting-sources=none), exit 0\n- Without --no-inherit-hooks: --setting-sources is absent from child argv, exit 0\n- Verify --settings /settings.json is always present in child argv in both modes\n\nConformance harness (PTY-level):\n- test_output_format_wire_compat: run claude-print --output-format json with mock-claude, verify all fields from the claude -p wire format are present, is_error=false, type=result, usage fields are integers\n- claude_version extra field does not cause parse failure with deny_unknown_fields strict struct\n\nDepends on: bf-4nq\n\nAcceptance criteria:\n- All tests compile and pass via cargo test\n- INV-1 verified in at least one test: after each test assert no claude-print-* dirs remain in TMPDIR","design":"","acceptance_criteria":"","notes":"","status":"open","priority":2,"issue_type":"task","created_at":"2026-06-10T06:07:43.981755082Z","updated_at":"2026-06-10T06:07:43.981755082Z","source_repo":".","compaction_level":0,"labels":["split-child"],"dependencies":[{"issue_id":"bf-69f","depends_on_id":"bf-4nq","type":"blocks","created_at":"2026-06-10T06:07:55.497924453Z","created_by":"cli","thread_id":""}]} +{"id":"bf-1vd","title":"Update plan.md: mark completed phases, document gaps","description":"All plan.md phase checkboxes still show '[ ]' despite phases 1-11 being implemented. Update the plan to reflect actual state.\n\n## Changes needed in docs/plan/plan.md\n\n1. Change all '- [ ]' items in Phases 1-11 to '- [x]' — all module-level deliverables have been committed.\n\n2. Add a ## Status section near the top of the Implementation Phases section (or after the phase list) documenting:\n - Phases 1-11 module implementation: COMPLETE\n - main() session orchestration: IN PROGRESS (bf-40i)\n - Binary-level E2E tests (AS-1/AS-2/AS-5): IN PROGRESS (bf-52c)\n - AS-4 billing classification: PENDING manual verification (requires credentials)\n - CI release binary: PENDING (Phase 11 WorkflowTemplate exists in declarative-config but no release has been cut)\n\n3. In the Phase 11 entry, note that the WorkflowTemplate was synced to ArgoCD but the install.sh end-to-end download test is blocked on a release binary existing (which requires main() to be complete first).\n\n## Complete when\n- All '- [ ]' in phases 1-11 are '- [x]'\n- Status section accurately reflects what is done vs pending\n- cargo test still passes (docs-only change, no code impact)","design":"","acceptance_criteria":"","notes":"","status":"in_progress","priority":2,"issue_type":"task","assignee":"claude-code-glm-47-alpha","created_at":"2026-06-11T00:39:49.249458285Z","updated_at":"2026-06-11T00:42:38.167818317Z","source_repo":".","compaction_level":0,"labels":["failure-count:1"]} +{"id":"bf-40i","title":"Wire main() session orchestration","description":"main() currently exits with 'not yet implemented' for any real invocation. Every module is implemented (hook.rs, pty.rs, event_loop.rs, terminal.rs, startup.rs, poller.rs, transcript.rs, emitter.rs) but nothing connects them. This bead wires main() into a working binary.\n\n## What main() must do\n\n1. **Prompt resolution** — read from: positional arg, --input-file path, or stdin (when stdin is not a TTY). Error with exit 4 if no prompt source found.\n\n2. **Resolve claude binary** — use cli.claude_binary if set, else 'claude' from PATH. Emit a human-readable error (exit 2) if not found.\n\n3. **Resolve claude_version** — run ` --version` and capture first line. Use 'unknown' on failure (non-fatal).\n\n4. **HookInstaller::new()** — creates temp dir, writes settings.json (merging or replacing depending on --no-inherit-hooks) and hook.sh (writes Stop payload to stop.fifo), mkfifo.\n\n5. **Self-pipe for SIGINT** — set up a pipe pair; install SIGINT handler that writes one byte to the write end. Pass read end to EventLoop::new().\n\n6. **PtySpawner::spawn()** — build the claude child argv:\n - argv[0]: claude binary path\n - --dangerously-skip-permissions\n - --settings \n - if --no-inherit-hooks: --setting-sources= (empty string)\n - if cli.model is set: --model \n - if cli.max_turns is set: --max-turns \n (Do NOT pass --output-format or --print to the child — it runs as interactive TUI)\n\n7. **TerminalEmu** (from terminal.rs) — instantiate; feed PTY chunks through it; write responses back to master_fd.\n\n8. **StartupSeq::new(prompt_bytes)** — instantiate with the resolved prompt.\n\n9. **EventLoop::new(master_fd, self_pipe_read)** — instantiate.\n\n10. **Run the event loop** — on each PTY chunk from EventLoop::run():\n - Feed chunk to TerminalEmu; write any responses to master_fd\n - Feed chunk to StartupSeq.feed(); match on StartupAction:\n - Write(bytes): write bytes to master_fd\n - HardTimeout: SIGTERM child, exit 2\n - None: continue\n - If StartupSeq.phase() == PromptInjected and FIFO not yet added:\n - Open the FIFO read-end via poller::open_fifo_nonblock()\n - Call event_loop.add_fifo_fd(fifo_fd)\n - Also call StartupSeq.poll_timers() after each poll() iteration\n\n11. **Handle ExitReason** from EventLoop::run():\n - FifoPayload(bytes): parse via poller::parse_stop_payload(), resolve via poller::resolve_stop_info()\n - ChildExited: emit error 'claude exited before Stop hook fired', exit 2\n - Interrupted: send SIGTERM to child pid, exit 130\n\n12. **For stream-json output format**: after Stop fires and transcript path is known, open the JSONL file and emit each line to stdout (replay mode — not real-time inotify). This satisfies the 'each line is valid JSON' contract.\n\n13. **Transcript reading** — call transcript::read_transcript() with the resolved path and last_assistant_message fallback from StopInfo. On failure: emit error, exit 2.\n\n14. **Emit** — call emitter::emit_success() or emitter::emit_error() as appropriate.\n\n15. **Cleanup** — PtySpawner::waitpid(), HookInstaller temp dir drops automatically.\n\n16. **Exit code mapping**:\n - 0: success\n - 1: assistant returned an error result (is_error in transcript)\n - 2: internal error / child died / no response\n - 3: timeout (--timeout exceeded)\n - 4: bad input (no prompt, invalid --input-file)\n - 130: interrupted (SIGINT)\n\n## Module API summary (all in src/)\n- HookInstaller::new() -> Result; fields: dir, settings_path, hook_path, fifo_path\n- PtySpawner::spawn(cmd: &CStr, args: &[CString]) -> Result; fields: master_fd, child_pid\n- EventLoop::new(master_fd: RawFd, self_pipe_read: RawFd); add_fifo_fd(fd: RawFd); run(on_output: F) -> Result\n- StartupSeq::new(prompt: Vec); feed(&mut self, chunk: &[u8]) -> StartupAction; poll_timers(&mut self) -> StartupAction; phase() -> &StartupPhase\n- TerminalEmu in terminal.rs — check its public API for feed/respond pattern\n- poller::open_fifo_nonblock(path: &Path) -> Result<(OwnedFd, OwnedFd)>; parse_stop_payload(bytes: &[u8]) -> Result; resolve_stop_info(payload: StopPayload) -> StopInfo\n- transcript::read_transcript(path: &Path, fallback: Option<&str>) -> Result\n- emitter::emit_success(writer, result, format, claude_version, duration_ms); emit_error(...)\n\n## Complete when\n- echo 'hello' | ./target/debug/claude-print exits non-zero only because claude binary requires auth (not 'not yet implemented')\n- PATH= ./target/debug/claude-print 'hello' exits 2 with human-readable error naming the missing binary (AS-5 passes)\n- cargo test passes with zero failures\n- --output-format json and --output-format stream-json paths are both reachable (no compile-time dead code warnings)","design":"","acceptance_criteria":"","notes":"","status":"in_progress","priority":0,"issue_type":"task","assignee":"claude-code-glm-47-claude-print-bravo","created_at":"2026-06-11T00:39:26.771582207Z","updated_at":"2026-06-11T00:39:55.943888506Z","source_repo":".","compaction_level":0} +{"id":"bf-4r6","title":"Write AGENTS.md (Phase 9 deliverable)","description":"Phase 9 required writing AGENTS.md but it was never created. Write it now.\n\nAGENTS.md is the file that tells AI coding agents (Claude Code, NEEDLE workers, etc.) how to work in this repo. It should cover:\n\n1. **Repo purpose** — claude-print is a drop-in replacement for 'claude -p' that drives the interactive TUI via PTY to preserve subscription billing after the June 15, 2026 cc_entrypoint split.\n\n2. **Build commands**:\n - Debug build: cargo build\n - Musl release: cargo build --target x86_64-unknown-linux-musl --release\n - Tests: cargo test (intercepted by ~/.local/bin/cargo → submits to iad-ci if clean)\n - Run --check: ./target/debug/claude-print --check\n\n3. **Test structure**:\n - Unit tests: inline in src/ modules (cargo test --lib)\n - Integration tests: tests/ directory — use mock_claude, no credentials needed\n - Binary E2E tests: tests/binary_e2e.rs — require compiled binary\n - mock_claude: test-fixtures/mock-claude/ — compiled as workspace member, controlled via env vars\n\n4. **Key invariants** (from plan.md):\n - MUST NOT change CLAUDE_CONFIG_DIR — transcripts go to ~/.claude/projects/\n - MUST clean up temp dir on all exit paths — no claude-print-* dirs in $TMPDIR\n - MUST forward SIGINT to child\n - MUST NOT pass --print or --output-format to the child claude process\n - cc_entrypoint=cli is the correctness invariant — verify via AS-4 before each release\n\n5. **Module map** — brief one-line description of each src/ file\n\n6. **Bead workflow** — uses br CLI with bf prefix; see .beads/config.yaml\n\n## Complete when\n- AGENTS.md exists at repo root\n- All build/test commands are accurate and runnable\n- cargo test still passes","design":"","acceptance_criteria":"","notes":"","status":"open","priority":2,"issue_type":"task","created_at":"2026-06-11T00:40:02.279353358Z","updated_at":"2026-06-11T00:40:02.279353358Z","source_repo":".","compaction_level":0} +{"id":"bf-52c","title":"Binary-level E2E tests: AS-1/AS-2/AS-5 via mock_claude","description":"Once main() is wired (bf-40i), write tests that invoke the compiled claude-print binary as a subprocess using mock_claude as the claude backend. These test the full pipeline end-to-end, not just individual modules.\n\n## Test infrastructure\n\nAll tests in this bead use the compiled debug binary (target/debug/claude-print) and set CLAUDE_BINARY (or --claude-binary) to the mock_claude binary path so they don't require real claude credentials.\n\nMock_claude is already a compiled workspace member at test-fixtures/mock-claude/. Read its src/main.rs to understand the env vars it responds to (MOCK_RESPONSE, MOCK_EXIT_CODE, MOCK_DELAY_STOP, etc.).\n\n## Tests to add in tests/binary_e2e.rs (new file)\n\n**AS-1 simulation (text output)**:\n- Invoke: claude-print --claude-binary 'test prompt'\n- Expected: exit 0, stdout contains non-empty text, no JSON syntax on stdout\n\n**AS-2 simulation (json output)**:\n- Invoke: claude-print --claude-binary --output-format json 'test prompt'\n- Expected: exit 0, stdout is valid single-line JSON with fields: type='result', subtype='success', is_error=false, result non-empty, claude_version present, usage object present\n\n**AS-5 (claude binary not found)**:\n- Invoke: claude-print --claude-binary /nonexistent 'hello'\n- Expected: exit 2, stderr contains human-readable message naming the missing binary\n- With --output-format json: stdout contains JSON with is_error=true, subtype='internal_error'\n\n**Stream-json format**:\n- Invoke: claude-print --claude-binary --output-format stream-json 'test prompt'\n- Expected: exit 0, each stdout line is valid JSON\n\n**No prompt error**:\n- Invoke: claude-print --claude-binary (no prompt, stdin is /dev/null)\n- Expected: exit 4\n\n**Version flag**:\n- Invoke: claude-print --claude-binary --version\n- Expected: exit 0, stdout contains 'claude-print' and 'wrapping'\n\n## Complete when\n- cargo test --test binary_e2e passes with all scenarios above\n- No tests skip or are marked #[ignore]","design":"","acceptance_criteria":"","notes":"","status":"open","priority":1,"issue_type":"task","created_at":"2026-06-11T00:39:39.672328785Z","updated_at":"2026-06-11T00:39:39.672328785Z","source_repo":".","compaction_level":0,"dependencies":[{"issue_id":"bf-52c","depends_on_id":"bf-40i","type":"blocks","created_at":"2026-06-11T00:40:06.297310808Z","created_by":"cli","thread_id":""}]} diff --git a/notes/bf-4eb.md b/notes/bf-4eb.md new file mode 100644 index 0000000..dcc0591 --- /dev/null +++ b/notes/bf-4eb.md @@ -0,0 +1,26 @@ +# bf-4eb: Starvation Alert — Beads Invisible to Worker + +## Diagnosis + +The starvation alert was triggered because both open beads were blocked by dependencies: + +- **bf-52c** (Binary-level E2E tests) — depends on bf-40i (Wire main()) +- **bf-4r6** (Write AGENTS.md) — depends on bf-40i (Wire main()) + +Since bf-40i is in_progress, `br ready` returned nothing, so the worker had nothing to claim. + +## Root Cause + +The dependency of bf-4r6 on bf-40i was overly conservative. Writing AGENTS.md (documentation of build commands, module map, repo purpose) does not require main() to be fully wired — it can be done independently. The dependency was likely added reflexively because both beads were created at the same time as "Phase 9/10 deliverables." + +bf-52c's dependency on bf-40i IS correct — binary E2E tests require a working binary, which requires main() to be wired. + +## Fix + +Removed the dependency: `br dep remove bf-4r6 bf-40i` + +After the fix, `br ready` shows bf-4r6 as claimable. A worker can now proceed with writing AGENTS.md while bf-40i is still being worked on. + +## Not a Configuration Error + +This was not a misconfiguration of exclude_labels, workspace paths, or filter settings — it was an overly conservative dependency creating a false bottleneck.