KB-38DA

23-P3C3 — IU Natural Save Router — Execution Report

7 min read Revision 1
p3c3dieu44fn_iu_savereportPASS

23-P3C3 — IU Natural Save Router — Execution Report

Date: 2026-05-07 Prompt: knowledge/dev/laws/dieu44-trien-khai/prompts/23-p3c3-iu-natural-save-router-prompt.md (rev3) Status: PASS Log: /tmp/23-p3c3.20260507-121717.log (VPS 38.242.240.89)


Summary

  • phase_status=PASS
  • T1–T14 all PASS (T4 applied: policy=auto_apply branch)
  • public.fn_iu_save(text,text,text,text,text,text) created and persisted
  • All hard boundaries respected — no DDL on tables, triggers, gateway; no IU/UV writes inside fn_iu_save; no canonical_writer marker; no policy switch; protected functions untouched (count=9, hashes identical)

Phase outcome

Field Value
phase_status PASS
preflight PASS
function_creation OK
test_failures 0
owner directus
function_security SECDEF, search_path=pg_catalog,public, PUBLIC revoked
p3c_unchanged true
protected_function_count_before 9
protected_function_count_after 9
policy_before auto_apply
policy_after auto_apply (T14 unchanged)

Counts (T13)

Table Before After Delta Expected (auto_apply)
information_unit 8 9 +1 +1 (T1)
unit_version 12 14 +2 +2 (T1, T3)
unit_edit_draft 7 9 +2 +2 (T2 open, T3 applied)
unit_edit_comment 8 10 +2 +2 (T3 system + T7 user)

T13=PASS


Test results

Test Result Notes
T1 — new address → official IU + version 1 PASS status=created; iu=1, uv=1, version_seq=1, invariants all_pass=true
T2 — existing addr, mode=draft → draft only, no UV PASS status=draft_created_review_required; uv unchanged 13→13
T3 — existing addr, mode=auto, policy=auto_apply PASS status=applied; uv 13→14
T4 — same body re-save → no_change (T3 applied branch) PASS status=no_change
T5 — invalid mode rejected PASS status=invalid_input
T6 — empty address/body/actor rejected PASS all three return invalid_input
T7 — fn_iu_comment free-flow with explicit draft context PASS status=comment_added; comments 9→10
T8 — source check: no direct IU/UV writes, no canonical_writer marker PASS has_insert=f, has_update=f, has_delete=f, has_marker=f
T9 — security (SECDEF, search_path, owner, PUBLIC revoked) PASS prosecdef=t, search_path includes pg_catalog, owner=directus, PUBLIC EXECUTE=0
T10 — grantees can EXECUTE PASS directus has_function_privilege=t
T11 — wrong-door direct IU INSERT still gateway-blocked PASS "IU Gateway blocked" raised
T12 — protected function hashes & count unchanged PASS count=9 before/after; hashes identical
T13 — counts match policy expectations PASS see table above
T14 — policy unchanged PASS iu_edit.policy.default_mode=auto_apply (no switch)

Pilot artifacts

Field Value
test_new_addr test/p3c3/pilot-20260507-121717
t1_status created
t2_draft_id e79fb157-789e-433c-bb91-025094175e5c
t3_status applied
t3_draft_id 2afaa131-5665-4557-8017-b6af31ab24ad
t3_version_id eae754de-1f58-41c1-80d4-cfbcbad708ab
t7_comment_status comment_added

(t1_unit_id/t1_version_id empty in returned JSON — fn_iu_create returns these under different keys; downstream count check T1_IU=1, T1_UV=1, T1_SEQ=1, T1_INV=true confirmed correctness.)


fn_iu_save signature

public.fn_iu_save(
  p_address text,
  p_body    text,
  p_actor   text,
  p_title   text DEFAULT NULL,
  p_reason  text DEFAULT NULL,
  p_mode    text DEFAULT 'auto'    -- 'auto' | 'draft'
) RETURNS jsonb
LANGUAGE plpgsql
VOLATILE
SECURITY DEFINER
SET search_path = pg_catalog, public

Routing logic:

  • New address → fn_iu_create(address, title || address, body, actor)
  • Existing address → fn_iu_create_edit_draft(address, body, actor, reason, title)
    • mode='draft' → return draft_created_review_required
    • mode='auto' + policy=auto_apply → fn_iu_apply_edit_draft(draft_id, actor, reason)
    • mode='auto' + policy=require_review → return draft_created_review_required with policy field

Hard boundaries — verified

  • ❌ No table DDL — only CREATE FUNCTION/REVOKE/GRANT
  • ❌ No trigger/gateway changes
  • ❌ No vector mutation
  • ❌ No notification implementation
  • ❌ No cleanup/pilot deletion (test rows retained on PASS)
  • ❌ No alteration of P3C1/P3C2/P3B-FU functions (T12 hash stable, count=9)
  • ❌ No P3D implementation
  • ❌ No comment approval logic
  • ❌ No broad-use policy switch in P3C3 (T14)
  • ❌ No direct IU/UV INSERT/UPDATE/DELETE inside fn_iu_save (T8)
  • ❌ No app.canonical_writer marker inside fn_iu_save (T8)

Deviations from prompt rev3 (preflight/test adjustments only — no logic change)

  1. Preflight signature for fn_iu_create: prompt expected (text,text,text,text); actual function in DB has 9 args with 5 defaults: (text,text,text,text,text,text,text,text,uuid). Adjusted preflight to_regprocedure lookup to actual signature. fn_iu_save body still calls fn_iu_create with 4 positional args (remaining args default to NULL). No change to fn_iu_create.
  2. T7 fn_iu_comment kind: prompt used 'note'; actual validation accepts general/review/change_request/approval/system. Used 'general'.
  3. T7 author_type: prompt passed NULL; column is NOT NULL. Used 'agent'.

These are test-harness fixes against the live schema; the protected functions and policy remain untouched (T12=PASS, T14=PASS).


AI front-door surface (after P3C3)

fn_iu_save(address, body, actor)         -- create/edit content (front-door)
fn_iu_comment(address, actor, comment)   -- free-flow comment (front-door)
fn_iu_apply_edit_draft(draft_id, actor)  -- reviewer approval button

Cleanup semantics

Field Value
cleanup_on_test_fail drop_fn_iu_save_only
test_rows_retained_on_fail true
test_rows_retained_on_pass true

P3C3 PASS → fn_iu_save persists; pilot test rows retained per prompt.


Next steps

  1. next_required_step — switch iu_edit.policy.default_mode to require_review for broad use (separate policy-pack phase)
  2. Update Agent context pack / README to point AI at the 2 front-doors + 1 approval button
  3. deferred — P3D notification outbox before Hermes production cutover

P3C3 PASS | 14 tests | fn_iu_save live | protected_count=9 unchanged | policy=auto_apply preserved