Proposal 071: Sensorium Workbench¶
Based on:
doc/project/40-proposals/019-supervised-local-http-json-middleware-executor.mddoc/project/40-proposals/045-sensorium-local-enaction-stratum.mddoc/project/40-proposals/048-sensorium-os-connector-action-classes.mddoc/project/40-proposals/049-json-e-middleware-transformer-executor.mddoc/project/40-proposals/055-bounded-deferred-operation-contract.mddoc/project/40-proposals/057-user-and-operator-notifications.mddoc/project/40-proposals/063-inquirium-model-inquiry-organ.mddoc/project/40-proposals/064-inquirium-implementation-recommendations.mddoc/project/40-proposals/066-inquirium-assistant-channel.mddoc/project/40-proposals/069-corpus.mddoc/project/40-proposals/070-room-primitive.mddoc/project/40-proposals/082-sensorium-interfaces.mddoc/project/60-solutions/015-host-owned-module-store/015-host-owned-module-store.mddoc/project/60-solutions/016-bounded-local-server-runtime/016-bounded-local-server-runtime.mddoc/project/60-solutions/019-middleware/019-middleware.mddoc/project/60-solutions/020-scheduler/020-scheduler.mddoc/project/60-solutions/023-artifact-delivery/023-artifact-delivery.mddoc/project/60-solutions/029-bounded-deferred-operations/029-bounded-deferred-operations.mddoc/project/60-solutions/030-sensorium/030-sensorium.mddoc/project/60-solutions/035-interaction-broker/035-interaction-broker.mddoc/project/60-solutions/039-notifications/039-notifications.mddoc/project/60-solutions/042-sensorium-workbench/042-sensorium-workbench.md
Status¶
Accepted / implemented local foundation.
The settled solution surface is promoted to
doc/project/60-solutions/042-sensorium-workbench/042-sensorium-workbench.md.
This proposal remains the rationale, design history, resolved-decision log, and
implementation tracker for Workbench. The promoted solution component owns the
current solution-level responsibility boundary. The host-owned operator
consent spine is implemented for exact and bounded-prefix Workbench terminal
commands: a pure
operator-consent-core contract crate, daemon-owned consent registry and
operator APIs, P066 notification/answer reuse, operator-consent.request.v1,
operator-consent-decision.v1, sensorium-workbench.consent-descriptor.v1,
and Workbench exact-argv/prefix runtime admission with shared append-only sidecar
merge, bounded refresh, active node-operator-binding.v1 enforcement for
answers and revocation, durable-grant grantability checks, inactive-binding
diagnostics, and dedicated operator UI. Native broker providers, explicit
artifact handoff, the Rust actuation bridge, a managed fixture-copy virtual
executor, and Agent/Corpus/Room tool-request lineage are also implemented.
The property-attested process-isolated backend architecture is frozen, and the
first vfkit-system.v1 host-lifecycle slice is implemented for
macos-vz-arm64.v1. The daemon-owned broker now covers allocation, closed-argv
launch, inspection, cooperative drain, teardown, recovery, exact process/socket/
resource identity, boot nonces, reconciliation, and quarantine without exposing
VMM administration sockets to Python. Process-level fake-vfkit evidence covers
replay, dirty exit, PID reuse, socket and binary substitution, missing storage,
and orphan cleanup. The packaged guest agent and host channel now cover exact
generation/plan/image/nonce binding, bounded process/PTY/file/lifecycle mechanics,
one total process-output budget, ioctl-backed PTY resize, atomically durable
content-bound patch staging, endpoint-identity revalidation, chunked transfer,
and local-transport conformance. Full-system image integration,
real-vfkit deployment evidence, and the virtualized Workbench PTY/file adapter
remain unimplemented. The freeze also requires closed capability vocabularies,
plan-bound operational context and policy floors, evidence-based logical image
equivalence, and sanitized classified serial diagnostics. The existing Workbench
environment/export contracts remain landed.
Date¶
2026-06-23
Executive Summary¶
Orbiplex will eventually need model-assisted workflows that can inspect and shape local software environments: run commands, observe terminal output, read bounded file snapshots, propose patches, apply approved changes, and operate inside disposable sandboxes. This is the capability class usually associated with LLM-managed agents.
In Orbiplex, the model must not become the commander of the node. Inquirium is the model inquiry organ. It may produce plans, command proposals, patch proposals, interpretations, and next-step candidates. The actual actuation surface belongs to Sensorium and remains host-authorized.
This proposal defines Sensorium Workbench as a specialized Sensorium connector/runtime for high-impact local workbench actuation:
Inquirium thinks.
Host authorizes.
Sensorium acts.
Workbench brokers terminal, filesystem, and sandbox effects.
Sensorium Workbench is not a new organ and not an Inquirium adapter. It is a Sensorium connector class, supervised like other middleware, with explicit capability groups for terminal sessions, workspace file snapshots, patch application, artifact exchange, and sandbox environments.
The first implementation should be narrow and local-only. It should be a supervised Workbench connector with its own readiness, lifecycle, operator status, and grants, even if it reuses lower-level Sensorium OS libraries. It should expose host-brokered terminal and filesystem capabilities over HTTP/JSON contracts, not direct terminal access to a model. It should be suitable for JSON-e Flow orchestration and future Inquirium assistant/agent loops, while preserving grants, leases, classification, audit, idempotency, and operator control.
Interactivity is part of the contract. Workbench should not force clients to invent private polling loops, sleep intervals, prompt scraping, or hidden watcher threads. Waiting for a prompt, checking that a file appeared, detecting that a command stopped making progress, and observing that an environment is ready should be expressed as host-brokered waits, watches, probes, and outcomes. The broker that joins observations across Workbench, Artifact Delivery, Memarium, approvals, and deferred operations should be a host-owned primitive, not a private feature of Sensorium Core.
Context And Problem Statement¶
Model-assisted development or system investigation needs a loop:
observe environment
ask model for next step
validate proposed action
execute bounded action
observe result
repeat
Without a proper local workbench boundary, the system tends toward one of two bad shapes:
- direct model-to-terminal control, where an LLM or agent runtime owns a shell, filesystem, and credential context;
- one-off OS actions hidden inside workflow scripts, where each workflow invents its own terminal, file, and sandbox mechanics.
Both shapes complect reasoning, authorization, and actuation. They also obscure the difference between a model proposing a command and the node actually running that command.
The existing Sensorium OS connector action classes are deliberately program-agnostic and mostly one-shot. They are good for bounded actions such as running an allowlisted script. They are not enough for interactive terminal sessions, screen snapshots, incremental command loops, workspace file exchange, or disposable virtual environments.
Interactive work also needs temporal coordination across component boundaries. A caller often needs to wait until something exists, wait until output becomes quiet, verify that a child process still lives, detect lack of progress, or race an expected observation against a deadline. If each component implements that on its own, the system drifts toward hidden polling, inconsistent timeout semantics, and unobservable background work.
Goals¶
- Define Sensorium Workbench as a specialized Sensorium connector/runtime.
- Keep Inquirium out of direct terminal/filesystem ownership.
- Provide a host-brokered PTY/session contract over HTTP/JSON.
- Provide bounded filesystem snapshot, read, patch, and artifact contracts.
- Support local workspaces and future virtualized sandboxes.
- Make all terminal and filesystem effects grant-bound, lease-bound, classified, audited, and operator-visible.
- Provide brokered wait/watch/probe contracts for interactive workflows.
- Support JSON-e Flow and built-in orchestration loops.
- Keep terminal bytes and file contents out of ordinary model traces unless explicitly admitted by policy.
Non-Goals¶
- This proposal does not define a general-purpose autonomous agent.
- It does not let Inquirium bypass host policy or Sensorium grants.
- It does not replace Sensorium OS one-shot action classes.
- It does not require remote execution, SSH, containers, or VMs in the first slice.
- It does not define a public/federated workbench protocol.
- It does not grant network egress, credential access, or arbitrary filesystem access by default.
- It does not make PTY transcripts durable facts by default.
- It does not require WebSockets or any specific streaming transport in the first slice.
- It does not allow unbounded blocking waits or component-private background polling as the normal interaction mechanism.
Decision¶
1. Workbench Is A Sensorium Connector Class¶
Sensorium Workbench is a Sensorium connector/runtime role:
Sensorium Core
owns capability admission, policy, grants, audit, and dispatch
Sensorium Workbench
owns PTY/session mechanics, workspace filesystem views, patch application,
local sandbox lifecycle, and artifact handoff
It may share low-level libraries with Sensorium OS, but it must have its own declared capability group, readiness report, operator status, lifecycle controls, grant surface, and refusal diagnostics. PTY sessions and filesystem writes have a materially higher risk profile than ordinary read-only observations or one-shot script invocations, so they must not inherit Sensorium OS authority by implication.
Implementation MAY begin as an optional capability group inside the existing Sensorium OS module if that reduces bootstrapping cost, but the public contract must still name the Workbench boundary separately. Once PTY sessions or writes are enabled, a separate supervised middleware connector is the preferred implementation shape.
When the boundary is stable enough to implement, the recommended split is:
sensorium-workbench-core: portable data contracts, state machines, validation, path rules, command profiles, and failure classes;sensorium-workbench-service: PTY/session management, workspace roots, patch application, sandbox lifecycle, persistence, and policy evaluation;sensorium-workbench-http: loopback HTTP mapping, bounded local server runtime integration, middleware init/report, and shutdown behavior.
A Python prototype is acceptable only if it follows the same bounded local server invariants: no unbounded per-request threads, explicit overload behavior, cooperative shutdown, no hidden residual child processes, and operator-visible cleanup failures.
Workbench and Sensorium OS must share the lower safety primitives that define
local actuation semantics. The shared lower module may be named
sensorium-actuation-core or, if bootstrapped from the existing OS connector
implementation, sensorium-os-core, but it must be consumed by both connector
classes. It owns path canonicalization, symlink-escape rejection, command
profile validation, allowlist interpretation, environment policy validation,
classification/sensitivity propagation, argv normalization, and content-digest
helpers. Reimplementing these rules separately in Workbench and Sensorium OS
would create a second vulnerability surface for traversal, argv injection, and
policy drift.
2. Inquirium Produces Intent, Not Effects¶
Inquirium may produce:
- a plan;
- a command proposal;
- a patch proposal;
- a file-inspection request;
- an interpretation of terminal output;
- a next-step candidate.
It must not directly own:
- a PTY;
- a shell process;
- a filesystem root;
- a VM or container;
- credentials;
- network egress.
The normal loop is:
UI / JSON-e Flow / built-in workflow
-> Inquirium generate/plan operation
-> host validates model proposal
-> Sensorium directive to Workbench
-> Workbench executes bounded local effect
-> Sensorium records outcome/observation/artifact refs
-> loop continues
An "agent adapter" for a full external agent runtime MAY exist later, including an MCP-like tool protocol or another tool-calling protocol. That protocol is an implementation detail below the host grant boundary. The adapter is still just a supervised runtime that requests host-granted tools. It does not become a commander and does not bypass Workbench or Sensorium.
3. Workbench Uses Declarative Tool Intents¶
Workbench should distinguish three levels of intent:
- raw terminal input, such as bytes sent to an interactive PTY;
- structured command intent, such as a command profile plus
argvdata; - structured edit intent, such as a patch artifact or file operation plan.
Model-driven workflows should prefer structured command and edit intents. Raw terminal input is a high-risk compatibility escape hatch for genuinely interactive programs, not the normal interface for model-generated actions.
The first contract should therefore expose separate operation classes:
terminal.input.commandfor host-validated command intent;terminal.input.rawfor bounded raw input to an existing PTY session;files.patch.applyfor approved patch application from an artifact ref.
terminal.input.command must avoid shell interpolation. A command request names
an allowlisted command profile and passes arguments as data. The host records a
normalized argv digest before execution, so traces can identify the effect
without storing prompt or terminal content.
Candidate command intent shape:
{
"schema": "sensorium-terminal-command.v1",
"schema/v": 1,
"directive/id": "directive:workbench-20260623-001",
"correlation/id": "workbench-loop:story009-001",
"idempotency/key": "idem:workbench-20260623-001",
"terminal.session/ref": "terminal-session:story009-abc",
"command.profile/ref": "command-profile:cargo-test",
"argv": ["cargo", "test", "-p", "orbiplex-node-nse"],
"cwd": {
"workspace/ref": "workspace:story009-local",
"root/ref": "root:repo",
"relative/path": "node"
},
"env": {
"mode": "profile-defaults-only"
},
"limits": {
"timeout_ms": 120000,
"stdout_bytes": 65536,
"stderr_bytes": 65536
},
"argv/normalized-sha256": "sha256:..."
}
4. Terminal Sessions Are Host-Brokered Resources¶
Workbench exposes terminal sessions as bounded resources, not as raw sockets to models. A terminal session has:
terminal.session/ref;- owning component/caller;
- sandbox/workspace binding;
- command profile;
- classification;
- max duration;
- idle timeout;
- max active sessions per connector and per workspace;
- bounded reader task permits;
- input/output queue depth caps;
- input/output byte caps;
- optional approval policy;
- audit/outcome records;
- explicit close semantics.
Terminal lifecycle is explicit:
requested -> starting -> running -> idle -> closing -> closed
\-> failed
\-> expired
\-> killed
Session creation, input, resize, signal, and close directives should carry
idempotency keys. Closing a session is idempotent. A cleanup failure is not
hidden behind closed; it is an operator-visible degraded state until the host
can confirm that child processes and temporary resources are gone.
PTY sessions must have their own bounded resource contract, separate from the
HTTP server request permits. A Workbench connector declares sessions/max,
sessions/per-workspace-max, reader-tasks/max, input-queue/max-depth, and
event-buffer/max-depth. When those limits are reached, session creation or
input admission fails fast with an overload/refusal outcome instead of queuing
unbounded reader loops or process handles.
The terminal event stream is append-only:
{
"schema": "sensorium-terminal-event.v1",
"schema/v": 1,
"terminal.session/ref": "terminal-session:story009-abc",
"correlation/id": "workbench-loop:story009-001",
"seq/no": 42,
"event/type": "output",
"stream": "pty",
"bytes/encoding": "utf-8",
"text": "cargo test ...",
"truncated": false,
"classification": {
"schema": "classification.v1",
"source_tier": "Personal",
"effective_tier": "Personal",
"provenance": {
"kind": "local-space",
"space": "Personal"
},
"bound_subjects": {
"personal_or_community": [
{
"kind": "role",
"id": "node-operator"
}
]
},
"declassify_trail": []
}
}
Terminal events are session-local observations. The authoritative directive outcome is a separate host audit fact that links caller, grant, directive id, session ref, status, byte counts, timing, and artifact refs. Raw output becomes durable only when capture policy stores it as an artifact or classified fact.
The model-facing view should usually be a bounded screen or event snapshot, not the unbounded raw transcript:
{
"schema": "sensorium-terminal-screen-snapshot.v1",
"schema/v": 1,
"terminal.session/ref": "terminal-session:story009-abc",
"correlation/id": "workbench-loop:story009-001",
"seq/from": 30,
"seq/to": 42,
"rows": ["$ cargo test", "test result: ok"],
"cursor": {"row": 2, "col": 16},
"truncated": false
}
5. Interactivity Is Brokered As Waits, Watches, And Probes¶
Interactive workflows need a brokered temporal layer. A component should not hold a raw socket, sleep for an arbitrary number of seconds, scrape a prompt, or spawn a private watcher thread just to know whether the world changed. Workbench should expose interaction primitives as data:
- a
watchobserves an event source from a cursor and returns bounded event batches or a stream-compatible cursor; - a
waitevaluates a declarative condition against observations until it is satisfied, cancelled, expired, or timed out; - a
probeactively asks Workbench to check a bounded fact about a resource, such as process liveness, environment readiness, file existence, digest change, artifact presence, or terminal quiescence.
The useful event sources are:
- terminal session events and screen snapshots;
- terminal command outcomes;
- file snapshot and digest observations;
- artifact admission and export outcomes;
- environment lifecycle changes;
- deferred operation status changes;
- operator approval or revocation events.
The natural long-term owner of inter-component interaction brokerage is a host-owned interaction-broker primitive: admission, grant checks, wait registry, cross-source joins, cancellation, operator visibility, and audit. Sensorium Core may consume this primitive for Workbench-backed flows, but it must not become the owner of AD, Memarium, approval, or deferred-operation joins. The Workbench connector owns connector-local observation production and active probes for resources it controls. A connector may complete a simple local wait directly, but a wait that spans Workbench, Artifact Delivery, Memarium, approvals, or deferred operations belongs to the host broker, with each domain component acting only as an observation source.
Waits and probes must be host-owned resources with refs, deadlines,
classification, idempotency keys, caller identity, grant context, byte caps, and
explicit outcomes. A wait that can outlive one HTTP request must become a
Bounded Deferred Operation. deferred-operation-status.v1 remains the
canonical lifecycle status model; interaction-broker-wait.outcome.v1 is the
domain result/projection carried directly by a short synchronous wait or under
deferred-operation-status.v1.result for async waits.
Candidate wait request:
{
"schema": "interaction-broker-wait.request.v1",
"schema/v": 1,
"wait/ref": "wait:story009-command-ready",
"correlation/id": "workbench-loop:story009-001",
"idempotency/key": "idem:wait-story009-command-ready",
"scope": {
"terminal.session/ref": "terminal-session:story009-abc"
},
"condition": {
"kind": "terminal.quiescent",
"after.seq/no": 42,
"quiet_ms": 750,
"require_process_alive": true
},
"deadline_ms": 10000,
"on_timeout": "return-not-kill"
}
Candidate wait outcome:
{
"schema": "interaction-broker-wait.outcome.v1",
"schema/v": 1,
"wait/ref": "wait:story009-command-ready",
"correlation/id": "workbench-loop:story009-001",
"condition/status": "satisfied",
"observed": {
"terminal.session/ref": "terminal-session:story009-abc",
"seq/from": 42,
"seq/to": 48
},
"duration_ms": 1180,
"classification": {
"schema": "classification.v1",
"source_tier": "Personal",
"effective_tier": "Personal",
"provenance": {
"kind": "local-space",
"space": "Personal"
},
"bound_subjects": {
"personal_or_community": [
{
"kind": "role",
"id": "node-operator"
}
]
},
"declassify_trail": []
}
}
For an async wait, the host returns and polls the canonical deferred status shape:
{
"schema": "deferred-operation-status.v1",
"schema/v": 1,
"status": "completed",
"operation/id": "deferred:interaction-broker.wait:story009-command-ready",
"operation/kind": "interaction-broker.wait",
"updated_at": "2026-06-23T12:00:00Z",
"result": {
"schema": "interaction-broker-wait.outcome.v1",
"schema/v": 1,
"wait/ref": "wait:story009-command-ready",
"correlation/id": "workbench-loop:story009-001",
"condition/status": "satisfied"
}
}
Conditions should be declarative and bounded. The first set should cover:
terminal.output.since: new output exists after a sequence number;terminal.quiescent: no new output for a stable window;terminal.command.done: a command outcome exists;terminal.process.alive: the session process is still alive;terminal.no_progress: no output, progress marker, or state change for a policy-defined interval;file.exists: a relative path exists under a root;file.digest.changed: a path digest differs from an observed digest;artifact.present: an artifact ref has been admitted;environment.ready: an environment reachedready;operation.done: a deferred operation reached a terminal status.
The MVP should keep each wait scoped to one primary resource. Multi-resource conditions should be expressed as host-side composition of smaller waits until there is a clear need for a dedicated join contract.
Silence is not automatically a hang. Hang detection needs a policy-defined
progress model: expected event cadence, quiet window, max idle interval, process
liveness, and optional probes. A terminal session may be alive and quiet
because the command is computing, waiting for input, or blocked. Workbench can
report maybe_hung, waiting_for_input, no_progress, or probe_failed, but
the host policy decides whether to continue, ask the operator, send input,
cancel, or kill.
Watch cursors and wait refs should be replayable for a bounded retention window. This lets a JSON-e Flow, UI, or Inquirium loop resume after a transient component restart without losing the causal edge between "I asked for this effect" and "this observation satisfied the next step".
6. Filesystem Access Is Lease And Snapshot Based¶
Workbench must not expose "the disk" as an ambient filesystem. It exposes:
- allowlisted workspace roots;
- canonical path validation;
- file and directory snapshots;
- bounded reads;
- patch proposals;
- approved patch application;
- artifact reads/writes through host object-store or artifact refs;
- provenance linking each write to operation, caller, policy, and session.
The filesystem address model should be host-owned and relative:
workspace/ref
path-space/ref
root/ref
relative/path
The connector canonicalizes root/ref + relative/path before every access,
rejects traversal, rejects NUL bytes, rejects empty paths where a file is
required, and rejects symlink escape outside the allowlisted root. A direct
file://... value received from a model or external agent is not authority.
If a direct data-plane lease is needed, the host translates it into a scoped
lease only after canonical validation, classification, expiry, and runtime or
operation binding.
Snapshots are metadata observations. They may reveal names, sizes, digests, and classifications, but they do not grant byte reads by themselves. Bounded file reads are separate directives, and writes should normally flow through patch application or artifact admission rather than ad hoc overwrite calls.
The model should receive file snapshots or selected excerpts. It should return patch proposals or edit intentions. Applying a patch is a Workbench directive under host policy.
Example patch request:
{
"schema": "sensorium-workbench.patch-apply.request.v1",
"schema/v": 1,
"workspace/ref": "workspace:story009-local",
"correlation/id": "workbench-loop:story009-001",
"patch/ref": "artifact:sha256:...",
"target/root": "root:repo",
"policy": {
"require_clean_apply": true,
"allow_create": true,
"allow_delete": false,
"max_changed_files": 12
}
}
7. Sandboxes Are Workbench Environments¶
Workbench can start with host-local workspaces. Future Sensorium Virt can
implement the same environment contract using containers, microVMs, emulators,
or remote disposable machines.
The stable abstraction is the environment:
workspace/ref
sandbox/ref
terminal.session/ref
artifact/ref
data-lease/ref
Environment lifecycle is explicit:
allocating -> ready -> draining -> closed
\-> failed
\-> expired
The first implementation should support only host-local allowlisted workspaces. Future virtualized backends must not change the Workbench contracts. They only provide different interpreters for the same environment, terminal, file, artifact, and teardown abstractions.
Backends are implementation choices:
- host-local directory;
- temporary copied workspace;
- container;
- VM;
- remote disposable environment;
- simulated fixture environment.
The backend must declare:
- locality;
- network policy;
- filesystem roots;
- credential policy;
- teardown policy;
- artifact export policy;
- resource limits.
7.1 Backend Capability Admission¶
A backend id selects an implementation; it is not evidence of isolation. Before a process-isolated environment is allocated, the host must compare a normalized environment requirement with a host-attested backend capability descriptor. The minimum descriptor vocabulary is:
backend/id
backend/provider
backend/version
backend/binary-digest
platform/ref
locality
host/architecture
guest/architecture
isolation/class
system/fidelity
control/transport
control/guest-endpoint
control/host-endpoint
control/channel-binding
boot/mode
storage/formats
device/classes
console/mode
network/profiles
host-filesystem-sharing/mode
credential-injection/mode
resource-enforcement/classes
lifecycle/operations
sensorium-virt-backend-capabilities.v1 is a closed contract, not an open map of
backend claims. additionalProperties is false; supported-value collections are
bounded sets with unique items; and every semantic value is selected from a
versioned enum. The initial V1 vocabulary is:
| Dimension | Closed V1 values |
|---|---|
locality |
local-only, remote-sandbox |
host/architecture, guest/architecture |
x86_64, arm64 |
isolation/class |
none, process-sandbox, shared-kernel-container, hardware-vm |
system/fidelity |
filesystem-view, process-runtime, shared-kernel-linux, full-system-linux |
control/transport |
none, local-process, virtio-vsock |
control/guest-endpoint |
none, af-vsock |
control/host-endpoint |
none, af-vsock, unix-domain-socket |
control/channel-binding |
none, environment-generation-boot-nonce |
boot/mode |
none, efi, direct-kernel |
storage/formats |
directory-copy, raw, kernel-initrd-rootfs |
device/classes |
virtio-block, virtio-vsock, virtio-rng, diagnostic-serial, virtio-net |
console/mode |
none, diagnostic-output-only |
network/profiles |
none, isolated, egress-allowlisted |
host-filesystem-sharing/mode |
denied, read-only, read-write |
credential-injection/mode |
denied, explicit-scoped |
resource-enforcement/classes |
host-cpu, host-memory, host-process, host-storage, host-io, guest-vcpu, guest-memory, guest-pids, guest-storage, channel-bounds |
lifecycle/operations |
allocate, start, inspect, drain, teardown, recover |
backend/id, backend/provider, and platform/ref resolve through bounded host
registries rather than semantic enums; an unknown identity is denied before
matching. Adding a new semantic value requires a schema/registry revision and
conformance evidence. Host
policy may select or equate only values already admitted by that version, so policy
configuration cannot turn an arbitrary string into evidence.
Plural descriptor fields such as network/profiles and device/classes contain
supported sets; the normalized plan records one selected scalar such as
network/profile and an exact selected device set. Locality remains a separate
requirement and never masquerades as an isolation class.
The host, not the backend adapter, owns this attestation. A backend may report raw facts, but a Rust validator maps the pinned binary, platform, enabled device set, and host controls to the effective descriptor. Unknown, missing, or unverified properties do not match a requirement.
Matching is conjunctive and property-based. hardware-vm is not a magic synonym
for every stronger-looking backend name, and the property dimensions do not form
one universal scalar ordering. A full-system proof can require, for example:
isolation/class = hardware-vm
system/fidelity = full-system-linux
control/transport = virtio-vsock
control/channel-binding = environment-generation-boot-nonce
host-filesystem-sharing/mode = denied
network/profile = none
Host policy may admit an explicit set of equivalent values on one dimension, but it must not infer equivalence from marketing labels such as container, sandbox, or microVM. The selected descriptor, normalized environment plan, policy ref, image manifest, and their digests become one immutable allocation input. Replay with the same idempotency key and plan digest returns the same environment; the same key with a different digest is a conflict.
The normalized plan also requires the exact effective
sensorium-operational-context.v1 value. The host derives it before allocation
from the environment candidate, the selected resource context, and a policy floor;
the backend adapter may neither default nor rewrite it after normalization. The
plan digest binds the source candidate digest, effective context, and policy ref.
The initial policy floor is test when network/profile != none or
host-filesystem-sharing/mode != denied. Any reachable network target or shared
host resource contributes its own context, and the effective class is the maximum
of the candidate, the floor, and those attached-resource classes. Missing target
context fails admission closed. A stricter deployment may raise this floor, but
none may lower a production or critical target to test. Raising the class does
not authorize the host to rewrite the candidate's untrusted context/summary;
the policy ref and candidate digest explain the raise. The reference full-system
configuration proof uses test. A disposable offline VM may use experimental,
while hardware-vm by itself never chooses an impact class.
The current sensorium-workbench-environment.v1 backend and executor.kind
fields remain useful projections, but they are too coarse to serve as isolation
evidence. Phase 4 must add a companion capability descriptor and normalized-plan
contract before enabling a process-isolated PTY.
7.2 Reference Full-System Profiles¶
The first implementation target is split by host platform rather than pretending that one VMM is portable across macOS and Linux:
| Profile | Role | Required substrate | Initial posture |
|---|---|---|---|
vfkit-system.v1 on macos-vz-arm64.v1 |
first developer reference backend and first implementation slice | Apple Silicon, Apple Virtualization Framework, pinned vfkit binary | full GNU/Linux arm64 system; EFI boot; raw working disk and per-environment EFI variable store; virtio-blk, virtio-vsock, virtio-rng, bounded diagnostic serial; no NIC |
cloud-hypervisor-system.v1 on linux-kvm-x86_64.v1 |
first Linux full-system deployment backend | Linux/KVM, cgroup v2, pinned Cloud Hypervisor binary, host filesystem confinement | full GNU/Linux x86_64 system; firmware boot from an explicit raw image; block, vsock, entropy, bounded diagnostic serial; no NIC by default |
firecracker-system.v1 on a compatible linux-kvm-*.v1 platform |
second Linux backend and hardened minimal-device profile | Linux/KVM and a jailer-equivalent launch boundary | introduced after the guest protocol and image manifest are stable; only the common block, vsock, entropy, console, resource, and teardown substrate is portable |
vfkit-system.v1 is selected first because the primary developer platform is
macOS on Apple Silicon and vfkit can boot a normal EFI disk image while exposing
bounded lifecycle inspection and control. Its host endpoint for a guest
virtio-vsock port is a dedicated Unix-domain socket. The domain contract still
names virtio-vsock; the UDS translation is private backend mechanics:
control/transport: virtio-vsock
control/guest-endpoint: af-vsock
control/host-endpoint: unix-domain-socket
The allowed vfkit device profile is closed. virtio-fs, Rosetta shares, host
directory mounts, host block-device passthrough, credentials, arbitrary host
sockets, graphics/input devices, and network devices are denied. The only host
socket exceptions are the exact broker-allocated VMM-administration and guest-
control sockets; the administration socket remains broker-private. For every
backend, diagnostic serial is output-only and bounded, never an interactive console or second input
path. Its bytes are untrusted guest data: ordinary status and logs retain only
metadata, while an explicitly admitted diagnostic capture inherits the environment
classification and operational context, has byte/time caps plus a digest and
truncation marker, and is subject to configured redaction. Operator presentation
uses a sanitized rendering that escapes control bytes and strips terminal-control
sequences, including ANSI CSI, OSC, and DCS; raw bytes are never written directly
to an operator terminal. Allocation creates an APFS copy-on-write clone of the
pinned raw base disk and a private EFI variable store; the base image remains
immutable. The process
is launched headlessly with an operator-pinned version and binary digest. An Intel
Mac profile may be registered later as macos-vz-x86_64.v1, but only after
separate image and conformance evidence; architecture substitution is not implicit.
cloud-hypervisor-system.v1 is the first Linux profile because its local REST
API maps cleanly to full-system lifecycle mechanics and it supports firmware boot
of ordinary raw Linux images. Orbiplex uses only a closed subset of the VMM:
virtio-block, virtio-vsock, virtio-rng, optional future isolated
virtio-net, and bounded serial diagnostics. virtio-fs, VFIO, vhost-user
devices, host directory mounts, arbitrary hotplug, live migration, and durable
memory snapshots are denied. Serial diagnostics follow the same bounded, classified,
sanitized output-only policy. Disk format is
explicit; format autodetection and backing-file chains are not admitted.
The Linux host broker runs the VMM under a dedicated unprivileged identity,
cgroup v2 limits, seccomp, and a file allowlist enforced by Landlock where the
pinned host/VMM combination supports it or by an equally explicit host wrapper.
If the selected profile requires one of these controls and the host cannot prove
it, allocation fails closed.
Firecracker follows as a separate backend because its smaller device model and jailer are valuable hardening, while its kernel/rootfs preparation and full-system shutdown mechanics should not define the first Workbench contract. This is a sequencing decision for the full GNU/Linux configuration proof, not a universal security ranking of VMMs.
OCI may distribute a signed and digest-pinned logical image artifact containing backend variants, the guest-agent binary, SBOM, provenance, and minimum guest protocol. An OCI runtime does not own Workbench allocation, lifecycle, recovery, or authority.
Implementation-source basis, verified on 2026-07-20: the official vfkit usage contract documents EFI boot, raw/APFS clone-backed disks, optional devices, Unix-socket REST control, and guest-vsock-to-host-UDS mapping; the official Cloud Hypervisor README and API contract document firmware boot and Unix-socket lifecycle control; the official Firecracker design, jailer, and vsock documents define the later minimal-device profile. Version numbers remain operator-pinned deployment data rather than proposal constants.
7.3 Two Ports And Three Ownership Layers¶
VMM lifecycle and guest Workbench mechanics are separate ports:
EnvironmentBackend
allocate start inspect drain teardown recover
GuestWorkbenchChannel
handshake spawn_process open_pty
terminal_input terminal_resize terminal_signal
file_snapshot file_read patch_stage artifact_export
inspect quiesce shutdown
The ports are logical contracts; they need not be one Rust trait across a process
boundary. Cloud Hypervisor, vfkit, and Firecracker differ behind
EnvironmentBackend. The same bounded guest protocol implements
GuestWorkbenchChannel, so SSH, a network interface, or a host-shared filesystem
never becomes public Workbench semantics.
Ownership is stratified:
sensorium-virt-coreis a pure Rust contract layer for backend capabilities, requirement matching, normalized plans, limits, lifecycle transitions, image compatibility, plan digests, recovery identity, and network/device/host- path refusal. A bounded companion process may expose these decisions to Python; absence, timeout, or malformed output fails closed.- the daemon-owned
virt-host-brokeris the host authority for working disks, process identities, VMM launch, exact API/control sockets, platform resource controls, optional Linux cgroups and network namespaces, resource enumeration, quarantine, and teardown. A concrete implementation may use a different module name without changing this ownership boundary. - the Python Workbench adapter owns connector mechanics: mapping an already normalized plan to bounded backend request data, readiness waits, bounded guest RPC, SQLite projections, Interaction Broker observations, and typed diagnostics. It receives broker-allocated identities and the exact guest-channel handle; the host broker retains the VMM administrative socket and mediates its narrow lifecycle operations. The adapter must not gain ambient authority to launch arbitrary VMM processes, open arbitrary host paths, create host network devices, or widen the normalized plan.
This preserves the current rule: Python runs connector mechanics; Rust owns semantic validation and host authority.
7.4 Guest Agent Contract¶
The reference image contains a small Rust process named
orbiplex-workbench-guest. It communicates only over virtio-vsock, without IP or
SSH. The initial handshake binds at least:
environment/ref
source/generation-ref
normalized-plan/digest
image/digest
guest-agent/protocol-version
guest/cid
boot/nonce
boot/nonce is generated for every start and must match the host recovery record.
A backend supplies it through a dedicated ephemeral read-only boot/config input or
an equivalently bound channel established by the host broker. It is a freshness
and channel-binding control, not cryptographic attestation that the guest is honest.
A stale agent, restored guest, old control socket, or previous source generation
is refused before any command is dispatched. Operation frames additionally bind
the environment, generation, operation id, sequence, deadline, payload length,
chunk count, and digest. Queues and reassembly buffers have hard byte, frame,
chunk, and time caps.
The implemented V1 wire vocabulary is closed to handshake, request, chunk,
result, and error. sensorium-virt-core owns the shared bindings, typed
operation set, honest succeeded/refused/unknown evidence rules, and hard
frame/chunk/transfer limits. The host derives the expected handshake exclusively
from the current vfkit recovery record and releases its broker lock before channel
I/O. It rechecks endpoint device/inode identity across connect; endpoint replacement
or listener loss refuses before the handshake, while the full handshake binding
remains the channel authority. The packaged Rust guest uses the same engine over Linux AF_VSOCK and a
feature-gated local Unix transport used only for conformance. That harness runs the
real guest binary and proves process, PTY, file, patch, export, lifecycle inspect,
quiesce, shutdown, admission refusal, deadline non-extension, exact wire bounds,
partial-transfer refusal, and content-bound replay after a lost patch-stage receipt,
in addition to stale-nonce, replay, overflow, and disconnect behavior; it is not VM, image,
systemd, kernel, cgroup, network, or vfkit deployment evidence.
output/bytes-max is one decoded-byte budget for a process result, shared by
stdout and stderr rather than multiplied per stream. PTY resize uses the terminal
ioctl directly and does not require an image-specific stty executable.
patch-stage is staging, not application: it atomically stores exact content
under a path/content/length-bound stage ref, returns that same ref for an exact
retry, never mutates the target, exposes count and bytes through inspect, and
retains at most 64 stages and 64 MiB in environment state until teardown. A
disconnect before complete transfer publishes no stage; a lost response after
commit is resolved by exact replay. Request parsing and pre-dispatch admission
failures are refused with admission evidence. unknown is reserved for an
admitted effect whose outcome cannot be proved.
The guest agent owns no authorization policy. It executes only normalized, already-admitted mechanics and returns untrusted observations. Root inside the guest can compromise the agent and falsify guest state; it must not thereby gain host paths, credentials, sockets, or ambient network access. Guest cgroups, including per-command PID limits, are useful defense in depth and conformance controls, but they are not a host security boundary against compromised guest root. Host-side CPU, memory, storage, process, and I/O limits remain mandatory.
7.5 Images, Resources, And Network¶
The logical image manifest pins the full-system image, architecture, boot variant, guest protocol, guest-agent digest, SBOM, provenance, and backend- specific artifacts. The initial vfkit variant contains an arm64 raw disk plus an EFI variable-store template. The initial Cloud Hypervisor variant contains an x86_64 raw disk plus pinned firmware. A later Firecracker variant may contain a kernel, initrd, and rootfs while preserving the same logical image ref where its userspace and protocol provenance are equivalent. Equivalence is manifest evidence, not a publisher assertion: variants under one logical image ref must share the canonical userspace/rootfs content digest, SBOM digest, build-provenance ref and digest, exact guest-agent binary digest, and guest-protocol/schema-set digest. Variant-specific kernel, initrd, firmware, disk-layout, and boot-artifact refs and digests remain separate. A mismatch or missing equivalence field requires a distinct logical image ref. Sharing the logical ref states common userspace and control- protocol lineage; it does not claim byte-identical boot artifacts or replace per-variant conformance. A consumer that requires an exact kernel or firmware pins the variant ref and digest as well as the logical image ref.
The reference guest is intentionally ordinary: a full GNU/Linux distribution,
systemd as PID 1, distribution kernel and initramfs, required virtio_*
drivers, harmless test modules such as dummy or loop, the Workbench guest
agent, no sshd, no user keys, no cloud credentials, no host mounts, and no
default NIC. Package tests use a pinned read-only repository artifact or disk;
they do not require Internet egress.
Limits are enforced at both strata where meaningful:
- vCPU and guest RAM are fixed by the normalized VMM plan and bounded again by host policy;
- working-disk virtual size and a node-wide physical-storage reservation prevent sparse images or many concurrent clones from exhausting the host; a native quota is used where the platform provides one;
- guest per-command CPU, PID, timeout, output, and filesystem limits are enforced by the guest supervisor as defense in depth;
- platform-available host process, memory, CPU, I/O, control-socket, console, and storage budgets contain a faulty or hostile guest independently of guest cooperation; unavailable controls remain explicit non-capabilities rather than implied guarantees;
- serial and vsock channels use bounded ring buffers and backpressure.
The initial reference network profile is none: no virtual network device is
attached. A later isolated profile may attach a NIC to an explicitly isolated
backend-specific network with no uplink, NAT, or default route. A future
egress-allowlisted profile requires its own grant and bounded DNS/proxy/firewall
contract. Linux netns/TAP/nftables and macOS user-mode networking are different
mechanisms and must produce separate platform evidence rather than share an
implementation-shaped promise.
7.6 Recovery And Conformance¶
Process-isolated recovery extends the existing Workbench startup sweep. The
host-private recovery record binds the pinned backend and binary digest,
environment and plan digests, image digest, process identity plus a reuse-safe
start marker, API/control socket identity, boot nonce, working disk identity,
resource-control identities, source generation, and any network resources.
Linux-specific fields such as cgroup, netns, TAP, UID/GID, and /proc start time
are present only for Linux profiles; macOS records equivalent process, socket,
disk, and launch identities without pretending that Linux primitives exist.
Before accepting new environment requests, the broker compares durable records
with live processes, sockets, disks, and platform resource controls; inspects the
VMM; performs the guest handshake; and recovers only an exact plan, image, nonce,
and generation match. Unknown, partial, or contradictory resources are
quarantined and then torn down. A previous-process running value is never
authoritative.
drain is monotonic and stops new sessions. teardown becomes terminal only
after the VMM is gone, control sockets and host resources are removed, retained
storage follows policy, and any requested export is durable. Memory snapshots
and live migration are outside v1 recovery; v1 either recovers the exact live VM
or safely tears it down and recreates from pinned image/storage policy.
An exact live-boot recovery preserves its source generation. Any recreated or new
guest boot advances the generation even when policy preserves the working disk.
The first backend is complete only when deployment evidence covers:
- full boot to
systemdand a generation/nonce-bound guest-agent handshake; - harmless kernel module, mount namespace, tmpfs/loop mount, and local package repository operations without host effects;
- absence of NIC, host paths, host environment, SSH agent, keychain, host credentials, and unallocated sockets;
- file, patch, explicit export, immutable-base-image, and deterministic teardown behavior;
- the P083 two-controller fenced PTY conformance suite against the real guest;
- CPU/RAM, guest PID, disk, serial, vsock, queue, timeout, and output exhaustion;
- crash/restart at every allocate/start/drain/teardown boundary, stale boot nonce, stale generation, and idempotent replay conflicts;
- bounded
allocate -> agent ready, PTY round-trip, file/patch/export, physical disk amplification, teardown, and reconciliation measurements.
A future full-system Story 012 profile may reuse the existing three-node Room, Corpus, Agent, and shared-terminal topology to prove collaborative GNU/Linux service configuration. It is an additive post-MVP acceptance profile; it does not retroactively change the completed Story 012 gate.
An environment also declares its operational impact through the P082-owned
sensorium-operational-context.v1 value. A connector or backend may supply an
operator-configured candidate default, but the exact normalized plan pins the
host-effective value before allocation and the resulting
sensorium-workbench-environment.v1 repeats it. One Workbench deployment may
operate both disposable test workspaces and live production systems. Host policy
may raise the candidate and records the effective value in every derived terminal-
screen, terminal-event, or actuation-interface publication; it may never lower it.
A read-only terminal over a production system remains production even though the
published access mode is observation-only. The selected network and host-share
profiles participate only as conservative policy floors; they do not replace the
actual context of a reachable or shared resource.
The environment also exposes a host-owned source generation reference. Replacement,
recreation, or an operational-context change advances that generation or otherwise
invalidates the old publication under P082's current-publication predicate. A change
such as test -> production must serialize creation of a new interface publication
and withdrawal of the old one as superseded. An operator may correct an erroneous
overclassification such as critical -> test through the same audited replacement
path with an explicit reason; consumer-side local policy still may only raise the
current source declaration.
8. HTTP Is The Middleware Transport, Not The Domain¶
Components communicate through the existing host/middleware style. Workbench may expose local HTTP endpoints to Sensorium Core, but the domain contract is Sensorium capability data, not ad hoc HTTP semantics.
These endpoints are connector-private loopback surfaces. Ordinary components,
JSON-e flows, Inquirium adapters, and UI clients should consume Sensorium host
capabilities or sensorium.directive.invoke actions instead of dialing the
Workbench connector directly.
Candidate local endpoints:
POST /v1/sensorium/workbench/terminal-sessions
GET /v1/sensorium/workbench/terminal-sessions/{session_ref}
POST /v1/sensorium/workbench/terminal-sessions/{session_ref}/commands
POST /v1/sensorium/workbench/terminal-sessions/{session_ref}/raw-input
POST /v1/sensorium/workbench/terminal-sessions/{session_ref}/resize
POST /v1/sensorium/workbench/terminal-sessions/{session_ref}/signal
GET /v1/sensorium/workbench/terminal-sessions/{session_ref}/events
POST /v1/sensorium/workbench/terminal-sessions/{session_ref}/close
POST /v1/sensorium/workbench/files/snapshot
POST /v1/sensorium/workbench/files/read
POST /v1/sensorium/workbench/patches/apply
POST /v1/sensorium/workbench/watches
GET /v1/sensorium/workbench/watches/{watch_ref}/events
POST /v1/sensorium/workbench/watches/{watch_ref}/close
POST /v1/sensorium/workbench/waits
GET /v1/sensorium/workbench/waits/{wait_ref}
POST /v1/sensorium/workbench/probes
POST /v1/sensorium/workbench/environments
GET /v1/sensorium/workbench/environments/{sandbox_ref}
POST /v1/sensorium/workbench/environments/{sandbox_ref}/close
The first Python connector slice intentionally exposes narrower loopback-private
paths such as /v1/workbench/file/read and a mediated
/v1/sensorium/connector/invoke entrypoint. The /v1/sensorium/workbench/...
shape above is the host/Sensorium-facing projection to keep stable as daemon
grant routing matures; it is not permission to bypass Sensorium Core by dialing
connector-local HTTP from flows, UI clients, or Inquirium adapters.
Those paths are loopback-private connector surfaces. They are not public node APIs and MUST bind through the bounded local server runtime only. Host/module authentication is still required because loopback is not authority.
| Endpoint family | Capability id | Required grant / caller posture |
|---|---|---|
| terminal session create/read/close | sensorium.workbench.terminal |
Explicit Workbench terminal grant; operator-approved by default. |
| structured terminal command | sensorium.workbench.terminal |
Directive grant plus command profile admission; generated commands use argv data, not shell interpolation. |
| raw terminal input / signal / resize | sensorium.workbench.terminal |
Local operator authority remains the default outside collaborative publication. The implemented P083-008 bridge accepts separately granted and fenced remote Sensorium Interface control without representing the caller as the operator. P083-009 adds Room collaboration through a separate current actuate grant, an exact interface grant, and the existing lease/generation fencing; Room observation remains separately authorized. |
| terminal events / screen snapshots | sensorium.workbench.terminal |
Read grant scoped to session ref and classification. |
| terminal capture to artifact | sensorium.workbench.terminal + sensorium.workbench.patch |
Terminal grant scoped to the session plus artifact-write grant; capture persists state and is not a read-only terminal action. |
| file snapshot/read | sensorium.workbench.file |
Bounded read grant scoped to workspace/root/path lease. |
| patch apply | sensorium.workbench.patch |
Write/patch grant plus digest/provenance checks; operator approval unless an explicit lease allows auto-apply. |
| watches | interaction-broker.watch |
Host broker grant scoped to observation source, cursor window, TTL, and classification. |
| waits | interaction-broker.wait |
Host broker grant scoped to observation source, deadline, and idempotency key. |
| operation status | interaction-broker.wait |
Status reads require an explicit wait grant; possession of an operation id is not authority. |
| probes | interaction-broker.probe |
Host broker grant scoped to target source and diagnostic purpose. |
| environment create/read/close | sensorium.workbench.env |
Environment grant scoped to backend, roots, teardown policy, and resource caps. |
Sensorium Core may wrap these as sensorium.directive.invoke actions so
ordinary consumers do not need to speak directly to the connector.
Streaming is an optimization, not the semantic contract. The same watch/wait contract should work through polling, bounded long-polling, server-sent events, or a future bidirectional local channel. The stable semantics are refs, cursors, deadlines, backpressure, caps, and terminal outcomes.
9. Approval And Autonomy Levels¶
Workbench is a high-impact actuator. Default posture:
- read-only snapshots may be allowed under a bounded read grant;
- terminal creation requires explicit workbench grant;
- terminal input that runs a command is a directive;
- filesystem writes require explicit write grant;
- patch application requires write grant and may require operator approval;
- network egress is denied unless the environment policy explicitly allows it;
- credential access is denied unless a separate sealed secret grant exists;
- destructive operations require a stronger approval profile.
Authority should be separated by effect class:
| Layer | May produce | May approve | May execute |
|---|---|---|---|
| Inquirium model | Plans, command intents, patch intents, explanations | no | no |
| JSON-e Flow / built-in workflow | Structured directives and policy context | only when granted by host policy | no |
| Host / Sensorium Core | Final directive, grant decision, idempotency key | yes | dispatch only |
| Workbench connector | Bounded local effect outcome | no | yes, within directive |
| Operator | Manual approval, revocation, emergency stop | yes | through host controls |
Autonomy levels should be expressed by policy, not by model identity. The same model output may be:
- advice-only;
- proposed command requiring approval;
- automatically executable in a disposable sandbox;
- automatically executable in a local workspace under narrow allowlists.
P072 continuation note: this section seeded the first implemented
authorization-policy-as-data slice. capability-authorization-policy.v1 now
projects the Workbench and Interaction Broker grant/posture/approval/autonomy
rows into registry-consumable policy sidecar data, while capability-registry.v1
remains the source for capability identity and eligibility.
Operator Consent Prompting¶
Workbench and Sensorium OS may later offer an interactive "ask the operator and remember the answer" path for effects that are not yet allowed, but are eligible for operator approval. This path must reuse the existing host-owned operator-question and notification primitives instead of creating a Workbench-specific notification handler.
The consent state machine belongs to the host:
- A Sensorium adapter or host workflow submits a typed
inquirium.operator-question.request.v1withrecipient/class = operator, a fail-closeddefault/on-timeout, a concreteoperation/ref, and a host-shapedwidget/kind. - The daemon projects the pending question to
notification-create.v1and renders schema-defined notification actions for the operator UI. - A node operator answers through the registered notification action target.
The submitting runtime-auth session must be bound to an active
node-operator-binding.v1whose capability profile isnode-primary-operator(Proposal 034). Ordinary participant acknowledgement is not enough to mutate execution policy or persistent allowlists. - The host records the answer as an auditable operator-question outcome and,
when granted, emits a domain-specific
operator-consent-decision.v1record that the relevant adapter binding can project into its own allowlist sidecar.
The notification is only the presentation and wake-up layer. It does not become domain authority, and an adapter must not grant itself new authority merely because it produced the question. The host validates both the runtime-auth session and its active node-operator binding, records the decision, owns revocation/list visibility, and controls whether a decision is one-shot or durable.
The consent lifecycle is layered over the P066 operator-question lifecycle. The
operator question remains pending -> answered | timed_out | cancelled |
superseded. The consent decision derived from it is pending -> granted |
denied | expired, and a previously granted consent may later become revoked
through the host-owned consent registry. revoked is therefore a consent-layer
state, not a synonym for P066 cancelled.
The minimal decision shape is:
{
"schema": "operator-consent-decision.v1",
"schema/v": 1,
"approval/ref": "approval:consent:sha256:<base64url>",
"operation/ref": "operator-question:<id>",
"operator/ref": "node-operator-binding:<id>",
"consent/decision": "granted",
"consent/scope": "remember-exact-argv",
"issued/at": "2026-07-06T00:00:00Z",
"expires/at": "2026-07-07T00:00:00Z",
"revocation/ref": null,
"delta/digest": "sha256:<base64url>",
"provenance": {
"source/component": "sensorium-workbench",
"requested/by": "component:sensorium-workbench",
"reason/code": "command-profile-missing"
}
}
delta/digest covers the concrete intent, not mutable audit metadata:
capability id, operation digest, workspace/root refs when present, proposed
scope, argv/action shape, and safety caps such as timeout, output bytes,
egress, credential policy, and result pointer constraints. This prevents the
same command or action shape from colliding across different workspaces,
capabilities, or safety envelopes.
approval/ref is derived deterministically by prefixing the exact
delta/digest with approval:consent:, so a digest
sha256:<base64url> becomes approval:consent:sha256:<base64url>.
For Workbench terminal commands, host-shaped choices should be ordered from narrow to broad:
deny- fail closed and optionally suppress repeated identical prompts for a bounded cooldown;allow-once- allow this exact command intent once without changing durable policy;remember-exact-argv- admit the exact argv, cwd/workspace, capability, and profile context as a durable sidecar delta;remember-argv-prefix- admit a bounded argv prefix plus explicitly declared variable-argument prefixes, both capped by host policy;remember-executable-any-args- a high-risk option that is disabled by default and available only under an explicit host policy/capability gate registered before implementation. Without that gate the consent layer must not render this option even when the widget kind permits it.
For Sensorium OS, the same consent state machine may approve a concrete action
catalog delta, but the binding remains connector-specific: Sensorium OS action
entries use action class, executable, result contract, and
result_pointer_fields; Workbench command profiles use argv prefixes, cwd,
environment, egress, timeout, and PTY/output caps. A single generic allowlist
format would hide these differences and should not be introduced.
The recommended persistence shape is hybrid:
- the host keeps a capability-scoped approval ledger/index for list, revoke, audit, deduplication, and policy reasoning;
- each adapter receives or materializes an adapter-specific sidecar projection that stores only the delta required by that adapter;
- the effective configuration is
main config + sidecar projection, validated after merge before execution; - sidecars may append admissible entries, but must not silently override safety caps such as egress denial, credential policy, maximum timeout, maximum bytes, or workspace-root boundaries unless a separate explicit policy says so.
Audit export for this flow is redacted by default. Full argv, parameter schemas, and action descriptors may be retained only under their classification policy; exported audit should prefer digest, capability id, source component, operator binding ref, selected scope, and redacted summaries. Secrets, tokens, passwords, and raw environment values are never audit payload.
Revoking or expiring a node-operator-binding.v1 does not rewrite historical
consent facts. The effective sidecar projection must, however, treat any
durable consent whose operator/ref points to a revoked or expired binding as
inactive and surface consent-operator-binding-inactive in diagnostics.
Likewise, an expired durable consent fact remains auditable history but is not
effective authority; Workbench projections omit it and surface
consent-expired. If host authorization policy later removes durable
grantability for the consent capability, the fact likewise remains audit
history, but the effective projection omits it and surfaces
consent-capability-not-grantable.
Implementation status 2026-07-07:
node:operator-consent-coredefines the host-owned request/decision data model, fail-closed timeout requirement, deterministicdelta/digest, andapproval:consent:<delta/digest>derivation.- The daemon persists pending/answered/expired/revoked consent records under
<data-dir>/storage/operator-consents.sqlite, exposes submit/list/detail/ revoke APIs, projects pending requests into P066 operator questions and durable notifications, and translates answered operator-question actions intooperator-consent-decision.v1. Operator-consent read and Workbench/Sensorium OS sidecar projection endpoints are operator surfaces; module callers are rejected fail-closed. Revocation also requires an active localnode-operator-binding.v1and records the active binding ref as the revoking operator. - The P066 notification action dispatcher rejects non-operator callers for
inquirium.operator-question.respond. Consent answers additionally require the answering operator participant to own an active localnode-operator-binding.v1with thenode-primary-operatorcapability profile, and durable answers fail closed unless the target capability is grantable under host capability authorization policy. If that host policy later removes durable grantability for a capability, existing durable consent facts are not deleted, but future effective projections omit them withconsent-capability-not-grantable. - Workbench emits
sensorium-workbench.consent-descriptor.v1forcommand-profile-missing, acceptsallow-onceandremember-exact-argvdecisions whose descriptor matches the current command exactly, and can load a host-projected exact-argv command-profile sidecar without loosening egress, credential, timeout, or output-byte caps. The connector refreshes the sidecar through a bounded TTL, validates sidecar entry schemas, and validates inline consent descriptor schemas before admission. The daemon omits expired durable decisions, decisions signed by inactive operator bindings, and decisions whose capability is no longer grantable for durable consent from the effective sidecar projection, emitsconsent-expired,consent-operator-binding-inactive, orconsent-capability-not-grantablediagnostics for those skipped entries, and the Workbench connector imports sidecar diagnostics into its operator-visible config diagnostics. - Sensorium OS uses the same host-owned consent registry for
remember-action-catalog-entrydurable decisions. The daemon projects granted Sensorium OS decisions intosensorium-os.action-catalog-sidecar.v1deltas, writes that sidecar to the Sensorium OS middleware config tree, applies the same expired/inactive-binding/no-longer-grantable filters, and the connector appends valid non-overriding deltas into its effective action catalog while importing projection diagnostics.
10. Trace And Memory¶
Workbench traces must be useful without leaking unnecessary content.
Trace records should include:
- caller;
correlation/idthreading directive, events, wait outcome, artifacts, and next directive;- session ref;
- workspace/sandbox refs;
- operation class;
- command digest and argv metadata;
- file refs and digests;
- result status;
- duration;
- byte counts;
- policy decisions;
- artifact refs;
- approval refs;
- watch/wait/probe refs;
- condition kind and normalized condition digest;
- deadline, timeout, cancellation, and progress status.
Raw terminal output and file contents should not be written into generic traces by default. If captured, they should be artifacts or Memarium facts under an explicit classification and retention policy.
This follows the broader Orbiplex pattern: an ephemeral observation is not a durable fact. A live terminal transcript, like a live room chat or an intermediate reasoning exchange, is operational context until a host policy explicitly captures, classifies, and admits it as an artifact or fact.
Workbench should reuse existing host-owned runtime primitives instead of creating private equivalents:
- Bounded Deferred Operations for long-running environment creation, test runs, indexing, batch edits, and other operations that outlive one HTTP request;
- Replay Scheduler for bounded periodic probes, maintenance watches, and policy-owned rechecks that must survive one immediate interaction loop;
- Artifact Delivery for moving patch artifacts, captured logs, build outputs, screenshots, and export bundles between components;
- Memarium for classified summaries or operator-approved durable observations;
- Host-Owned Module Store for installing and activating Workbench connector packages, tool profiles, and future backend modules.
Process termination is never broker-owned. When a wait or probe reports maybe_hung,
timeout, or no progress, the Interaction Broker emits the diagnostic outcome only; the
Workbench connector or operator decides whether to cancel, signal, kill, ask the user,
or keep observing.
11. Relationship To Existing Sensorium OS¶
Sensorium OS remains the generic OS action connector for allowlisted one-shot actions. Sensorium Workbench is for interactive or workspace-shaped action:
| Capability | Sensorium OS | Sensorium Workbench |
|---|---|---|
| One-shot read-only process | primary | possible |
| Allowlisted script | primary | possible |
| Interactive PTY | no | primary |
| Screen/event snapshots | no | primary |
| Workspace file snapshot | limited | primary |
| Patch apply | no or narrow | primary |
| Disposable sandbox | no | primary/future |
| Agent loop support | indirect | primary actuator |
Workbench does not replace Sensorium OS. It provides a stricter, more observable boundary for effects that are too stateful for the one-shot action catalog.
The first Workbench implementation should be independently shippable before any Inquirium agent loop exists. JSON-e Flow, operator UI, and direct Sensorium directives are sufficient to validate the actuator boundary, resource caps, wait/watch/probe semantics, and audit behavior.
12. Relationship To Agent Adapters¶
A future Inquirium adapter may wrap a whole agent runtime, including an MCP-like tool protocol. That adapter may be useful, but it must still call host-granted tools. Tool execution remains outside the adapter:
agent runtime
-> requests terminal/file/sandbox tool
-> host policy gate
-> Sensorium Workbench directive
-> audited effect
If an agent runtime has its own terminal/filesystem access that bypasses Workbench, it is not an acceptable Inquirium adapter for Orbiplex Node.
Corpus or room-deliberation experts may later use Workbench as an actuation surface for grounded reasoning, such as running a test or inspecting a local artifact during deliberation. That use remains mediated by host policy: deliberation proposes the act, Workbench executes only after Sensorium grants, and the resulting observation is not a durable fact unless admitted.
Storage And Recovery Contract¶
Workbench and the host Interaction Broker are stateful enough to require the
same store discipline as other daemon-owned ledgers. Any session, wait, watch,
probe, sandbox, approval, idempotency, or cleanup store must follow the Temporal
Storage Convention / Storage and Database Schema Design contract: explicit
user_version migrations, WAL-oriented pragmas where SQLite is used,
busy_timeout, foreign keys where relationships exist, stable idempotency keys,
bounded retention, and replay or projection diagnostics. Short-lived caches may
remain disposable, but the decision to make a store disposable must be explicit.
The first daemon implementation should use two separate stores so that local actuation lifecycle and horizontal coordination do not become one accidental database:
<data-dir>/storage/sensorium-workbench.sqlitefor Workbench-owned sessions, command intents, terminal events metadata, workspace roots, patch attempts, cleanup records, and idempotency decisions;<data-dir>/storage/interaction-broker.sqlitefor host-owned waits, watches, probes, cursor bindings, source refs, deadlines, final outcomes, and idempotency decisions.
Both stores are metadata-first. They must not store raw terminal transcripts, file contents, prompts, credentials, or source blobs by default. Large or sensitive bytes move through classified artifact/object-store handles or through explicit capture facts with retention policy.
Minimum Workbench tables or equivalent records:
environments:environment/ref, workspace refs, root refs, backend, status, classification digest, limits digest, cleanup status;terminal_sessions:terminal.session/ref, environment ref, command profile ref, state, caps digest, last event sequence, opened/closed timestamps;terminal_events: session ref, sequence number, event kind, byte count, optional byte digest/ref, status, classification digest, retention class;command_intents: command id, session ref, idempotency key, normalized argv digest, cwd address, timeout, outcome ref;file_snapshotsandpatch_attempts: metadata, digests, artifact refs, and refusal/apply diagnostics;cleanup_records: previous process generation, discovered resource, action taken, terminal cleanup status.
Minimum Interaction Broker tables or equivalent records:
broker_sources: source kind, source ref, provider component, classification digest, retention window;watches: watch ref, source ref, cursor, TTL, caps, idempotency key, status;waits: wait ref, source ref, condition digest, deadline, idempotency key, deferred operation id, condition status, final outcome digest/ref;probes: probe ref, source ref, condition digest, timeout, idempotency key, outcome digest/ref;cursor_replay: source ref, sequence/cursor, event digest/ref, retained until;recovery_records: previous generation resources and explicit recovery outcomes.
Daemon restart recovery is part of the safety contract, not an operator afterthought. On startup the Workbench runtime must run one authoritative recovery sweep before accepting new PTY, file, patch, or environment requests:
- enumerate runtime-owned child processes, PTY sessions, reader tasks, temporary workspace/sandbox roots, active waits, and watch cursors from the previous process generation;
- terminate or quarantine residual child processes and PTY resources using the connector's cleanup policy;
- remove or quarantine temporary roots that are not explicitly retained by policy;
- mark interrupted sessions, waits, watches, and probes as
failed-retryable,failed, ordegradedaccording to the persisted state and cleanup outcome; - append metadata-only recovery facts and expose cleanup failures in operator status.
This mirrors the Artifact Delivery recovery rule: a previous-process running
state is not silently trusted after restart. There is one source of truth for
recovery state, and no hidden background shell is allowed to survive merely
because the daemon crashed. Recovery status values should be boring and
operator-readable: recovered, terminated, quarantined,
failed-retryable, failed-permanent, expired, and unknown.
Trade-offs¶
| Choice | Benefit | Cost / constraint |
|---|---|---|
| Workbench as Sensorium connector, not Inquirium adapter | Preserves the organ boundary: models propose, Sensorium acts. | Requires one more host-routed step in agent-like loops. |
| Structured command intents before raw PTY input | Easier policy checks, idempotency, traces, replay, and tests. | Some interactive programs need a raw-input escape hatch later. |
| Snapshot/lease-based filesystem model | Avoids ambient disk authority and keeps path validation host-owned. | More explicit plumbing for file reads and patch workflows. |
| Host-owned brokered waits, watches, and probes | Makes interactive coordination visible, bounded, replayable, and testable across components without coupling Sensorium to every domain source. | Adds a small temporal contract layer before richer agent loops feel natural. |
| Shared actuation core for OS and Workbench | Reduces traversal, argv injection, allowlist, and classification drift. | Requires extracting safety primitives instead of copying code into the new connector. |
| Host-local first slice | Delivers useful developer workflows quickly. | Does not yet isolate arbitrary code as strongly as containers or VMs. |
| Property-attested backend admission | Lets one requirement select different substrates without treating names as security claims. | Adds descriptor, normalization, policy, digest, and per-platform evidence contracts. |
| vfkit first on macOS; Cloud Hypervisor first on Linux | Makes the first full-system proof executable on the primary developer host while retaining a direct KVM deployment path. | Requires two lifecycle adapters and separate host-containment evidence instead of one nominally portable VMM. |
| One bounded guest agent instead of SSH or host shares | Keeps PTY, file, patch, and export semantics common across VMMs and removes credential-shaped control. | The image must carry and update the agent, and all guest-returned state remains untrusted. |
| No memory snapshots in recovery v1 | Keeps boot freshness, source generation, and grant expiry reasoned from live facts. | Recovery may require a slower full boot or teardown/recreate path. |
| Metadata traces by default | Reduces prompt, terminal, secret, and source-code leakage. | Debugging deep agent failures may require explicit capture artifacts. |
| Reuse host-owned primitives | Keeps lifecycle, artifacts, and deferred work consistent across components. | Workbench implementation must integrate with existing registries instead of inventing local shortcuts. |
Failure Modes And Mitigations¶
| Failure mode | Mitigation |
|---|---|
| Model output is treated as authority. | Require host validation and Sensorium grants before every Workbench directive. |
| Command text is executed through shell interpolation. | Use command profiles and argv data for model-driven commands; reserve raw input for approved interactive sessions. |
| Path traversal or symlink escape reaches outside the workspace. | Canonicalize every path under root/ref + relative/path; reject traversal, NUL bytes, empty invalid paths, and symlink escape. |
| PTY output leaks secrets into generic traces. | Store only metadata by default; capture raw bytes only as classified artifacts or facts. |
| Long-running process survives session close. | Make cleanup part of the state machine; report degraded cleanup failures to operator status. |
| Daemon restarts while PTY sessions or sandboxes are active. | Run a startup recovery sweep that terminates or quarantines residual child processes, reader tasks, PTY resources, and temporary roots before accepting new Workbench requests. |
| Workflow blocks on a long-running operation. | Use Bounded Deferred Operations for work that can outlive one HTTP request. |
| Client invents private polling or watcher loops. | Provide host-owned watch/wait/probe refs with deadlines, cursors, caps, and outcomes. |
| Quiet terminal is misclassified as hung. | Separate quiescent, waiting_for_input, no_progress, maybe_hung, and probe_failed states under policy. |
| Watch cursor is lost during component restart. | Keep bounded replay windows and explicit cursors for watch sources. |
| Event producer overwhelms a consumer. | Enforce byte/event caps, cursor windows, truncation markers, and backpressure/overload status. |
| Wait outcome overwhelms deferred-operation consumers. | Bound observed and diagnostics by schema shape and by host-owned serialized byte/count caps before projection into deferred-operation-status.v1. |
| Agent adapter bypasses Sensorium tools. | Reject adapters that own their own terminal/filesystem authority outside host grants. |
| One adapter-level default labels test and production environments alike. | Pin operational context on the exact environment/resource; treat the adapter value only as an operator-configured candidate default. |
| A read-only viewport is labeled less cautiously than the environment it observes. | Require every derived P082/P083 resource to inherit the environment class; host policy may raise but never lower it. |
| An environment changes impact class while an old interface remains readable. | Advance or invalidate the source generation, publish an immutable replacement, withdraw the old interface as superseded, and let P082 refuse old-generation or superseded reads. |
| A backend name is accepted as proof of isolation or system fidelity. | Match exact host-attested capability properties against a normalized requirement; unknown or unverified properties fail closed. |
| Policy treats an unknown capability string as a new equivalent property. | Use closed, versioned enums for every semantic descriptor dimension and registry-bound backend/platform refs; require schema and conformance changes before a new value can match. |
| A network or host-share profile is added without raising operational caution or inheriting the target context. | Resolve the effective operational context in the normalized plan, apply at least the test floor, inherit higher attached-resource classes, and deny unknown target context. |
| Backend-specific image variants share one logical ref without comparable provenance. | Require common userspace, SBOM, build provenance, guest-agent, and protocol/schema-set digests; otherwise issue distinct logical refs and retain exact variant digests. |
| Python gains an administrative VMM socket or arbitrary host process-launch authority. | Keep VMM launch, resource allocation, exact sockets, and teardown in the daemon-owned host broker; provide the adapter only normalized plans and broker-allocated handles. |
| A previous guest boot or restored VM reconnects under current authority. | Bind every handshake and operation to environment, source generation, image/plan digests, and a per-boot nonce; reject stale or contradictory recovery state. |
| Guest root disables guest-agent or guest-cgroup controls. | Treat all guest output as untrusted and retain independent host CPU, memory, storage, process, I/O, socket, and network containment. |
| Guest serial output injects terminal controls or sensitive content into operator diagnostics. | Keep ordinary logs metadata-only; bound and classify explicit captures; sanitize ANSI/control sequences at presentation; apply configured redaction without treating it as complete secret detection. |
| Sparse disks or many APFS clones exhaust host storage. | Combine a fixed virtual-disk maximum with node-wide physical-storage reservation/accounting and a native quota where available. |
| A memory snapshot silently revives expired grants, nonces, or source generations. | Exclude memory snapshots and live migration from v1 recovery; recover only the exact live VM or recreate from pinned image/storage policy. |
| Workbench grows into a second orchestration core. | Keep Workbench as an actuator: no policy selection, no model routing, no workflow ownership. |
Adversarial Actuator Test Matrix¶
This matrix is a release gate for any Workbench runtime that can write files,
spawn PTYs, apply patches, create sandboxes, or expose brokered waits across a
process boundary. The cases must be encoded as golden vectors in
sensorium-actuation-core and run by both the Rust Workbench implementation and
Python Sensorium OS conformance tests. The required posture is refusal-first:
every negative vector must fail before the corresponding runtime surface can be
enabled by default.
| Class | Required negative or stress cases |
|---|---|
| Path validation | Reject .., absolute paths, empty paths where a file is required, NUL bytes, symlink escape, root self-access when a file is required, and path-space/root mismatch. |
| Command intent | Reject shell strings, argv injection through profile escape, unknown command profile, cwd outside root, env override outside policy, timeout above max, and output cap overflow. |
| PTY lifecycle | Enforce sessions/max, per-workspace session caps, reader task caps, input queue caps, idle timeout, TTL expiry, close idempotency, and overload refusal. |
| Network and credentials | Deny egress, keychain, SSH agent, browser profile, clipboard, desktop automation, and sealed secret access without explicit future grants. |
| Cleanup | Surface residual child processes, failed process kill, leaked temporary roots, and sandbox teardown failure as operator-visible degraded states. |
| Idempotency and replay | Replaying session create, command intent, wait, probe, close, and patch apply with the same idempotency key must not duplicate effects. |
| Interaction broker | Reject waits without scope, waits extending beyond grant expiry, unbounded deadlines, lost cursor replay outside retention, and cross-source waits not owned by the host broker. |
| Artifact and patch | Reject digest mismatch, size mismatch, patch outside root, dirty apply when clean apply is required, unexpected delete, and artifact admission without provenance. |
Candidate Data Contracts¶
Every top-level Workbench artifact should carry both schema and schema/v.
Embedded classification.v1 labels keep the existing classification-family
shape: schema, source_tier, effective_tier, provenance,
bound_subjects, and declassify_trail, without schema/v.
| Schema | Purpose |
|---|---|
sensorium-workbench-environment.v1 |
Declares workspace/sandbox backend, roots, locality, egress, credentials, teardown. |
sensorium-virt-backend-capabilities.v1 |
Closed host-attested backend/platform refs and versioned enum sets for locality, architecture, isolation, fidelity, transport, device, network, lifecycle, and resource enforcement. |
sensorium-virt-environment-plan.v1 |
Canonical requirement, selected profile, exact P082 operational context and policy floor, attached-resource context, policy ref, resource plan, image ref, and allocation-idempotency digests. |
sensorium-virt-image-manifest.v1 |
Logical full-system image whose shared userspace/SBOM/provenance/agent/protocol digests prove variant equivalence while exact boot artifacts remain variant-specific. |
sensorium-virt-recovery-record.v1 |
Host-private identity for VMM process, sockets, working storage, boot nonce, source generation, platform resources, and reconciliation status. |
sensorium-virt-guest-frame.v1 |
Bounded handshake and operation envelope for the guest channel, including environment/generation binding, sequence, deadline, chunk caps, and payload digest. |
sensorium-virt.host.request.v1 |
Closed internal ingress envelope for fixture and vfkit allocation, exact environment start/inspect/drain/teardown/recover bindings, and authoritative host reconciliation. Caller payloads never select host paths, VMM binaries, sockets, or argv. |
sensorium-terminal-session.v1 |
Session descriptor: command profile, workspace, classification, limits, status. |
sensorium-terminal-command.v1 |
Structured command intent with command profile, argv data, idempotency key, and normalized argv digest. |
sensorium-terminal-input.v1 |
Bounded raw input event to an existing session. |
sensorium-terminal-event.v1 |
Append-only output/status event. |
sensorium-terminal-screen-snapshot.v1 |
Bounded model/UI view over recent terminal state. |
sensorium-workbench-error-codes.v1 |
Shared runtime diagnostic code vocabulary for Workbench refusal, recovery, patch, artifact, file, terminal, wait, and configuration failures. |
interaction-broker-watch.v1 |
Cursor-bound subscription over a registered source provider with caps, TTL, and classification. |
interaction-broker-wait.request.v1 |
Declarative bounded condition over observations, with deadline and idempotency key. |
interaction-broker-wait.outcome.v1 |
Domain result/projection for a satisfied or terminal wait condition; async lifecycle status is still deferred-operation-status.v1. |
interaction-broker-probe.v1 |
Active bounded check for liveness, readiness, file state, artifact presence, or progress. |
sensorium-file-snapshot.v1 |
Directory/file metadata snapshot under an allowlisted root. |
sensorium-file-read-result.v1 |
Bounded file content or artifact ref. |
sensorium-workbench-patch.v1 |
Patch proposal artifact and metadata. |
sensorium-workbench-patch-apply-result.v1 |
Applied/rejected patch result with changed files and digests. |
sensorium-workbench-outcome.v1 |
Host audit fact linking directive id, grant, caller, session/environment refs, status, timing, byte counts, and artifacts. |
sensorium-actuation.bridge.request.v1 |
Bounded request from the Python connector to the Rust actuation validator. |
sensorium-actuation.bridge.response.v1 |
Fail-closed Rust validation result with typed diagnostics. |
sensorium-virt-workspace-export.v1 |
Bounded content bundle exported from a managed virtual workspace. |
sensorium-virt-export-result.v1 |
Artifact descriptor and counts produced by explicit virtual workspace export. |
sensorium-virt-teardown-result.v1 |
Terminal lifecycle and cleanup result for managed environment teardown. |
sensorium-workbench-tool-request.v1 |
Host-verified Agent, Corpus, or Room lineage around a Sensorium Workbench directive. |
capability-authorization-policy.v1 |
P072 Phase 4 sidecar for per-capability required grants, caller posture, approval mode, autonomy floor, and COI policy for Workbench and Interaction Broker capability ids. |
Phase 0 schema ownership belongs to the Workbench implementation owner. The owner must publish JSON Schema files and positive/negative examples before any corresponding cross-process connector route is exposed. Rust DTOs may precede schemas only while they remain in-process and unwired.
Security Invariants¶
- Default deny.
- No ambient terminal.
- No ambient filesystem.
- No shell interpolation for generated commands.
- Workbench and Sensorium OS must use the same lower actuation primitives for path canonicalization, command profiles, allowlists, argv normalization, and classification/sensitivity propagation.
- Canonical path validation before every file access.
- Writes only under allowlisted workspace roots.
- Network egress denied by default.
- Credentials denied by default.
- Clipboard access, keychain access, SSH agent access, browser profile access, desktop automation, and GUI event injection are denied by default and require separate future capability contracts.
- A backend id is never accepted as isolation evidence without a matching host-attested capability descriptor and normalized plan digest.
- The reference full-system profile has no NIC, SSH service, host share, credential injection, or arbitrary host socket.
- VMM lifecycle authority, working-storage allocation, platform resource controls, and recovery remain daemon-owned; the Python adapter receives only exact broker-allocated handles.
- Every guest boot has a fresh nonce bound to environment, image, plan, source generation, and the dedicated control endpoint.
- Guest-agent output is untrusted; guest-side cgroups and supervisors do not replace independent host resource containment.
- Every accepted directive has exactly one outcome record.
- Every wait/watch/probe has explicit scope, deadline or TTL, caps, and final lifecycle status.
- A wait must not extend authority beyond the grant that created it.
- PTY sessions, reader tasks, input queues, and event buffers are bounded by connector-declared caps.
- Terminal output and file bytes are bounded and classified.
- Long-running sessions have TTL and idle timeout.
- Closing a sandbox tears down processes and temporary storage unless retention policy explicitly preserves artifacts.
- Inquirium cannot bypass Workbench by choosing a different model or adapter.
First Implementation Slice¶
The first slice should be deliberately small:
- Add Workbench capability declarations to Sensorium Core.
- Extract or identify the shared actuation core used by Sensorium OS and Workbench for path, command, allowlist, classification, and argv rules.
- Implement a local-only supervised Workbench connector.
- Support one environment type: allowlisted host-local workspace.
- Support terminal session create, structured command intent, events, resize, signal, and close with strict limits.
- Support explicit PTY session, reader-task, queue, and event-buffer caps.
- Support short synchronous waits for terminal command done, terminal quiescence, environment ready, file exists, and artifact present.
- Support watch cursors for terminal events and deferred operation outcomes.
- Support file snapshot and bounded read.
- Support patch apply from artifact ref, with no deletes by default.
- Add JSON-e Flow examples for observe -> ask Inquirium -> propose command -> approve -> execute -> observe.
- Add operator status showing active sessions, workspaces, waits, watches, limits, last outcomes, and suspected no-progress states.
- Add the adversarial actuator test matrix before enabling write or PTY features by default.
The first slice does not need containers, VMs, remote execution, credential grants, raw terminal input for model-driven commands, or autonomous multi-step agent loops. It also does not need WebSockets; polling or bounded long-polling is enough if cursor and outcome semantics are stable.
Phase Release Gates¶
Phase 1 may begin only when Phase 0 has frozen schemas/examples for the specific surfaces being exposed, capability ids are registered, the storage/recovery contract is documented, and the adversarial matrix has executable golden vectors for path and command-intent refusal. PTY creation may not be enabled by default until PTY lifecycle, cleanup, oversized-output, orphan-after-crash, and credential-egress vectors pass.
Phase 2 may begin only when the local connector produces metadata-only outcomes, operator-visible status, and bounded recovery facts for Phase 1 effects. Sensorium Core must consume Workbench through grants/directives, not by reaching into connector-local HTTP details.
Phase 3/4 integration with room, Corpus, or agent loops may begin only after Workbench has a stable refusal-first conformance suite shared with Python Sensorium OS and after watch/wait/probe replay semantics are backed by bounded retention.
Open Questions¶
No unresolved questions remain for the current local Workbench foundation, Phase 3A operator-consent slices, or the frozen Phase 4 full-system backend architecture. Backend-specific implementation findings may reopen only a bounded property or profile decision; they must not be hidden as adapter-local behavior.
Resolved Decisions¶
- Workbench packaging. Workbench starts as a separate supervised connector. It may reuse Sensorium OS internals, but its operational identity, capability declarations, limits, traces, and lifecycle are distinct.
- Terminal screen model. The default LLM-facing terminal observation is a bounded viewport snapshot with cursor position and a digest/ref for omitted backlog. It does not expose full transcripts unless explicitly captured under a separate policy.
- Patch model. Patch application supports both unified diff and structured edit operations. Unified diff remains the human-readable lowest common denominator; structured edits exist for machine-authored, schema-checked transformations.
- Filesystem writes. Local filesystem writes require explicit approval by default. Writes inside an already granted leased workspace may be auto-allowed only when the lease and policy say so; outside that lease, approval remains required.
- Terminal-to-Memarium capture. Terminal sessions create Memarium facts only on explicit capture. Outcome summaries are not mirrored automatically.
- First sandbox backend. After host-local workspaces, the first sandbox backend is a fixture-only virtual workspace. Containers and microVMs are later substrate implementations.
- File tree exposure. Workbench exposes file trees to models through query-style leases. A lease is narrower and easier to revoke than a full direct snapshot.
- Raw PTY input. Raw PTY input remains operator-only outside an explicitly
published actuation interface. Model-driven workflows normally use structured
command/file intents, while the implemented P083-008 bridge permits separately
granted remote terminal bytes only under the exact exclusive lease, generation,
epoch, sequence, method, deadline, and Workbench session checks defined by
Proposal 083. P083-009 now derives the
canonical remote caller from a current Room
actuatesession and still requires the exact interface grant and fenced lease. Observation never turns into command authority, and the remote caller is never represented as operator. - Command profile completeness. The first implementation requires executable identity, argv schema, cwd policy, env policy, timeout, egress, and output capture policy before a command profile can be accepted.
- MVP wait conditions. MVP waits cover process exit, stdout/stderr pattern, file exists/changes, and timeout. Component-specific probes can be added later.
- Watch replay window. Local Workbench watch cursors keep a bounded replay window by both count and time, with the laptop profile defaulting to 1,000 events or 10 minutes unless policy overrides it. The eventual watch request schema must carry both event/byte caps and a time-window or TTL axis; the broker enforces the narrowest applicable bound.
maybe_hung.maybe_hungis diagnostic only. It does not automatically create operator questions or kill processes.- Interaction Broker status. The host-owned interaction broker should be promoted into its own solution document before Workbench implementation exposes a cross-process runtime surface.
- Laptop PTY caps. The default local laptop profile is conservative: 2 active PTY sessions, 4 reader tasks, input queue depth 256, and event buffer depth 1,000. These caps are policy-configurable.
- Async wait diagnostics. Early async wait diagnostics use
deferred-operation-status.v1.extensions; no separate common wait/probe extension is promoted before implementation. - Workbench DTO schema gate. All candidate Workbench and interaction-broker DTOs need JSON Schema projections before the first cross-process boundary is exposed: watch request, wait request, wait outcome, probe request, command profile, command intent, relative path address, and PTY resource caps.
- Timeout termination. Timeout policy does not authorize kill-on-timeout from the host interaction broker. Process termination remains a connector/operator directive separate from wait outcome semantics.
- Deferred id validation. The host interaction broker must share the exact
deterministic-id validator with the deferred-operation registry before cross-process
broker APIs are exposed. Broker acceptance of an operation-done condition must call
the deferred-operation validator, not merely check the
deferred:prefix. - Relative path validation. Relative path syntax validation moves into a small
shared utility crate consumed by both
sensorium-actuation-coreandinteraction-broker-core. - Hard-MVP documentation visibility. Workbench foundation appears in hard-MVP implementation docs as a planned post-MVP seed. This keeps the runtime boundary visible to implementers without claiming that Workbench itself is part of hard-MVP.
- Shared actuation core adoption. Python Sensorium OS remains a separately
audited reference connector, while Workbench consumes
sensorium-actuation-corethrough a bounded required companion process with no Python validation fallback. The shared core is the contract plus golden vectors from day zero, not merely the Rust crate. Canonical rules for path canonicalization, symlink escape refusal, allowlists, command profiles, and classification must be expressed as data/reference rules with golden vectors. The Rustsensorium-actuation-corecarries those vectors as the reference implementation; Python Sensorium OS must run the same conformance vectors. Workbench usessensorium-actuation.bridge.{request,response}.v1over a 64-KiB fail-closed process boundary rather than embedding Rust through FFI. - Capability registration. The reserved capability ids are
sensorium.workbench.terminal,sensorium.workbench.file,sensorium.workbench.patch,sensorium.workbench.env,interaction-broker.wait,interaction-broker.watch, andinteraction-broker.probe. They are registered before runtime work so that Workbench and broker authority does not appear as untracked informal module power. - State-store discipline. Workbench and Interaction Broker stores must follow
the Temporal Storage Convention / Storage and Database Schema Design contract:
explicit migrations, WAL-oriented SQLite pragmas,
busy_timeout, foreign keys, idempotency keys, bounded retention, and replay/projection diagnostics. - Restart recovery sweep. A Workbench runtime must enumerate and terminate or quarantine residual child processes, PTY resources, reader tasks, and temporary sandbox roots on daemon restart before accepting new requests. Interrupted sessions and waits must become explicit failed/degraded records, never invisible live residue.
- Command profile default-deny.
allowed_workspace_rootsmust be non-empty. Empty filesystem authority is a profile error, not a wildcard. Emptyallowed_arg_prefixesmeans no variable argv atoms are allowed beyond executable plusfixed_args; it never means allow arbitrary argv. - Command identity admission.
command/idmay be omitted on incoming command intent. The host assigns it when missing, preserves it when present and valid, and records the resulting value onsensorium-terminal-command.v1for correlation and audit. - Empty environment defaults. Empty strings in
EnvPolicy::Allowlisted.defaultsare explicit environment values, not unset/clear operations. If Workbench later needs unset semantics, it must model them as a separate explicit operation. - Terminal command scope binding. A broker source provider must validate
that
TerminalCommandDone.command/idbelongs to the persistedterminal.session/ref -> command/idrelation before accepting the wait condition. The host broker validates the generic shape and scope; the source provider owns the Workbench-specific binding check. - Host-local workspace root admission. The first Workbench connector slice
admits only explicitly configured, absolute, existing directory roots and
refuses empty paths, relative paths, duplicate
(workspace/ref, root/ref)pairs, and the filesystem root itself. This does not make the connector a general filesystem broker; workspace roots remain operator-scoped grants. - Command profile validation source. The Python Workbench connector calls
the required
orbiplex-sensorium-actuation-contractcompanion process for command-profile and relative-path decisions. Missing, malformed, timed-out, or refused responses fail readiness or the affected request closed. Shared golden vectors remain the cross-language conformance layer. - Terminal capture authorization. Terminal capture is a terminal read plus
an artifact write. The session event read requires a
sensorium.workbench.terminalgrant scoped to the session, while the persisted capture artifact requires a separatesensorium.workbench.patchartifact-write grant. Capability reports may use the patch capability as the primary persisted-effect capability, but handlers must enforce both sides. - Connector idempotency admission. Connector-mediated probes, watches,
waits, terminal mutations, terminal capture, artifact writes, and patch
apply must carry a valid
idempotency/key. The first local implementation enforces presence at the connector boundary and de-duplicates async waits by this key; broader host-issued replay tokens remain a later host-broker layer. - Operation status authorization. Deferred operation status is not public
by operation id. Status reads require an explicit capability grant for the
relevant operation family, with the local Workbench wait pilot using
interaction-broker.wait. - Operator consent prompting. Interactive approval for new Sensorium OS or
Workbench operations reuses host-owned
inquirium.operator-question.request.v1projected through durable notifications. The host owns the state machine, runtime-auth session validation against an activenode-operator-binding.v1, audit, revocation/list visibility, and durable approval ledger. Adapters own only the binding from a granted decision into their adapter-specific sidecar projection; they may request consent but must not mutate their own authority outside the host approval path. Durable grants amplify authority and therefore require an explicit affirmative operator action from an active runtime-auth session bound to an activenode-operator-binding.v1, plus a host grantability policy/capability gate for the requested consent scope. A detached operator signature may be added later for high-risk or long-lived consent classes, but it is not required for the MVP path. If one runtime-auth session can present more than one active operator binding, one applicablenode-primary-operatorbinding is sufficient; the selected binding must be deterministic or explicitly selected by the host and recorded asoperator/ref. - Consent revocation authority. Revoking a durable consent in the MVP
requires an authenticated active node-operator runtime session bound to an
active
node-operator-binding.v1; it does not require a fresh detached operator signature. This is acceptable because revocation reduces authority. The audit record must still capture the runtime session ref, operator binding ref, timestamp, target consent, and reason. Revocation uses a dedicated operator surface,POST /v1/operator-consents/{approval_ref}/revoke, withapproval_refURL-encoded. It is not represented as anotherinquirium.operator-question.respondanswer, because it acts on an already materialized durable consent rather than on a pending question. - Effective sidecar merge timing. Effective sidecar projections are cached with deterministic invalidation on consent grant, revocation, expiry, main-config changes, and node restart/warm-recovery when the shared sidecar merge primitive owns the projection. The current Workbench connector implementation uses a bounded sidecar refresh TTL, validates the refreshed sidecar before use, and consumes the validated projection rather than treating a startup snapshot as final.
- Bounded argv-prefix consent.
remember-argv-prefixis limited by host caps for fixed prefix length and variable-prefix count. The effective profile is bound to the exact workspace/root/path context reviewed by the operator and may not widen egress, credential environment, timeout, or output-byte policy. Arbitrary executable plus arbitrary argv remains denied. - First Sensorium Virt executor.
fixture-copy.v1is a managed-copy executor, not a process sandbox. It copies a bounded symlink-free source root under the Workbench data directory, permits approved writes only to the managed copy, supports explicit bounded artifact export, and deletes only the managed copy on operator-confirmed teardown. PTY stays unavailable until a backend provides process isolation. - Product tool-request lineage. Agent, Corpus, and Room use
sensorium-workbench-tool-request.v1as an optional request profile ofsensorium.directive.invoke, not as a direct connector route. The host verifies the admitted effect proposal, active Corpus round, or current execution-derived answer-room membership before stamping lineage and passing the ordinary directive to Sensorium Core. One Agent effect proposal binds to onedirective/idwith replay of that same directive allowed. - Operational impact belongs to the exact environment. An adapter may define
a default
sensorium-operational-context.v1, but each Workbench environment pins its candidate class. Host policy may raise it, never lower it, and every derived P082/P083 publication inherits the resulting value and source generation. Read-only access does not reduce the class of a production or critical source. Source-side correction uses a reasoned immutable replacement; it is not blocked by the consumer-side monotonicity rule. - Backend properties, not backend names, prove suitability. Process-isolated
allocation requires a host-attested backend capability descriptor matched
conjunctively against a normalized environment requirement. Missing or
unverified isolation, fidelity, transport, device, network, host-share, or
resource-enforcement properties fail closed. The selected plan and image are
digest-bound to idempotency and recovery. Operator configuration pins the
required properties and registries, not fixture-generated image or capability
refs whose values are content-derived. Workbench verifies that the returned
backend/idequals the selected executor; exact capability, variant, and image refs/digests remain host-derived evidence bound by the normalized plan. - Reference full-system backend sequence.
vfkit-system.v1onmacos-vz-arm64.v1is the first developer reference and first implementation slice.cloud-hypervisor-system.v1onlinux-kvm-x86_64.v1is the first Linux deployment profile.firecracker-system.v1follows after the guest protocol and image manifest stabilize as the smaller-device hardened Linux profile. This ordering serves the GNU/Linux configuration proof and is not a universal VMM security ranking. - VMM lifecycle and guest mechanics are separate ports.
EnvironmentBackendowns allocate/start/inspect/drain/teardown/recover mechanics.GuestWorkbenchChannelowns bounded process, PTY, file, patch, export, quiesce, and shutdown mechanics over one shared guest protocol. SSH, a network interface, and host filesystem sharing are not Workbench semantics. Each backend advertises the exact supported lifecycle subset. The processlessfixture-copy.v1allocation reachesreadyatomically and therefore does not advertise a separatestart; itsrecoversupport is the host-owned reconciliation sweep, not caller-selected resurrection of one environment. - Rust owns validation and host authority; Python owns connector mechanics.
A pure
sensorium-virt-corevalidates capabilities and plans. A daemon-owned host broker allocates storage and platform resources, launches and reconciles VMMs, and issues exact control handles. The Python Workbench adapter maps normalized plans to bounded broker requests and guest-channel RPC without a validation fallback, VMM administrative socket, or ambient host authority. - Guest control uses a bounded virtio-vsock agent. The reference image runs
orbiplex-workbench-guestwithout IP or SSH. Every boot uses a fresh nonce; handshake and operations bind environment, source generation, plan/image digests, sequence, deadlines, byte/chunk caps, and payload digests. The guest owns no policy and all returned state remains untrusted. - Default VM posture is no-device network and no host sharing. The initial vfkit and Cloud Hypervisor profiles attach only block, vsock, entropy, and bounded diagnostic serial devices. vfkit maps guest AF_VSOCK to one broker- allocated host Unix socket. OCI may distribute pinned image artifacts but does not own lifecycle. Isolated networking is a later, separately evidenced platform profile.
- Recovery v1 does not use memory snapshots. Startup reconciliation binds
exact process/socket/storage identities, boot nonce, plan/image digests, and
source generation. It recovers only an exact live match; partial or unknown
resources are quarantined and torn down. Memory snapshots and live migration
remain excluded until freshness and authority semantics receive a separate
contract. A
hardware-vmrecord inreadyordrainingmust carry process, control-socket, and boot-nonce identity; a processless fixture record omits those fields.recorded-atis validated evidence, not an ordering authority: lifecycle transitions and exact generation/resource identities establish freshness even when a host wall clock moves backwards. - Operational context is part of the normalized VM plan. The host resolves
the exact P082 context before allocation and binds the candidate digest,
effective value, and policy ref into the plan digest. Non-
nonenetworking or non-denied host sharing has a minimumtestfloor, then inherits any higher reachable/shared-resource class. Missing target context denies allocation. Every guest observation and actuation interface inherits the resulting context and source generation without backend or carrier reinterpretation. The reference full-system configuration proof istest; a contained offline disposable VM may remainexperimental, because isolation class and operational impact are orthogonal. The candidate digest binds the pre-policy candidate and therefore intentionally need not equal the digest of the effective context after a floor or attached-resource raise. The current Workbench default remainstest; selectingresearchorexperimentalfor a contained offline environment is an explicit operator decision, not an inferred downgrade. - Logical image equivalence requires comparable provenance. Backend variants share one logical image ref only when the manifest proves identical canonical userspace/rootfs, SBOM, build provenance, guest-agent binary, and guest-protocol/ schema-set digests. Kernel, initrd, firmware, disk layout, and boot artifact identities remain variant-specific and independently conformance-tested.
- Backend capability semantics use closed versioned vocabularies. Semantic
dimensions in
sensorium-virt-backend-capabilities.v1are enums and bounded enum sets with no additional properties. Backend and platform identities resolve through host registries. New values require a schema/registry revision and evidence; policy cannot bless an unknown string as equivalent. - Diagnostic serial is an untrusted output artifact. It is output-only and bounded, absent from ordinary content logs, and never rendered raw. Explicit captures inherit environment classification and operational context, carry digest/truncation metadata, pass configured redaction, and are sanitized against ANSI and other control-sequence injection at the operator presentation boundary.
- The standalone Sensorium Virt companion is an explicit development path.
virt_host.standalone_companion_enabledis a literal boolean, defaults to false, and may be enabled only for local development or conformance. A missing or ill-typed value cannot enable it. Supervised channel mode never falls back to the companion when the daemon runtime orsensorium.virt.hostcapability is absent; the environment refuses admission instead. Both the daemon and companion boundaries expose only a bounded typed code plus a stable public message. Raw host paths, subprocess stderr, internal exception text, and capability failure details remain host-local diagnostics. - Disabling a VMM profile preserves only terminal cleanup authority. A
literal
vfkit.enabled = falsedenies allocate, start, recover, inspect, and drain. When the complete operator-pinned profile remains available, the daemon may load it only forenvironment.teardownandhost.reconcile; this permits bounded resource removal without silently retaining the ordinary lifecycle. A missingenabledfield is reported as not configured, not as an explicit operator disable.
Next Actions And Implementation Tracker¶
Status legend: [ ] not started · [~] in progress · [x] done (with code
evidence) · [!] blocked/needs decision.
Phase 0 - Contract Freeze¶
- [x] Decide whether first implementation is a separate Workbench connector or an optional capability group inside Sensorium OS. Decision: separate supervised Workbench connector.
- [x] Promote the host-owned interaction broker into a separate solution before
implementation exposes a cross-process runtime surface. Solution 035 now
defines Interaction Broker as a horizontal host primitive; the initial unwired
Rust foundation exists in
node/interaction-broker-core. - [x] Define the shared actuation core boundary consumed by Sensorium OS and
Workbench.
node/sensorium-actuation-coreowns the Rust reference rules and golden vectors. Workbench invokes its bounded companion-process contract for path and command-profile admission; Python Sensorium OS remains conformance- bound without sharing Workbench process lifecycle. - [x] Define
sensorium-workbench-environment.v1. - [x] Define terminal session/command/raw-input/event/snapshot schemas. The accepted terminal observation model is a bounded viewport snapshot with cursor and backlog digest/ref.
- [x] Define watch/wait/probe schemas, status values, cursor rules, and timeout
semantics. The initial host-owned watch/wait/probe contract lives in
node/interaction-broker-core, including bounded caps, deadlines, correlation ids, no-progress vocabulary, deferred-operation projection, and source-provider validation for persistedterminal.session/ref -> command/idbindings, plus published JSON Schemas/examples. - [x] Require
schemaandschema/von every top-level Workbench schema while preserving embeddedclassification.v1as schema-only. - [x] Assign Phase 0 schema ownership and publish JSON Schema files plus positive/negative examples before exposing any corresponding cross-process connector route.
- [x] Define file snapshot/read and patch apply schemas. Patch apply supports both unified diff and structured edit operations.
- [x] Define operator-visible status fields and audit outcome shape.
- [x] Define the Workbench/Interaction Broker storage contract and startup recovery
sweep. Stores must use explicit migrations, WAL-oriented SQLite pragmas,
busy_timeout, foreign keys where applicable, idempotency keys, and metadata-only recovery facts; restart recovery must kill or quarantine orphan PTY/child processes and temp roots before new requests are admitted. - [x] Define command profile fields and normalized argv digest rules. The
initial unwired contract lives in
node/sensorium-actuation-core, including argv-as-data validation, environment policy, timeout/output caps, workspace root policy, default-deny workspace roots, empty-prefix-as-no-variable-argv, host assignment or preservation of validcommand/id, explicit empty environment defaults, canonical JSON argv digest, and published schema/examples. - [x] Define
correlation/idthreading across directive, events, wait outcome, artifacts, and next directive. - [x] Define async wait status as
deferred-operation-status.v1with Workbench wait outcome as the result projection, not as a parallel status model.node/interaction-broker-corecontains the conversion helper and consumes the shared deferred-operation id validator. Wait outcomes are bounded by host serialized byte/count caps before projection. The daemon broker registers long waits in the host deferred-operation registry and projects their terminal outcomes through the canonical status contract. - [x] Decide MVP policy for raw PTY input. Decision: operator-only in MVP.
- [x] Decide MVP wait conditions and no-progress vocabulary. MVP waits cover process
exit, stdout/stderr pattern, file exists/changes, and timeout;
maybe_hungis diagnostic only. - [x] Define the adversarial actuator test matrix as a required acceptance
suite. The matrix is now specified as a refusal-first release gate and must be
encoded as
sensorium-actuation-coregolden vectors plus Python connector conformance tests before write/PTY runtime surfaces are enabled. Published relative-path and command-profile golden vectors are published and consumed by Rust and the Python Workbench connector tests; they reject traversal, embedded current-directory components, trailing slash forms, backslash separators, missing fixed argv prefixes, disallowed executables, and variable argv atoms outside explicit allowlisted prefixes. - [x] Enforce the Phase Release Gates before Phase 1+ runtime work: frozen schemas for exposed surfaces, registered capabilities, documented storage/recovery contract, and executable refusal-first golden vectors for the relevant effect classes.
- [x] Bind Python Workbench decisions to
sensorium-actuation-corethrough a stable process boundary. The required bounded companion-process bridge owns relative-path and command-profile decisions, and the connector fails closed when the bridge is absent, unavailable, times out, or returns a malformed response. Development and test profiles do not enable a Python fallback.
Phase 1 - Local Workbench Connector¶
- [x] Add a supervised local Workbench connector module. Node now ships the
opt-in
middleware-modules/sensorium-workbenchPython connector with/healthz,/readyz,/shutdownz,/v1/middleware/init, status/config, factory config, and daemon factory/inventory coverage. It usesseed_config: falseand remains disabled until an operator configures it. - [x] Consume the shared actuation core instead of reimplementing path, command-profile, allowlist, classification, and argv rules. The connector calls the required Rust companion process for relative-path and command- profile decisions and is tested against shared golden vectors plus traversal, root-self, symlink-traversal refusal, oversized reads, dangerous env stripping, command-profile denial, bridge timeout/unavailability, and malformed response refusal.
- [x] Implement host-local allowlisted workspace environment. The connector
exposes configured
workspace_rootsassensorium-workbench-environment.v1; missing, unavailable, relative, duplicate, empty, or filesystem-root workspace roots make/readyzfail closed with typed diagnostics. - [x] Implement terminal session create/commands/events/resize/signal/close.
The opt-in Python Workbench connector now creates bounded terminal sessions,
spawns structured argv commands through a PTY without shell interpolation,
admits variable arguments only through explicit
allowed_argv_prefixes, hard-denies dangerous environment override keys, records terminal events in SQLite, exposes event cursors, and supports resize/signal/close under explicit terminal grants. Factory config keeps the runtime disabled until an operator setsterminal_enabled: trueand provides command profiles. - [x] Enforce PTY session, reader-task, input queue, and event buffer caps with
explicit overload/refusal outcomes. Laptop defaults remain
2sessions,4reader tasks, queue depth256, and event buffer1000; the connector also caps command timeout and output bytes. - [x] Implement watch cursors for terminal and generalized source events. The connector exposes bounded synthetic/local event cursors for environment/read/probe events and per-session terminal event cursors; the host broker adds stable snapshot cursors for file-tree, Artifact Delivery, approval/consent, Memarium-query, and dynamically registered sources. Operation outcomes remain in the canonical deferred-operation status/wait path instead of introducing a second cursor-bearing lifecycle model.
- [x] Implement short bounded waits for command done, terminal quiescence,
environment ready, file exists, and artifact present. The connector now has a
bounded wait path over probe conditions for each MVP condition. Short waits run
synchronously up to
sync_wait_max_ms; explicit async waits returndeferred-operation.v1and project throughdeferred-operation-status.v1. - [x] Implement active probes for process liveness, environment readiness, file existence/digest, and artifact presence. Environment readiness, file existence/digest, process-alive, terminal-command-done, terminal-quiescent, terminal-no-progress, and artifact-present probes are implemented.
- [x] Keep raw PTY input disabled or operator-only until an explicit policy is accepted. Raw PTY input is implemented only as an operator-confirmed grant path; model-driven raw input remains denied.
- [x] Implement TTL, idle timeout, byte caps, process cleanup, and refusal
diagnostics. Request body caps, file read byte caps, terminal command timeout,
command output byte caps, session caps, process termination on close/timeout,
startup orphan process signaling, event payload caps, SQLite retention cleanup,
typed refusal diagnostics, and opt-in
terminal_idle_timeout_msidle cleanup for open non-running sessions on terminal admission paths exist./v1/statusremains a read-only projection and does not close sessions. By policy, running commands are governed bycommand_timeout_ms, explicit close, or operator signal rather than an idle sweep. - [x] Implement file snapshot and bounded file read. Snapshot lists symlinks as metadata without following them; reads refuse symlink traversal and files over the host read cap.
- [x] Implement patch apply from artifact ref with digest/provenance. Patch
apply is now an opt-in artifact-backed path behind
sensorium.workbench.patchplus operator confirmation. It verifies artifact digest and size, supports structured create/replace/append plus a narrow single-file unified-diff path, refuses deletes by default, plans structured edits before applying them, rolls back previously applied structured writes on later write failure, records metadata-only outcomes, and uses the same workspace containment and symlink checks as reads. - [x] Use Bounded Deferred Operations for environment setup or command runs that
outlive one HTTP request. The current terminal command endpoint returns
202 acceptedand exposes event/wait polling. Async waits now return the canonicaldeferred-operation.v1/deferred-operation-status.v1shapes, require an explicit wait grant for status reads, de-duplicate byidempotency/key, mark interrupted pending/running wait operations as failed with retry diagnostics on startup, and mark previously starting/running terminal commands plus failed terminal-command spawn attempts as failed for bounded post-restart/idempotent replay. Terminal command runs invoked through the daemon host capability surface now register daemon-ownedsensorium-workbench.terminal-commandBounded Deferred Operations and poll command state through the host Interaction Broker terminal provider. Daemon cancel for those command BDOs now calls the Workbenchsensorium.workbench.terminal.command.cancelaction with a host-owned operator-confirmed grant, maps the connector transition throughcancel_requested/signaled/terminated/cancel_failed, and projects terminated commands as canonical BDOcancelledstatus. Terminalcommand.doneevents now carrysignal_originso timeout-drivenSIGTERM, operator cancel, and ordinary process exit remain distinguishable in the event stream. - [x] Run the adversarial actuator test matrix before enabling write or PTY
features by default. The executable conformance and acceptance suites cover traversal, root self,
symlink traversal, oversized files, grant-required mediated read, command
profile denial including variable argv beyond a fixed prefix, dangerous env
override stripping, credential-like env override refusal before command start,
request/profile egress refusal, operator-only raw input denial, retired
session refs, residual-child startup recovery status diagnostics, and a PTY
happy path. It now also covers artifact digest mismatch, terminal capture
to artifact, terminal-capture artifact-write grant refusal, delete-forbidden
patch apply, successful structured patch apply, structured patch rollback on
partial write failure, connector-local deferred wait projection, operation
status grant refusal, connector idempotency-key refusal/conflict, interrupted
operation recovery, interrupted terminal-command recovery, failed-spawn
terminal-command replay, TTL cleanup for replay records, idempotent replay for
terminal command/cancel/capture/artifact/patch effects, an executable PTY story
smoke, a Python Workbench actuation conformance runner against shared golden
vectors, and the daemon rule that Inquirium cannot directly invoke Sensorium
connectors. It now also covers the
fixture-virtual-workspacemanaged-copy executor: source-copy caps and symlink refusal, approved patching only in the copy, bounded export, source immutability, persisted lifecycle, idempotent teardown, and PTY refusal without process isolation.
Phase 2 - Sensorium Integration¶
- [x] Add Sensorium Core capability routing for Workbench directives. The
connector exposes
/v1/sensorium/connector/invokeand Workbench action ids for Sensorium Core mediated routing; Sensorium Core already dispatches allowlisted connector directives with directive metadata and idempotency. - [x] Route cross-source waits through the host interaction broker rather than
making Sensorium Core own AD, Memarium, approval, or deferred-operation joins.
The daemon broker now owns grant-context admission for JSON-e/module
wait/watch/probe calls through daemon-issued host-local HMAC grant material
requested by
bindings.host_grant_requests, keeps deferred-operationOperationDonewaits host-owned, and wires live Workbench file-tree plus terminal providers for file probes, file waits, file-tree watch batches, terminal liveness/progress probes, terminal waits, and terminal watch batches. Dynamic non-Workbench provider registration/status APIs now exist with bounded observed-state joins for artifact, environment, approval, and Memarium-query providers, includingapproval-stateandmemarium-query-statewait conditions. Domain-native Artifact Delivery, approval/consent, and Memarium-query providers now expose bounded snapshots and stable watch cursors; other domains join through dynamic registration. - [x] Add grant and policy checks for terminal command, terminal raw input,
file snapshot, file read, and patch apply. The connector enforces explicit
grant envelopes for mediated file/probe/watch/wait actions and terminal
actions; raw input, resize, and signal additionally require operator
confirmation; terminal capture requires both terminal-session and
artifact-write grants; operation status reads require an explicit wait grant;
and daemon broker dispatch now requires JSON-e/module callers to request the
relevant broker grant in
bindings.host_grant_requests, then admits the call only after daemon-issued host-local HMAC grant material is minted and verified. - [x] Extract Workbench grant/autonomy policy into the
authorization-policy-as-data sidecar.
capability-authorization-policy.v1now carries required grants, caller posture, approval mode, autonomy floor, and COI policy for the P071 Workbench and Interaction Broker capability ids; P072 Phase 4 is marked landed against this contract. - [x] Record directive outcomes and metadata-only traces. Terminal runtime now records sessions, commands, events, terminal captures, local artifacts, connector-local deferred waits, patch applications, idempotency replay records with bounded replay TTLs, startup recovery diagnostics, lifecycle diagnostics, and metadata-only outcomes durably in connector SQLite or bounded in-process operator status. Host broker audit and explicit artifact handoff audit are implemented. Session refs are retired after first use to keep the audit trail unambiguous.
- [x] Add operator status/control surfaces for active sessions and sandboxes.
/v1/statusreports terminal enablement, PTY caps, active session count, session summaries, startup recovery diagnostics, lifecycle diagnostics, and idle-closed session diagnostics when admission paths sweep sessions under configuredterminal_idle_timeout_ms; the status endpoint itself stays read-only. Session close and managed virtual-environment teardown are explicit control surfaces. - [x] Expose active waits, watches, deadlines, and suspected no-progress states in operator status. Event cursors, command status, connector-local active wait count/status, no-progress probe diagnostics, host-broker status/providers/ resource read APIs, provider health, ownership, recent resources, and remediation paths are exposed in node-ui.
- [x] Link captured outputs through Artifact Delivery or Memarium only under
explicit classification and retention policy. Terminal capture now writes a
bounded local artifact descriptor with classification and provenance. The
daemon verifies bytes and descriptor digest/size before explicit idempotent
Artifact Delivery resolver and/or metadata-only Memarium handoff.
Handoff replay binds
idempotency/keyto both the normalized request andcorrelation/id, preventing retries from being attributed to another trace.
Phase 3 - Inquirium/JSON-e Flow Integration¶
- [x] Add JSON-e Flow example: inspect terminal output through bounded snapshot.
Implemented under
node/middleware-runtime/fixtures/json-e-flow/sensorium-workbench/. - [x] Add JSON-e Flow example: model proposes command, host validates, Workbench executes.
- [x] Add JSON-e Flow example: wait for a Workbench condition without private polling in the flow step.
- [x] Add Inquirium assistant-channel guidance for Workbench-backed tool use. The Workbench README and JSON-e Flow examples document the non-authoritative Inquirium proposal path: model output becomes intent, while Sensorium grants and Workbench execute.
- [x] Add negative tests proving Inquirium cannot directly invoke Workbench
without grants. The daemon dispatch regression now explicitly asserts that
inquirium-corecannot dispatchsensorium.connector.invoke; onlysensorium-coremay reach connector-local invoke. - [x] Add story-level Workbench PTY acceptance smoke. Implemented as
node:tools/acceptance/workbench-pty-story.py; it creates a terminal session, runs allowlisted argv through the PTY, waits for command completion, reads bounded terminal events, captures them to an artifact, replays idempotent command/capture calls, and checks fail-closed command-profile and raw-input refusal paths. - [x] Add shared Workbench actuation conformance runner. Implemented as
node:tools/conformance/workbench_actuation_conformance.py; it validates the Python connector against shared relative-path and command-profile golden vectors plus runtime refusal invariants for command profile, no-egress, and credential-env denial. P083-010 extends it with a real interactive shell PTY, two fenced Sensorium controller authority shapes, resize/input markers, signal, and bounded process completion. - [x] Add the shared Agent/Corpus/Room Workbench tool-request boundary.
sensorium-workbench-tool-request.v1wraps an ordinarysensorium.directive.invokerequest. The daemon verifies Agent proposal and parameter digest, active Corpus round ownership, or current execution-derived answer-room membership, stamps host-owned lineage, and then uses Sensorium Core. It never exposes a direct Workbench connector route to those products.
Phase 3A - Host-Owned Operator Consent For Allowlist Deltas¶
- [x] Define
operator-consent-coreas a pure host-owned contract layer. It should model consent requests, operation descriptors, selectable scope options, deduplication keys, TTLs, fail-closed timeout defaults, decision statuses (pending,granted,denied,expired,revoked), and the distinction betweenoperator_confirmedauthority and ordinaryuser_acknowledgedvisibility. It should also define theoperator-consent-decision.v1payload shape and the mapping from P066 operator-question lifecycle states to consent decision states. It must defineapproval/refasapproval:consent:<delta/digest>, e.g.approval:consent:sha256:<base64url>. - [x] Add a daemon-owned consent registry and audit ledger under the node
data-dir. The natural key should include capability id, source component,
operation digest, workspace/root ref when present, proposed scope, and
requester. The registry must support idempotent request replay, list, detail,
revoke, expiry sweep, duplicate suppression, and redacted audit export.
Revocation is authorized by an authenticated active node-operator runtime
session bound to an active
node-operator-binding.v1; it does not require a fresh detached operator signature in the MVP. Redacted export must omit secret material and raw environment values, and should prefer digests plus redacted summaries for argv, parameters, and action descriptors. - [x] Reuse
inquirium.operator-question.request.v1and durable notifications for the prompt/answer surface. The consent layer should build a typed operator question withrecipient/class = operator, registered widget kindsingle-choice, a fail-closeddefault/on-timeout, and a response target owned by the daemon. No Sensorium adapter should create its own notification action handler. - [x] Reuse the P066 notification projection and answer routing
(
assistant-interaction-notification-projectionand action targetinquirium.operator-question.respond) instead of adding another notification handler. The consent answer handler should validate that the submitting runtime-auth session is bound to an activenode-operator-binding.v1withnode-primary-operatorand that the requested durable grant passes the host grantability policy/capability gate, then translate the selected option into anoperator-consent-decisionrecord without letting the adapter mutate policy directly. The implemented exact-argv path performs active binding validation at answer time and fails closed for durable scopes whose capability is not grantable by host capability authorization policy. - [x] Define Workbench consent scope choices. The supported options are
deny,allow-once,remember-exact-argv, andremember-argv-prefix.remember-executable-any-argsis a high-risk optional policy extension and must remain disabled unless an explicit host policy/capability gate enables it; the gate must be registered before runtime implementation and the option must be hidden when the gate is absent.remember-argv-prefixhas host-policy caps for maximum fixed prefix length and maximum variable-prefix entries. The runtime admits deny, allow-once, exact argv, and workspace-bound bounded prefixes. It does not expose arbitrary-executable consent. - [x] Implement the Workbench sidecar projection. A granted durable decision
should append a command-profile delta scoped by workspace/root, cwd policy,
argv exact/prefix data, allowed variable prefixes, environment policy,
egress policy, timeout/output caps, approval ref, operator ref, expiry, and
revocation ref. The projection must not raise safety caps or loosen egress,
credential, workspace, timeout, or byte limits beyond the main policy.
Its approval digest must cover capability id, operation digest,
workspace/root refs, proposed argv scope, and safety caps, not just argv text.
The reviewed Workbench consent descriptor is published as
sensorium-workbench.consent-descriptor.v1. The implemented projection supports exact argv and bounded workspace/root/path-bound argv prefixes, validates command-profile sidecar entry schema ids, rejects inline decisions whose descriptor schema is notsensorium-workbench.consent-descriptor.v1, and refreshes the sidecar through a bounded TTL. The effective daemon projection filters entries whoseoperator/refno longer points to an active localnode-operator-binding.v1and reportsconsent-operator-binding-inactive, filters expired durable consent and reportsconsent-expired, filters capabilities no longer grantable for durable consent and reportsconsent-capability-not-grantable, and leaves those diagnostics visible to the Workbench connector. - [x] Define the Sensorium OS action-catalog sidecar projection. A granted
Sensorium OS decision should materialize a catalog delta shaped like P048
action declarations: action class, executable or script root, argv shape,
parameter schema, limits, result contract,
result_pointer_fields, sensitivity, approval ref, operator ref, expiry, and revocation ref. The consent descriptor should be promoted to its own schema rather than an untyped inline blob inside the operator-question request. The descriptor schema is published. The implemented daemon projection emitssensorium-os.action-catalog-sidecar.v1, publishes the binding/delta/sidecar schemas, writes the sidecar to the Sensorium OS middleware config tree, reuses the same effective durable filters as Workbench, and the connector loads append-only non-overriding deltas before running its existing action-catalog validator. - [x] Add a shared sidecar merge primitive for adapter config deltas. It
lives beside the existing path/config utility strata, supports append-only
allowlist deltas first, reports merge provenance, and requires schema
validation after
main config + sidecaris composed. Avoid generic deep-override semantics for security-sensitive caps. Sidecar entries whoseoperator/refpoints to a revoked or expired node-operator binding must be inactive in the effective projection.node:config-sidecar-corenow owns the append-only provenance-preserving merge and conflict semantics used by the Workbench and Sensorium OS projections; both still validate the composed adapter-specific schema before activation. - [x] Add operator UI/API surfaces for consent visibility and revocation:
pending requests, answered decisions, durable sidecar entries, expiry,
selected scope, operation digest, source component, operator ref, issued/at,
expires/at, revocation/ref, delta/digest, and revoke/deny actions. Revocation
uses
POST /v1/operator-consents/{approval_ref}/revoke, not the operator-question answer endpoint. The UI should make it clear which entries are one-shot, durable, expired, or revoked. The daemon API and dedicated node-ui consent screen expose this state and revoke action. - [x] Add integration tests and fixtures. P066-owned primitives cover request deduplication, timeout fail-closed, widget contract validation, and duplicate answer replay metadata. P071-owned tests should cover deny, allow-once without sidecar mutation, remember-exact argv, remember-prefix, active node-operator-binding enforcement, participant-only denial of consent, sidecar merge validation, stale/inactive operator binding diagnostics, revocation removal from the effective projection, and refusal of attempts to loosen safety caps. Current coverage includes core digest/timeout validation, registry request/answer/replay/projection behavior, semantic duplicate request replay after deny/grant/revoke, Workbench consent denial, exact-decision admission, consent-disabled denial, operator-read endpoint module-caller denial, active-binding revoke authority, expired durable projection filtering, sidecar schema validation, dynamic sidecar refresh, imported sidecar diagnostics, prefix workspace/root/path binding, shared merge conflicts/provenance, and sidecar cap-refusal tests.
Phase 4 - Virtualized Backends¶
- [x] Define the first
Sensorium Virtbackend contract for the same environment, file, patch, artifact export, lifecycle, and teardown abstractions. The synchronized environment/export/result schemas preserve the boundary for later process-isolated executors. - [x] Implement the first managed virtual executor.
fixture-copy.v1copies a bounded symlink-free source tree under the Workbench data directory and permits approved patching only against that copy. It is disposable but is not described as a process sandbox; PTY stays unavailable. - [x] Freeze process-isolated backend admission as a conjunction of host-attested
properties rather than a backend-name allowlist. The selected reference sequence
is
vfkit-system.v1onmacos-vz-arm64.v1, thencloud-hypervisor-system.v1onlinux-kvm-x86_64.v1, followed by a separately hardened Firecracker profile. - [x] Publish
sensorium-virt-backend-capabilities.v1,sensorium-virt-environment-plan.v1,sensorium-virt-image-manifest.v1,sensorium-virt-recovery-record.v1,sensorium-virt-guest-frame.v1, and the closed internalsensorium-virt.host.request.v1envelope with positive and refusal fixtures. Capability dimensions must use the closed V1 vocabularies above and refuse unknown enum values and unregistered backend or platform refs. The normalized plan must bind the exact P082 operational context, its candidate digest, policy ref, selected network/host-share floor, and attached- resource context. The image manifest must prove logical-variant equivalence from common userspace, SBOM, provenance, guest-agent, and protocol/schema-set digests. The canonical schemas, positive examples, refusal fixtures, Node protocol mirrors, and schema-gate mappings are present. - [x] Evolve the environment projection to carry only exact refs/digests from those host-owned contracts rather than backend claims. The fixture projection now carries the host-returned plan, capabilities, image-variant, generation, and recovery refs/digests; the same metadata is persisted in the Workbench store.
- [x] Implement
sensorium-virt-corecapability/plan/image/lifecycle/recovery and guest-frame validation plus a bounded fail-closed companion surface for the Python adapter. The pure Rust crate covers all P082 impact classes includingresearch, rejects duplicate set entries, unregistered backend/platform refs, mismatched canonical digests, property or image-variant mismatches, digest-valid but semantically unbounded plans, illegal lifecycle transitions, stale recovery and guest bindings, malformed recovery process/ control-socket identity or timestamps, and dishonest payload length/digest declarations. - [x] Implement the first daemon-owned host-broker slice for exact fixture working-
storage allocation, authoritative startup enumeration, contradictory/orphaned
state quarantine, content-bound idempotency, generation supersession, inspect,
drain, and deterministic teardown. In supervised operation
fixture-copy.v1reaches this authority through the internal, non-passportablesensorium.virt.hostchannel capability, restricted to thesensorium-workbenchmodule. The daemon selects the state root and admitsfixture.prepareonly when source path, workspace/root refs, operational context, policy ref, and copy limits match layered operator configuration. The boundedsensorium-virt.host.request.v1companion remains only for local development and conformance, requires explicit literal-booleanvirt_host.standalone_companion_enabled = true, and defaults to disabled; an ill-typed value is a configuration error and remains disabled. Supervised channel mode never falls back to it when daemon admission is unavailable. Mutations are serialized by a broker lock shared across daemon and companion processes; tree, state, and configuration directory enumeration is capped before materialization. Python no longer creates or removes managed environment trees and receives no arbitrary process, host-path, network-device, or VMM-admin operation. Both the daemon admission path and the standalone companion validate the closed host request through Node schema-gate. Reconciliation returns full aggregate counts plus at most 64 structured diagnostics with opaque record/resource refs and an explicit truncation marker; host refusal envelopes and Workbench errors use allowlisted public messages, so raw host paths, subprocess diagnostics, capability failure details, and unbounded error strings do not cross into Workbench. The connector also refuses a host plan whosebackend/iddiffers from the configured executor kind. Schema-gate regression coverage removes one required capability dimension and proves that missing properties are refusal, not a wildcard. - [x] Extend the host broker with VMM process launch, API/control socket allocation,
bounded VMM resource-plan projection, boot identity, and platform-specific
recovery for
vfkit-system.v1; keep that authority out of the Python connector. The daemon loads an operator-authored, digest-pinned vfkit profile and admits only the closedvfkit.allocateand lifecycle operations. The broker owns private state, fsync-backed APFS-cloned raw disk and EFI variable store allocation, short private Unix socket paths, CSPRNG boot nonces, exact PID/start-marker and socket-inode identities, with a durable launch intent committed before process creation and process identity persisted before waiting for socket readiness. Startup recovery finds and terminates an exact matching launch that escaped the PID commit, while content-bound replay, generation supersession, cooperative stop, deterministic teardown, orphan detection, and quarantine remain enforced. The vfkit API client exposes a closed typed lifecycle operation set rather than accepting free-form method, endpoint, or body strings. A disabled profile keeps only teardown/reconcile authority as resolved decision 53. The socket root is opened with no-follow directory semantics, permissioned through its descriptor, pinned by device/inode identity, and rechecked before lifecycle use. The feature-gated 18-case process harness includes refusal of the fake VMM without conformance authority, dead-listener, interrupted-launch, boot-nonce freshness, socket-root substitution, and generation-supersession evidence in addition to the original lifecycle cases. The fake VMM binary and non-macOS conformance constructor are absent from normal builds, and the fake binary refuses without the marker emitted only by that constructor. An operator-authored binary digest remains an explicit host trust decision; vendor-only provenance requires package policy or an allowlist rather than heuristic recognition of executable bytes. Host paths and VMM arguments never enter the caller request or response. - [x] Implement and package
orbiplex-workbench-guestwith generation/plan/image/ nonce-bound virtio-vsock handshake, bounded process and PTY control, chunked file/patch/export frames, defense-in-depth guest resource limits, lifecycle inspect, quiesce, and shutdown.sensorium-virt-host::GuestWorkbenchChannelvalidates exact bindings, monotonic sequence, deadlines, outcomes, and transfer metadata. The vfkit broker derives the channel binding from its authoritative live recovery record. A feature-gated local-transport suite runs the actual guest binary and covers the happy path plus stale nonce, replayed sequence, malformed request and transfer admission, exact output and wire bounds, deadline non-extension, partial transfer, and durable exact patch-stage replay after a lost receipt, quiesce refusal, and deterministic shutdown without claiming full-system deployment evidence. Host-channel tests separately cover endpoint replacement, dead listeners, exact maximum response transfer, and oversized response metadata. Readiness is tracked as three distinct facts: guestprotocol implemented; real-binary localconformance proven; full-system vfkitdeployment evidence pending. - [x] Implement the host-lifecycle adapter for
vfkit-system.v1as the first process-isolated backend slice onmacos-vz-arm64.v1: pinned binary, EFI full-system GNU/Linux arm64 image, APFS working-disk clone, private EFI variable store, dedicated vsock-to-UDS control socket, closed block/vsock/rng device set, and no NIC, serial channel, host share, Rosetta, SSH, credential injection, or memory snapshots. The target profile's output-only diagnostic serial remains disabled until retained output has a continuously enforced byte bound; periodic truncation is not such evidence. A separate fake-vfkit process harness exercises the exact command surface and lifecycle without claiming full-system or Apple Virtualization Framework evidence. Real-vfkit boot and guest-channel evidence remain owned by the next item. - [ ] Run vfkit deployment evidence for systemd/PID 1, harmless kernel and mount operations, local package installation, host non-interference, no-secret/no- network posture, P083 two-controller PTY fencing, file/patch/export behavior, resource exhaustion, stale nonce/generation refusal, crash-point recovery, idempotency conflicts, teardown, unknown capability and image-equivalence refusal, operational-context floor/inheritance, serial ANSI/control injection sanitization, explicit-capture classification, and bounded performance measurements. Add the resulting full-system collaborative scenario as an additive Story 012 profile, not a reinterpretation of the completed story.
- [ ] Implement
cloud-hypervisor-system.v1as the first Linux deployment profile after the backend-neutral vfkit slice proves the contracts. Require an explicit raw image, pinned firmware/VMM digest, dedicated unprivileged identity, cgroup v2, host filesystem confinement, closed devices, no default NIC, and the same guest protocol and conformance suite. - [ ] Implement
firecracker-system.v1only after the guest protocol and image manifest stabilize; require the same backend-neutral conformance plus a jailer-equivalent host profile. Keep Incus, crosvm, OCI-to-VM runtimes, Kata, containers, gVisor, and Wasm as separately classified optional backends rather than substitutes for the full-system hardware-VM proof. - [x] Add artifact export and teardown tests, including source immutability, idempotent replay, managed-root containment, and persisted lifecycle state.
- [x] Add local-runtime policy tests for denied egress and denied credential env override access. Broader virtualized-backend policy tests remain tied to the future Sensorium Virt backend contract.
Phase 5 - Sensorium Interface Source Projection¶
- [x] Expose Workbench terminal screen snapshots as a P082
latest-statesource without granting terminal control. - [x] Expose Workbench terminal events as a separate P082
ordered-eventssource with bounded replay and explicit gap semantics. - [x] Prove the collaborative read-only terminal view through the WSS Room adapter, including current Room-plus-interface authority intersection, cursor omission, grant-revocation close, and durable Room survival.
- [x] Keep publication, grants, subscriptions, direct-peer admission, SSE, and Room carrier semantics owned by Proposal 082 / Solution 046 rather than the Workbench connector.
- [x] Add operational-impact defaults and exact environment pinning. Extend the
environment contract and connector configuration with
sensorium-operational-context.v1, require an effective value before publishing Workbench-backed collaborative or remotely invokable interfaces, expose a host-ownedsource/generation-ref, and inherit both into every derived P082/P083 resource. Serialize immutable replacement and old-publication withdrawal on impact change; enforce P082's 512-byte UTF-8 summary cap; and test mixed test/production resources under one adapter, host-only raising, reasonedcritical -> testcorrection,test -> productionreplacement, old-generation and superseded-id refusal, and missing/oversized-value refusal. The environment schema and bundled connector now require exact root- and environment-level context, derive a process-epoch-bound generation from the complete environment projection, pin actuation grants to both environment ref and current generation, and refuse stale authority. Runtime replacement/race tests plus Workbench mixed-context and summary-provenance tests provide the Phase 5 evidence.