Sensorium HOWTO¶
This HOWTO is an operational guide for node operators, power users, and middleware developers. It shows how to admit observations, define and invoke finite Sensorium OS actions, use stateful Workbench operations, obtain operator consent, and publish a bounded Sensorium Interface. For shorter conceptual answers, see the Sensorium FAQ.
Responsibility map¶
Sensorium keeps public intent above connector mechanics. A caller never selects a connector or receives its private credentials.
flowchart LR
C["Middleware / Agent / JSON-e Flow"] -->|"host capability"| H["Daemon admission"]
H --> S["Sensorium Core"]
S -->|"private dispatch"| K["Sensorium connector"]
K --> W["External world"]
W -->|"candidate signal"| K
K --> S
S --> O["Observation read model"]
S --> A["Outcome audit"]
O -->|"explicit publication"| I["Sensorium Interfaces"]
I --> R["Authorized local or remote consumer"]
The daemon owns caller authentication, capability admission, provider selection, and common deferred operations. Sensorium Core owns observation admission, the action catalog boundary, directive validation, connector dispatch, and outcomes. A connector owns protocol or operating-system mechanics. Sensorium Interfaces separately owns publication, grants, cursors, leases, classification, and revocation.
Choose the passage before configuring a connector¶
| Need | Passage | Stable public handle |
|---|---|---|
| Submit or query a local signal | Sensorium observation | sensorium.observe.* |
| Perform one bounded catalogued effect | Sensorium directive | sensorium.directive.invoke + action_id |
| Manage files, PTY sessions, patches, or environments | Workbench operation through a directive | sensorium.workbench.* action id |
| Expose a bounded representation to another consumer | Sensorium Interface | exact interface resource and grant |
| Deliver durable or large bytes | Artifact Delivery | artifact envelope and recipient selector |
| Ask a model for advice or structured intent | Inquirium | inquirium.* capability |
Do not collapse these paths. An observation is not a command. A Room carrier is not an interface grant. Model output is not actuation authority. A file reference is not permission to deliver the file.
Call only the public host-capability surface¶
Host capabilities use:
POST /v1/host/capabilities/{capability_id}
A supervised middleware call must carry its daemon-issued module authentication and component identity. Browser and operator calls use their own runtime-authenticated surfaces. The examples below show request bodies only; do not copy an authentication token into configuration, a template, or a trace.
Never call sensorium.connector.invoke directly. It is the private seam by which
Sensorium Core talks to a connector after policy admission.
Configure Sensorium Core policy¶
Sensorium Core is a built-in Rust organ, not an enable/disable middleware process. Its
sensorium_core configuration controls admission policy and bounded local stores:
{
"sensorium_core": {
"allowed_sensitivity_classes": [
"public",
"community",
"private",
"operational-sensitive"
],
"quarantine_sensitivity_classes": ["sensitive-personal"],
"default_observation_ttl_sec": 300,
"default_consumer_scopes": ["sensorium.read.local"],
"max_observations": 50000,
"max_outcomes": 10000,
"max_idempotency_entries": 5000
}
}
Treat sensitivity, TTL, and capacities as policy. Do not enlarge them merely to make a failing connector appear healthy. Validate the complete node profile after changing configuration:
cargo run -p orbiplex-node-daemon -- check-config --data-dir "$DATA_DIR"
Submit an observation candidate¶
A producer submits a candidate, not a completed sensorium-observation.v1. Sensorium
adds the observation id, ingestion time, expiry, admission decision, and any missing
host-owned defaults.
{
"candidate": {
"signal/kind": "com.example.monitor/temperature",
"signal/family": "temperature",
"payload": {"celsius": 41.7},
"confidence": {
"class": "high",
"rationale": "calibrated local sensor"
},
"freshness": {"ttl_sec": 60},
"sensitivity": {"class": "operational-sensitive"},
"source/ref": {
"kind": "device",
"value": "sensor:rack-a"
}
}
}
Send it to sensorium.observe.submit. An allowed class returns status: admitted
with the canonical observation. A quarantined class returns HTTP 202 without placing
the candidate in the ordinary read model. A class with no policy is rejected.
Do not use source/ref as a secret container. Redact or replace a sensitive source
with an opaque local reference before admission.
Query the local observation read model¶
Query the same semantic fields used by the observation:
{
"signal/family": "temperature",
"limit": 20
}
Call sensorium.observe.query for newest-first records. Use
sensorium.observation.get with observation/id for one record and
sensorium.topic.summary for a bounded count by signal/kind or signal/family.
These are local read-model operations. They do not subscribe a remote peer or publish
the data to Agora.
Define a finite Sensorium OS action¶
Use Sensorium OS when the effect is finite, has a stable action id, and can be fully described by an operator-owned catalog entry. The following illustrative entry runs a bundled read-only repository-status script. Replace the path and digest with the exact installed artifact; never use a placeholder digest in an active catalog.
{
"action_id": "example.repo.status",
"class": "allowlisted-script",
"executable": {
"kind": "script",
"path": "repo_status.py",
"interpreter": "python3",
"argv_shape": "stdin"
},
"sha256": "<sha256-hex-of-repo_status.py>",
"parameter_transport": "stdin",
"default_timeout_ms": 3000,
"max_timeout_ms": 10000,
"parameters_schema": {
"type": "object",
"additionalProperties": false,
"required": ["workspace/ref"],
"properties": {
"workspace/ref": {"type": "string", "minLength": 1}
}
},
"limits": {
"stdout_max_bytes": 16384,
"stderr_max_bytes": 4096
},
"cwd": "@script-dir",
"sensitivity_class": "operational-sensitive",
"subject_kind": "repository-status",
"observation_ttl_sec": 60,
"connector_incidental_effects": ["disk-access-timestamp-update"],
"result_contract": {
"signal_kind": "com.example.repo/status-read",
"signal_family": "repository/status",
"result_pointer_fields": ["status", "branch", "changed/count"]
}
}
Place actions under sensorium_os.action_catalog, keep sensorium_os.enabled false
until review, and allowlist the resolved script directory in
sensorium_os.allowed_workdirs. An empty workdir list refuses every action, including
one with cwd: "@script-dir".
Sensorium OS currently executes the implemented C1/C2 finite profiles. Declaring a higher-impact class does not make its required isolation exist: unavailable classes remain fail-closed.
Authorize and inspect the Sensorium OS catalog¶
Enabling the process is not enough. The effective catalog must match an operator-signed authorization sidecar.
- Open
/operator/sensorium-os. - Review the catalog hash, per-action contract, limits, sidecar state, and runtime availability.
- Sign the reported catalog or record an explicit denial.
- Reload the catalog and verify
available_action_idsrather than relying on the informational class list.
The daemon's corresponding operator endpoints are:
POST /v1/operator/sensorium-os/action-catalog/sidecar/sign
POST /v1/operator/sensorium-os/action-catalog/sidecar/deny
Signing uses the operator participant key in the daemon. Sensorium OS verifies the artifact but never unlocks or owns that key. Prefer a signed denial over deleting the sidecar because denial preserves the reason and audit trail.
Invoke a Sensorium action¶
After caller authority, catalog authorization, and connector readiness are all true,
invoke the action through sensorium.directive.invoke:
{
"directive": {
"schema": "sensorium-directive.v1",
"schema/v": 1,
"directive/id": "directive:example-repo-status:001",
"directive/issued_at": "2026-07-21T10:00:00Z",
"issuer": {
"module_id": "example.maintenance-flow"
},
"action_id": "example.repo.status",
"parameters": {
"workspace/ref": "workspace:mail-server"
},
"timing": {
"timeout_ms": 5000,
"mode": "sync"
},
"idempotency/key": "example-repo-status:workspace-mail-server:001",
"correlation/id": "correlation:mail-server-diagnosis:001"
}
}
Use a stable idempotency key for a retry of the same semantic request. Reusing it with different parameters is a conflict, not a second invocation. The result points to the audit outcome and any observations or artifacts admitted from connector output.
Invoke Sensorium from a JSON-e Flow¶
A flow renders the complete directive and calls one literal host capability:
{
"allowed_calls": ["sensorium.directive.invoke"],
"steps": [
{
"kind": "render",
"id": "render_directive",
"as": "directive_request",
"template": {
"directive": {
"schema": "sensorium-directive.v1",
"schema/v": 1,
"directive/id": "${directive_id}",
"directive/issued_at": "${now}",
"issuer": {"module_id": "example.maintenance-flow"},
"action_id": "example.repo.status",
"parameters": {"workspace/ref": "${workspace_ref}"},
"timing": {"timeout_ms": 5000, "mode": "sync"},
"idempotency/key": "${idempotency_key}"
}
}
},
{
"kind": "call",
"id": "invoke_sensorium",
"capability": "sensorium.directive.invoke",
"input": "$.directive_request",
"as": "sensorium_result"
},
{
"kind": "respond",
"id": "respond",
"input": "$.sensorium_result"
}
]
}
This is a fragment of a json_e_flow definition, not a complete middleware config.
The flow's allowed_calls prevents dynamic effect selection; it does not grant the
module permission to invoke Sensorium. Keep capability ids literal and render only the
request body. See the JSON-e and JSON-e Flows
HOWTO for complete definitions and dry-run.
Use deferred action mode deliberately¶
An action must opt into asynchronous execution in its catalog:
{
"action_id": "example.long-running-check",
"execution_mode_support": "either",
"deferred_profile": {
"preferred_retry_after_seconds": 15,
"preferred_max_ttl_seconds": 900
}
}
Set timing.mode to async in the directive. Sensorium returns
deferred-operation.v1; the daemon applies its own stricter retry and TTL policy.
Persist or surface the operation id, then use the common host registry or
sensorium.operation.status. Do not pass the deferred envelope to code expecting the
domain result. Cancellation is available only when the operation exposes a valid
cancel path.
Configure Sensorium Workbench safely¶
Workbench is disabled by default and refuses readiness without explicit workspace roots. Start with read-only file access and keep terminal and patch disabled:
{
"sensorium_workbench": {
"enabled": true,
"workspace_roots": [
{
"workspace/ref": "workspace:mail-server",
"root/ref": "root:configuration",
"path": "/srv/orbiplex-workspaces/mail-server",
"backend": "host-local-workspace"
}
],
"operational_context_default": {
"schema": "sensorium-operational-context.v1",
"schema/v": 1,
"impact/class": "test",
"context/summary": "Disposable mail-server test environment"
},
"terminal_enabled": false,
"patch_enabled": false,
"command_profiles": []
}
}
The root path must be absolute, existing, and not /. Workbench canonicalizes relative
paths below the root and refuses traversal, NUL, root-self file reads, and symlink
escape. host-local-workspace is not process isolation. Use the fixture virtual
backend only for its documented managed-copy semantics; do not describe it as a full
VM.
Read a Workbench file through Sensorium¶
Use the Workbench operation id as the directive's action_id:
{
"directive": {
"schema": "sensorium-directive.v1",
"schema/v": 1,
"directive/id": "directive:workbench-read:001",
"directive/issued_at": "2026-07-21T10:05:00Z",
"issuer": {"module_id": "example.diagnostic-agent"},
"action_id": "sensorium.workbench.file.read",
"parameters": {
"address": {
"schema": "sensorium-relative-path-address.v1",
"schema/v": 1,
"workspace/ref": "workspace:mail-server",
"root/ref": "root:configuration",
"relative/path": "etc/postfix/main.cf"
}
},
"timing": {"timeout_ms": 3000, "mode": "sync"},
"idempotency/key": "workbench-read:main-cf:001"
}
}
The caller needs the public Sensorium invocation authority and the matching
sensorium.workbench.file grant. Knowing the workspace ref or relative path is not
enough.
Enable a bounded terminal profile¶
Only enable the terminal after file-only diagnostics prove insufficient. A compact Workbench config profile can admit exact argv vectors:
{
"terminal_enabled": true,
"command_profiles": [
{
"profile/ref": "command-profile:mail-read-only",
"argv/prefixes": [
["/usr/sbin/postconf", "-n"],
["/usr/bin/systemctl", "status", "postfix", "--no-pager"]
],
"allowed_argv_prefixes": []
}
]
}
An empty allowed_argv_prefixes means no extra argv atoms. It does not mean arbitrary
arguments. Workbench spawns argv data without shell interpolation and refuses
credential-like or process-loader environment keys. Network egress remains denied
unless a separately reviewed contract explicitly permits it.
The ordinary sequence is:
sensorium.workbench.terminal.session.createfor an allowlisted relative address;sensorium.workbench.terminal.commandwithsession/refand structuredargv;sensorium.workbench.terminal.eventswith a bounded cursor and caps;sensorium.workbench.terminal.closewhen the session is no longer needed.
Raw terminal input, resize, signal, command cancel, and patch application are operator-only surfaces. A terminal grant does not imply patch authority. Capturing a terminal representation as an artifact requires both terminal-read and artifact-write authority.
Let a model propose, but not authorize, a command¶
Keep model inference and actuation in separate steps:
goal and bounded terminal evidence
-> Inquirium returns a structured command proposal
-> policy or operator reviews argv
-> JSON-e Flow renders sensorium-directive.v1
-> Sensorium and Workbench apply grants and command profile
-> Interaction Broker waits for a terminal condition
Do not interpolate free-form model text into a shell string. Bind the final reviewed
argv to a command profile. If the workflow belongs to an Agent, Corpus round, or Room,
use sensorium-workbench-tool-request.v1 so the daemon can verify lineage before
performing the ordinary Sensorium admission.
Request and revoke interactive consent¶
When a valid operation is refused only because the current allowlist lacks the exact action or argv shape, the host may create an operator consent request. The operator UI offers the narrowest choices first: allow once, exact argv, bounded argv prefix, or deny. Only a participant with an active node-operator binding can create durable authority.
Inspect active and historical grants at:
/operator/consents
Revocation uses the authenticated operator route and leaves an audit fact. The daemon then regenerates the relevant projection:
Workbench consent -> command-profile sidecar
Sensorium OS consent -> action-catalog sidecar
Sidecars append non-conflicting deltas and remain subordinate to main configuration, capability policy, workspace boundaries, and runtime limits. They are not a second unrestricted configuration file.
Publish a Sensorium Interface only when local access is insufficient¶
First choose one exact source projection, such as a Sensorium observation query or a Workbench terminal screen. Then:
- create an immutable interface publication with classification, source generation,
limits, and
sensorium-operational-context.v1where applicable; - issue a grant for the exact resource and methods;
- read one bounded batch or create a bounded subscription;
- use local host, direct-peer, SSE, or Room WSS only as a carrier;
- revoke the grant or supersede the publication when the source changes.
The source's generation and latest publication determine freshness. A changed source
generation or a superseding publication makes an old publication stale. Consumers
must fail closed rather than continue under an obsolete test context after the same
resource has become production.
For interactive control, use Sensorium Interactive Interfaces (P083), the actuation half of Solution 046, with its separate resource, grant, claim, lease, fencing, invoke, and receipt contracts. Observation authority never implies control authority.
Keep artifacts, delivery, and memory separate¶
Sensorium may return a bounded result, observation refs, and artifact refs. It does not decide that an artifact should be sent to a peer or written into long-term memory.
- Use Artifact Delivery for recipient selection, transport, admission, and receipts.
- Use Memarium for explicit durable facts under its own space policy.
- Use Sensorium Interfaces for bounded live or latest-state access.
- Keep raw terminal data, credentials, private prompts, and connector internals out of audit records.
See the Artifact Delivery HOWTO for the handoff and the Memarium HOWTO for durable recording.
Diagnose failures in authority order¶
Use this order to avoid debugging the wrong layer:
| Layer | Inspect | Typical refusal |
|---|---|---|
| Caller | capability binding, passport, operator session | caller not authorized |
| Sensorium Core | sensorium.health, sensorium.directive.list |
action absent, parameters invalid, timeout too large |
| Catalog/consent | catalog hash, sidecar, /operator/consents |
catalog unsigned, consent expired or revoked |
| Connector | readiness, action availability, workspace and backend | root unavailable, class unsupported, runtime disabled |
| Operation | idempotency record, deferred status, current generation | conflict, expired, stale session |
| Outcome | sensorium.audit.read |
connector failure or timeout |
| Interface | publication, grant, cursor, lease, classification | stale publication, revoked grant, cursor mismatch |
A 200 connector health response does not prove that one action is authorized. An
authorized action does not prove that its backend is available. Preserve these as
separate diagnostics.
Review checklist¶
Before activating a new connector or operation, confirm:
- callers use a stable
action_id, neverconnector_id; - request and result schemas are closed enough for the security boundary;
- parameters contain no shell, raw SQL, credentials, or hidden executable selection;
- workspaces, paths, environment, network, time, bytes, and concurrency are bounded;
- retries use idempotency keys and conflicts are visible;
- operator-only effects require a fresh operator binding or durable reviewed consent;
- deferred work has status, expiry, and explicit cancellation semantics;
- observations and audit facts exclude raw secrets;
- large output becomes a verified artifact reference;
- remote exposure is an explicit Sensorium Interface publication;
- the documented isolation claim matches the backend that is actually deployed;
- refusal tests cover malformed input, missing authority, stale state, replay, and recovery after restart.
Canonical references¶
- Solution 030: Sensorium
- Solution 042: Sensorium Workbench
- Solution 046: Sensorium Interfaces
- Proposal 045: Sensorium Local Enaction Stratum
- Proposal 048: Sensorium OS Connector Action Classes
- Proposal 071: Sensorium Workbench
- Proposal 082: Sensorium Interfaces
- Proposal 083: Sensorium Interactive Interfaces