Skip to content

fix(miner): use claude/codex's real non-interactive CLI argv#5382

Merged
JSONbored merged 1 commit into
mainfrom
fix/miner-cli-provider-argv-5135
Jul 12, 2026
Merged

fix(miner): use claude/codex's real non-interactive CLI argv#5382
JSONbored merged 1 commit into
mainfrom
fix/miner-cli-provider-argv-5135

Conversation

@JSONbored

Copy link
Copy Markdown
Owner

Summary

While tracing #5135's cost tracking, found that defaultCliSubprocessArgs built ["--max-turns", N, "--acceptance-criteria", path, instructions]neither --max-turns nor --acceptance-criteria is a real flag on the claude or codex CLI (verified against claude --help and codex exec --help, plus a live invocation). The argv also never included -p/--print (claude) or the exec subcommand (codex) at all. Without those, a spawned claude/codex process starts an interactive session against a subprocess whose stdin is closed — meaning the claude-cli/codex-cli providers had no real non-interactive argv shape in production.

Fix

Splits the shared builder into defaultClaudeCliArgs (--print --output-format json --permission-mode acceptEdits) and defaultCodexCliArgs (exec --json --sandbox workspace-write), matching each CLI's own real, verified interface. --output-format json/--json also finally activate claudeErrorStatus/codexErrorFromStdout's existing JSON(L) parsing, which was already written for exactly this shape but never actually triggered since the flag was never passed.

Two more real, previously-latent gaps this exposed

  • Claude's own documented behavior ("--output-format json sometimes exits non-zero") implies it can also exit 0 while the JSON envelope reports is_error: true — confirmed empirically via a live invocation. claudeErrorStatus was already written to detect this exact shape but was only ever checked on the code !== 0 branch; now also checked on success exit codes.
  • Adds real cost parsing (ported from src/selfhost/ai.ts's own COST_KEYS/extractCliUsage best-effort pattern) so claude-cli/codex-cli now report costUsd from their own real JSON(L) output too, closing the "CLI providers report no cost" gap fix(miner): wire real dollar-cost tracking into the loop's budgetSpent #5356 documented as a deliberate limitation.

driver-factory.ts's buildCliArgsWithConfiguredModel is now command-aware: codex's own -m/--model flag is scoped to the exec subcommand (per codex exec --help) and must land after "exec", not prefixed before everything the way claude's top-level --model flag can be — a single shared prefix-everything scheme would have silently misparsed for codex.

Test plan

  • New regression: real argv assertions for both claude and codex default builders
  • New regression: fails closed at construction time for an unrecognized command with no buildArgs override; an explicit override still works
  • New regression: ok:false when --output-format json's envelope carries is_error:true even on exit code 0; still ok:true on a genuine success envelope; never inspected for non-claude commands
  • New regression: real cost extraction for both providers (single JSON result for claude, JSONL stream for codex, tolerant of malformed/negative/non-numeric values and blank lines) — includes 100% branch coverage on every new line
  • npx vitest run test/unit — 738 files / 14,654 tests pass
  • npx tsc --noEmit -p . --incremental false (fresh, no cache) — clean
  • npm run test:driver-parity, npm run test --workspace @jsonbored/gittensory-engine (520 node:test cases) — pass
  • npm run --prefix packages/gittensory-miner build — pass
  • git diff --check — clean
  • Verified 100% line + branch coverage on both touched source files via a full, unsharded npm run test:coverage run (cross-checked against the exact diff hunks, not just the file totals)

Advances #5135

defaultCliSubprocessArgs built ["--max-turns", N, "--acceptance-criteria",
path, instructions] -- neither --max-turns nor --acceptance-criteria is
a real flag on the claude or codex CLI (verified against `claude --help`
and `codex exec --help`, plus a live invocation), and the argv never
included -p/--print (claude) or the exec subcommand (codex) at all.
Without those, a spawned claude/codex process starts an INTERACTIVE
session against a subprocess whose stdin is closed -- meaning the
claude-cli/codex-cli providers had no real non-interactive argv shape
in production.

Splits the shared builder into defaultClaudeCliArgs (--print
--output-format json --permission-mode acceptEdits) and
defaultCodexCliArgs (exec --json --sandbox workspace-write), matching
each CLI's own real, verified interface. --output-format json / --json
also finally activate claudeErrorStatus/codexErrorFromStdout's existing
JSON(L) parsing, which was already written for exactly this shape but
never actually triggered since the flag was never passed.

Surfaces two more real, previously-latent gaps this exposed:
- claude's own documented behavior ("--output-format json sometimes
  exits non-zero") implies it can also exit 0 while the JSON envelope
  reports is_error: true -- confirmed empirically via a live invocation.
  claudeErrorStatus was already written to detect this exact shape but
  was only ever checked on the code!==0 branch; now also checked on
  success exit codes.
- Adds real cost parsing (ported from src/selfhost/ai.ts's own
  COST_KEYS/extractCliUsage best-effort pattern) so claude-cli/codex-cli
  now report costUsd from their own real JSON(L) output too, closing
  the "CLI providers report no cost" gap #5356 documented.

driver-factory.ts's buildCliArgsWithConfiguredModel is now command-aware:
codex's own -m/--model flag is scoped to the exec subcommand (per codex
exec --help) and must land after "exec", not prefixed before everything
the way claude's top-level --model flag can be -- a single shared
prefix-everything scheme would have silently misparsed for codex.
@superagent-security

Copy link
Copy Markdown
Contributor

Superagent didn't find any vulnerabilities or security issues in this PR.

@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
gittensory-ui d2af581 Commit Preview URL

Branch Preview URL
Jul 12 2026, 03:49 PM

@codecov

codecov Bot commented Jul 12, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 94.40%. Comparing base (f23886d) to head (d2af581).
⚠️ Report is 2 commits behind head on main.
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #5382      +/-   ##
==========================================
- Coverage   94.43%   94.40%   -0.04%     
==========================================
  Files         551      551              
  Lines       44191    44223      +32     
  Branches    14641    14654      +13     
==========================================
+ Hits        41732    41747      +15     
- Misses       1784     1801      +17     
  Partials      675      675              
Flag Coverage Δ
shard-1 44.05% <83.78%> (-0.10%) ⬇️
shard-2 34.70% <37.83%> (+0.11%) ⬆️
shard-3 31.96% <2.70%> (+0.40%) ⬆️
shard-4 31.13% <35.13%> (-0.15%) ⬇️
shard-5 33.24% <54.05%> (-0.08%) ⬇️
shard-6 43.31% <2.70%> (-0.10%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
...ttensory-engine/src/miner/cli-subprocess-driver.ts 100.00% <100.00%> (ø)
...ages/gittensory-engine/src/miner/driver-factory.ts 100.00% <100.00%> (ø)

... and 1 file with indirect coverage changes

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@JSONbored JSONbored self-assigned this Jul 12, 2026
@gittensory-orb gittensory-orb Bot added the gittensor:bug Gittensor-scored bug fix — scores a 0.05x multiplier. label Jul 12, 2026
@JSONbored JSONbored merged commit b4175d6 into main Jul 12, 2026
19 checks passed
@JSONbored JSONbored deleted the fix/miner-cli-provider-argv-5135 branch July 12, 2026 15:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

gittensor:bug Gittensor-scored bug fix — scores a 0.05x multiplier.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant