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
| Property | Value |
|---|---|
| Capability | data.row.write |
| Risk class | Destructive - autonomy L3 |
| Min. permission | Member |
| Availability | Admin only (CLI/HTTP; never advertised over MCP) |
| Idempotent | No |
| Egress | None - 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
| Property | Value |
|---|---|
| Capability | data.row.read |
| Risk class | Read - autonomy L0 |
| Min. permission | Member |
| Availability | On demand (MCP tier 2) |
| Idempotent | Yes |
| Egress | None - in-box (pure Postgres, no outbound call) |
| Render schema | Yes - 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.