Repository navigation
fix(sandbox): acknowledge initial policy load and expose SDK labels #2159
Description
Summary
Two OpenShell lifecycle/API gaps block the policy-bound per-job sandbox integration in NVIDIA-AI-Blueprints/aiq#298 for AI-Q 2.2:
- A newly created sandbox can reach
Readyand expose an effective policy while the same revision remainsPendingindefinitely. - The public Python SDK cannot send gateway-object labels or list sandboxes by label selector, although the protobuf supports both.
AI-Q intentionally fails closed instead of exposing execution without authoritative policy attestation.
Confirmed policy-state behavior
Reproduced on macOS/Apple Silicon with Docker Desktop:
| OpenShell | Creation path | Result |
|---|---|---|
| 0.0.72 | clean gateway diagnostic | Ready; effective policy present; matching revision remains Pending; current_policy_version=0 |
| 0.0.77 | CLI directly, without AI-Q | Ready; revision 2 is Effective via policy get; revision 2 remains Pending via policy list; revision 1 is Superseded |
The state remained stable rather than transitioning to LOADED. The policy itself was successfully constructed and applied. landlock.compatibility: best_effort is therefore not an attestation bypass or explanation; it controls filesystem-enforcement compatibility.
Linux has not yet been reproduced. The observed behavior is confirmed on the macOS/Docker Desktop path; source inspection suggests shared lifecycle logic, but a Linux run is required to establish platform scope.
Minimal reproduction
- Create a sandbox with an explicit policy.
- Wait until the sandbox reaches
Ready. - Compare
policy get <sandbox> -o json,policy list <sandbox>, and the sandbox'scurrent_policy_version. - Observe an effective positive revision while that same revision remains
Pending. - Delete the sandbox and verify it is absent.
Expected contract
After initial policy construction:
- report the exact sandbox-scoped revision as
LOADED; - report
FAILEDwith a load error when construction fails; - never leave a successfully applied initial revision permanently
Pending; - continue reporting later hot-reload revisions normally.
Suspected source path
Inspection of v0.0.72 and v0.0.74 found:
load_policy()constructs the initialOpaEngine;- the first
run_policy_poll_loop()iteration recordsconfig_revisionandpolicy_hash; ReportPolicyStatus(LOADED)is sent only from the laterpolicy_changedbranch;- an unchanged initial hash never enters that branch.
The same runtime symptom is present in 0.0.77; its exact source path should be confirmed against that tag.
Python SDK label/selector gap
CreateSandboxRequest supports request-level labels and ListSandboxes supports label_selector, but the public Python lifecycle API does not expose them:
SandboxClient.create(),create_session(), andSandbox(...)cannot forward gateway labels;SandboxClient.list()cannot forward a selector;SandboxRefdoes not retain gateway metadata labels.
Template labels reach Docker/runtime resources, but gateway selectors inspect gateway-object metadata. Consequently, a Python-created AI-Q sandbox is not returned by:
openshell sandbox list --selector aiq=deep-researchProposed fix
Initial policy acknowledgement
- Preserve the fetched sandbox policy version/source through initial construction.
- Report initial success or failure exactly once.
- Track the acknowledged version so later polling does not duplicate it.
- Preserve existing hot-reload behavior.
Python SDK
Add optional, source-compatible parameters:
nameandlabelsfor creation/session/Sandbox;label_selectorfor listing;- immutable gateway labels on
SandboxRef.
The lifecycle and SDK fixes may land separately, but AI-Q requires both in a tagged release.
Acceptance criteria
- Initial success and failure acknowledgement tests.
- Later policy-revision/hot-reload regression tests.
- Python request-label and selector-forwarding tests.
- Docker E2E: create →
Ready→LOADED→ selector membership → execute → delete. - Direct lookup and selector both confirm deletion.
- Tagged release with compatible CLI, Python SDK, and gateway versions.
- AI-Q macOS demo validation with explicit
best_effort. - AI-Q Linux production validation with
hard_requirement.
Downstream impact
This issue blocks AI-Q #298. It blocks only the OpenShell-specific live acceptance for stacked artifact-lifecycle PR AI-Q #305; #305's provider-independent artifact-storage implementation can be restacked onto develop and proceed separately. AI-Q will not treat Pending as success, weaken attestation, or pin an unreleased fork.
A focused implementation PR can be prepared after maintainer triage and the repository's human state:agent-ready gate.
Activity
KyleZheng1284 commentedon Jul 7, 2026
Cross-project impact: blocks AI-Q 2.2 OpenShell integration
This issue currently blocks NVIDIA-AI-Blueprints/aiq#298, which integrates policy-bound, per-job OpenShell sandboxes for the AI-Q 2.2 release. The AI-Q PR has been marked
BLOCKEDand will continue to fail closed rather than expose execution before authoritative policy attestation succeeds.There is now an additional reproduction using the OpenShell 0.0.77 CLI directly, without AI-Q, on macOS/Docker Desktop:
Ready;openshell policy getreports revision 2 asEffective;openshell policy listleaves revision 2Pending, with revision 1Superseded;This also shows that upgrading from the earlier 0.0.72 reproduction to 0.0.77 does not by itself resolve the policy-state contradiction.
best_effortis not being treated as an attestation bypass; it only changes Landlock compatibility.For AI-Q to unblock, we need:
Effective + Pending;LOADEDorFAILEDexactly once ifPendingis not intended;hard_requirementlive acceptance.A focused upstream implementation PR can be prepared after maintainer triage and the repository's human
state:agent-readygate. A Linux CLI-only reproduction is still needed to establish whether the observed runtime manifestation is limited to macOS/Docker Desktop or is platform-independent.johntmyers commentedon Jul 7, 2026
@KyleZheng1284 I'm unable to reproduce. I see a different gap where current version was 1 vs 0 between the policy get and sandbox list commands but I'm not seeing the Pending state. Will post a more thorough analysis shortly.
johntmyers commentedon Jul 7, 2026
test(sandbox): add sparse-policy revision-2 acknowledgement e2e
test(sandbox): add sparse-policy revision-2 acknowledgement e2e
test(sandbox): add sparse-policy revision-2 acknowledgement e2e
fix(sandbox): acknowledge initial policy revision; expose SDK labels/…
feat: isolate and attest OpenShell jobs (#298)
feat: isolate and attest OpenShell jobs (NVIDIA-AI-Blueprints#298)
Chore/resync 20260820 (#4)