opbox

The import.* family (2 verbs). Every verb enters through the one front door: it is capability-checked, permission-checked, scope-checked and audited before it runs (see Security & permissions). Each entry below lists its capability, risk class (which fixes the minimum autonomy level), the minimum caller permission, its availability tier, whether it is idempotent, and any outbound egress.

Commitimport.commit

PropertyValue
Capabilitydata.row.write
Risk classDestructive - autonomy L3
Min. permissionMember
AvailabilityAdmin only (CLI/HTTP; never advertised over MCP)
IdempotentNo
EgressNone - in-box (pure Postgres, no outbound call)

{ tableId, rows: [ { id?, fields } ], mergeWithLocks? }. Commits an import. DELEGATES to row.bulk (INV-1 - NO new bulk engine; the bounded batch + per-row guards + the PII-encrypt-at-the-Fact path all live in the one write path). HUMAN-only: an import is a human act of record (the dispatch records ONE AuditEvent attributed to the HUMAN actor + the human-driven source, not agent/system) - an AGENT/SYSTEM caller is refused fail-closed, so a caged agent cannot drive a regulated bulk import. Regulated cells (an is_pii column) are ENCRYPTED at the verb (INV-7) by the SAME set_fact PII path row.bulk uses - no plaintext regulated cell is ever stored. Partial-failure is reported as the row.bulk result (atomic on the dispatch tx - a hard row error rolls the whole import back, never a half-import).

Call POST /v/import.commit with a JSON body; returns JSON (or { error, code }). Not advertised over MCP (admin-only); reachable via the CLI and HTTP doors.

Previewimport.preview

PropertyValue
Capabilitydata.row.read
Risk classRead - autonomy L0
Min. permissionMember
AvailabilityOn demand (MCP tier 2)
IdempotentYes
EgressNone - in-box (pure Postgres, no outbound call)
Render schemaYes - drives an inline chat artefact and a GUI panel

{ tableId, rows: [ { fields } ], matchKey? }. A DRY-RUN: classifies each input row as create / update / reject against the target table’s schema, with a per-cell coercion result, and writes/computes NOTHING canonical (INV-6 - a preview is a projection, never a write). matchKey (a column key) names the upsert match column: a row whose match value already exists is update, else create. A row that targets a computed column, a missing column, or the lock keyspace is classified reject with the reason. The shape mirrors what import.commit will do, so the human sees the exact outcome first.

Call POST /v/import.preview with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool import.preview.