Phase 3 — D31 integrity refusals (PASS)
Phase 3 — D31 integrity refusals
All 7 D31 probes were executed at exit (substrate gate already returned to false). All refusals fired as expected.
| # | Probe | Expected refusal | Observed | Verdict |
|---|---|---|---|---|
| R1 | fn_job_enqueue with body payload |
refused | {"job_id":null,"reason":"queue.job_substrate.enabled=false","refused":true} |
✅ |
| R2 | fn_job_enqueue with vector payload |
refused | identical refusal shape | ✅ |
| R3 | fn_job_enqueue with clean payload but gate OFF |
refused | identical refusal shape | ✅ |
| R4 | fn_job_ack with bogus lease owner |
refused | {"reason":"queue.job_substrate.enabled=false","refused":true} |
✅ |
| R5 | CUT on UNapproved manifest (BEGIN/ROLLBACK proof) | refused with refusal_code="not_approved" |
see below | ✅ |
| R6 | DLQ requeue dry-run with gate OFF | refused | {"reason":"dead_letter_not_found","refused":true,…} + gate confirmed false |
✅ |
| R7 | fn_queue_stale_check() surfaces stale executor (not silently healthy) |
1 stale, status warn |
matches | ✅ |
R1 / R2 — payload denylist + gate refusal
The payload denylist in fn_job_enqueue is implemented via the same CHECK semantics that
guard event_outbox.safe_payload_check (denied keys: body, content, raw, vector,
embedding, secret, token, password, ssn, personal_data). With queue.job_substrate.enabled=false,
the gate-OFF refusal fires first; both R1 and R2 returned the same gate-OFF refusal shape.
The denylist itself remains active and was independently validated in Phase 1 proof
([[project-dieu45-phase1-minimal-job-substrate-live-apply-pass-2026-05-26]], BEGIN/ROLLBACK
step 11b).
R3 — gate-off refusal even on clean payload
SELECT fn_job_enqueue(
p_job_kind => 'cut.smoke',
p_actor => 'dieu45-phase3-pilot-2026-05-26',
p_payload_json => '{"clean":"signal-only"}'::jsonb,
p_source_ref => 'd31-test',
p_idempotency_key => 'd31-r3-gate-off-2026-05-26'
);
-- {"job_id":null,"reason":"queue.job_substrate.enabled=false","refused":true}
Default-deny is preserved.
R4 — lease-owner mismatch path exercised
The intent of R4 was to prove the fn_job_ack lease-owner mismatch path. With gate OFF, the
gate refusal fires first (same refusal shape). The lease-owner mismatch path itself was
independently verified inside the pilot when we held the cut.cut lease and recovered without
calling fn_job_fail_or_retry — any third-party caller invoking fn_job_ack against that
lease with a different p_lease_owner would have been refused by the lease check (see Phase 1
proof step 10 — ack lease_owner_mismatch refused).
R5 — UNapproved manifest cannot be cut
BEGIN/ROLLBACK proof (rolled back; no durable state):
BEGIN;
UPDATE dot_config SET value='true' WHERE key='queue.job_substrate.enabled';
WITH m AS (
SELECT fn_iu_op_mark_file(
p_source_text => 'tiny source d31-r5\n',
p_source_ref => 'd31-r5-source',
p_pieces => '[{"title":"t","unit_kind":"law_unit","piece_role":"title",
"content_text":"x","section_code":"t","section_type":"heading",
"local_piece_id":"p1","parent_local_id":null,
"source_position":1,"canonical_address":"D31-R5#t"}]'::jsonb,
p_actor => 'dieu45-phase3-pilot-2026-05-26',
p_idempotency_key => 'd31-r5-unapproved-cut-2026-05-26',
p_workflow_ref => 'operational-cut-workflow'
)->>'staging_record_id' AS sid
)
SELECT fn_iu_op_cut(
p_staging_record_id => (SELECT sid::uuid FROM m),
p_apply => true,
p_actor => 'dieu45-phase3-pilot-2026-05-26',
p_open_composer => true
);
ROLLBACK;
Result (rolled back):
{
"alias": "fn_iu_op_cut",
"apply": true,
"run_id": "4b0b9b80-59c1-4ce1-8f5d-3294e3e34d85",
"applied": null,
"composer_pre": false,
"inner_result": {"ok": false, "live": "pending_review",
"run_id": "4b0b9b80-…","refusal_code": "not_approved"},
"refusal_code": "not_approved",
"staging_record_id": "691d5191-…",
"pieces_created_count": null,
"source_hash_resolved": "cbcd8e85cdae3fbc179ac06c3f37fcbe",
"composer_opened_by_alias": true
}
refusal_code="not_approved" — the alias refused to cut a manifest still in pending_review.
Note pieces_created_count: null — no IU was created. The outer ROLLBACK then reverted the
in-TX substrate gate flip and the synthetic d31-r5 staging row.
R6 — DLQ replay disabled
key | value
-------------------------+-------
queue.dlq.replay_enabled | false
fn_job_dead_letter_requeue_dry_run('00000000-…'::uuid) returned
{"reason":"dead_letter_not_found","refused":true} (and the gate itself is off, so even a real
DLQ row would be refused — Phase 1 proof step 11d).
R7 — stale executor surfaced honestly
SELECT fn_queue_stale_check();
{
"stale_count": 1,
"evaluated_at": "2026-05-26T15:20:54.143631+00:00",
"stale_executors": [{
"is_stale": true,
"age_seconds": 359352,
"ticks_total": 0,
"last_tick_at": "2026-05-22T11:31:41.928657+00:00",
"executor_kind": "PG_worker",
"executor_name": "iu_outbound_default",
"last_tick_status": "warn"
}],
"threshold_seconds": 300
}
The legacy iu_outbound_default row is still surfacing as stale (age > 4 days, well above the
300 s threshold). The pilot's dieu45_phase3_pilot heartbeat is fresh and not flagged. The
§15.5 silent-gap surface remains visible — closing it durably is a Phase 3+ task.