Skip to content

PROD-250: fix(core): reject malformed governance responses - #10

Open
salamisandwich77 wants to merge 20 commits into
mainfrom
feat/PROD-250-sandbox-core-contract
Open

PROD-250: fix(core): reject malformed governance responses#10
salamisandwich77 wants to merge 20 commits into
mainfrom
feat/PROD-250-sandbox-core-contract

Conversation

@salamisandwich77

Copy link
Copy Markdown
Collaborator

Strict governance-response parsing and the sandbox execution contract in the base SDK.

@salamisandwich77
salamisandwich77 marked this pull request as ready for review August 11, 2026 07:04
- Absorb openbox_sandbox package tree from openbox-sandbox-sdk-python
- Add openbox-sandbox-agent console script entry point
- Add openbox_sandbox to hatch/mypy/ruff config
- Bump to v1.2.0

The sandbox SDK is now part of the base SDK. Consumers no longer
need to install openbox-sandbox-sdk-python separately.
Dispatcher, runtime client, engine, deployment, command profiles, policy
templates, and the contract/receipt/registry/release surfaces updated to the
latest working state (operation-in-event evaluation, single-client
convergence, trace join, workflow-governance events).
…failure

The dispatcher swallowed the underlying error and returned a generic
sandbox_create_failed. Now the NormalizedDispatchError carries an
optional detail field populated from the transport error message,
the create_failed response detail, or the boundary_failed response,
so the caller sees the actual cause.
The natural sandbox path posts ActivityCompleted from the dispatcher,
which previously carried only disposition and cleanup. Now it parses the
profile-admitted typed result and includes the full execution evidence
(sandbox_id, exit_code, timeout, stdout/stderr bytes) plus the typed
values in the governance event output so the Core can surface them.
The event output now carries the sandbox's printed output (UTF-8,
truncated at 64 KiB) alongside the byte counts so the console can
render what the sandbox produced. Raw bodies stay bounded — the
profile-admitted typed result remains the durable business data.
The interceptor evaluates the ActivityStarted verdict through Core, then
calls dispatch_with_decision — which previously passed report_core=False,
so the completed hook and ActivityCompleted never reached Core. The
sandbox span synthesis therefore produced empty attributes. The caller
still owns the pre-evaluation; only the COMPLETED evidence now flows.
_report_sandbox_result no-ops without a governance client, so the
no-Core callers are unaffected.
…ped parse

dispatch_with_decision now reports the completed sandbox evidence to
Core (report_core=True). The typed-result parsing stays in the wrapper
— the dispatcher profile bundle has no result schemas.
urllib's default client fingerprint gets 403 code 1010 from
Cloudflare-style bot protection; the interceptor's verdict path worked
(httpx) but the dispatcher's governance report died with
GovernanceTransportError. Same request through httpx with a stable
OpenBox-SDK User-Agent passes.
test (3.11) and test (3.12) have both been failing on this branch since
13 August: ruff reports F401 for `ssl` in the dispatcher governance client.
The import was left behind when the urllib opener was removed, and nothing
in the file refers to it.

ruff passes and 631 tests pass.
@salamisandwich77
salamisandwich77 force-pushed the feat/PROD-250-sandbox-core-contract branch from 8abff2e to f48f828 Compare August 27, 2026 17:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant