Skip to content
Open
20 changes: 20 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,23 @@
### Sandboxed verification emits a versioned, binary-safe trusted result bundle

- `scripts/ci/sandboxed_verify.py --result-file <path>` now keeps command
stdout, command stderr, and the wrapper-controlled JSON envelope in three
exclusive sibling files. The stream files preserve arbitrary and large
binary bytes exactly; their SHA-256 digests and byte lengths are bound into
the `sandboxed_verify.execution.v1` envelope with argv, exit code, explicit
completed/timeout/copy-rejection/internal-error state, runtime identity,
requested network mode, and allowed environment names. Result-directory
traversal uses directory file descriptors with no-follow semantics for every ancestor, and every bundle
file uses exclusive creation, closing the nested-symlink and substitution
races in the first result-file implementation. A bounded evidence-write
failure returns 125 without a traceback when the command succeeded, preserves
an existing command/timeout/copy-rejection failure code, and cannot skip
temporary sandbox cleanup unless `--keep-sandbox` explicitly requests
retention. The envelope explicitly records that this helper supplies a copied
workspace and scrubbed environment, not OS process isolation or enforced
network policy. Legacy stdout-marker mode remains available for human-only
calls. Refs #2086, #2088.

### Failed-check finding names the Strix sandbox instead of the gateway

- `opencode-review-dispatch.yml`'s `emit_strix_provider_failure_finding` rendered one fixed finding for every `STRIX_PROVIDER_UNAVAILABLE` line, whose Root cause read "The contextual-orchestrator gateway or its discovered provider pool was unavailable for this run". `#1953` had just given the Strix sandbox bootstrap failure its own second verdict token (`STRIX_SANDBOX_UNAVAILABLE`) precisely because that attribution is wrong for it -- the sandbox container never reaches its Caido proxy, so the run dies before the gateway serves anything -- and this consumer re-applied the wrong attribution one step downstream, into the review findings and the failure census. The emitter now branches on the second token: a sandbox verdict gets a finding that names Strix's sandbox, says the verdict does not name the gateway, and tells the reader not to change gateway or provider configuration on its strength. A `STRIX_PROVIDER_UNAVAILABLE` line without the token keeps its existing text verbatim, so the gateway class has no regression surface. No test covered this finding text at all before (`gateway or its discovered provider pool` matched nothing under `tests/`); `tests/test_opencode_dispatch_strix_sandbox_finding.py` now runs the production emitter from the published run block and pins both directions plus the no-signal case. Refs #1953, #1935.
Expand Down
21 changes: 17 additions & 4 deletions docs/pr-review-and-merge-procedure.md
Original file line number Diff line number Diff line change
Expand Up @@ -215,10 +215,23 @@ the specific environment variable names required and record why they were
needed. The central helper is
`python3 scripts/ci/sandboxed_verify.py --repo-root <reviewed worktree> --
<verification command>`; reviews should cite its `SANDBOXED_VERIFY_RESULT`
line when the helper is used. Use `--network required`, `--allow-env NAME`,
and `--evidence-note "why"` only for repository-required verification. This
helper does not replace the existing bash, task, webfetch, websearch, lsp,
CodeGraph, DeepWiki, Context7, or web_search review policy.
line when the helper is used. For machine handoff, pass `--result-file
<trusted path>`: the helper exclusively creates that versioned envelope plus
`<trusted path>.stdout` and `<trusted path>.stderr`. Those files preserve all
command-controlled stdout and stderr bytes exactly, including marker-shaped or
JSON-shaped content; only the wrapper-authored envelope is trusted control
data. The envelope records hashes, byte lengths, argv, exit code,
`completed`/`timed_out`/`copy_rejected`/`internal_error` state, runtime
identity, allowed environment names, and the requested network mode. It also
says explicitly that this copy-and-scrub helper provides no OS process isolation and does not
enforce network policy. Trusted result paths reject symlink ancestors and
existing bundle files; evidence-write failure is bounded, returns 125 only
when the command succeeded, preserves an existing command/timeout/copy failure
status, and never skips sandbox cleanup unless `--keep-sandbox` explicitly
requests retention. Use `--network required`, `--allow-env NAME`, and
`--evidence-note "why"` only for repository-required verification. This helper
does not replace the existing bash, task, webfetch, websearch, lsp, CodeGraph,
DeepWiki, Context7, or web_search review policy.
Scratch PoC files are not committed.

For web applications with both backend and frontend surfaces, the preferred
Expand Down
Loading
Loading