P3D — B3-F0a Sibling Policy Materialization Design
P3D — B3-F0a Sibling Policy Materialization Design
Date: 2026-05-12 Mode: DESIGN ONLY
1. Problem
B3-F0 dry-run found SIBLING_POLICY_NOT_IN_PG. The approved scope for fn_birth_registry_auto_id (3 collections) exists only as GPT review snapshot. Gate logic must read from PG, not from embedded list.
2. Policy store: dot_config
dot_config already stores vocab.* and other system policy. Adding policy.* is consistent. Columns verified from B3-P inventory: key (text), value (text), description (text), updated_at (timestamptz).
JSON value stored as text in the value column (dot_config.value is text, not jsonb — Agent must verify live).
3. Policy key + value
key = policy.birth_trigger.accepted_sibling_scope
value = {
"version": 1,
"source_review": "knowledge/dev/laws/dieu44-trien-khai/reviews/gpt-review-b3a2a-variant-function-equivalence-probe-pass-2026-05-12.md",
"entries": [
{"function":"fn_birth_registry_auto_id","collections":["governance_relations","law_dot_enforcement","law_jurisdiction"]}
]
}
description = Scoped sibling birth trigger functions accepted by onboarding gate. Each entry defines a function name and the collections approved to use it. Gate reads this key to validate trigger bindings. Materialized by B3-F0a.
This IS policy, not runtime hardcode. The 3 collection names are the approved exception content, stored as PG data with a source review reference. Runtime gate logic must read this row and must not embed the list in code. Any later scope change must update the policy row through a reviewed policy-materialization flow.
4. Gate reads policy at runtime
Gate logic:
1. Read dot_config WHERE key = 'policy.birth_trigger.accepted_sibling_scope'
2. Parse JSON object with `version`, `source_review`, and `entries` array
3. For each entry: resolve function OID by proname
4. Check if collection's trigger binding matches any approved entry
5. If match → OK. If no match → GAP: OUT_OF_SCOPE_SIBLING
No hardcoded list in gate function. Policy changes = UPDATE dot_config row.
5. Conflict handling
Key absent → INSERT
Key exists + equivalent value (same JSON semantic content after canonical JSON parse/sort; not raw string compare) → PASS_ALREADY_EXISTS
Key exists + different value → BLOCKED_EXISTING_CONFLICT (report, do not overwrite)
6. Rollback
If INSERT: DELETE WHERE key = 'policy.birth_trigger.accepted_sibling_scope'
If UPDATE: restore captured old value
B3-F0a Design | 2026-05-12