KB-496A

91000x · 07 — Carry-Forward (100000x re-author plan + memory updates)

12 min read Revision 1
iu-core91000xcarry-forward100000x-roadmapre-author-planmemory2026-05-26

91000x · 07 — Carry-Forward

Phase: F (carry-forward component)
Status: complete list of next-step work
Date: 2026-05-26

A. 100000x macro charter — Re-author + apply 040/041 + full proof

The 100000x macro must produce migrations 040R and 041R (R = re-authored) against live signatures, then run the full 8-step proof from 90000x report 07.

040R — re-author plan

Author intent (90000x report 05) Live signature/schema 040R fix
v_unit_id := fn_iu_create(unit_kind, content_text, section_type, piece_role, canonical_address, source_position) returning uuid fn_iu_create(p_canonical_address, p_title, p_body, p_actor, p_unit_kind, p_section_type, p_owner_ref, p_publication_type, p_parent_ref) returning jsonb v_result := fn_iu_create(p_canonical_address := piece->>'canonical_address', p_title := piece->>'content_text' (first line), p_body := piece->>'content_text', p_actor := 'iu_core_100000x_cut', p_unit_kind := piece->>'unit_kind', p_section_type := piece->>'section_type', p_parent_ref := v_local_to_unit->>parent_local_id); v_unit_id := (v_result->>'id')::uuid;
PERFORM fn_iu_collection_add_piece(parent_uuid, child_uuid, piece_role, source_position) fn_iu_collection_add_piece(p_collection_id uuid, p_iu_id uuid, p_piece_order integer, p_piece_role text, p_actor text) returning jsonb PERFORM fn_iu_collection_add_piece(p_collection_id := parent_uuid, p_iu_id := child_uuid, p_piece_order := (piece->>'source_position')::int, p_piece_role := piece->>'piece_role', p_actor := 'iu_core_100000x_cut');
piece_role carried in 040 piece payload information_unit table has NO piece_role column Drop piece_role from piece storage on information_unit; the role lives only in the collection membership edge (piece_role on fn_iu_collection_add_piece)
source_position stored on piece information_unit has sort_order (integer), not source_position Map manifest source_positionsort_order
Reference iu.information_unit live: public.information_unit Drop iu. schema prefix

040R minimum contract preserved:

  • Same input: (p_staging_record_id uuid, p_apply boolean, p_source_hash text, p_actor text) returning jsonb
  • Same G1-G7 guards (not_found, wrong_kind, not_approved, incomplete_approval, digest_changed, source_changed, composer_gate_closed)
  • Same atomic TX shape (SELECT FOR UPDATE, audit row, piece-create loop, staging transition to consumed)
  • Same idempotency (consumed lifecycle blocks re-cut via G3)

041R — re-author plan

Author intent Live 041R fix
iu.information_unit references public.information_unit drop schema prefix
WHERE id = ANY(v_pieces_created) id exists ✅ unchanged
source_position for axis-A check column is sort_order replace with sort_order
piece_role IS NULL OR section_type IS NULL for axis-B no piece_role column on information_unit; section_type exists axis-B becomes section_type IS NULL only — piece_role axis-B check moves to collection-edge query
iu_sql_link.parent_unit_id/child_unit_id for axis-C subtree roots iu_sql_link is IU↔SQL-object link table, NOT parent/child IU edges Use public.information_unit.parent_or_container_ref (uuid, exists, nullable) OR use the collection-membership edge table (TBD via schema inspection)
fn_iu_subtree(root) for subtree size live: (p_root uuid) RETURNS TABLE(iu_id, canonical_address, depth, parent_id, relative_depth) unchanged — (SELECT count(*) FROM fn_iu_subtree(r.id)) works

Pre-100000x discovery work

Before authoring 040R/041R bodies, inspect live to confirm:

-- Parent-child IU edge table (replacement for iu_sql_link assumption)
SELECT table_schema, table_name FROM information_schema.tables
WHERE table_name LIKE '%collection_membership%' OR table_name LIKE '%piece_collection%'
   OR table_name LIKE 'iu_%collection%' OR table_name LIKE '%information_unit%link%';

-- information_unit edge cols (any FK from information_unit to itself?)
SELECT conname, pg_get_constraintdef(oid) FROM pg_constraint
WHERE conrelid='public.information_unit'::regclass AND contype='f';

These results determine the axis-C and subtree path in 041R.

B. 100000x apply runbook

  1. Discovery — run the inspection queries above; document live signatures for fn_iu_create, fn_iu_collection_add_piece, plus the parent-child edge table.
  2. Author 040R + 041R in a fresh KB pack …/v0.6-iu-core-100000x-cut-pipeline-applied/.
  3. Apply 040R, 041R via workflow_admin socket-trust channel.
  4. Run full proof from 90000x report 07 (all 7 steps).
  5. Negative refusal matrix for 040R G1-G7.
  6. SSOT bumpcutter_agent/iu_core/dot_commands.py::_REGISTRY gets all 6 new DOTs in one commit (this run's 4 + 100000x's 2). Tests get the same 6-DOT delta.
  7. Patch 91000x report 00 verdict from PARTIAL → keep PARTIAL_WITH_EXACT_GAP unchanged (this report is frozen evidence of the discovered gap).
  8. First real Điều 37 cut — user supplies source; CUT executor runs against real source; verify-cut goes green.

C. Memory updates to write (this conversation)

Refresh existing

  1. [[feedback-channel-memory-drifts-verify-live]] — add 5 more drifts:
    • iu_core_retention_policy.keep_days CHECK requires >=1 (not >=0).
    • dot_iu_command_catalog.category vocab {collection,piece,lifecycle,read,health} (re-confirmed from 50000x; still authoritative).
    • dot_iu_command_run schema is (run_id, command_name, category, run_mode, run_status, mutating, params_digest, gate_snapshot, evidence, actor, created_at) with CHECKs on run_mode {plan,apply,verify} and run_status {planned,applied,verified,refused,failed}. NO column payload_json, NO column status.
    • iu_staging_payload.payload_kind vocab {json,text,blob_ref} + exclusive_chk: text must use payload_text, json must use payload_json, blob_ref must use blob_ref.
    • iu_staging_payload.byte_len is NOT NULL — all INSERTs must compute and supply.
    • entity_species.code (not entity_code) — already noted but re-confirmed.

New memories

  1. [[feedback-fn-iu-create-returns-jsonb-not-uuid]] — live signature is (p_canonical_address text, p_title text, p_body text, p_actor text, p_unit_kind text DEFAULT NULL, p_section_type text DEFAULT NULL, p_owner_ref text DEFAULT NULL, p_publication_type text DEFAULT NULL, p_parent_ref uuid DEFAULT NULL) RETURNS jsonb. Extract uuid via (result->>'id')::uuid. Authored 90000x mig 040 had wrong signature assumption — this is the canonical reference for any future CUT executor.

  2. [[feedback-fn-iu-collection-add-piece-signature]] — live: (p_collection_id uuid, p_iu_id uuid, p_piece_order integer, p_piece_role text, p_actor text) RETURNS jsonb. 5 args; piece_order is integer (3rd positional); piece_role is text (4th). Always use named parameter call style to avoid drift.

  3. [[feedback-information-unit-no-piece-role-column]]public.information_unit has no piece_role column. piece_role is a property of the collection-membership edge, not the piece. Axis-B "piece_role required" must check the edge, not the piece row. Has sort_order (integer) not source_position.

  4. [[feedback-iu-sql-link-is-iu-to-sql-not-parent-child-iu]]iu_sql_link links IU pieces to underlying SQL objects (unit_id, unit_version_id, canonical_address, link_role, object_kind, object_schema, object_name, collection_name, row_pk, function_identity, trigger_name, object_fingerprint). NOT parent-child IU edges. For parent-child IU lookup, use information_unit.parent_or_container_ref (uuid) or the collection-membership edge table.

  5. [[feedback-iu-vector-sync-point-has-no-staging-path]]iu_vector_sync_point columns: point_key, source_kind, source_path, content_digest, sync_status, indexed_digest, point_count, last_actor, created_at, updated_at, unit_id, parent_piece_id, chunk_index, chunk_count, summary_marker, axis_refs. No staging_record_id or staging_payload_id. Structural no-vector guarantee — staging rows CANNOT appear in VSP.

  6. [[feedback-plpgsql-check-function-bodies-defers-sql-stmt-resolution]]check_function_bodies=on (PostgreSQL default) parses plpgsql expressions at CREATE time but defers SQL statement (SELECT/INSERT/UPDATE) column-resolution to runtime. CREATE FUNCTION succeeds with bad column refs in INSERT/SELECT inside the body; runtime fails at first invocation. Always test CREATE + invocation (or EXPLAIN ANALYZE of a fn invocation in a TX) before declaring substrate live.

  7. [[project-iu-core-91000x-apply-mark-to-cut-pipeline-and-proof-partial-with-exact-gap-2026-05-26]] — project memory for this macro.

D. Files NOT touched by this macro (re-confirmed for safety)

Surface Why preserved
production_documents mission rule + structurally absent in directus DB
Qdrant collections mission rule + no MCP write surface
Nuxt deployment mission rule
iu_core.retention_enabled gate stays inert per default
Existing 4 staging DOTs (create/approve/consume/reject) unmodified
fn_iu_core_retention_cleanup unmodified; staging gets its own worker (fn_iu_staging_cleanup)
25000x mig 033 auto-instantiate path unmodified
dot_iu_command_run audit retention unchanged
PR #669 not touched
cutter_agent/iu_core/dot_commands.py _REGISTRY NOT bumped (4 of 6 applied; see Phase E SSOT decision)
Pinning tests unchanged

E. If 100000x discovers MORE drift

The same principle from this macro applies:

  • Surgical column-name/value drift within a fn body that doesn't change contract/signature/algorithm → patch under the same drift-patch rule.
  • Schema-level drift (wrong table, wrong column count, type mismatch on return) requiring re-imagining of the body → re-author in 100000x with explicit gap report.
  • Architectural drift (wrong fn entirely doesn't exist) → STOP, escalate to operator design review.

F. End state after 100000x apply + full proof green

  • 7-stage operating flow LIVE: INPUT → MARK → VERIFY-MARK → APPROVE → CUT → VERIFY-CUT → CLEANUP-15D.
  • 36 DOTs, +6 fns relative to pre-91000x, +0 retention rows (D36 prior preserved), 3 CHECK refinements (already live).
  • Phase G fixture proof PASS-WITH-FIXTURE.
  • Pinning tests bumped, D9 conformance bumped, 1-2 commits.
  • First real Điều 37 cut unblocked (user-supplied source).
  • SSOT _REGISTRY synced.
  • [[feedback-pg-hba-local-trust-unblocks-role-channel]] — apply channel.
  • [[feedback-honest-channel-block-beats-partial-trigger]] — apply discipline.
  • [[feedback-honest-partial-over-fake-pass]] — verdict pattern (PARTIAL_WITH_EXACT_GAP correctly used).
  • 80000x operational doctrine — MARK is not CUT.
  • 90000x reports 02-06 — original authored bodies (the basis for the patches in 91000x and re-author in 100000x).
Back to Knowledge Hub knowledge/dev/laws/dieu44-trien-khai/v0.6-iu-core-91000x-apply-mark-to-cut-pipeline-and-proof/07-carry-forward.md