KB-4277
06 · D30/D31 protection refresh
5 min read Revision 1
dieu44iu_cutd30d31protection
06 · D30/D31 protection refresh
D30 = invariants (no side-effects in forbidden surfaces). D31 = refusal/integrity (CHECK + gate + alias refusals).
D30 — invariants
| id | check | expected | observed |
|---|---|---|---|
| D30.1 | event_outbox count | background growth only since baseline | 135,822 at start of E (baseline = 135,822 at start of mission; no mig 053–origin rows since gate.job_substrate=false) |
| D30.2 | information_unit count | 200 unchanged | 200 |
| D30.3 | iu_vector_sync_point count | 152 unchanged | 152 |
| D30.4 | production_documents present | false | production_documents_present=false |
| D30.5 | pg_cron extension installed | false | pg_cron_installed=false |
| D30.6 | gates safe at exit | substrate=false, heartbeat=true, dlq.replay=false, lease.reaper=false, composer=false, runtime.phase=phase2_governance | all match |
| D30.7 | iu_route_worker_cursor frozen since 2026-05-22 | last_run_at=2026-05-22 11:31:41.928657+00 | match (worker_name=iu_outbound_default) |
| D30.8 | 6-alias MARK/CUT prosrc md5 | 750b06b610f50065f1117961813d9df4 |
match |
D31 — refusal/integrity
| id | surface | input | expected | observed |
|---|---|---|---|---|
| D31.1 | job_queue.payload_safe_check CHECK constraint |
catalog read | refuses 10 keys: body/content/raw/vector/embedding/secret/token/password/ssn/personal_data on payload_json AND metadata AND safe_payload |
confirmed (3 CHECK rows) |
| D31.1 live | fn_job_enqueue(payload_json={body:'leak'}, …) |
refused (gate-off short-circuit) | {refused:true, reason:'queue.job_substrate.enabled=false'} |
confirmed |
| D31.2 | fn_cut_heartbeat_ping('iu_outbound_default','PG_worker','ok','{}') |
refused=true, reason='protected_legacy_silent_passive' |
match | |
| D31.3 | fn_cut_heartbeat_ping('cut_pipeline_test','MOT','ok','{}') |
RAISE 7-vocab violation | executor_kind MOT not in 7-vocab (DOT/Agent/Hermes/Codex/PG_worker/external_worker/future_Kestra_adapter) |
|
| D31.4 | fn_cut_mark_staged_file(…, p_pieces=NULL, …) |
RAISE | p_pieces must be non-empty jsonb array |
|
| D31.5 | fn_cut_mark_staged_file(…, p_pieces='[]', …) |
RAISE | p_pieces must be non-empty jsonb array |
|
| D31.6 | fn_cut_mark_staged_file(…, pieces=[{section_type:'heading'}], …) |
RAISE on content_text first | piece[0].content_text is required (would cause "body required" at CUT) |
|
| D31.7 | fn_cut_cleanup_dry_run(15) then SELECT count(*) FROM cut_request |
count unchanged | pre=1, post=1 (no DELETE side-effect) |
D31 additional — table-level CHECK reads
job_queue:
CHECK (NOT (payload_json ? 'body') AND … 10 keys)
CHECK (NOT (metadata ? 'body') AND … 10 keys)
CHECK (NOT (safe_payload? 'body') AND … 10 keys)
queue_heartbeat:
CHECK (NOT (metadata ? 'body') AND … 10 keys)
CHECK (executor_kind = ANY ['DOT','Agent','Hermes','Codex','PG_worker','external_worker','future_Kestra_adapter'])
CHECK (last_tick_status = ANY ['ok','warn','error'])
CHECK (btrim(executor_name) <> '')
These are unchanged by mig 053. fn_cut_heartbeat_ping enforces the
executor_kind / status vocab at the wrapper level so callers see an
intelligible error before hitting the CHECK row constraint.
Integrity invariants preserved by mig 053
- mig 052 contract intact: 9
fn_cut_*functions still present with same signatures (fn_cut_request_add(text,text,text),fn_cut_request_transition,fn_cut_copy_to_staging,fn_cut_mark_staged_file← REPLACED,fn_cut_verify_mark,fn_cut_apply,fn_cut_verify_cut,fn_cut_complete,fn_cut_request_signal). - Vocab CHECK on
cut_request.status(13-status set) unchanged. cut_request_transitionaudit table append-only — no rows touched.- Approval-gate semantics in
fn_cut_apply/fn_iu_op_cutunchanged (still requiresmark_verifiedstatus; still callsfn_iu_op_cut(p_apply, …)).
Conclusion
D30 8/8 PASS, D31 7/7 PASS (+ 3 CHECK catalog confirmations). Migration 053 is invariant-preserving and refusal-tight.