02 — AX-PROCESS Generator Gap Root Cause
02 — AX-PROCESS Generator Membership Gap: Root Cause (Phase 2)
Symptom
Generated (v1) AX-PROCESS = 19 nodes; current = 22. Three nodes present in current and absent in generated: job:cut, WF-001, WF-002.
Source trace
The current contract chain is: current → current_v2 → reliability → contract_v2 → contract (v1 base UNION). The v1 base UNION holds the per-axis legs. The AX-PROCESS portion has THREE legs:
- Candidate leg: from wf_process_candidate (candidate_code as node, member_count as count) → 19 rows.
- job:cut leg: a single literal node job:cut; count = distinct job_kind in job_queue matching the cut prefix = 8; substrate job_queue; governance READY_FOR_PRESIDENT; lifecycle verified.
- workflows leg: from the workflows table (process_code as node, title as label); count = number of workflow_steps for that workflow; lifecycle born; governance BORN_NO_AXIS_ASSIGNMENT; substrate workflow_steps. This yields exactly WF-001 (10) and WF-002 (60) — the workflows table has 2 rows.
Why the generator missed them
The generator manifest declared AX-PROCESS source_kind candidate+workflow+jobcut and node_count 22, but the manifest's generated_leg_sql bound ONLY wf_process_candidate. The job:cut and workflows legs were declared in intent but never emitted into the leg SQL. So the generated backbone produced 19, not 22.
Decision: union into the AX-PROCESS leg (not a separate axis)
These three are all AX-PROCESS nodes in the current contract (same axis_code, same route prefix). The correct fix is to UNION the candidate, job:cut, and workflows legs into one AX-PROCESS generated leg — reproducing the current contract's structure exactly. Confirmed cardinalities: candidate 19, job:cut count 8, workflows 2 (WF-001, WF-002) → 22. The 19 candidate nodes already matched current on count (the v1 count-diff total was 1, entirely AX-PXT), so only the membership of the 3 needs adding, with the same count expressions current uses.