The cell.* 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.
Lockcell.lock
| Property | Value |
|---|---|
| Capability | data.cell.lock |
| Risk class | Sensitive - autonomy L2 |
| Min. permission | Admin |
| Availability | On demand (MCP tier 2) |
| Idempotent | Yes |
| Egress | None - in-box (pure Postgres, no outbound call) |
The ONLY verb that mutates the typed cell-lock trio (data_fact.locked /
locked_by_id / locked_at - the promoted __lock__* keyspace, gotcha 14). locked=true (default) pins
the cell to its current canonical value (hand-verified); locked=false unpins. ROLE-GATED: a write to
the lock keyspace through any GENERIC verb (cell.set / row.patch / row.bulk) is refused by the
reject_lock_keyspace fence - only this SENSITIVE/L2/ADMIN verb may touch it. HUMAN-only (mirroring
the management.rs HUMAN-only guard): an agent/system caller cannot pin a cell as hand-verified. The
cell must already have a Fact to pin (you cannot pin an empty cell); a computed cell has no Fact (INV-6)
so it cannot be locked.
Input { rowId, key, locked? } (fields ending in ? are optional)
Call POST /v/cell.lock with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool cell.lock.
Setcell.set
| Property | Value |
|---|---|
| Capability | data.cell.write |
| Risk class | Write - autonomy L1 |
| Min. permission | Member |
| Availability | Admin only (CLI/HTTP; never advertised over MCP) |
| Idempotent | No |
| Egress | None - in-box (pure Postgres, no outbound call) |
s the ONE canonical Fact for (row, column-key) - the C7 single source of truth. Upserts on uq_data_fact_row_column (latest write wins). REJECTS a write to a computed column (INV-6) and a prototype-pollution key. (A __lock__ed cell IS overwritable by an explicit cell.set in this skeleton; the lock-honouring path is row.patch - cell.lock is a later beat.)
Input { rowId, key, value } (fields ending in ? are optional)
Call POST /v/cell.set with a JSON body; returns JSON (or { error, code }). Not advertised over MCP (admin-only); reachable via the CLI and HTTP doors.