KB-8BBB

70000x · 07 — Lessons (6 new + 4 refreshed)</title> <parameter name="tags">["iu-core","70000x","lessons","feedback"]

4 min read Revision 1

70000x · 07 — Lessons (new + refreshed)

NEW

L1 — local all all trust is the workflow_admin unblock channel

50000x packaged mig 036 as authored-only because no workflow_admin auth path was known. 70000x live discovery: inside the postgres container, pg_hba.conf has local all all trust. Any role (including superusers) can connect over the Unix socket via docker exec -i postgres psql -U <role> -d directus with no password. With workflow_admin connection available, mig 036 applies as the owner — no GRANT needed. Rule: before declaring a privilege block, probe with -U <role-name> via the trust channel. → [[feedback-pg-hba-local-trust-unblocks-role-channel]]

L2 — information_unit.status does not exist; it's lifecycle_status

T01 first iteration failed with column "status" does not exist. The actual column is lifecycle_status. Rule: for IU lifecycle filtering, always use lifecycle_status. → [[feedback-information-unit-status-column-is-lifecycle-status]]

L3 — event_outbox.payload does not exist; it's safe_payload

T05 first iteration filtered WHERE payload->>'phase'=... and failed. The actual JSONB column is safe_payload (the redacted-safe view, paired with payload_classification). Rule: for event_outbox JSONB extraction, always use safe_payload. → [[feedback-event-outbox-jsonb-column-is-safe-payload]]

L4 — fn_iu_create unit_kind vocab is {design_doc_section, law_unit}

T04 first iteration passed "unit_kind":"document" and got Not in vocab. Available: design_doc_section, law_unit. Cross-link with [[feedback-section-type-and-piece-role-vocab-enforced]] — section_type vocab is broader, unit_kind is just those two. Rule: mint with unit_kind ∈ {design_doc_section, law_unit}. For composed test docs, design_doc_section is the default. → [[feedback-fn-iu-create-unit-kind-vocab-is-two]]

L5 — iu_sql_link.link_role CHECK vocab is 11 roles, NOT reference

T06 first iteration failed iu_sql_link_link_role_chk. Allowed: represents, describes, governs, source_of_truth_for, derived_from, emits_event_for, consumes_event_from, validates, renders, indexes, reports_on. Rule: for iu_sql_link.link_role, pick from the 11-role vocab. → [[feedback-iu-sql-link-link-role-vocab-eleven]]

L6 — fn_iu_sql_link_inbound_capture is a trigger function

T06 first tried SELECT fn_iu_sql_link_inbound_capture() and got trigger functions can only be called as triggers. The function returns trigger and must be invoked via a trigger. Rule: before calling a fn_iu_* directly, check its return type. If trigger, it must be invoked via a trigger. Identify with pg_proc.prorettype = 'trigger'::regtype. → [[feedback-trigger-functions-only-callable-via-triggers]]

REFRESHED

R1 — [[feedback-pinning-tests-bump-per-macro]]

At 70000x, 15 pinning sites + DDL SSOT + 1 total assertion needed coordinated bumps from 65/6/181 to 66/7/183 for a single trigger+fn DDL change. Sites grow linearly with every SSOT macro. Future opportunity: a pinning_constants module — cuts bump radius from 15 to 1.

R2 — [[feedback-in-tx-gate-toggle-reversibility]]

Proven AGAIN at 70000x T04 (composer_enabled) + T05 (piece_event_runtime.emit_enabled). Durable across 7 macros. Defensive pre-ROLLBACK gate-flip-back is the right default.

R3 — [[feedback-honest-channel-block-beats-partial-trigger]]

50000x's honest channel-block was vindicated at 70000x: when the channel was discovered (local trust line), unblock was one-step with NO state recovery needed. A half-application at 50000x would have left a corrupt fn+no-trigger mix.

R4 — [[feedback-no-truncated-uuids-for-apply-sql]]

Refreshed at T06: used (SELECT id FROM ... LIMIT 1) inline subqueries to fetch full uuids in-place for FK and jsonb row_pk fields.

Back to Knowledge Hub knowledge/dev/laws/dieu44-trien-khai/v0.6-iu-core-70000x-full-test-readiness-six-user-flows-open-goal/07-lessons.md