Skip to content

Commit d074d1c

Browse files
authored
fix(mcp): exit 1 when JSON envelope contains ok:false (ultraworkers#2995)
* fix(mcp): exit 1 when JSON envelope contains ok:false mcp info, mcp describe, and mcp list-filter all return {"action":"error","ok":false,...} but previously exited 0, requiring automation callers to inspect the envelope field. After this fix: print_mcp detects ok:false in the rendered JSON value and calls process::exit(1) after printing, so the exit code reflects the semantic error in the envelope. Unaffected: mcp list, mcp show, mcp help all have no ok field and continue to exit 0 (they are not error paths). Closes ROADMAP ultraworkers#68 (partial — agents bogus/mcp show nonexistent found:false remain exit:0 as they use different envelope shapes). * feat(scripts): add dogfood-build.sh — build from checkout and verify provenance Builds claw from the current HEAD, then checks that the binary's git_sha matches git rev-parse --short HEAD. Exits non-zero if the binary is stale or provenance is opaque (git_sha: null). Usage: CLAW=$(bash scripts/dogfood-build.sh) # fail-fast if stale $CLAW version --output-format json # provenance confirmed Addresses ROADMAP ultraworkers#69: dogfooders using a stale installed binary cannot attribute behavior to specific commits. This script makes dogfood round zero unambiguous. Also documents the safe workaround for contributors who have a stale system-installed binary.
1 parent caeac82 commit d074d1c

2 files changed

Lines changed: 49 additions & 4 deletions

File tree

rust/crates/rusty-claude-cli/src/main.rs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5107,10 +5107,17 @@ impl LiveCli {
51075107
let cwd = env::current_dir()?;
51085108
match output_format {
51095109
CliOutputFormat::Text => println!("{}", handle_mcp_slash_command(args, &cwd)?),
5110-
CliOutputFormat::Json => println!(
5111-
"{}",
5112-
serde_json::to_string_pretty(&handle_mcp_slash_command_json(args, &cwd)?)?
5113-
),
5110+
CliOutputFormat::Json => {
5111+
let value = handle_mcp_slash_command_json(args, &cwd)?;
5112+
// Propagate ok:false → non-zero exit so automation callers
5113+
// can rely on exit code instead of inspecting the envelope.
5114+
// (#68: mcp error envelopes previously always exited 0.)
5115+
let is_error = value.get("ok").and_then(|v| v.as_bool()) == Some(false);
5116+
println!("{}", serde_json::to_string_pretty(&value)?);
5117+
if is_error {
5118+
std::process::exit(1);
5119+
}
5120+
}
51145121
}
51155122
Ok(())
51165123
}

scripts/dogfood-build.sh

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
#!/usr/bin/env bash
2+
# dogfood-build.sh — Build claw from current checkout and verify provenance.
3+
# Usage: bash scripts/dogfood-build.sh
4+
# On success: prints the verified binary path. Use as:
5+
# CLAW=$(bash scripts/dogfood-build.sh) && $CLAW version --output-format json
6+
set -euo pipefail
7+
8+
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
9+
RUST_DIR="$REPO_ROOT/rust"
10+
BINARY="$RUST_DIR/target/debug/claw"
11+
EXPECTED_SHA="$(git -C "$REPO_ROOT" rev-parse --short HEAD)"
12+
13+
echo "▶ Building claw from $REPO_ROOT ($(git -C "$REPO_ROOT" log --oneline -1))..." >&2
14+
cargo build --manifest-path "$RUST_DIR/Cargo.toml" -p rusty-claude-cli -q
15+
16+
if [[ ! -x "$BINARY" ]]; then
17+
echo "✗ Build succeeded but binary not found at $BINARY" >&2
18+
exit 1
19+
fi
20+
21+
BINARY_SHA=$("$BINARY" version --output-format json 2>/dev/null \
22+
| python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('git_sha','null'))" 2>/dev/null || echo "null")
23+
24+
if [[ "$BINARY_SHA" == "null" || -z "$BINARY_SHA" ]]; then
25+
echo "✗ Provenance check failed: binary reports git_sha: null" >&2
26+
echo " Binary: $BINARY" >&2
27+
exit 1
28+
fi
29+
30+
if [[ "$BINARY_SHA" != "$EXPECTED_SHA" ]]; then
31+
echo "✗ Provenance mismatch: binary=$BINARY_SHA, HEAD=$EXPECTED_SHA" >&2
32+
echo " Rerun after 'git pull' or check for uncommitted changes." >&2
33+
exit 1
34+
fi
35+
36+
echo "✓ Binary verified: $BINARY_SHA == HEAD ($EXPECTED_SHA)" >&2
37+
echo " To dogfood: export CLAW=$BINARY" >&2
38+
echo "$BINARY"

0 commit comments

Comments
 (0)