IU 4-Mothers Master Design Rev2 — WS2+WS3 IU-Centered Master + 4 Mothers Binding (DRAFT 2026-05-27)
Master Design Rev2 — IU-Centered Master Architecture + 4 Mothers Binding (WS2 + WS3)
Path:
knowledge/dev/design/v0.6-iu-4mothers-event-foundation-rev2/04-iu-centered-4mothers-binding-design.mdStatus: DRAFT Rev2 (document-only). Companion to00-master-design-rev2.md. Date: 2026-05-27 Authority: Rev2 brief §2 (IU doctrine), §3 (IU brick), §4 (IU bundle), §5 (4 Mothers), §9 (KG feedback), §10 (Usage evidence), §11 (No-double-ownership), §12 (Old infra). Boundary preserved: Điều 38/39 (IU), Điều 45 (queue/event), Điều 32 (approval), Điều 28/33 (UI/data plane), Điều 7 (Assembly First). Boundary: 4 Mothers are khuôn đúc around IU; they do NOT own IU body, queue/event core, or approval. This design extends existing PG substrate (reuse-first) and proposes registry-level columns; no migration in this macro.
§1. Scope and boundaries
This document designs:
- The IU-centered master architecture: IU as the central assembly unit of every workflow (2..500 step), with no parallel "workflow artifact" track (Rev2 §2 doctrine).
- The IU brick fields (Rev2 §3 11-field requirement).
- The IU bundle / Step Pack (Rev2 §4).
- The 4 Mothers binding: MOW / MOT / MOIT / MOUT each as a binding shape around IU, reusing existing PG tables where possible.
- The IU version policy at design level (Rev2 §2 D2.6 + OD15).
- The KG feedback bridge from this side (KG proposals land in
proposaltable — see WS4 §8). - The usage evidence schema sketched here, computed in
03-event-5layer-…§9.
This document does not design:
- The 9-state floor / transition matrix / workflow UI — see
02-step-state-machine-and-workflow-ui-design.md. - The event/queue/realtime/DLQ substrate — see
03-event-5layer-realtime-dlq-design.md. - OSS tool selection — see
05-oss-candidate-strategy-rev2.md. - Approval quorum — Điều 32 surface.
§2. IU-Centered doctrine — design statement
§2.1 IU as the only central assembly unit
Per Rev2 §2 D2.1, every workflow step, task, form, output, event, or governance artifact assembles around an IU or an IU bundle. There is no "workflow artifact track separate from IU". Design consequence:
workflow_step_defhas no body column. Its narrative / instruction / policy / contract come exclusively from a bound IU or IU bundle.task_def(template) likewise — no body column. Tasks render their content from bound IU/bundle.- MOIT / MOUT registries describe shape (field set / output structure), not narrative; IU describes meaning.
§2.2 Build-once, reuse-many — singleton body source
information_unit.canonical_body_* (and iu_version for versioned body) is the only SoT for IU narrative. Render layer materializes for any surface (task UI, workflow doc viewer, notification body, audit log, MOUT render). Sentinel: design-time grep of tasks.body, workflow_step_def.description_text, event_outbox.payload.body_text must return zero non-render-template rows.
§2.3 No duplicate text invariant (D2.3) — render-layer pattern
Every IU body display goes through a render call:
render_iu_body(iu_unit_id, iu_version_id, render_surface, render_context) → bytes
Render surfaces (paper):
task.envelope.instruction— MOT region 4 (instruction).workflow.doc.step_box— Standard Process View step node body popover.notification.iu_event— notification render.mout.inline_block— MOUT inline block in MOT region 3 (reference).governance.audit_excerpt— audit timeline excerpt.
Render emits iu.rendered event (per 03-event-5layer-… §3.3). Sentinel: any surface displaying IU content corresponds to a render_iu_body call site.
MP-D6 — render_iu_body permission / cache / audit contract (binding):
Pre-render checks (refuse render if any fails; each refusal logged to event_validation_audit with a structured reason code):
| Check | Refusal code | Meaning |
|---|---|---|
iu_version_exists |
iu_version_not_found |
(iu_unit_id, iu_version_id) resolves to a real iu_version row. |
governance_state_allowed |
iu_governance_state_blocked |
IU governance_state ∈ allowed set per surface (e.g. notification.iu_event allows only active; governance.audit_excerpt may show deprecated/archived with badge). Surface→allowed-states map declared in dot_config render.governance_state_allowed.<surface>. |
permission_filter_backend |
render_permission_denied |
Backend permission predicate (fn_render_permission_check(surface, render_context, principal)) returns true. Permission is backend-enforced; Nuxt never decides visibility. |
context_scope_allowed |
render_context_scope_mismatch |
render_context (workflow_run_id / task_run_id / notification_target_id / audit_trace_id) is scoped to the principal's reachable graph; cross-context render refused. |
Audit event (mandatory). Every successful render_iu_body call MUST emit a single iu.rendered event into event_outbox carrying iu_unit_id, iu_version_id, render_surface, render_context_id, principal_id, permission_scope_hash, cache_hit ∈ {true, false}, trace_id. Refused renders MUST emit iu.render_refused with the refusal code. Sentinel: zero IU body bytes leave PG without a corresponding iu.rendered (or refusal) row.
Cache key (binding):
render_cache_key = hash(
iu_unit_id,
iu_version_id,
render_surface,
permission_scope_hash -- digest of permission-affecting context (principal role set, tenant, language)
)
permission_scope_hash MUST be part of the cache key so that two principals with different permissions never share the same cache entry. render_context fields that affect the rendered bytes (locale, surface variant, dark/high-contrast mode) extend the key per render_cache_key_extension.<surface> declared in dot_config.
Notification render — no permission leak. Notification surface (notification.iu_event) MUST render IU content filtered through the recipient's permission scope, NOT the producer's. If recipient's permission_filter_backend denies (or partially denies) parts of the IU body, the notification renders only the permitted slice (or refuses with render_permission_denied if the slice is empty). Notification SHOULD NEVER include raw IU body bytes broader than what the recipient could read by directly opening the IU. Sentinel: notification payloads pass through the same permission predicate as direct IU view; no bypass path exists.
§2.4 4 Mothers as khuôn đúc (D2.4)
MOW/MOT/MOIT/MOUT shape flow / UI / IO contracts around IU but do not own:
- IU body / IU axes / IU split-merge — Điều 38/39 own.
- Queue / event core / executor boundary / heartbeat — Điều 45 owns.
- Approval — Điều 32 owns.
- Birth registry / event_type registry — Điều 0-G owns.
§2.5 Uniform assembly primitive (D2.5) — design proof for 500-step
Same primitive scales:
- 2-step workflow → 2
workflow_step_defrows, each binding an IU brick or bundle, connected byworkflow_step_relations. - 500-step workflow → 500
workflow_step_defrows (or N bundles each covering K steps), sameworkflow_step_relationsconnecting them, same MOW orchestration.
No separate schema, no separate component path. Long-workflow UI uses virtualization (see WS4 §6.3). Sentinel: workflows.step_count distribution covers full range without a sibling workflow_long_step_def table.
§2.6 IU version policy (D2.6 + OD15) — design at requirement level
- Active workflow_run pins IU version. Step run captures
pinned_iu_version_idat step entry. Any IU edit after that does NOT affect the running step (no in-flight surprise). - New workflow_run picks per policy. Per-workflow
iu_pin_policycolumn (paper) onworkflow_def:pin(default) /auto_upgrade_minor/auto_upgrade_major_with_approval/hybrid_per_step. - Upgrade in flight blocked. Only governance-approved migrations move an active workflow_run to a new IU version (rare; Điều 32 + Điều 30 reversibility).
- Bundle versioning composes. An IU bundle has its own version; bundle version pins members. Migrating a bundle version migrates all bound steps consistently.
Default per OD15: pin for all workflows; opt-in upgrade per workflow. Future flexibility preserved.
§2.7 Editing IU does not require touching multiple tables
Edit lifecycle:
- Author edits IU → new
iu_versionrow +iu.editedevent. - KG impact analysis (Rev2 §9) lists active workflows using prior version — surfaces in governance UI (
vw_iu_impact_analysis(iu_unit_id, new_version_id)). - Per workflow policy (§2.6), upgrade rolls forward — or stays pinned.
- Render layer always pulls pinned version for active runs; new runs pick per policy.
Sentinel: editing an IU never requires UPDATE on workflow_step_def, tasks, iu_notification_event, etc.
§3. IU as Process Brick — 11 fields (Rev2 §3)
§3.1 Brick fields (design schema sketch)
These fields are exposed per IU through information_unit row + binding tables — most live on information_unit itself; some derive from joins.
| Field | Storage location | Vocab / type | Source |
|---|---|---|---|
iu_unit_id |
information_unit.iu_unit_id [VL] |
text PK | row 1 |
iu_version_id |
iu_version.iu_version_id [VL] |
uuid | row 1 |
iu_role_in_process |
new column on iu_process_binding (proposal) or denormalized on IU |
enum: instruction | decision_gate | input_contract | output_contract | policy | checklist | SOP | validation_rule | event_hook | report_context |
new vocab dot_config vocab.iu_role_in_process.* |
assembly_slot |
new iu_assembly_slot_registry (paper) |
enum per parent role (MOW step slot / MOT region / MOIT field group / MOUT block) | row 27 iu_three_axis_envelope (axis source for slot resolution) |
precondition_config |
new on iu_process_binding |
jsonb (config DSL) → references trigger/guard registries | row 4 IU trigger model |
postcondition_config |
new on iu_process_binding |
jsonb (emitted events + output contracts + next-step signals) | row 4 |
io_contract_refs |
new on iu_process_binding |
jsonb (refs to MOIT/MOUT schema rows) | rows 28-31 (CRS-gated) |
executor_class_ref |
new on iu_process_binding |
text FK → executor_class_registry |
row 14, row 20, G3 |
event_contract_ref |
new on iu_process_binding |
text[] FK → event_type_registry |
row 10 |
kg_edge_refs |
derived view over iu_kg_edge |
text[] | row 21 (KG edges) |
governance_state |
iu_lifecycle_log derived current state |
enum: proposed | approved | active | deprecated | archived |
row 8 |
iu_process_binding is a new binding table (paper) keyed by (iu_unit_id, role_in_process, scope_ref) so the same IU can have different process roles in different contexts (e.g. instruction in MOT, validation_rule in MOIT).
§3.2 Role-in-process taxonomy
| Role | Meaning | Typical binding sites |
|---|---|---|
instruction |
The "how-to" content for a step/task | MOT region 4; Standard Process View step body |
decision_gate |
A binary/multi-way decision the workflow must resolve | MOW branching condition |
input_contract |
What input the step requires | MOIT form schema source |
output_contract |
What output the step must produce | MOUT block schema source + postcondition event payload |
policy |
A constraint / rule applied to the step | Step guard predicate config |
checklist |
An enumerated list of items to verify | MOT region 4 (rendered as checkbox UI) |
SOP |
Standard Operating Procedure pack | Multi-step bundle scope |
validation_rule |
Server-side rule applied to input/output | MOIT validation; MOUT computed field |
event_hook |
Trigger / consumer mapping at IU level | Producer registration; subscriber registration |
report_context |
Reporting / aggregation context | MOUT view definition |
Vocab lives in dot_config vocab.iu_role_in_process.* (paper). Adding a new role is a Birth Registry act (Điều 0-G).
§3.3 Precondition / postcondition config
Precondition config (paper DSL):
{
"kind": "all_of",
"items": [
{ "kind": "step_state", "step_def_id": "<id>", "state": "completed" },
{ "kind": "trigger_event", "event_type": "external.callback_received", "matcher": { "tag": "vendor_invoice" } },
{ "kind": "time_gate", "after": "PT2H" }
]
}
Postcondition config (paper DSL):
{
"emit_events": [{ "event_type": "step.completed", "fields": ["iu_unit_id", "step_run_id"] }],
"output_contract_ref": "mout.invoice_review_summary",
"next_step_signals": [{ "to_step_def_id": "<id>", "kind": "ready" }]
}
Validation: precondition config validated at workflow_def proposal-accept time (fn_workflow_def_validate). Trigger events referenced must exist in event_type_registry. Step refs must exist in workflow_step_def.
§3.4 Uniform primitive (D2.5) — design schema
workflow_step_def (extension columns, paper):
workflow_step_def
step_def_id uuid PK
workflow_def_id uuid FK
step_label text
step_kind text -- 'iu' | 'bundle' | 'assembly_view' | 'task_template'
binding_iu_unit_id text nullable
binding_bundle_id text nullable
binding_assembly_view_id text nullable
binding_task_template_id uuid nullable
mandatory bool default true
optional bool default false
iu_pin_policy text -- 'pin' | 'auto_upgrade_minor' | 'auto_upgrade_major_with_approval' | 'hybrid_per_step' (overrides workflow_def default)
state_machine_id text FK -> state_machine_def
deadline_policy_jsonb jsonb
pic_assignment_policy_jsonb jsonb
...
Exactly one of binding_iu_unit_id | binding_bundle_id | binding_assembly_view_id | binding_task_template_id is non-NULL — enforced by check constraint (paper).
§3.5 KG bridge (Rev2 §9 + §3 kg_edge_refs)
iu_kg_edge (existing, rev1 §1) records semantic edges. Bridge to MOW/MOT:
- Workflow author can request KG suggestions for "what other IUs are typically used together" → query
iu_kg_edge+iu_usage_evidence(paper, see03-event-5layer-…§9). - KG proposals (add edge / bundle / split / merge / re-parent / no-action) land in the generic
proposaltable (WS4 §8) — never auto-mutate registry. - IU
kg_edge_refsfield is a derived view overiu_kg_edge; not a stored column.
Sentinel: KG never writes workflow_registry, iu_process_binding, or iu_bundle_* directly — only via proposal rows.
§3.6 IU does NOT own execute logic (Rev2 §3 boundary)
information_unit and its bindings carry stable knowledge + typed relations + contracts + governance metadata. Runtime execution lives in:
- MOW (orchestration — choose next step) — but MOW does not own executor either.
- Executor class (DOT / SQL / AI / Human / External / Notification / Render) — actually executes.
- MOT envelopes the task and calls executor class.
Sentinel: no DDL or function row stores executor code inside information_unit / iu_version.
§3.7 IU Bundle / Step Pack (Rev2 §4)
iu_piece_collection + iu_piece_membership + iu_collection_template_* [VL row 26] mapped to bundle:
| Concept | Existing table | Bundle role |
|---|---|---|
| Bundle id + version | iu_piece_collection (extend with bundle_version) |
Stable bundle pointer |
| Member IUs + order | iu_piece_membership (with ordinal, member_role) |
N IU members + slot order + typed role |
| Template (reusable bundle shape) | iu_collection_template_* |
Bundle template for reuse |
| Governance state | iu_lifecycle_log (extended scope) |
Lifecycle |
Bundle binding modes (Rev2 §4 R4.4):
- Mode (a)
step_kind='iu'— single IU brick binding. - Mode (b)
step_kind='bundle'— IU bundle binding (multiple IUs with typed roles). - Mode (c)
step_kind='assembly_view'— typed IU assembly view (e.g. all IUs of roleinstructionwith tagvendor_review). - Mode (d)
step_kind='task_template'— IU-backed task template (defines task envelope + bound IU(s)).
Sentinel: every workflow_step_def row has exactly one of the 4 binding refs populated; no body text.
§3.8 Bundle versioning + governance
iu_piece_collection (extension)
bundle_id uuid PK
bundle_version text semver
governance_state text -- 'proposed' | 'approved' | 'active' | 'deprecated' | 'archived'
active_active_unique boolean -- partial index ensuring 1 active per bundle_id
…
Bundle bump = new version row + governance proposal + Điều 32 approval if active_workflow_run count > 0 for prior version.
§4. 4 Mothers binding map
§4.1 MOW — IU Assembly Orchestrator binding
| Concern | Design | PG substrate | Reuse |
|---|---|---|---|
| Workflow graph | workflow_def + workflow_step_def + workflow_step_relations |
workflows + workflow_steps + workflow_step_relations [VL row 16] |
reuse |
| Workflow runtime | workflow_run + step_run (paper) |
reuse workflows for def, add workflow_run for runtime — paper-only; concrete shape in Phase 1 |
extension |
| Step binding | workflow_step_def.binding_* (4 modes — §3.7) |
extension columns | extension |
| Branching condition | workflow_step_relations + condition config jsonb |
reuse | reuse |
| Parallel branches | workflow_step_relations with parallel_group_id |
extension | extension |
| Sub-workflow boundary | workflow_step_def.binding_sub_workflow_def_id (mode addition) |
extension | extension |
| Proposal mode | workflow_change_requests [VL row 17] |
reuse | reuse |
| Categories / classification | workflow_categories [VL row 18] |
reuse | reuse |
| Long-running snapshot / replay | workflow_run_snapshot (paper, derived) |
extension | extension |
| Resume safety | step_run.pinned_iu_version_id + replay events |
extension | extension |
Boundary: MOW orchestrator (process / function) reads workflow_def, fires step ready events, listens for step completed events, advances graph. MOW does not own queue (job_queue lives under Điều 45), does not own IU body (Điều 38/39), does not own approval (Điều 32).
Sentinel: MOW source contains zero IU body writes; MOW source has zero approval logic; queue inserts go through Layer 2 broker dispatch (§4 of 03-event-5layer-…).
§4.2 MOT — IU-Backed Task Envelope
4 UI regions (Rev2 §5.2) render from refs, not copies:
| Region | Content source |
|---|---|
| Header | task_run metadata (id, PIC, deadline, status, state_code, waiting_facet, trace_id) |
| Input (region 1) | MOIT contract referenced by IU brick / bundle binding → <MOITForm formId contextRef /> |
| Reference (region 2) | MOUT contract referenced → <MOUTBlock blockId contextRef /> |
| Instruction (region 3 according to brief §5.2 (header/input/reference/instruction); we adopt the same ordering) | IU or IU bundle render via render_iu_body(...) |
Format declared in config: text / video / audio / sơ đồ (declared per IU binding via render_format field).
Automated task envelope = same task_run row, no UI; executor leases and runs.
MOT is not an executor (Rev2 §11.5 + §5.2). MOT calls executor class registered in executor_class_registry (see 03-event-5layer-… §5.1).
MOT does not own approval (Rev2 §5.2 + §11). Approval calls go to Điều 32 surface.
PG substrate:
| Concern | Design | PG substrate | Reuse |
|---|---|---|---|
| Task def (template) | task_def (paper) |
reuse tasks for runtime; add task_def for templates — Phase 1 |
extension |
| Task runtime | task_run (paper) |
reuse tasks + add task_run |
extension |
| Checkpoints | task_checkpoints [VL row 19] |
reuse | reuse |
| Comments | task_comments [VL row 19] |
reuse | reuse |
| State machine | state_machine_id per task_run |
new state_machine_registry |
extension |
| IU binding | task_def.binding_iu_unit_id / binding_bundle_id / binding_assembly_view_id |
extension | extension |
§4.3 MOIT — IU-Context-Aware Input
| Concern | Design | PG substrate | CRS gate |
|---|---|---|---|
| Field definitions | field_registry [CRS row 28] |
survey-gated | G7 |
| Form definitions | input_form_registry [CRS row 29] |
survey-gated | G7 |
| Per-field IU link | field_registry.iu_unit_id (paper) |
survey-gated; need to verify field_registry shape exists | G7 |
| Form binding to IU-task context | input_form_registry.context_kind ∈ task_def | step_def | iu_bundle |
survey-gated | G7 |
| Direct vs staging policy | form_submission_policy (paper) — direct | staging_then_approve |
extension | — |
| Validation | validation_rule (IU role) refs |
extension | — |
| Nuxt component | <MOITForm formId contextRef /> zero logic |
— | — |
Critical CRS gate: WS8 §S1 must survey field_registry / input_form_registry before any of these design extensions become real. If survey shows the registries differ from rev1 §6.3 inferred shape, design must adapt before Phase 1. MP-D7 binding (06-… §S16): no executable artifact may reference these registries by literal name until VL or Điều-32-approved shape-adapter.
DOT assembly: registry → DOT function checks fields against vocab → assembles form structure + validation. Existing pattern (rev1).
§4.4 MOUT — IU-Backed Output Views
| Concern | Design | PG substrate | CRS / OD |
|---|---|---|---|
| Output / report blocks | output_table_registry [CRS row 30] |
survey-gated | G7 |
| DOT functions for aggregation | dot_function_registry [CRS row 31] |
survey-gated; OD13 ownership | G7, OD13 |
| Block binding to IU source | output_table_registry.iu_source_id (paper) |
survey-gated | G7 |
| SQL link | iu_sql_link [VL row 5] |
reuse | — |
| Computed fields | generated columns / materialized views / DOT functions (per Rev2 §5.4) | reuse + extension | OD13 |
| Inline (in MOT region 2 reference) | <MOUTBlock blockId contextRef /> zero logic |
— | — |
| Matrix independent route | <MOUTTable tableId contextRef /> zero logic |
— | — |
| Realtime | through realtime gateway (§7 of 03-event-5layer-…) |
gateway | — |
| Permission filter | backend route on every MOUT fetch | gateway | — |
OD13 default kept: MOUT-aligned namespace for dot_function_registry (e.g. dot.fn.mout.invoice_total). Registry SoT in PG. See 06-… §S13. MP-D7 binding (06-… §S16): no executable artifact may reference output_table_registry / dot_function_registry by literal name until VL or Điều-32-approved shape-adapter.
§4.5 Directus boundary (Rev2 §12 row 23)
Directus = API/admin/staging only:
- Allowed: admin UI for IU/registry CRUD via Directus collection wrappers (governed), staging data for
proposalrows pre-approval. - Forbidden: Directus realtime as app event plane (Rev2 §15 L2/L6 + boundary); Directus flows running app workflow logic (legacy flows respected but not extended).
- Sentinel: any Directus row that mirrors a PG registry row must point back to PG primary row (Hiến pháp NT13).
§4.6 No-Double-Ownership — design check
| Concern | Owner | This design's relation |
|---|---|---|
| Queue / event core / executor boundary / state machine ≥9 / heartbeat | Điều 45 | consume / call only |
| IU axis / compose / split / merge / SQL link / structure ops | Điều 38 + Điều 39 | reference / bind only |
| Approval quorum | Điều 32 | call API only |
| DOT lifecycle | Điều 35 v5.2 | call DOT pair only |
| UI render shell | Điều 28 / S178 | implement only as render |
| 4-DB / 3-layer | Điều 33 v2.1 | route Nuxt → backend gateway → PG/Directus |
| Birth registry | Điều 0-G | register IU / event_type / executor_class / state |
| Governance org | Điều 37 v3.3 | same UI / backend filter |
| Reversibility | Điều 30 | every extension has rollback |
| Integrity / audit | Điều 31 v1.2 | every binding has audit row |
| Assembly First | Điều 7 | OSS as adapter only |
| 4 Mothers app layer | Future Điều XX | only NEW concern owned by this design |
§5. IU version policy (OD15 default kept)
§5.1 Per-workflow_def iu_pin_policy
workflow_def.iu_pin_policy:
'pin' -- default; active workflow_run pins versions
'auto_upgrade_minor' -- auto-upgrade minor version (additive changes)
'auto_upgrade_major_with_approval' -- major upgrade only with Điều 32 approval
'hybrid_per_step' -- per-step override via workflow_step_def.iu_pin_policy
Per-step override available for hybrid_per_step workflows.
§5.2 Bundle version pins members
When a bundle version is pinned, all its IU member versions are also pinned (transitively). Bundle bump produces a new pin set; old runs stay on prior set.
§5.3 Edit IU during active run — no in-flight surprise
Step_run captures pinned_iu_version_id at step entry (T1 / T2 in 02-step-state-machine-… §4). Subsequent IU edits create new versions but do not affect the pinned step. Render layer fetches by pinned version.
§5.4 Migration of active run to new IU version
Migration scenario:
- Critical bug in IU body (e.g. instruction wrong).
- Author releases hotfix IU version.
- Operator initiates "rolling upgrade" — proposal: migrate active step_runs to new pin.
- Điều 32 approval required.
- On approval,
step_run.pinned_iu_version_idupdated in single TX + emitsstep.iu_version_migrated. - Audit row in
iu_lifecycle_logrecords actor + approval ref + prior version.
Sentinel: zero step_run.pinned_iu_version_id UPDATE without an approval_id reference in the same audit row.
§6. Governance lifecycle for IU artifacts
§6.1 IU governance state machine
States: proposed → approved → active → deprecated → archived.
Transitions:
| From | To | Actor | Trigger | Audit |
|---|---|---|---|---|
| (none) | proposed |
author | RPC iu_propose | iu_lifecycle_log: created |
proposed |
approved |
reviewer (Điều 32) | RPC approve | iu_lifecycle_log: approved + approval_id |
approved |
active |
system | governance promote | iu_lifecycle_log: activated |
active |
deprecated |
governance | RPC deprecate (with reason_code) | iu_lifecycle_log: deprecated + reason |
deprecated |
archived |
system | timer / governance | iu_lifecycle_log: archived |
active |
active |
author + Điều 32 | RPC edit_active (creates new version) | iu_lifecycle_log: edit_active + new_version_id |
This is the IU-scope state machine, distinct from the step/task state machine in WS4. Same state_machine_registry substrate.
§6.2 Bundle governance
Bundle parallels IU governance (proposed/approved/active/deprecated/archived). Bundle activation requires all member IUs to be active.
§6.3 Audit ledger
iu_lifecycle_log [VL row 8] records all transitions. New fields (paper) for binding to 4 Mothers context: affected_workflow_def_ids, affected_step_run_ids (for in-flight migration audit).
§7. Usage Evidence schema sketch (Rev2 §10 — bridge to KG)
See 03-event-5layer-realtime-dlq-design.md §9 for derivation. Here the role of the table from the IU side:
iu_usage_evidence
evidence_id uuid PK
signal_kind text -- 8 signal classes
iu_unit_id_a text
iu_unit_id_b text nullable -- pair signals
workflow_run_id uuid nullable
step_run_id uuid nullable
evidence_payload_jsonb jsonb
evidence_window_start timestamptz
evidence_window_end timestamptz
evidence_strength float -- normalized
computed_at timestamptz
computed_by_fn text
KG feedback reads from this table and emits proposals. Sentinel: KG never reads event_outbox / job_queue directly — only iu_usage_evidence.
§8. Cross-references
- 9-state floor / transitions / workflow UI / governance UI →
02-step-state-machine-and-workflow-ui-design.md. - Event 5-layer / executor class registry / heartbeat / idempotency / realtime gateway / DLQ →
03-event-5layer-realtime-dlq-design.md. - OSS labels for any tool that might encroach on IU / 4 Mothers boundary →
05-oss-candidate-strategy-rev2.md. - IU version policy default (OD15), proposal table OD2, executor_class_registry ownership OD3, dot_function_registry OD13, generic vs per-domain proposal OD2 — see
06-open-decisions-and-readiness.md.
§9. Acceptance criteria for this WS (WS2 + WS3)
A1. IU-centered doctrine §2 preserves 2..500 uniform primitive; no parallel workflow track.
A2. IU brick fields §3.1 cover Rev2 §3 11 fields with PG substrate + vocab anchors.
A3. IU bundle §3.7 maps to existing iu_piece_collection* row 26 [VL]; no new substrate when reuse fits.
A4. 4 Mothers binding §4 reuses workflows, workflow_steps, workflow_step_relations, workflow_change_requests, tasks, task_checkpoints, task_comments, workflow_categories [VL]; introduces extension columns only.
A5. CRS rows (§12 rows 28-31) gated by survey in WS8 §S1; design depends on no CRS row prior to verified_live. MP-D7 strict form applies in §4.3 + §4.4: no executable artifact references these registries by name until VL or Điều-32-approved shape-adapter.
A6. IU version policy §5 default pin; per-workflow override; migration requires Điều 32 approval; sentinel for unauthorized migration.
A7. No-double-ownership §4.6 preserved — only NEW concern = 4 Mothers application layer (future Điều XX).
A8. KG bridge §3.5 — proposals only, never auto-mutate.
A9. Render layer §2.3 — IU body singleton via render_iu_body(...) call sites. MP-D6 binding: pre-render checks (iu_version_exists, governance_state_allowed, permission_filter_backend, context_scope_allowed) + mandatory iu.rendered audit event + cache key includes permission_scope_hash + notification render uses recipient-scope permission.
A10. No PG mutation; no migration; no DOT command run; no law enactment; all schemas paper-only.
End WS2+WS3 design.