OpenBot delivery observation
The OpenBot adapter records a small, verifiable delivery trail for work that starts in SEIF. It is an observation boundary, not model telemetry. OpenBot is local-first and its public project description lists persistent queues, but this integration has no documented Local Scripts/CLI delivery-status polling contract. The bridge therefore keeps the established openbot-cli run <agent> - --json invocation and adds no assumed CLI flags or polling calls. See the upstream OpenBot repository.
What SEIF observes
The local bridge (web/openbot-bridge.mjs) is the source for these receipts. It emits an event only when it directly observes the transition:
| Receipt | Observation |
|---|---|
handoff.fetched | The bridge received a pending hand-off from SEIF. |
openbot.queued | The bridge persisted the local submission intent. |
openbot.delivery.observed | The Local Scripts process was started or is running. |
openbot.delivery.terminal | That local process exited or failed. This is not a statement about model reasoning or work quality. |
gateway.api.observed | The bridge wrote an observed response to a filesystem API request. |
handback.observed | A hand-back file was found, then SEIF accepted or rejected its HTTP submission. |
heartbeat / error | The bridge checked in, or recorded a bounded delivery-stage failure. |
The current bridge tells the agent, rather than the bridge process, to fetch context_url. It does not emit context.fetched or context.available for that action. Those receipt types are reserved for a future bridge that fetches or stages context itself.
A webhook HTTP 200 or 202 records only webhook-accepted: the endpoint accepted the HTTP delivery. It does not prove that OpenBot ran an agent. The same distinction applies to a bridge 202, which only confirms the adapter accepted the local submission state.
SEIF does not receive or infer OpenBot model/provider names, token counts, cost, tool calls, prompts, context contents, model responses, or reasoning. A chat started directly in OpenBot remains outside this boundary.
Idempotency and local durability
Each hand-off has an opaque, stable SHA-256 handoffId and a separate stable submissionKey, both derived from the hand-off token. The token itself never goes in a receipt. Before launching Local Scripts, the bridge atomically records the submission state. A restarted bridge recognizes the same key and does not launch the same hand-off again. A process interrupted after launch but before its terminal observation remains inconclusive rather than being silently replayed.
The bridge stores its ledger and receipt outbox beneath its SEIF application-support directory. Files are atomically replaced with mode 0600; bridge-owned directories use 0700. The receipt queue is capped at 128 pending entries and 512 state-change keys. Network failure retains the original receipt id for retry. The host deduplicates by (project_id, receipt.id).
Host receipt endpoint and status projection
POST /openbot/bridge/<bridge-capability>/receipts authenticates by the bridge capability already present in the bridge URL. It accepts 1–64 receipts per request, rejects unknown fields, validates IDs and states, and binds each hand-off receipt to the project owning that capability. Only minimized fields are accepted:
{
"id": "sha256 receipt id",
"type": "openbot.delivery.observed",
"handoffId": "sha256 hand-off id",
"state": "local-script-running",
"agent": "optional agent identifier",
"messageId": "optional opaque identifier",
"deliveryId": "optional opaque identifier",
"submissionKey": "sha256 submission key",
"requestId": "sha256 API-request digest",
"status": 200,
"size": 123,
"digest": "sha256 optional hand-back digest"
}
It never accepts a hand-off token, prompt, context, response, tool input, hand-back body, or credential. Receipts persist by project and hand-off. GET /api/projects/:id/openbot projects each hand-off's opaque identifiers, last observed state/time, and its recent minimized receipts so the existing connections UI can display a checked state without trusting a client-side claim.
See OpenBot portability for project interchange and HTTP turn observation for the analogous HTTP context evidence boundary.