KB-14E7 rev 23

FIX7 Refactor Blueprint - Dependency-Safe Construction Order

19 min read Revision 23
fix7architecturerefactor-blueprintconstruction-order

04 - Dependency-Safe Construction Order

This is the future construction order, not SQL to apply now. It extends the approved RP-03 "Normative Creation Order" (10 steps) and the doc 02 §2.6 reversal with the refactor-specific steps (legacy freeze/deprecate, authoritative repoint, owner/ACL cutover). Every destructive or live step is explicitly OPERATOR_GATED; T1-authorable steps produce reviewable artifacts only.

Legend - who: T1 = T1 may author the artifact (no apply); OP = operator must run the live step under explicit authority. proof references guards in doc 06. no-go = stop condition.

step name object / action preconditions type who proof after rollback (doc 05) no-go
S00 re-baseline inventory (candidate discovery = diagnostic only) re-dump live qt001/birth/DOT defs + ACL + ownership; enumerate and capture the current Directus SELECT grant set on business base tables (MX-1, consumed by S09 #21); produce a CANDIDATE legacy set by name + owner (live 2026-06-08: 45 functions + 1 procedure + 20 tables + 196 views, all owner directus, all proacl=NULL/PUBLIC EXECUTE, none SECURITY DEFINER; 0 qt001 routines outside public; 0 trigger bypass vector) - this candidate set is evidence ONLY and is explicitly non-binding (name-pattern fragility is live-proven: views = 0/183/196 by literal - doc 01, doc 02 §H.1); classify all UNKNOWN_REQUIRES_REVIEW. The operational target for S15/S16/S17 is NOT this scan - it is the sealed legacy-disposition set (doc 02 §H): each candidate is classified by dependency_manifest #11 closure + effective-privilege evidence, assigned exactly one disposition (§I), bound by regprocedure/regclass + prokind + source_sha256 + privilege_acl_hash, sealed into authority_scope_manifest #20 (+ #27 for STUB_FAIL_CLOSED bodies) at S09/S12, and exact-set both-EXCEPT proven vs catalog design approved read-only T1 candidate captured == doc 01; 0 unknown; Directus SELECT set captured; G-DOT-FROZEN/G-DOT-NOOVERWRITE baseline; no step may treat the S00 scan as authority (G-LEGACY-TARGET-SEALED) n/a any unknown object role; Directus SELECT set not captured; any operational target derived from name pattern alone
S01 roles + schema + domains create 3 roles, qt001_cp, 4 domains S00 ADD OP roles/schema/domains exist, owner-isolated drop empty schema/roles schema name collision
S02 catalog root code_catalog_set/_family/_item + sealed bootstrap + owner-only immutable trigger + 3 exact-set families S01 ADD OP G-CATALOG-SEAL; families both-EXCEPT drop empty catalog (no refs) bootstrap seal mismatch
S03 manifest anchors manifest_set, manifest_item_envelope (global-unique item_id), immutable trigger S02 ADD OP conservation rule; immutable trigger fires drop empty anchors DELETE/TRUNCATE not denied
S04 27 child contracts create #01..#27 in dependency order; 4 forward child FKs DEFERRED S03 ADD OP 27 tables exist; headers exact reverse-order drop empty (doc 02 §2.6) any contract DDL conflict -> T1 stop
S05 operator/operand compat operator_operand_compatibility S04 ADD OP G-OPERAND-TYPED (operand type matches compat for every rule/measurement operand); typed-operand CHECK coverage drop empty type mismatch
S06 registries + activation evidence_registry,human_identity_registry,principal_registry,analyzer_run,manifest_activation S04 ADD OP FK targets resolvable drop empty cycle not breakable
S07 11 runtime-evidence tables create non-authority tables; 7 RANGE-partitioned; FK to registries/anchors inline S06 ADD OP G-RUNTIME-NONAUTH (count=11, not in 27); inbound FK stable reverse-order drop empty any classed as authority
S08 deferred constraints apply all deferred FK groups 1..5 (doc 06 RP-03) incl cycle-break ALTERs S04,S06,S07 ADD OP both-EXCEPT constraint set; dropped-FK rehearsal -> OBJECT_AUTHORITY_IMMUTABLE drop added constraints any deferred FK missing
S09 sealed DATA: catalog + 27 manifest rows + legacy-disposition set seed code_catalog rows; 27-manifest item rows; #20 authority-scope rows (TABLE/CONSTRAINT/INDEX/runtime-evidence + expected_constraint_set_sha256); #20 legacy-disposition rows (LEGACY_FUNCTION/PROCEDURE/TABLE/VIEW, each with regprocedure/regclass+prokind+source_sha256+privilege_acl_hash+disposition+expected_legacy_set_sha256; doc 02 §H/§I) + #27 STUB_FAIL_CLOSED body bindings; #21 Directus read-contract rows (== existing SELECT set) S08 ADD(DATA) OP G-EXACTSET-20; G-LEGACY-TARGET-SEALED (sealed set both-EXCEPT vs catalog empty; 0 unknown; set-hash recomputes); G-DIRECTUS-READ preflight new candidate version seed count != expected_item_count; legacy set both-EXCEPT non-empty; any disposition missing
S10 sealed DATA: 14 gates + 7 hashes + thresholds readiness_gate_manifest 14 rows; hash_component_manifest H01..H07 incl H04_SCOPE_V1 + H02/H05 total orders; #05 retention/#06 sealed thresholds; #23 workload profiles S09 ADD(DATA) OP G-GATES-14; G-HASH-7; G-HASHDET (H01/H02/H04/H05 recompute) new candidate version gate/hash count off; hash non-deterministic
S11 exact-set verification both-EXCEPT child vs envelope; family coverage; adapter-input edge (#24 vs #11); PG constraint/index both-EXCEPT; CP-06 fixtures S09,S10 verify T1+OP all both-EXCEPT empty; fixtures pass n/a (read) any EXCEPT non-empty
S12 seal candidate seal manifests: child==envelope, count==expected, ordinals contiguous, hashes recompute S11 SEAL OP (quorum) seal accepts only if every check passes unseal not allowed; new version any seal check fails
S13 authoritative repoint authoring author gateway_manifest #26 (pin the QT001 writer gateway identity - §Writer-gateway-identity below) + writer_repoint_manifest #27: bind old/new source_sha256, rollback_stub source, STUB_FAIL_CLOSED legacy body bindings; dependency_manifest #11 closure proves new entrypoints reach NO legacy object S00,S12 ADD(DATA) T1 author G-REPOINT-SRC; G-WRITER-GATEWAY-IDENTITY (gateway pinned by regprocedure+source_sha256+owner); G-NOLEGACY-PRE (#11 closure legacy_reached=0, non-vacuous; sealed set complete, 0 unknown, dispositions assigned, rollback artifacts staged - does NOT require EXECUTE yet revoked) rollback stub repoints back any legacy object reachable; gateway identity not pinned; any unknown
S14 activate manifest exact quorum + epoch binding activation via manifest_activation; one ACTIVE per type S12,S13 ACTIVATE OP (quorum) G-EPOCH-TOCTOU; one-active index holds rollback = new candidate prior payload caller-supplied lifecycle; epoch drift
S15 authoritative path cutover + legacy neutralization in one atomic operator transaction: repoint the live writer to the manifest-active path via the #26-pinned QT001 writer gateway (G-WRITER-GATEWAY-IDENTITY) AND REVOKE EXECUTE - from PUBLIC, directus, every role except qt001_cp_owner - over the COMPLETE sealed legacy-disposition set (doc 02 §H, NOT a name-pattern scan); then replace ONLY the STUB_FAIL_CLOSED-classified apply/writer/planner entrypoints with a fail-closed stub, leaving every REVOKE_ONLY member's body unchanged (Codex BLOCKER 3; the apply fn fn_dot_birth_qt001_apply + apply proc sp_dot_birth_qt001_apply are certain STUB members, the rest of the STUB set is fixed by the sealed #11 classification). The per-object prior privilege state (the privilege_acl_hash snapshot) is read-back-verified before the REVOKE so rollback is recoverable; this closes the activation→freeze window over the whole sealed set S14 LIVE REPOINT OP precondition G-NOLEGACY-PRE + valid operator_authorization (doc 07); proof G-NOLEGACY-POST (over sealed set: non-owner-effective-EXECUTE=0, STUB members fail-closed); G-WRITER-GATEWAY-IDENTITY; G-DOT-NOOVERWRITE; G-BIRTH-NEUTRAL; gateway fail-closed atomic deactivate-first rollback (doc 05 §note 5): supersede new path → verify readiness BLOCKED → verify gateway cannot route new path → restore per-disposition (STUB: pinned #27 body + ACL; REVOKE_ONLY: ACL only) → G-NOMIXED-AUTHORITY any legacy still effective-executable by non-owner OR still reachable; mixed old+new authority; birth row delta; gateway identity drift
S16 owner/ACL cutover (control-plane scoped) transfer only qt001_cp control objects + the sealed legacy-disposition set (doc 02 §H, the same sealed set neutralized at S15 - never a name-pattern scan) to qt001_cp_owner; REVOKE directus/PUBLIC authority on those control objects only; re-grant exact #21 SELECT to Directus. The #26 QT001 writer gateway is born qt001_cp_owner at PKG-E and has NO owner transition here (not directus-owned at any phase - resolves Codex CHECK_D). Directus retains full authority over its own directus_* application tables and the business base tables it legitimately owns (XH-4) S15 LIVE ACL OP precondition: complete effective-privilege ACL snapshot captured + hash-bound + read-back-verified + restore-rehearsed BEFORE any REVOKE (doc 05 invariant 3: owner + relacl/proacl + pg_attribute.attacl column ACL + sequence ACL + nspacl + pg_default_acl + role-membership effective privilege via pg_auth_members) + valid operator_authorization; proof G-OWNER-CUTOVER (effective-privilege, role-membership-aware), G-DIRECTUS-APP-INTACT, G-DIRECTUS-READ (SELECT preserved), PUBLIC EXECUTE on control objects gone restore prior ownership + full effective-privilege ACL from the verified snapshot (both-direction effective-privilege match) Directus loses required SELECT or app-table authority; readiness un-blocks falsely; ACL snapshot absent/unverified
S17 legacy freeze freeze the sealed FREEZE_NO_CHANGE members (20 tables) + DEPRECATE_READONLY-bound routines/views (doc 02 §I): revoke writes, mark sentinel; bodies unchanged (no stub); plan_v2 stays unreachable S15 (#11 proven non-dependence) FREEZE OP G-LEGACY-FROZEN; G-LEGACY-TARGET-SEALED (over sealed set); birth/QT-002 path intact restore prior grants/flag per disposition birth gateway transitively depends on a frozen object
S18 legacy deprecate deprecate (not drop) legacy qt001_*; retain as read-only history S17 + stable active period DEPRECATE OP history readable; no active reference restore deprecation flag any active reference remains
S19 post-cutover verification re-run all guards; readiness gate facts; bypass-vector facts; scale runs (REAL_RUN, separately gated) S18 verify T1+OP full 35-guard suite green incl. G-NOLEGACY-POST/G-NOMIXED-AUTHORITY/G-WRITER-GATEWAY-IDENTITY/G-LEGACY-TARGET-SEALED/G-NO-QT001-PERMIT-DURING-FIX7/G-DOT-NOOVERWRITE/G-LEGACY-FROZEN; readiness reflects real facts n/a any guard red

Dependency notes

  • FK cycles (manifest_set <-> manifest_activation; evidence/identity/principal) are broken by the deferred ALTERs in S08 (doc 06 groups 3-5), exactly as approved RP-03.
  • The 4 forward child FKs (policy-rule/operator; metric/unit; capability/workload; signoff/tier) are deferred to S08 so the 27 tables can be created in any internal order in S04.
  • Expected-constraint catalog (#20) must be seeded in S09 BEFORE seal S12 so S11 both-EXCEPT has a target; the dropped-deferred-FK rehearsal in S08 must already fail OBJECT_AUTHORITY_IMMUTABLE.
  • regclass binding order (XHigh-E): hash_component_manifest #10 has source_relation regclass NOT NULL, so the runtime-evidence tables (S07) and the 27 surfaces (S04) MUST physically exist before any #10/H02/H04/H05 row is seeded (S10). The order S04/S07 < S10 already satisfies this; the constraint is now explicit so an implementer cannot reorder #10 seeding ahead of its referenced relations. Likewise storage_class_manifest/adapter regprocedure columns require the referenced functions to exist before those rows seed.
  • The authoritative repoint (S13->S15) is the load-bearing refactor act and the historical failure point: it MUST be gated on the dependency_manifest #11 closure proof (G-NOLEGACY-PRE before the cutover, G-NOLEGACY-POST after it - the guard is phase-split, Codex BLOCKER 2), reproducing the FIX5 recursive-callgraph discipline as sealed data over the sealed legacy-disposition set, not a name deny-list. PRE proves structural closure + sealed-set completeness + staged rollback and does NOT require EXECUTE already revoked (so it can gate the very step that revokes); POST proves effective non-owner-executability=0 after the step. This removes the prior deadlock (a single G-NOLEGACY that was required green before the action that made it green).
  • Owner/ACL cutover (S16) MUST run only after the manifest path is active and proven (S14/S15), because it is the step that strips the directus authority that currently keeps readiness BLOCKED
    • doing it earlier would orphan the live writer.
  • Atomicity / no mixed authority (Max-D + Codex BLOCKER 4): the live cutover steps S15 (repoint+neutralize) and S16 (owner/ACL) each execute as a single atomic operator transaction with a guard-verified end state (G-NOLEGACY-POST / G-OWNER-CUTOVER / G-DIRECTUS-READ + G-NOMIXED-AUTHORITY). The two authority paths (new qt001_cp active path vs legacy executable path) are mutually exclusive at every observable point - G-NOMIXED-AUTHORITY fails closed if both are simultaneously active/executable. The S15 rollback is an explicit ordered atomic sequence, deactivation-first (doc 05 note 5): (1) supersede/deactivate the new authoritative path in manifest_activation; (2) verify readiness BLOCKED; (3) verify the writer gateway cannot route to the new active path (no ACTIVE manifest for the writer); (4) only THEN restore legacy state per disposition (STUB_FAIL_CLOSED: pinned #27 source_sha256 body + captured ACL; REVOKE_ONLY: captured ACL only - replaying the captured snapshot, never issuing a fresh blanket GRANT); (5) verify G-NOMIXED-AUTHORITY + G-BIRTH-NEUTRAL. Any step that cannot prove the safe-blocked state halts fail-closed. The "never CREATE OR REPLACE the gateway" rule applies to the qt001_cp writer gateway and the birth gateway (owner-isolation / DO_NOT_TOUCH); restoring a STUB_FAIL_CLOSED legacy body to its pinned prior source IS an authorized operator function-replacement of a legacy object and does not contradict that rule (Codex CR-E3 - the two are different object classes). S16 partial failure restores ownership + full effective-privilege ACL from the verified snapshot.
  • Legacy freeze/deprecate (S17/S18) MUST run only after #11 proves no live-required object (birth gateway, QT-002) depends on the frozen target.

Writer-gateway-identity (phase-explicit; Codex BLOCKER 6 / CHECK_D)

S15/S16 reference the writer gateway by pinned identity, never a name pattern. The QT001 control-plane writer gateway is the single sealed gateway_manifest #26 row:

attribute value / contract
object the QT001 control-plane writer gateway function in schema qt001_cp
identity regprocedure (schema + name + identity arguments) + prokind, pinned in #26
owner before S15 qt001_cp_owner (born owner-isolated at PKG-E/S01-S14; there is NO directus phase for the new gateway)
owner after S15 qt001_cp_owner (unchanged)
owner after S16 qt001_cp_owner (no owner transition - resolves the CHECK_D ambiguity)
source_sha256 before/after the #26-bound hash, unchanged across cutover - the cutover repoints the live writer to route through the gateway via manifest_activation, it does not rewrite the gateway body
expected active path after S15 live writer → #26 gateway → manifest-active path
expected active path before S15 legacy apply/writer (directus-owned, member of the sealed set)
rollback stub source #27 rollback_stub_source_sha256 (re-points away from the new gateway, restores legacy per disposition)
#26 binding gateway identity + source_sha256 + fail_closed=true
#27 binding old_source_sha256 = legacy writer; new_source_sha256 = #26 gateway; rollback_stub_source + STUB_FAIL_CLOSED body bindings
fn_birth_registry_auto DO_NOT_TOUCH; explicitly NOT the QT001 writer gateway (it is the birth gateway, a different layer; directus-owned; protected by G-BIRTH-NEUTRAL + G-DOT-FROZEN + policy, not owner-isolation)

Phase-explicit ownership of the objects S15/S16 touch:

object class owner before S15 after S15 after S16
new qt001_cp writer gateway (#26) qt001_cp_owner qt001_cp_owner qt001_cp_owner
legacy apply/writer (sealed STUB_FAIL_CLOSED) directus directus (stubbed body, EXECUTE revoked) qt001_cp_owner (or frozen)
other legacy routines (sealed REVOKE_ONLY) directus directus (body unchanged, EXECUTE revoked) qt001_cp_owner (or frozen)
birth gateway fn_birth_registry_auto directus directus directus (DO_NOT_TOUCH)

Guard G-WRITER-GATEWAY-IDENTITY (doc 06) verifies the live active writer post-S15 == the #26-bound regprocedure with matching source_sha256 and owner qt001_cp_owner; that the legacy writer/apply objects are members of the sealed #20/#27 set; and that fn_birth_registry_auto is unchanged. No guard may assume the post-S16 owner state at S15 (each phase has its explicit expected owner above).

No-SQL-now boundary

This document defines order only. No CREATE/ALTER/GRANT/REVOKE/seal/activate is performed. S01-S19 each become reviewable artifacts in later, separately authorized packages (doc 07), and the LIVE/SEAL/ACTIVATE/REVOKE/FREEZE steps are OPERATOR_GATED.

Back to Knowledge Hub knowledge/dev/reports/architecture/t1-fix7-existing-system-refactor-execution-blueprint-2026-06-08/04-dependency-safe-construction-order.md