Repository navigation
Exec bytes are always base64, and the protocol is one protocol - #601
Merged
Merged
Conversation
A one-shot answer is {exit_code, stdout, stderr} with stdout and stderr always standard
base64, so the bytes are exact by construction; the request carries stdin as base64.
There is no output_base64 flag, no exact flag, no fallback to a stream for exactness, and
no lossy mode. Raw exec returns bytes in the Rust, TypeScript and Python clients; helpers
decode text in one place.
The version ladder is gone with it: no stdin, streaming, jobs or notify probes, no argv
chunk write, no client-side job emulation over an endpoint, and no fault backends whose
only purpose was to exercise those fallbacks. An endpoint is execd or implements the
whole contract. The file helpers look at the sandbox's tools once, in one lazy command.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HJRTKuPpNNqCLEdyUwZj64
… follow the base64 answer Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HJRTKuPpNNqCLEdyUwZj64
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HJRTKuPpNNqCLEdyUwZj64
… single protocol Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HJRTKuPpNNqCLEdyUwZj64
…point for its own tests Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HJRTKuPpNNqCLEdyUwZj64
… merged parsers Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HJRTKuPpNNqCLEdyUwZj64
…ppy and fuzz corpus follow Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HJRTKuPpNNqCLEdyUwZj64
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HJRTKuPpNNqCLEdyUwZj64
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HJRTKuPpNNqCLEdyUwZj64
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HJRTKuPpNNqCLEdyUwZj64
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HJRTKuPpNNqCLEdyUwZj64
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HJRTKuPpNNqCLEdyUwZj64
This was referenced Oct 27, 2026
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Replaces the bytes design of #587 and removes the version ladder. There is one exec protocol; every endpoint is
execdor implements all of it; nothing is negotiated or probed.The contract
{ "command", "args", "cwd"?, "timeout_ms", "stdin"? },stdinstandard base64.{ "exit_code", "stdout", "stderr" },stdoutandstderralways standard padded base64 (the empty string for none). One shape, no flag; the bytes are exact by construction. The cap is on the decoded bytes (422unchanged); the timeout note is appended to the stderr bytes.stream: true), jobs (job) and job notify are features of the same protocol, not versions.Deleted
output_base64, the output probe, the stream-for-exactness path,exacteverywhere (Rust, TS, Python, DRIVER.md, drivers),exact_exec/output_base64capabilities,fault-v12-text, the lossy scenarios, the mock'shonors_output_base64/lossy_output_base64,exec_endpoint/exact.rs.catecho), streaming, jobs, notify. The argv-chunk write fallback.HttpExecRunner's fall-back-to-baseline jobs. Notify advertisement (EXECD_KEPT_JOBS_SURVIVE_IDLE, N1-N3, N9) and the baseline's notifier.fault-no-stdin,fault-v11,fault-baseline-jobs,local-no-stdin), and the mock options behind them (honors_stdin,Protocol::V11,jobs,refuses_extensions,notify,kept_jobs_survive_idle).Environment probe
The tools the file helpers rely on (
rg,grep -Z,find -printf, thedd/base64read window) are checked in onesh -c(script F of FILES-OVER-EXEC.md), lazily on the first operation that needs it, cached per sandbox. A write never probes. Round trips before the first file op,Sandbox::connectthen a read: 6 before (five sequential probes, then the read), 2 after; a write: 6 before, 1 after.Clients
runreturningExecResultwithVec<u8>output;ExecOutputis code plus bytes; norun_exact.stdout_text()is the one place bytes become text;ShellFshas oneTextconversion.CellRunnerforwardsrunonly.output.jsonvectors.bashappends the raw bytes to its accumulator; the model sees text from there.Also changed
output.json,frames.json,jobs.json,notify-*.json;output.jsonis rewritten for the new shape (valid answers, invalid answers).corrupts_base64on the mock, and a verifier test that catches it. The verifier keeps one output check: every byte value 0-255 on stdout and stderr, plus both streams with an exit code.sandbox://capabilitiesresource reportssearch_engine,find_printf,read_window;SANDBOX_JOBS_ROOTand thestdincap override are gone; the exec tool keeps its text-when-UTF-8-else-base64 rule.exec-liveCI target usesdocker exec -i(writes send stdin), and thecurlnotify target andsandbox_jobs_notifyare gone.crates/execd:tests/output.rsandtests/timeout.rsreplaceexact_output.rs/v11_timeout.rs; docs and README updated. Every ARCHITECTURE.md/README that named the old design is updated.Proof (merged tree)
Matrix,
0 failon every cell (pass / known-defect / unsupported / skipped):(mcp reports
exec_stream, the job-stream ops and caller-chosen mtime unsupported, as before.)test:differentialpasses on all five backends with five drivers.cargo clippy --workspace --all-targets -D warnings,cargo fmt,dprint check, TS (tsc, vitest 123) and Python (pytest 157, ruff, mypy --strict) are clean. execd's own tests pass.Notes
ShellJobs(jobs over plain commands) remains for non-execd transports (TemplateRunner, this host); it offers no notify.--notify-origin. The e2e modesBaselineandNoEgressare gone with the advertisement they tested.🤖 Generated with Claude Code
https://claude.ai/code/session_01HJRTKuPpNNqCLEdyUwZj64