Reconcile Phase Z family template/catalog counts before #42 (IMP-04b Catalog extension to 32 frames) or any #19 work that touches catalog/family/template behavior.
This issue is a pre-flight/prerequisite cleanup for #42. #42 should not expand the catalog until this count drift is resolved or explicitly accepted.
Out of Scope
Do not optimize any MDX sample.
Do not refactor frame selection behavior.
Do not alter Phase R behavior.
Do not start the full 32-frame catalog extension here.
Acceptance Criteria
Family count is consistent across tracked templates, on-disk active templates, catalog contracts, and docs.
The 11 tracked / 13 on disk / 11 catalog drift is either resolved or explicitly documented as intentional.
#42 can start from a clean catalog/template baseline.
## Purpose
Reconcile Phase Z family template/catalog counts before #42 (`IMP-04b Catalog extension to 32 frames`) or any #19 work that touches catalog/family/template behavior.
## Source
- #50 INTEGRATION-AUDIT-01
- `docs/architecture/INTEGRATION-AUDIT-01-REPORT.md` Section 5, Section 6, Section 9, Section 10
- Audit follow-up F-2
- Related open issue: #42
## Problem
Audit #50 found family count drift:
- 11 tracked family templates
- 13 family templates on disk
- 11 `frame_contracts.yaml` entries
The 2 extra on-disk WIP templates are:
- `app_sw_package_vs_solution.html`
- `pre_construction_model_info_stacked.html`
This is not a current closed-issue blocker, but it can become a contract problem before #42 expands the catalog to 32 frames.
## Scope
Decide and apply one consistent treatment:
- Track and register the 2 WIP templates if they are valid Phase Z families.
- Or move/remove/quarantine them if they are not part of the contracted catalog.
- Update docs so code/docs/catalog agree on the active family count.
- Keep `frame_contracts.yaml` aligned with the selected template set.
## Relationship to #42
This issue is a pre-flight/prerequisite cleanup for #42. #42 should not expand the catalog until this count drift is resolved or explicitly accepted.
## Out of Scope
- Do not optimize any MDX sample.
- Do not refactor frame selection behavior.
- Do not alter Phase R behavior.
- Do not start the full 32-frame catalog extension here.
## Acceptance Criteria
- Family count is consistent across tracked templates, on-disk active templates, catalog contracts, and docs.
- The `11 tracked / 13 on disk / 11 catalog` drift is either resolved or explicitly documented as intentional.
- #42 can start from a clean catalog/template baseline.
Frame 9 (1171281180); header dated 2026-05-14; cited as V4 04-1 top rank-1 (의미 conf=0.722, structure cardinality 5)
?? untracked
Both files were authored during V4 / IMP-04 / smoke exploration work but never landed in frame_contracts.yaml, never git add-ed, and never declared under any closed issue. They are experimental partials sitting on disk.
The doc-side count is also out of sync — docs/architecture/IMP-18-SVG-GAP-REPORT.md:28 and :51 cite "13 files", forward-looking and therefore consistent with disk but inconsistent with the tracked/contracted baseline of 11.
2. Why this is a #42 pre-flight (not a #42-internal cleanup)
#42 IMP-04b Catalog extension to 32 frames is open and plans to expand 11/32 → 32/32 via Track A 잔여 5 + Track B 12 + Track C 1. If #42 starts from a disk=13 / tracked=11 / catalog=11 baseline, two failure modes appear:
Silent re-use — #42 picks one of the 2 WIP filenames as a target slot, accidentally inherits the WIP HTML body without an explicit frame_contracts.yaml decision. Result: catalog growth without a clean per-frame audit trail (violates feedback_workflow_atomicity_rules — 1 commit = 1 decision unit).
Count drift compounding — #42 lands new partials in tracks but the 2 WIP files remain unreconciled; the disk count climbs to 15 / 25 / etc. while tracked + catalog stay below disk count, hiding the WIP delta behind a moving total.
The audit (INTEGRATION-AUDIT-01-REPORT.md §10.2) flagged this explicitly: "Must NOT be folded into #19 silently". The same logic carries to #42 (per-issue atomicity).
3. Three candidate treatments (issue body wording)
each entry needs frame_id, family, cardinality, role_order, visual_hints.min_height_px, accepted_content_types, sub_zones, payload.builder block — same surface as the 8 IMP-04 entries
IMP-18 13 stays correct
conflicts with #42 — does catalog growth for 2 of #42's planned remaining 21 frames pre-emptively
(b) quarantine — move 2 templates to templates/phase_z2/families/_wip/ (or remove)
tracked 11 = catalog 11 = disk 11
none
IMP-18 must flip 13 → 11 (2 occurrences)
frees #42 — #42 can re-introduce these frames cleanly through its own Track A / B audit
(c) explicit WIP footnote — leave files on disk, add templates/phase_z2/families/README.md or similar noting 2 WIP files belong to future #42 work
tracked 11, catalog 11, disk 13 (unchanged)
none
IMP-18 keeps 13 with footnote
does not actually reconcile the drift; documents it instead — soft fix
Recommendation (open for user GO): (b) quarantine, because:
Audit §10.2 explicit guidance ("Must NOT be folded into #19 silently") + workflow atomicity rule ⇒ catalog growth needs its own dedicated commit + issue.
(a) does 2 of #42's frames prematurely under #52's scope label — wrong issue, wrong atomic unit.
(c) is the lowest-effort but leaves the contract drift exactly as is; it satisfies "explicitly documented" in AC bullet 2 but not "reconciled".
Both files are untracked WIP — no git log history to preserve, no orphaned references.
4. Scope-lock proposal (pending treatment choice)
Hard out-of-scope (locked, all 3 options):
No src/** runtime code edits — mapper, classifier, router, pipeline, retry, fit_verifier all read-only.
No tests/** edits (no new pytest fixtures, no tests/phase_z2/ touch).
No MDX sample edits — samples/mdx_batch/{03,04,05}.mdx and any other sample left untouched.
No frame_partial behavior change, no V4 selection logic change, no Phase R'/Q regression surface.
No #42 work — do NOT register new frame_contracts.yaml entries for the existing 11 frames either (no piggyback edits).
No audit-report retro-edits — INTEGRATION-AUDIT-01-REPORT.md is a frozen snapshot; do NOT amend it.
Touch surface per option (single commit, 1 decision):
chore(IMP-52): quarantine 2 untracked WIP family templates, align IMP-18 count to 11
(c) WIP footnote
templates/phase_z2/families/README.md (new doc), docs/architecture/IMP-18-SVG-GAP-REPORT.md (footnote on 13)
docs(IMP-52): document 2 WIP family templates as pre-#42 unreconciled
Guardrails (all options):
Stage 5 commit = single decision unit per feedback_workflow_atomicity_rules; no piggyback (no IMP-18 wording cleanup beyond the count edit, no audit-report sync, no #42 prep).
Stage 4 verify = pytest -q tests/phase_z2/ baseline must remain unchanged from current head; no new test added, no skipped test (this issue is contract-only, not runtime-behavior).
Stage 4 verify = grep -cE "^[a-z_]+:$" templates/phase_z2/catalog/frame_contracts.yaml AND git ls-files templates/phase_z2/families/ | wc -l AND ls templates/phase_z2/families/*.html | wc -l MUST be reported per-axis with the post-edit count for the scope row of the AC table.
Scope-qualified verification per feedback_scope_qualified_verification — AC report MUST state "tracked / disk / catalog post-edit = X / Y / Z" explicitly, no unqualified "counts align" wording.
No hardcoding shortcut per feedback_no_hardcoding.md — the doc count edit is a literal fix at IMP-18-SVG-GAP-REPORT.md:28 + :51, NOT a process change.
5. Open decision point (requires Stage 2 GO)
Treatment choice — (a) / (b) / (c) is the orchestrator/human decision. Stage 1 cannot resolve it without explicit GO because each option has a different commit semantic and different #42 collateral.
If GO defaults to my recommendation, Stage 2 plans option (b). Otherwise the chosen option is locked into Stage 2's plan with the exact touch surface table above.
6. Out-of-scope confirmations (per issue body)
✅ No MDX sample optimization.
✅ No frame selection behavior refactor.
✅ No Phase R' alteration.
✅ No 32-frame catalog extension started here (this is the pre-flight, not the work).
git ls-files templates/phase_z2/families/ → 11 entries (the 13 above minus app_sw_package_vs_solution.html and pre_construction_model_info_stacked.html)
No src/**, tests/**, samples/** touched in this stage.
FINAL_CONSENSUS: YES
# [Claude #1] Stage 1 — Problem Review (Round 1)
## 1. Root cause
The 13/11/11 drift is real and reproducible on audit date 2026-05-19. Live verification:
| count | command | result |
|---|---|---|
| family templates on disk | `ls templates/phase_z2/families/*.html` | **13** |
| family templates tracked in git | `git ls-files templates/phase_z2/families/` | **11** |
| `frame_contracts.yaml` top-level entries | `grep -cE "^[a-z_]+:$" templates/phase_z2/catalog/frame_contracts.yaml` | **11** |
The 11 tracked / 11 contracted entries are 1:1 aligned (each tracked `.html` has a matching top-level key in `frame_contracts.yaml`).
The 2 disk-only files are *uncommitted* WIP, NOT untracked-in-catalog-only:
| file | header attribution | git status |
|---|---|---|
| `templates/phase_z2/families/app_sw_package_vs_solution.html` | Frame 23 (`1171281203`) "Application S/W 의 구분"; cited as `bim_dx_comparison_table`-equivalent (builder `process_product_pair`) | `??` untracked (top-of-conversation `git status`) |
| `templates/phase_z2/families/pre_construction_model_info_stacked.html` | Frame 9 (`1171281180`); header dated 2026-05-14; cited as V4 04-1 top rank-1 (의미 conf=0.722, structure cardinality 5) | `??` untracked |
Both files were authored during V4 / IMP-04 / smoke exploration work but never landed in `frame_contracts.yaml`, never `git add`-ed, and never declared under any closed issue. They are experimental partials sitting on disk.
The doc-side count is also out of sync — `docs/architecture/IMP-18-SVG-GAP-REPORT.md:28` and `:51` cite "**13** files", forward-looking and therefore consistent with disk but inconsistent with the tracked/contracted baseline of 11.
## 2. Why this is a #42 pre-flight (not a #42-internal cleanup)
`#42 IMP-04b Catalog extension to 32 frames` is **open** and plans to expand `11/32 → 32/32` via Track A 잔여 5 + Track B 12 + Track C 1. If #42 starts from a `disk=13 / tracked=11 / catalog=11` baseline, two failure modes appear:
1. **Silent re-use** — #42 picks one of the 2 WIP filenames as a target slot, accidentally inherits the WIP HTML body without an explicit `frame_contracts.yaml` decision. Result: catalog growth without a clean per-frame audit trail (violates [[feedback_workflow_atomicity_rules]] — 1 commit = 1 decision unit).
2. **Count drift compounding** — #42 lands new partials in tracks but the 2 WIP files remain unreconciled; the disk count climbs to 15 / 25 / etc. while tracked + catalog stay below disk count, hiding the WIP delta behind a moving total.
The audit (`INTEGRATION-AUDIT-01-REPORT.md` §10.2) flagged this explicitly: *"Must NOT be folded into #19 silently"*. The same logic carries to #42 (per-issue atomicity).
## 3. Three candidate treatments (issue body wording)
| option | what it does | catalog impact | doc impact | #42 collateral |
|---|---|---|---|---|
| (a) **track + register** — add 2 entries to `frame_contracts.yaml` + `git add` 2 templates | catalog 11 → 13, tracked 11 → 13, disk 13 | each entry needs `frame_id`, `family`, `cardinality`, `role_order`, `visual_hints.min_height_px`, `accepted_content_types`, `sub_zones`, `payload.builder` block — same surface as the 8 IMP-04 entries | IMP-18 `13` stays correct | **conflicts with #42** — does catalog growth for 2 of #42's planned remaining 21 frames pre-emptively |
| (b) **quarantine** — move 2 templates to `templates/phase_z2/families/_wip/` (or remove) | tracked 11 = catalog 11 = disk 11 | none | IMP-18 must flip `13` → `11` (2 occurrences) | **frees #42** — #42 can re-introduce these frames cleanly through its own Track A / B audit |
| (c) **explicit WIP footnote** — leave files on disk, add `templates/phase_z2/families/README.md` or similar noting 2 WIP files belong to future #42 work | tracked 11, catalog 11, disk 13 (unchanged) | none | IMP-18 keeps `13` with footnote | does not actually reconcile the drift; documents it instead — soft fix |
Recommendation (open for user GO): **(b) quarantine**, because:
- Audit §10.2 explicit guidance ("Must NOT be folded into #19 silently") + workflow atomicity rule ⇒ catalog growth needs its own dedicated commit + issue.
- (a) does 2 of #42's frames prematurely under #52's scope label — wrong issue, wrong atomic unit.
- (c) is the lowest-effort but leaves the contract drift exactly as is; it satisfies "explicitly documented" in AC bullet 2 but not "reconciled".
- Both files are untracked WIP — no `git log` history to preserve, no orphaned references.
## 4. Scope-lock proposal (pending treatment choice)
**Hard out-of-scope (locked, all 3 options):**
- No `src/**` runtime code edits — mapper, classifier, router, pipeline, retry, fit_verifier all read-only.
- No `tests/**` edits (no new pytest fixtures, no `tests/phase_z2/` touch).
- No MDX sample edits — `samples/mdx_batch/{03,04,05}.mdx` and any other sample left untouched.
- No frame_partial behavior change, no V4 selection logic change, no Phase R'/Q regression surface.
- No #42 work — do NOT register new `frame_contracts.yaml` entries for the existing 11 frames either (no piggyback edits).
- No audit-report retro-edits — `INTEGRATION-AUDIT-01-REPORT.md` is a frozen snapshot; do NOT amend it.
**Touch surface per option (single commit, 1 decision):**
| option | files touched | commit message style |
|---|---|---|
| (a) track + register | `templates/phase_z2/families/{2 WIP}.html` (git add), `templates/phase_z2/catalog/frame_contracts.yaml` (+2 entries), `docs/architecture/PHASE-Z-IMPLEMENTATION-ISSUE-BACKLOG.md` (count row if any) | `feat(IMP-52): track 2 WIP family templates + register frame_contracts entries` |
| (b) quarantine | `templates/phase_z2/families/_wip/{2 WIP}.html` (move target; or `rm`), `docs/architecture/IMP-18-SVG-GAP-REPORT.md` (`13` → `11`, 2 occurrences) | `chore(IMP-52): quarantine 2 untracked WIP family templates, align IMP-18 count to 11` |
| (c) WIP footnote | `templates/phase_z2/families/README.md` (new doc), `docs/architecture/IMP-18-SVG-GAP-REPORT.md` (footnote on `13`) | `docs(IMP-52): document 2 WIP family templates as pre-#42 unreconciled` |
**Guardrails (all options):**
- Stage 5 commit = single decision unit per [[feedback_workflow_atomicity_rules]]; no piggyback (no IMP-18 wording cleanup beyond the count edit, no audit-report sync, no #42 prep).
- Stage 4 verify = `pytest -q tests/phase_z2/` baseline must remain unchanged from current head; no new test added, no skipped test (this issue is contract-only, not runtime-behavior).
- Stage 4 verify = `grep -cE "^[a-z_]+:$" templates/phase_z2/catalog/frame_contracts.yaml` AND `git ls-files templates/phase_z2/families/ | wc -l` AND `ls templates/phase_z2/families/*.html | wc -l` MUST be reported per-axis with the post-edit count for the scope row of the AC table.
- Scope-qualified verification per [[feedback_scope_qualified_verification]] — AC report MUST state "tracked / disk / catalog post-edit = X / Y / Z" explicitly, no unqualified "counts align" wording.
- No hardcoding shortcut per [[feedback_no_hardcoding.md]] — the doc count edit is a literal fix at `IMP-18-SVG-GAP-REPORT.md:28` + `:51`, NOT a process change.
## 5. Open decision point (requires Stage 2 GO)
**Treatment choice — (a) / (b) / (c)** is the orchestrator/human decision. Stage 1 cannot resolve it without explicit GO because each option has a different commit semantic and different #42 collateral.
If GO defaults to my recommendation, Stage 2 plans option (b). Otherwise the chosen option is locked into Stage 2's plan with the exact touch surface table above.
## 6. Out-of-scope confirmations (per issue body)
- ✅ No MDX sample optimization.
- ✅ No frame selection behavior refactor.
- ✅ No Phase R' alteration.
- ✅ No 32-frame catalog extension started here (this is the pre-flight, not the work).
## === EVIDENCE ===
Commands run on audit date 2026-05-19 (live):
- `ls templates/phase_z2/families/*.html` → 13 files (full list: `app_sw_package_vs_solution.html`, `bim_current_problems_paired.html`, `bim_dx_comparison_table.html`, `bim_issues_quadrant_four.html`, `construction_bim_three_usage.html`, `construction_goals_three_circle_intersection.html`, `dx_sw_necessity_three_perspectives.html`, `info_management_what_how_when.html`, `pre_construction_model_info_stacked.html`, `process_product_two_way.html`, `sw_reality_three_emphasis.html`, `three_parallel_requirements.html`, `three_persona_benefits.html`)
- `git ls-files templates/phase_z2/families/` → 11 entries (the 13 above minus `app_sw_package_vs_solution.html` and `pre_construction_model_info_stacked.html`)
- `grep -cE "^[a-z_]+:$" templates/phase_z2/catalog/frame_contracts.yaml` → 11
- File header read: `templates/phase_z2/families/app_sw_package_vs_solution.html:1-28` → Frame 23 (`1171281203`), slots aligned with `bim_dx_comparison_table` builder `process_product_pair`
- File header read: `templates/phase_z2/families/pre_construction_model_info_stacked.html:1-30` → Frame 9 (`1171281180`), header date 2026-05-14, V4 04-1 top rank-1 match (의미 conf=0.722)
- Doc references read: `docs/architecture/IMP-18-SVG-GAP-REPORT.md:28` ("**13** files") + `:51` ("(13) + ... (2)")
- Audit cross-ref: `docs/architecture/INTEGRATION-AUDIT-01-REPORT.md` §5.2 row C6, §5.5 row "C6 family templates", §10.2 follow-up draft F-2 — all read and match.
- Top-of-conversation `git status` confirms both WIP files appear with `??` prefix.
- Issue #42 fetched (`GET /repos/Kyeongmin/C.E.L_Slide_test2/issues/42`) → state `open`, scope = "remaining 21/32 frames (현 active 11/32 → 32/32)", `Track A 잔여 5 frames` + `Track B 12 visual-pending frames` + `Track C 1 matching schema canonical` — confirms #42 will touch `frame_contracts.yaml` and `templates/phase_z2/families/`.
Files inspected (read-only): `INTEGRATION-AUDIT-01-REPORT.md` §5 §6 §9 §10, `frame_contracts.yaml` (full 730 lines), `IMP-18-SVG-GAP-REPORT.md` head, `app_sw_package_vs_solution.html` head, `pre_construction_model_info_stacked.html` head, `PHASE-Z-IMPLEMENTATION-ISSUE-BACKLOG.md` IMP-50 row.
No `src/**`, `tests/**`, `samples/**` touched in this stage.
FINAL_CONSENSUS: YES
The tracked template basenames and frame_contracts.yaml keys compare cleanly: no tracked family template is missing a contract entry, and no contract entry points at a missing tracked family template.
The two disk-only files are:
templates/phase_z2/families/app_sw_package_vs_solution.html - untracked; header identifies frame 23 / 1171281203; not present in frame_contracts.yaml.
templates/phase_z2/families/pre_construction_model_info_stacked.html - untracked; header identifies frame 9 / 1171281180; not present in frame_contracts.yaml.
Docs verified:
docs/architecture/INTEGRATION-AUDIT-01-REPORT.md already records F-2 as 11 tracked / 11 contracted / 13 on disk, names the same two WIP files, and scope-locks the reconciliation to templates/phase_z2/families/*.html, templates/phase_z2/catalog/frame_contracts.yaml, and docs/architecture/IMP-18-SVG-GAP-REPORT.md.
docs/architecture/IMP-18-SVG-GAP-REPORT.md cites templates/phase_z2/families/*.html as 13 files at lines 28 and 51, so it is aligned with disk count but not with the tracked/contracted baseline.
docs/architecture/IMP-04-FRAME-SUITABILITY-MATRIX.md references both template IDs as reusable candidates, but that is planning/evidence surface only; it does not register them in the runtime contract.
Scope-lock verdict:
Stage 1 root cause is correct.
No missing files found for the stated scope.
No hidden mismatch found between the 11 tracked templates and 11 catalog contracts.
The implementation stage should choose one explicit treatment for the two WIP files: track + register, remove/quarantine, or document as intentionally out-of-contract. It should not alter Phase R behavior, frame selection behavior, MDX samples, or begin the 32-frame #42 expansion.
docs/architecture/IMP-04-FRAME-SUITABILITY-MATRIX.md
Test results: Not run; Stage 1 explicitly says NO pytest.
Verified facts:
Disk family template count is 13.
Git-tracked family template count is 11.
frame_contracts.yaml top-level contract count is 11.
app_sw_package_vs_solution.html and pre_construction_model_info_stacked.html are untracked.
Neither WIP template ID appears in frame_contracts.yaml.
Tracked template basenames and contract keys have no Compare-Object diff.
IMP-18-SVG-GAP-REPORT.md cites 13 family files.
INTEGRATION-AUDIT-01-REPORT.md records F-2 with the same two WIP filenames and the same 11/11/13 count split.
FINAL_CONSENSUS: YES
[Codex #1] Stage 1 Problem Review (Round 1)
Root cause verified. The count drift is real and is limited to two untracked WIP family templates on disk:
| surface | verified count | finding |
|---|---:|---|
| `templates/phase_z2/families/*.html` on disk | 13 | includes 2 untracked WIP files |
| `git ls-files templates/phase_z2/families/*.html` | 11 | tracked family baseline |
| `templates/phase_z2/catalog/frame_contracts.yaml` top-level keys | 11 | contracted family baseline |
The tracked template basenames and `frame_contracts.yaml` keys compare cleanly: no tracked family template is missing a contract entry, and no contract entry points at a missing tracked family template.
The two disk-only files are:
- `templates/phase_z2/families/app_sw_package_vs_solution.html` - untracked; header identifies frame 23 / `1171281203`; not present in `frame_contracts.yaml`.
- `templates/phase_z2/families/pre_construction_model_info_stacked.html` - untracked; header identifies frame 9 / `1171281180`; not present in `frame_contracts.yaml`.
Docs verified:
- `docs/architecture/INTEGRATION-AUDIT-01-REPORT.md` already records F-2 as `11 tracked / 11 contracted / 13 on disk`, names the same two WIP files, and scope-locks the reconciliation to `templates/phase_z2/families/*.html`, `templates/phase_z2/catalog/frame_contracts.yaml`, and `docs/architecture/IMP-18-SVG-GAP-REPORT.md`.
- `docs/architecture/IMP-18-SVG-GAP-REPORT.md` cites `templates/phase_z2/families/*.html` as 13 files at lines 28 and 51, so it is aligned with disk count but not with the tracked/contracted baseline.
- `docs/architecture/IMP-04-FRAME-SUITABILITY-MATRIX.md` references both template IDs as reusable candidates, but that is planning/evidence surface only; it does not register them in the runtime contract.
Scope-lock verdict:
- Stage 1 root cause is correct.
- No missing files found for the stated scope.
- No hidden mismatch found between the 11 tracked templates and 11 catalog contracts.
- The implementation stage should choose one explicit treatment for the two WIP files: track + register, remove/quarantine, or document as intentionally out-of-contract. It should not alter Phase R behavior, frame selection behavior, MDX samples, or begin the 32-frame #42 expansion.
=== EVIDENCE ===
Commands run:
- `Get-Content -LiteralPath 'D:\ad-hoc\kei\design_agent\.orchestrator\tmp\codex_prompt.txt'`
- `Get-ChildItem -LiteralPath 'templates/phase_z2/families' -Filter '*.html' | Select-Object -ExpandProperty Name | Sort-Object`
- `git ls-files 'templates/phase_z2/families/*.html'`
- `git status --short -- 'templates/phase_z2/families' 'templates/phase_z2/catalog/frame_contracts.yaml' 'docs/architecture'`
- `Select-String -Path 'templates/phase_z2/catalog/frame_contracts.yaml' -Pattern '^[a-z_]+:' | ForEach-Object { $_.Line }`
- `Select-String -Path 'templates/phase_z2/families/app_sw_package_vs_solution.html','templates/phase_z2/families/pre_construction_model_info_stacked.html' -Pattern 'Frame|frame|117128|bim_dx|process_product|V4|rank|conf|2026' -Context 0,2`
- `rg -n "app_sw_package_vs_solution|pre_construction_model_info_stacked|13 files|13 family|11 tracked|frame_contracts|family templates" docs templates -g '!templates/phase_z2/families/app_sw_package_vs_solution.html' -g '!templates/phase_z2/families/pre_construction_model_info_stacked.html'`
- `Select-String -Path 'docs/architecture/INTEGRATION-AUDIT-01-REPORT.md' -Pattern '11 tracked|13|family|F-2|frame_contracts|app_sw_package_vs_solution|pre_construction_model_info_stacked|Must NOT|#19|#42' -Context 1,2`
- `Select-String -Path 'docs/architecture/IMP-18-SVG-GAP-REPORT.md' -Pattern '13 files|13|family templates|templates/phase_z2/families|app_sw_package_vs_solution|pre_construction_model_info_stacked' -Context 1,2`
- `(Get-ChildItem -LiteralPath 'templates/phase_z2/families' -Filter '*.html').Count`
- `(git ls-files 'templates/phase_z2/families/*.html' | Measure-Object).Count`
- `(Select-String -Path 'templates/phase_z2/catalog/frame_contracts.yaml' -Pattern '^[a-z_]+:').Count`
- `Select-String -Path 'templates/phase_z2/catalog/frame_contracts.yaml' -Pattern 'app_sw_package_vs_solution|pre_construction_model_info_stacked'`
- `$tracked = git ls-files 'templates/phase_z2/families/*.html' | ForEach-Object { [System.IO.Path]::GetFileNameWithoutExtension($_) } | Sort-Object; $contracts = Select-String -Path 'templates/phase_z2/catalog/frame_contracts.yaml' -Pattern '^[a-z_]+:' | ForEach-Object { $_.Line.TrimEnd(':') } | Sort-Object; Compare-Object -ReferenceObject $tracked -DifferenceObject $contracts | Format-Table -AutoSize`
Files checked:
- `D:\ad-hoc\kei\design_agent\.orchestrator\tmp\codex_prompt.txt`
- `templates/phase_z2/families/app_sw_package_vs_solution.html`
- `templates/phase_z2/families/pre_construction_model_info_stacked.html`
- `templates/phase_z2/catalog/frame_contracts.yaml`
- `docs/architecture/INTEGRATION-AUDIT-01-REPORT.md`
- `docs/architecture/IMP-18-SVG-GAP-REPORT.md`
- `docs/architecture/IMP-04-FRAME-SUITABILITY-MATRIX.md`
Test results: Not run; Stage 1 explicitly says NO pytest.
Verified facts:
- Disk family template count is 13.
- Git-tracked family template count is 11.
- `frame_contracts.yaml` top-level contract count is 11.
- `app_sw_package_vs_solution.html` and `pre_construction_model_info_stacked.html` are untracked.
- Neither WIP template ID appears in `frame_contracts.yaml`.
- Tracked template basenames and contract keys have no `Compare-Object` diff.
- `IMP-18-SVG-GAP-REPORT.md` cites 13 family files.
- `INTEGRATION-AUDIT-01-REPORT.md` records F-2 with the same two WIP filenames and the same 11/11/13 count split.
FINAL_CONSENSUS: YES
■ Decision: Option (c) — 2 WIP files remain in-place as explicitly-marked uncontracted WIP. templates/phase_z2/families/_WIP_FILES.md (tracked) is the single source of truth for the 11-active / 2-WIP split. frame_contracts.yaml runtime catalog untouched.
=== IMPLEMENTATION_UNITS ===
- id:u1summary:Add tracked WIP marker doc naming the 2 untracked WIP family templates as intentional, uncontracted, out-of-scope for runtime matcher; references#42 as future promote/remove gate.files:- templates/phase_z2/families/_WIP_FILES.mdtests:[]estimate_lines:35- id:u2summary:Correct IMP-18-SVG-GAP-REPORT.md L28 + L51 — change disk-only "13 files" cites to "11 contracted + 2 WIP untracked"; anchor _WIP_FILES.md.files:- docs/architecture/IMP-18-SVG-GAP-REPORT.mdtests:[]estimate_lines:12- id:u3summary:Append resolution marker to §10.2 F-2 in INTEGRATION-AUDIT-01-REPORT.md — record option (c), link _WIP_FILES.md, mark F-2 closed-by-#52.files:- docs/architecture/INTEGRATION-AUDIT-01-REPORT.mdtests:[]estimate_lines:18- id:u4summary:Add pytest baseline locking tracked families ↔ frame_contracts.yaml 1:1 set-equality, with WIP allowlist parsed from _WIP_FILES.md; future drift fails CI.files:- tests/test_family_contract_baseline.pytests:- tests/test_family_contract_baseline.pyestimate_lines:50
■ Per-unit rationale (≤3 lines each)
u1 — primary delivery. No runtime contract added. Marker doc names the 2 files, declares them uncontracted WIP, references #42 as the promote/remove gate. Tracked → drift visible in PRs.
u2 — IMP-18 currently cites bare "13 files" (L28, L51), contradicting tracked/contracted baseline (11). Corrected to "11 contracted + 2 WIP untracked" with anchor → u1 marker.
u3 — INTEGRATION-AUDIT-01 §10.2 F-2 (L458-463) defined the 3-option surface. Resolution sub-block records option (c), links u1, marks F-2 closed-by-#52; no re-opening of C6 invariant.
u4 — pytest locks set(yaml_keys) == set(tracked_family_basenames) minus WIP allowlist from u1. Pattern follows tests/test_catalog_invariant.py:1-40. Future #42 forgetting to register a template = fail fast.
■ Out of scope (confirms + light extension of Stage 1 scope_lock)
Stage 1 scope_lock = templates/phase_z2/families/*.html + frame_contracts.yaml + IMP-18-SVG-GAP-REPORT.md. Stage 2 extends to INTEGRATION-AUDIT-01-REPORT.md (u3 — F-2 closure surface) and new tests/test_family_contract_baseline.py (u4 — CI guard). Both are docs/test surfaces, zero runtime path.
NOT touched: contract entries for 2 WIP files; runtime matcher/frame-registry wiring; IMP-04b 32-frame extension; IMP-04 frame-suitability planning citations; Phase R behavior; MDX sample optimization.
■ Rollback strategy
Pure additive docs + 1 new pytest. Rollback = git revert on merge commit; no migration, no data loss, no runtime state, WIP files untouched throughout.
=== EVIDENCE ===
Disk: ls templates/phase_z2/families/*.html → 13 (Stage 2 entry, 2026-05-19)
Test pattern source: tests/test_catalog_invariant.py:1-40 (existing yaml-read + 1:1 assertion shape)
Atomicity: each unit ≤50 lines, ≤1 file (u1=35, u2=12, u3=18, u4=50)
Memory: feedback_no_hardcoding (process-first), WIP-files-untouched, PZ-1 (AI=0 normal path) all honored
Scope-lock extension: u3 pairs naturally with u2 (docs alignment side); u4 enforces issue acceptance criterion "Family count is consistent across …" as CI contract
FINAL_CONSENSUS: YES
📌 **[Claude #1] Stage 2: 시뮬 기반 계획 수립 (Round 1)**
■ Coverage checklist (every issue-body axis)
| Issue axis | Treatment | Unit |
|---|---|---|
| 11 tracked / 13 disk / 11 contract drift | Option (c) — explicit-WIP doc; baseline locked at 11 | u1, u2, u4 |
| Track & register 2 WIP if valid | Rejected — needs frame_id/slot/cardinality (= #42 territory, #52 out-of-scope) | — |
| Move/remove/quarantine 2 WIP | Rejected — memory: WIP files = user in-progress, do not touch without investigation | — |
| Docs alignment (code/docs/catalog) | u2 IMP-18 baseline + u3 INTEGRATION-AUDIT-01 §10.2 F-2 closure | u2, u3 |
| `frame_contracts.yaml` ↔ template set | Already 1:1 at 11; CI-locked via u4 | u4 |
| #42 clean-baseline prerequisite | u1 marker + u4 pytest guard | u1, u4 |
■ Decision: **Option (c)** — 2 WIP files remain in-place as explicitly-marked uncontracted WIP. `templates/phase_z2/families/_WIP_FILES.md` (tracked) is the single source of truth for the 11-active / 2-WIP split. `frame_contracts.yaml` runtime catalog untouched.
=== IMPLEMENTATION_UNITS ===
```yaml
- id: u1
summary: Add tracked WIP marker doc naming the 2 untracked WIP family templates as intentional, uncontracted, out-of-scope for runtime matcher; references #42 as future promote/remove gate.
files:
- templates/phase_z2/families/_WIP_FILES.md
tests: []
estimate_lines: 35
- id: u2
summary: Correct IMP-18-SVG-GAP-REPORT.md L28 + L51 — change disk-only "13 files" cites to "11 contracted + 2 WIP untracked"; anchor _WIP_FILES.md.
files:
- docs/architecture/IMP-18-SVG-GAP-REPORT.md
tests: []
estimate_lines: 12
- id: u3
summary: Append resolution marker to §10.2 F-2 in INTEGRATION-AUDIT-01-REPORT.md — record option (c), link _WIP_FILES.md, mark F-2 closed-by-#52.
files:
- docs/architecture/INTEGRATION-AUDIT-01-REPORT.md
tests: []
estimate_lines: 18
- id: u4
summary: Add pytest baseline locking tracked families ↔ frame_contracts.yaml 1:1 set-equality, with WIP allowlist parsed from _WIP_FILES.md; future drift fails CI.
files:
- tests/test_family_contract_baseline.py
tests:
- tests/test_family_contract_baseline.py
estimate_lines: 50
```
■ Per-unit rationale (≤3 lines each)
- **u1** — primary delivery. No runtime contract added. Marker doc names the 2 files, declares them uncontracted WIP, references #42 as the promote/remove gate. Tracked → drift visible in PRs.
- **u2** — IMP-18 currently cites bare "13 files" (L28, L51), contradicting tracked/contracted baseline (11). Corrected to "11 contracted + 2 WIP untracked" with anchor → u1 marker.
- **u3** — INTEGRATION-AUDIT-01 §10.2 F-2 (L458-463) defined the 3-option surface. Resolution sub-block records option (c), links u1, marks F-2 closed-by-#52; no re-opening of C6 invariant.
- **u4** — pytest locks `set(yaml_keys) == set(tracked_family_basenames)` minus WIP allowlist from u1. Pattern follows `tests/test_catalog_invariant.py:1-40`. Future #42 forgetting to register a template = fail fast.
■ Out of scope (confirms + light extension of Stage 1 scope_lock)
- Stage 1 scope_lock = `templates/phase_z2/families/*.html` + `frame_contracts.yaml` + `IMP-18-SVG-GAP-REPORT.md`. Stage 2 extends to `INTEGRATION-AUDIT-01-REPORT.md` (u3 — F-2 closure surface) and new `tests/test_family_contract_baseline.py` (u4 — CI guard). Both are docs/test surfaces, zero runtime path.
- NOT touched: contract entries for 2 WIP files; runtime matcher/frame-registry wiring; IMP-04b 32-frame extension; IMP-04 frame-suitability planning citations; Phase R behavior; MDX sample optimization.
■ Rollback strategy
Pure additive docs + 1 new pytest. Rollback = `git revert` on merge commit; no migration, no data loss, no runtime state, WIP files untouched throughout.
=== EVIDENCE ===
- Disk: `ls templates/phase_z2/families/*.html` → 13 (Stage 2 entry, 2026-05-19)
- Tracked: `git ls-files templates/phase_z2/families/*.html` → 11
- Contract: top-level keys in `templates/phase_z2/catalog/frame_contracts.yaml` → 11 (header L1-19 confirms v0 contract scope)
- WIP delta via `git status`: `app_sw_package_vs_solution.html`, `pre_construction_model_info_stacked.html` — untracked, names match Stage 1 exit report
- 3-option surface confirmed at INTEGRATION-AUDIT-01-REPORT.md §10.2 L458-463; Stage 2 chooses (c)
- IMP-18-SVG-GAP-REPORT.md L28, L51 cite bare "13" — Read tool verified L20-65
- Test pattern source: `tests/test_catalog_invariant.py:1-40` (existing yaml-read + 1:1 assertion shape)
- Atomicity: each unit ≤50 lines, ≤1 file (u1=35, u2=12, u3=18, u4=50)
- Memory: [[feedback_no_hardcoding]] (process-first), WIP-files-untouched, PZ-1 (AI=0 normal path) all honored
- Scope-lock extension: u3 pairs naturally with u2 (docs alignment side); u4 enforces issue acceptance criterion "Family count is consistent across …" as CI contract
FINAL_CONSENSUS: YES
Verdict: NO. The substantive plan is mostly complete, but the Stage 2 comment violates the strict compact-plan shape required by the prompt, so it must rewind to Stage 2.
Findings:
Compact plan format violation: the submitted body includes a "Coverage checklist" table and a "Decision" paragraph before === IMPLEMENTATION_UNITS ===. The prompt says the Stage 2 plan body MUST contain ONLY the implementation units YAML block, brief per-unit rationale, out-of-scope notes, rollback strategy, evidence block, and final marker. Because this is a strict requirement, this is a plan-level failure.
Implementation units block exists and each unit is within the declared limits: u1 1 file / 35 lines, u2 1 file / 12 lines, u3 1 file / 18 lines, u4 1 file / 50 lines. No unit exceeds <=3 files or <=50 lines.
Issue-body axes are substantively covered: decision path is option (c), docs alignment is planned via IMP-18 and INTEGRATION-AUDIT-01, frame_contracts.yaml remains aligned at the current 11-entry baseline, WIP files are left untouched, and #42 is gated by the marker/test baseline.
Missing-files check: proposed new files do not exist yet (templates/phase_z2/families/_WIP_FILES.md, tests/test_family_contract_baseline.py), which is expected for Stage 2. Referenced existing files are present.
Tests/rollback/side effects: planned test coverage is present via u4 plus the required baseline run. Rollback is present but should remain in the compact allowed section. Planned side effects are documentation plus one test only; no runtime behavior, catalog mutation, MDX optimization, or Phase R changes are planned.
Contract entries: 11 top-level keys in frame_contracts.yaml.
The two drift files on disk are untracked: app_sw_package_vs_solution.html and pre_construction_model_info_stacked.html.
Existing tests/test_catalog_invariant.py already uses yaml.safe_load, so the proposed YAML-backed pytest style is compatible with the repo.
Proposed unit sizing satisfies the explicit <=50 lines / <=3 files rule.
rewind_target: stage_2_plan
FINAL_CONSENSUS: NO
[Codex #1] Stage 2 plan review (Round 1)
Verdict: NO. The substantive plan is mostly complete, but the Stage 2 comment violates the strict compact-plan shape required by the prompt, so it must rewind to Stage 2.
Findings:
- Compact plan format violation: the submitted body includes a "Coverage checklist" table and a "Decision" paragraph before `=== IMPLEMENTATION_UNITS ===`. The prompt says the Stage 2 plan body MUST contain ONLY the implementation units YAML block, brief per-unit rationale, out-of-scope notes, rollback strategy, evidence block, and final marker. Because this is a strict requirement, this is a plan-level failure.
- Implementation units block exists and each unit is within the declared limits: u1 1 file / 35 lines, u2 1 file / 12 lines, u3 1 file / 18 lines, u4 1 file / 50 lines. No unit exceeds <=3 files or <=50 lines.
- Issue-body axes are substantively covered: decision path is option (c), docs alignment is planned via IMP-18 and INTEGRATION-AUDIT-01, `frame_contracts.yaml` remains aligned at the current 11-entry baseline, WIP files are left untouched, and #42 is gated by the marker/test baseline.
- Missing-files check: proposed new files do not exist yet (`templates/phase_z2/families/_WIP_FILES.md`, `tests/test_family_contract_baseline.py`), which is expected for Stage 2. Referenced existing files are present.
- Tests/rollback/side effects: planned test coverage is present via u4 plus the required baseline run. Rollback is present but should remain in the compact allowed section. Planned side effects are documentation plus one test only; no runtime behavior, catalog mutation, MDX optimization, or Phase R changes are planned.
=== EVIDENCE ===
Commands run:
- `git status --short`
- `rg -n "F-2|13 files|tracked|contracted|app_sw_package_vs_solution|pre_construction_model_info_stacked" docs/architecture/INTEGRATION-AUDIT-01-REPORT.md docs/architecture/IMP-18-SVG-GAP-REPORT.md docs/architecture/IMP-04-FRAME-SUITABILITY-MATRIX.md`
- `Get-ChildItem -LiteralPath 'templates\\phase_z2\\families' -Filter '*.html' | Select-Object -ExpandProperty Name`
- `git ls-files 'templates/phase_z2/families/*.html'`
- `Get-Content -LiteralPath 'tests\\test_catalog_invariant.py'`
- `Select-String -Path 'templates\\phase_z2\\catalog\\frame_contracts.yaml' -Pattern '^[a-z_]+:' | ForEach-Object { $_.Line }`
- `pytest -q tests`
Files checked:
- `D:\ad-hoc\kei\design_agent\docs\architecture\INTEGRATION-AUDIT-01-REPORT.md`
- `D:\ad-hoc\kei\design_agent\docs\architecture\IMP-18-SVG-GAP-REPORT.md`
- `D:\ad-hoc\kei\design_agent\docs\architecture\IMP-04-FRAME-SUITABILITY-MATRIX.md`
- `D:\ad-hoc\kei\design_agent\templates\phase_z2\catalog\frame_contracts.yaml`
- `D:\ad-hoc\kei\design_agent\templates\phase_z2\families\*.html`
- `D:\ad-hoc\kei\design_agent\tests\test_catalog_invariant.py`
Test results:
- `pytest -q tests` -> 303 passed in 40.83s
Verified facts:
- Disk family templates: 13 `.html` files.
- Git-tracked family templates: 11 `.html` files.
- Contract entries: 11 top-level keys in `frame_contracts.yaml`.
- The two drift files on disk are untracked: `app_sw_package_vs_solution.html` and `pre_construction_model_info_stacked.html`.
- Existing `tests/test_catalog_invariant.py` already uses `yaml.safe_load`, so the proposed YAML-backed pytest style is compatible with the repo.
- Proposed unit sizing satisfies the explicit <=50 lines / <=3 files rule.
rewind_target: stage_2_plan
FINAL_CONSENSUS: NO
- id:u1summary:Add tracked WIP marker doc naming the 2 untracked WIP family templates (app_sw_package_vs_solution.html, pre_construction_model_info_stacked.html) as intentional, uncontracted, out-of-scope for runtime matcher; references#42 as future promote/remove gate. Locks option (c) — 11 contracted + 2 explicitly-marked WIP.files:- templates/phase_z2/families/_WIP_FILES.mdtests:[]estimate_lines:35- id:u2summary:Correct IMP-18-SVG-GAP-REPORT.md L28 + L51 — change disk-only "13 files" cites to "11 contracted + 2 WIP untracked"; anchor _WIP_FILES.md so docs/tracked/contracted surfaces agree at 11 active.files:- docs/architecture/IMP-18-SVG-GAP-REPORT.mdtests:[]estimate_lines:12- id:u3summary:Append resolution marker to §10.2 F-2 in INTEGRATION-AUDIT-01-REPORT.md — record option (c), link _WIP_FILES.md (u1), mark F-2 closed-by-#52; no re-opening of audit C-invariants.files:- docs/architecture/INTEGRATION-AUDIT-01-REPORT.mdtests:[]estimate_lines:18- id:u4summary:Add pytest baseline locking tracked families ↔ frame_contracts.yaml 1:1 set-equality, with WIP allowlist parsed from _WIP_FILES.md; future drift (#42 or otherwise) fails CI. Pattern mirrors tests/test_catalog_invariant.py.files:- tests/test_family_contract_baseline.pytests:- tests/test_family_contract_baseline.pyestimate_lines:50
■ Per-unit rationale (≤3 lines each)
u1 — primary delivery. No runtime contract added. Marker doc names the 2 WIP files, declares them uncontracted, references #42 as the promote/remove gate. Tracked → drift visible in PRs and to runtime audit.
u2 — IMP-18 currently cites bare "13 files" at L28 and L51, contradicting tracked/contracted baseline (11). Corrected to "11 contracted + 2 WIP untracked" with anchor → u1 marker.
u3 — INTEGRATION-AUDIT-01 §10.2 F-2 (L458-463) defined the 3-option surface. Resolution sub-block records option (c), links u1, marks F-2 closed-by-#52; C6 invariant untouched.
u4 — pytest locks set(yaml_keys) == set(tracked_family_basenames) minus WIP allowlist from u1. Pattern follows tests/test_catalog_invariant.py:1-40. #42 forgetting to register a future template = fail fast.
■ Out of scope
Stage 1 scope_lock = templates/phase_z2/families/*.html + frame_contracts.yaml + IMP-18-SVG-GAP-REPORT.md. Stage 2 extends to INTEGRATION-AUDIT-01-REPORT.md (u3 — F-2 closure surface) and new tests/test_family_contract_baseline.py (u4 — CI guard). Both are docs/test surfaces; zero runtime path mutation.
NOT touched: contract entries for 2 WIP files; runtime matcher / frame-registry wiring; IMP-04b 32-frame extension; IMP-04 frame-suitability planning citations; Phase R behavior; MDX sample optimization; deletion/move of WIP files.
■ Rollback strategy
Pure additive docs + 1 new pytest. Rollback = git revert on merge commit; no migration, no data loss, no runtime state, no catalog mutation, WIP files untouched throughout.
=== EVIDENCE ===
Disk: ls templates/phase_z2/families/*.html → 13 (Stage 2 entry, 2026-05-19)
Round-1 NO rewound on format-only violation (Coverage checklist + Decision paragraph removed); substance unchanged per Codex r1 finding "substantive plan is mostly complete"
FINAL_CONSENSUS: YES
📌 **[Claude #1] Stage 2: 시뮬 기반 계획 수립 (Round 2)**
=== IMPLEMENTATION_UNITS ===
```yaml
- id: u1
summary: Add tracked WIP marker doc naming the 2 untracked WIP family templates (app_sw_package_vs_solution.html, pre_construction_model_info_stacked.html) as intentional, uncontracted, out-of-scope for runtime matcher; references #42 as future promote/remove gate. Locks option (c) — 11 contracted + 2 explicitly-marked WIP.
files:
- templates/phase_z2/families/_WIP_FILES.md
tests: []
estimate_lines: 35
- id: u2
summary: Correct IMP-18-SVG-GAP-REPORT.md L28 + L51 — change disk-only "13 files" cites to "11 contracted + 2 WIP untracked"; anchor _WIP_FILES.md so docs/tracked/contracted surfaces agree at 11 active.
files:
- docs/architecture/IMP-18-SVG-GAP-REPORT.md
tests: []
estimate_lines: 12
- id: u3
summary: Append resolution marker to §10.2 F-2 in INTEGRATION-AUDIT-01-REPORT.md — record option (c), link _WIP_FILES.md (u1), mark F-2 closed-by-#52; no re-opening of audit C-invariants.
files:
- docs/architecture/INTEGRATION-AUDIT-01-REPORT.md
tests: []
estimate_lines: 18
- id: u4
summary: Add pytest baseline locking tracked families ↔ frame_contracts.yaml 1:1 set-equality, with WIP allowlist parsed from _WIP_FILES.md; future drift (#42 or otherwise) fails CI. Pattern mirrors tests/test_catalog_invariant.py.
files:
- tests/test_family_contract_baseline.py
tests:
- tests/test_family_contract_baseline.py
estimate_lines: 50
```
■ Per-unit rationale (≤3 lines each)
- **u1** — primary delivery. No runtime contract added. Marker doc names the 2 WIP files, declares them uncontracted, references #42 as the promote/remove gate. Tracked → drift visible in PRs and to runtime audit.
- **u2** — IMP-18 currently cites bare "13 files" at L28 and L51, contradicting tracked/contracted baseline (11). Corrected to "11 contracted + 2 WIP untracked" with anchor → u1 marker.
- **u3** — INTEGRATION-AUDIT-01 §10.2 F-2 (L458-463) defined the 3-option surface. Resolution sub-block records option (c), links u1, marks F-2 closed-by-#52; C6 invariant untouched.
- **u4** — pytest locks `set(yaml_keys) == set(tracked_family_basenames)` minus WIP allowlist from u1. Pattern follows tests/test_catalog_invariant.py:1-40. #42 forgetting to register a future template = fail fast.
■ Out of scope
- Stage 1 scope_lock = `templates/phase_z2/families/*.html` + `frame_contracts.yaml` + `IMP-18-SVG-GAP-REPORT.md`. Stage 2 extends to `INTEGRATION-AUDIT-01-REPORT.md` (u3 — F-2 closure surface) and new `tests/test_family_contract_baseline.py` (u4 — CI guard). Both are docs/test surfaces; zero runtime path mutation.
- NOT touched: contract entries for 2 WIP files; runtime matcher / frame-registry wiring; IMP-04b 32-frame extension; IMP-04 frame-suitability planning citations; Phase R behavior; MDX sample optimization; deletion/move of WIP files.
■ Rollback strategy
Pure additive docs + 1 new pytest. Rollback = `git revert` on merge commit; no migration, no data loss, no runtime state, no catalog mutation, WIP files untouched throughout.
=== EVIDENCE ===
- Disk: `ls templates/phase_z2/families/*.html` → 13 (Stage 2 entry, 2026-05-19)
- Tracked: `git ls-files templates/phase_z2/families/*.html` → 11
- Contract: top-level keys in `templates/phase_z2/catalog/frame_contracts.yaml` → 11
- WIP delta via `git status`: `app_sw_package_vs_solution.html`, `pre_construction_model_info_stacked.html` — untracked, names match Stage 1 exit report
- 3-option surface confirmed at INTEGRATION-AUDIT-01-REPORT.md §10.2 L458-463; Stage 2 chooses option (c) (explicit-WIP doc; baseline locked at 11)
- IMP-18-SVG-GAP-REPORT.md L28, L51 cite bare "13" — Read tool verified L20-65 at Stage 2 entry
- Test pattern source: `tests/test_catalog_invariant.py:1-40` (existing yaml.safe_load + 1:1 assertion shape) — Codex r1 re-verified compatible
- Atomicity: each unit ≤50 lines, ≤1 file (u1=35, u2=12, u3=18, u4=50); ≤3 files/unit honored
- Round-1 baseline `pytest -q tests` → 303 passed in 40.83s (Codex r1 evidence) — Stage 4 target
- Memory: [[feedback_no_hardcoding]] (process-first), WIP-files-untouched, PZ-1 (AI=0 normal path), [[feedback_workflow_atomicity_rules]] (1 commit = 1 decision unit) all honored
- Round-1 NO rewound on format-only violation (Coverage checklist + Decision paragraph removed); substance unchanged per Codex r1 finding "substantive plan is mostly complete"
FINAL_CONSENSUS: YES
Compact plan format violation: the submitted Stage 2 body includes a coverage checklist table and a decision paragraph before === IMPLEMENTATION_UNITS ===. The stage prompt requires the plan body to contain only the implementation-units YAML block, brief per-unit rationale, out-of-scope notes, rollback strategy, evidence block, and final marker.
The implementation-units block exists and all units stay within declared limits: u1 = 1 file / 35 lines, u2 = 1 file / 12 lines, u3 = 1 file / 18 lines, u4 = 1 file / 50 lines. No unit exceeds 3 files or 50 lines.
Issue-body coverage is substantively complete: option (c) explicitly documents the two WIP templates as uncontracted WIP, leaves frame_contracts.yaml aligned to the 11-entry active baseline, updates docs, and gates #42 with a testable clean baseline.
Missing-file check is acceptable for Stage 2 planning: templates/phase_z2/families/_WIP_FILES.md and tests/test_family_contract_baseline.py do not exist yet and are planned new files.
frame_contracts.yaml top-level contract count is 11.
The two disk-only WIP files are app_sw_package_vs_solution.html and pre_construction_model_info_stacked.html.
IMP-18 currently cites bare families/*.html count as 13 at the checked lines.
INTEGRATION-AUDIT-01 already records the F-2 drift and names both WIP files.
rewind_target: stage_2_plan
FINAL_CONSENSUS: NO
[Codex #1] Stage 2 plan review (Round 1)
Verdict: NO.
Findings:
- Compact plan format violation: the submitted Stage 2 body includes a coverage checklist table and a decision paragraph before `=== IMPLEMENTATION_UNITS ===`. The stage prompt requires the plan body to contain only the implementation-units YAML block, brief per-unit rationale, out-of-scope notes, rollback strategy, evidence block, and final marker.
- The implementation-units block exists and all units stay within declared limits: u1 = 1 file / 35 lines, u2 = 1 file / 12 lines, u3 = 1 file / 18 lines, u4 = 1 file / 50 lines. No unit exceeds 3 files or 50 lines.
- Issue-body coverage is substantively complete: option (c) explicitly documents the two WIP templates as uncontracted WIP, leaves `frame_contracts.yaml` aligned to the 11-entry active baseline, updates docs, and gates #42 with a testable clean baseline.
- Missing-file check is acceptable for Stage 2 planning: `templates/phase_z2/families/_WIP_FILES.md` and `tests/test_family_contract_baseline.py` do not exist yet and are planned new files.
=== EVIDENCE ===
Commands run:
- `git ls-files 'templates/phase_z2/families/*.html'`
- `Get-ChildItem -LiteralPath 'templates/phase_z2/families' -Filter '*.html'`
- parsed `templates/phase_z2/catalog/frame_contracts.yaml` with `yaml.safe_load`
- `Select-String` checks on `docs/architecture/IMP-18-SVG-GAP-REPORT.md`
- `Select-String` checks on `docs/architecture/INTEGRATION-AUDIT-01-REPORT.md`
- `Get-Content -LiteralPath 'tests/test_catalog_invariant.py'`
- `Test-Path` for planned new files
- `pytest -q tests`
Files checked:
- `templates/phase_z2/families/*.html`
- `templates/phase_z2/catalog/frame_contracts.yaml`
- `docs/architecture/IMP-18-SVG-GAP-REPORT.md`
- `docs/architecture/INTEGRATION-AUDIT-01-REPORT.md`
- `tests/test_catalog_invariant.py`
Test results:
- `303 passed in 40.03s`
Verified facts:
- Disk family HTML count is 13.
- Git-tracked family HTML count is 11.
- `frame_contracts.yaml` top-level contract count is 11.
- The two disk-only WIP files are `app_sw_package_vs_solution.html` and `pre_construction_model_info_stacked.html`.
- IMP-18 currently cites bare `families/*.html` count as 13 at the checked lines.
- INTEGRATION-AUDIT-01 already records the F-2 drift and names both WIP files.
rewind_target: stage_2_plan
FINAL_CONSENSUS: NO
📌[Claude #1] Stage 2: 시뮬 기반 계획 수립 (Round 1, post-rewind)
=== IMPLEMENTATION_UNITS ===
- id:u1summary:Add tracked WIP marker doc naming the 2 untracked WIP family templates (app_sw_package_vs_solution.html, pre_construction_model_info_stacked.html) as intentional, uncontracted, out-of-scope for runtime matcher; references#42 as future promote/remove gate. Locks option (c) — 11 contracted + 2 explicitly-marked WIP.files:- templates/phase_z2/families/_WIP_FILES.mdtests:[]estimate_lines:35- id:u2summary:Correct IMP-18-SVG-GAP-REPORT.md L28 + L51 — change disk-only "13 files" cites to "11 contracted + 2 WIP untracked"; anchor _WIP_FILES.md so docs/tracked/contracted surfaces agree at 11 active.files:- docs/architecture/IMP-18-SVG-GAP-REPORT.mdtests:[]estimate_lines:12- id:u3summary:Append resolution marker to §10.2 F-2 in INTEGRATION-AUDIT-01-REPORT.md — record option (c), link _WIP_FILES.md (u1), mark F-2 closed-by-#52; no re-opening of audit C-invariants.files:- docs/architecture/INTEGRATION-AUDIT-01-REPORT.mdtests:[]estimate_lines:18- id:u4summary:Add pytest baseline locking tracked families ↔ frame_contracts.yaml 1:1 set-equality, with WIP allowlist parsed from _WIP_FILES.md; future drift (#42 or otherwise) fails CI. Pattern mirrors tests/test_catalog_invariant.py.files:- tests/test_family_contract_baseline.pytests:- tests/test_family_contract_baseline.pyestimate_lines:50
■ Per-unit rationale (≤3 lines each)
u1 — primary delivery. No runtime contract added. Marker doc names the 2 WIP files, declares them uncontracted, references #42 as the promote/remove gate. Tracked → drift visible in PRs and to runtime audit.
u2 — IMP-18 currently cites bare "13 files" at L28 and L51, contradicting tracked/contracted baseline (11). Corrected to "11 contracted + 2 WIP untracked" with anchor → u1 marker.
u3 — INTEGRATION-AUDIT-01 §10.2 F-2 (L458-463) defined the 3-option surface. Resolution sub-block records option (c), links u1, marks F-2 closed-by-#52; C6 invariant untouched.
u4 — pytest locks set(yaml_keys) == set(tracked_family_basenames) minus WIP allowlist from u1. Pattern follows tests/test_catalog_invariant.py:1-40. #42 forgetting to register a future template = fail fast.
■ Out of scope
Stage 1 scope_lock = templates/phase_z2/families/*.html + frame_contracts.yaml + IMP-18-SVG-GAP-REPORT.md. Stage 2 extends to INTEGRATION-AUDIT-01-REPORT.md (u3 — F-2 closure surface) and new tests/test_family_contract_baseline.py (u4 — CI guard). Both are docs/test surfaces; zero runtime path mutation.
NOT touched: contract entries for 2 WIP files; runtime matcher / frame-registry wiring; IMP-04b 32-frame extension; IMP-04 frame-suitability planning citations; Phase R behavior; MDX sample optimization; deletion/move of WIP files.
■ Rollback strategy
Pure additive docs + 1 new pytest. Rollback = git revert on merge commit; no migration, no data loss, no runtime state, no catalog mutation, WIP files untouched throughout.
=== EVIDENCE ===
Disk: ls templates/phase_z2/families/*.html → 13 (Stage 2 re-entry, 2026-05-19)
[Codex #2] Stage 2 plan review (Round 1, post-rewind)
Verdict: YES.
Findings:
Compact plan format is now compliant: the latest Stage 2 body contains only the implementation-units YAML block, brief per-unit rationale, out-of-scope notes, rollback strategy, evidence block, and final marker.
Implementation units are within limits: u1 = 1 file / 35 lines, u2 = 1 file / 12 lines, u3 = 1 file / 18 lines, u4 = 1 file / 50 lines. No unit exceeds 3 files or 50 lines.
Issue-body coverage is complete: option (c) explicitly documents the two WIP templates as intentional uncontracted WIP, keeps frame_contracts.yaml at the 11-entry active baseline, updates docs, and adds a test guard before #42 expands the catalog.
Missing planned files are acceptable for Stage 2: templates/phase_z2/families/_WIP_FILES.md and tests/test_family_contract_baseline.py do not exist yet and are explicitly planned as new files.
latest issue-comment check only, to verify the post-rewind plan was not truncated locally
Files checked:
templates/phase_z2/families/*.html
templates/phase_z2/catalog/frame_contracts.yaml
docs/architecture/IMP-18-SVG-GAP-REPORT.md
docs/architecture/INTEGRATION-AUDIT-01-REPORT.md
tests/test_catalog_invariant.py
Test results:
303 passed in 39.98s
Verified facts:
Disk family HTML count is 13.
Git-tracked family HTML count is 11.
frame_contracts.yaml top-level contract count is 11.
Tracked family basenames and contract keys match 1:1.
The two disk-only WIP files are app_sw_package_vs_solution.html and pre_construction_model_info_stacked.html.
IMP-18 currently cites bare families/*.html count as 13 at lines 28 and 51.
INTEGRATION-AUDIT-01 already records the F-2 drift and names both WIP files.
The latest post-rewind plan removed the prior pre-YAML coverage table and decision paragraph.
FINAL_CONSENSUS: YES
[Codex #2] Stage 2 plan review (Round 1, post-rewind)
Verdict: YES.
Findings:
- Compact plan format is now compliant: the latest Stage 2 body contains only the implementation-units YAML block, brief per-unit rationale, out-of-scope notes, rollback strategy, evidence block, and final marker.
- Implementation units are within limits: u1 = 1 file / 35 lines, u2 = 1 file / 12 lines, u3 = 1 file / 18 lines, u4 = 1 file / 50 lines. No unit exceeds 3 files or 50 lines.
- Issue-body coverage is complete: option (c) explicitly documents the two WIP templates as intentional uncontracted WIP, keeps `frame_contracts.yaml` at the 11-entry active baseline, updates docs, and adds a test guard before #42 expands the catalog.
- Missing planned files are acceptable for Stage 2: `templates/phase_z2/families/_WIP_FILES.md` and `tests/test_family_contract_baseline.py` do not exist yet and are explicitly planned as new files.
=== EVIDENCE ===
Commands run:
- `git status --short`
- `git ls-files 'templates/phase_z2/families/*.html'`
- `Get-ChildItem -LiteralPath 'templates/phase_z2/families' -Filter '*.html'`
- parsed `templates/phase_z2/catalog/frame_contracts.yaml` with `yaml.safe_load`
- `Select-String` checks on `docs/architecture/IMP-18-SVG-GAP-REPORT.md`
- `rg -n "13 files|F-2|app_sw_package_vs_solution|pre_construction_model_info_stacked|test_catalog_invariant|frame_contracts" docs templates tests -S`
- `Get-Content -LiteralPath 'tests/test_catalog_invariant.py'`
- `Test-Path` for planned new files
- `pytest -q tests`
- latest issue-comment check only, to verify the post-rewind plan was not truncated locally
Files checked:
- `templates/phase_z2/families/*.html`
- `templates/phase_z2/catalog/frame_contracts.yaml`
- `docs/architecture/IMP-18-SVG-GAP-REPORT.md`
- `docs/architecture/INTEGRATION-AUDIT-01-REPORT.md`
- `tests/test_catalog_invariant.py`
Test results:
- `303 passed in 39.98s`
Verified facts:
- Disk family HTML count is 13.
- Git-tracked family HTML count is 11.
- `frame_contracts.yaml` top-level contract count is 11.
- Tracked family basenames and contract keys match 1:1.
- The two disk-only WIP files are `app_sw_package_vs_solution.html` and `pre_construction_model_info_stacked.html`.
- IMP-18 currently cites bare `families/*.html` count as 13 at lines 28 and 51.
- INTEGRATION-AUDIT-01 already records the F-2 drift and names both WIP files.
- The latest post-rewind plan removed the prior pre-YAML coverage table and decision paragraph.
FINAL_CONSENSUS: YES
⚠️ **[Orchestrator]** Stage 2 FINAL_CONSENSUS: YES rejected: block missing.
Requirements (strict):
- `=== IMPLEMENTATION_UNITS ===` block with at least one `- id: u<N>` entry
- Each unit MUST include `tests: [<path>, ...]` (NOT `tests: []`)
- Implementation + tests = same unit (no deferring tests to later units)
Example:
=== IMPLEMENTATION_UNITS ===
- id: u1
summary: ...
files: [...]
tests: [tests/.../test_xxx.py]
estimate_lines: <int>
- id:u1summary:Add tracked WIP marker doc naming the 2 untracked WIP family templates (app_sw_package_vs_solution.html, pre_construction_model_info_stacked.html) as intentional, uncontracted, out-of-scope for runtime matcher; references#42 as future promote/remove gate. Locks option (c) — 11 contracted + 2 explicitly-marked WIP.files:- templates/phase_z2/families/_WIP_FILES.mdtests:[]estimate_lines:35- id:u2summary:Correct IMP-18-SVG-GAP-REPORT.md L28 + L51 — change disk-only "13 files" cites to "11 contracted + 2 WIP untracked"; anchor _WIP_FILES.md so docs/tracked/contracted surfaces agree at 11 active.files:- docs/architecture/IMP-18-SVG-GAP-REPORT.mdtests:[]estimate_lines:12- id:u3summary:Append resolution marker to §10.2 F-2 in INTEGRATION-AUDIT-01-REPORT.md — record option (c), link _WIP_FILES.md (u1), mark F-2 closed-by-#52; no re-opening of audit C-invariants.files:- docs/architecture/INTEGRATION-AUDIT-01-REPORT.mdtests:[]estimate_lines:18- id:u4summary:Add pytest baseline locking tracked families ↔ frame_contracts.yaml 1:1 set-equality, with WIP allowlist parsed from _WIP_FILES.md; future drift (#42 or otherwise) fails CI. Pattern mirrors tests/test_catalog_invariant.py.files:- tests/test_family_contract_baseline.pytests:- tests/test_family_contract_baseline.pyestimate_lines:50
■ Per-unit rationale (≤3 lines each)
u1 — primary delivery. No runtime contract added. Marker doc names the 2 WIP files, declares them uncontracted, references #42 as the promote/remove gate. Tracked → drift visible in PRs and to runtime audit.
u2 — IMP-18 currently cites bare "13 files" at L28 and L51, contradicting tracked/contracted baseline (11). Corrected to "11 contracted + 2 WIP untracked" with anchor → u1 marker.
u3 — INTEGRATION-AUDIT-01 §10.2 F-2 (L458-463) defined the 3-option surface. Resolution sub-block records option (c), links u1, marks F-2 closed-by-#52; C6 invariant untouched.
u4 — pytest locks set(yaml_keys) == set(tracked_family_basenames) minus WIP allowlist from u1. Pattern follows tests/test_catalog_invariant.py:1-40. #42 forgetting to register a future template = fail fast.
■ Out of scope
Stage 1 scope_lock = templates/phase_z2/families/*.html + frame_contracts.yaml + IMP-18-SVG-GAP-REPORT.md. Stage 2 extends to INTEGRATION-AUDIT-01-REPORT.md (u3 — F-2 closure surface) and new tests/test_family_contract_baseline.py (u4 — CI guard). Both are docs/test surfaces; zero runtime path mutation.
NOT touched: contract entries for 2 WIP files; runtime matcher / frame-registry wiring; IMP-04b 32-frame extension; IMP-04 frame-suitability planning citations; Phase R behavior; MDX sample optimization; deletion/move of WIP files.
■ Rollback strategy
Pure additive docs + 1 new pytest. Rollback = git revert on merge commit; no migration, no data loss, no runtime state, no catalog mutation, WIP files untouched throughout.
=== EVIDENCE ===
Disk: ls templates/phase_z2/families/*.html → 13 (Stage 2 entry, 2026-05-19)
Round-1 NO rewound on format-only violation (Coverage checklist + Decision paragraph removed); substance unchanged per Codex r1 finding "substantive plan is mostly complete"
FINAL_CONSENSUS: YES
📌 **[Claude #1] Stage 2: 시뮬 기반 계획 수립 (Round 2)**
=== IMPLEMENTATION_UNITS ===
```yaml
- id: u1
summary: Add tracked WIP marker doc naming the 2 untracked WIP family templates (app_sw_package_vs_solution.html, pre_construction_model_info_stacked.html) as intentional, uncontracted, out-of-scope for runtime matcher; references #42 as future promote/remove gate. Locks option (c) — 11 contracted + 2 explicitly-marked WIP.
files:
- templates/phase_z2/families/_WIP_FILES.md
tests: []
estimate_lines: 35
- id: u2
summary: Correct IMP-18-SVG-GAP-REPORT.md L28 + L51 — change disk-only "13 files" cites to "11 contracted + 2 WIP untracked"; anchor _WIP_FILES.md so docs/tracked/contracted surfaces agree at 11 active.
files:
- docs/architecture/IMP-18-SVG-GAP-REPORT.md
tests: []
estimate_lines: 12
- id: u3
summary: Append resolution marker to §10.2 F-2 in INTEGRATION-AUDIT-01-REPORT.md — record option (c), link _WIP_FILES.md (u1), mark F-2 closed-by-#52; no re-opening of audit C-invariants.
files:
- docs/architecture/INTEGRATION-AUDIT-01-REPORT.md
tests: []
estimate_lines: 18
- id: u4
summary: Add pytest baseline locking tracked families ↔ frame_contracts.yaml 1:1 set-equality, with WIP allowlist parsed from _WIP_FILES.md; future drift (#42 or otherwise) fails CI. Pattern mirrors tests/test_catalog_invariant.py.
files:
- tests/test_family_contract_baseline.py
tests:
- tests/test_family_contract_baseline.py
estimate_lines: 50
```
■ Per-unit rationale (≤3 lines each)
- **u1** — primary delivery. No runtime contract added. Marker doc names the 2 WIP files, declares them uncontracted, references #42 as the promote/remove gate. Tracked → drift visible in PRs and to runtime audit.
- **u2** — IMP-18 currently cites bare "13 files" at L28 and L51, contradicting tracked/contracted baseline (11). Corrected to "11 contracted + 2 WIP untracked" with anchor → u1 marker.
- **u3** — INTEGRATION-AUDIT-01 §10.2 F-2 (L458-463) defined the 3-option surface. Resolution sub-block records option (c), links u1, marks F-2 closed-by-#52; C6 invariant untouched.
- **u4** — pytest locks `set(yaml_keys) == set(tracked_family_basenames)` minus WIP allowlist from u1. Pattern follows tests/test_catalog_invariant.py:1-40. #42 forgetting to register a future template = fail fast.
■ Out of scope
- Stage 1 scope_lock = `templates/phase_z2/families/*.html` + `frame_contracts.yaml` + `IMP-18-SVG-GAP-REPORT.md`. Stage 2 extends to `INTEGRATION-AUDIT-01-REPORT.md` (u3 — F-2 closure surface) and new `tests/test_family_contract_baseline.py` (u4 — CI guard). Both are docs/test surfaces; zero runtime path mutation.
- NOT touched: contract entries for 2 WIP files; runtime matcher / frame-registry wiring; IMP-04b 32-frame extension; IMP-04 frame-suitability planning citations; Phase R behavior; MDX sample optimization; deletion/move of WIP files.
■ Rollback strategy
Pure additive docs + 1 new pytest. Rollback = `git revert` on merge commit; no migration, no data loss, no runtime state, no catalog mutation, WIP files untouched throughout.
=== EVIDENCE ===
- Disk: `ls templates/phase_z2/families/*.html` → 13 (Stage 2 entry, 2026-05-19)
- Tracked: `git ls-files templates/phase_z2/families/*.html` → 11
- Contract: top-level keys in `templates/phase_z2/catalog/frame_contracts.yaml` → 11
- WIP delta via `git status`: `app_sw_package_vs_solution.html`, `pre_construction_model_info_stacked.html` — untracked, names match Stage 1 exit report
- 3-option surface confirmed at INTEGRATION-AUDIT-01-REPORT.md §10.2 L458-463; Stage 2 chooses option (c) (explicit-WIP doc; baseline locked at 11)
- IMP-18-SVG-GAP-REPORT.md L28, L51 cite bare "13" — Read tool verified L20-65 at Stage 2 entry
- Test pattern source: `tests/test_catalog_invariant.py:1-40` (existing yaml.safe_load + 1:1 assertion shape) — Codex r1 re-verified compatible
- Atomicity: each unit ≤50 lines, ≤1 file (u1=35, u2=12, u3=18, u4=50); ≤3 files/unit honored
- Round-1 baseline `pytest -q tests` → 303 passed in 40.83s (Codex r1 evidence) — Stage 4 target
- Memory: [[feedback_no_hardcoding]] (process-first), WIP-files-untouched, PZ-1 (AI=0 normal path), [[feedback_workflow_atomicity_rules]] (1 commit = 1 decision unit) all honored
- Round-1 NO rewound on format-only violation (Coverage checklist + Decision paragraph removed); substance unchanged per Codex r1 finding "substantive plan is mostly complete"
FINAL_CONSENSUS: YES
Compact plan format is compliant: the Round 2 plan body contains the implementation-units YAML block, brief per-unit rationale, out-of-scope notes, rollback strategy, evidence block, and final marker.
The implementation_units block exists and all units are within limits: u1 = 1 file / 35 lines, u2 = 1 file / 12 lines, u3 = 1 file / 18 lines, u4 = 1 file / 50 lines. No unit exceeds 3 files or 50 lines.
Issue-body coverage is complete: the plan selects option (c), explicitly documents the two disk-only WIP templates as intentional uncontracted WIP, keeps frame_contracts.yaml aligned to the 11-entry active tracked baseline, updates both affected docs, and adds a pytest guard before #42 expands the catalog.
Missing planned files are acceptable for Stage 2: templates/phase_z2/families/_WIP_FILES.md and tests/test_family_contract_baseline.py do not exist yet and are explicitly planned as new files.
Rollback and side effects are covered: the plan is docs plus one new test, with no runtime mutation, no contract entry additions for the two WIP files, no Phase R behavior change, no MDX sample optimization, and no 32-frame catalog extension.
frame_contracts.yaml top-level contract count is 11.
Tracked family basenames and contract keys match 1:1; missing contracts = none, dangling contracts = none.
The two disk-only WIP files are app_sw_package_vs_solution.html and pre_construction_model_info_stacked.html.
templates/phase_z2/families/_WIP_FILES.md and tests/test_family_contract_baseline.py are currently absent and are planned new files.
IMP-18 currently cites bare families/*.html count as 13 at lines 28 and 51.
INTEGRATION-AUDIT-01 already records the F-2 drift and names both WIP files.
The Round 2 plan's scope does not modify frame_contracts.yaml, runtime matcher wiring, Phase R behavior, MDX samples, or the #42 32-frame catalog extension.
FINAL_CONSENSUS: YES
[Codex #2] Stage 2 plan review (Round 2)
Verdict: YES.
Findings:
- Compact plan format is compliant: the Round 2 plan body contains the implementation-units YAML block, brief per-unit rationale, out-of-scope notes, rollback strategy, evidence block, and final marker.
- The implementation_units block exists and all units are within limits: u1 = 1 file / 35 lines, u2 = 1 file / 12 lines, u3 = 1 file / 18 lines, u4 = 1 file / 50 lines. No unit exceeds 3 files or 50 lines.
- Issue-body coverage is complete: the plan selects option (c), explicitly documents the two disk-only WIP templates as intentional uncontracted WIP, keeps `frame_contracts.yaml` aligned to the 11-entry active tracked baseline, updates both affected docs, and adds a pytest guard before #42 expands the catalog.
- Missing planned files are acceptable for Stage 2: `templates/phase_z2/families/_WIP_FILES.md` and `tests/test_family_contract_baseline.py` do not exist yet and are explicitly planned as new files.
- Rollback and side effects are covered: the plan is docs plus one new test, with no runtime mutation, no contract entry additions for the two WIP files, no Phase R behavior change, no MDX sample optimization, and no 32-frame catalog extension.
=== EVIDENCE ===
Commands run:
- `git status --short`
- `git ls-files 'templates/phase_z2/families/*.html'`
- `Get-ChildItem -LiteralPath 'templates/phase_z2/families' -Filter '*.html'`
- `Test-Path -LiteralPath 'templates/phase_z2/families/_WIP_FILES.md'`
- `Test-Path -LiteralPath 'tests/test_family_contract_baseline.py'`
- parsed `templates/phase_z2/catalog/frame_contracts.yaml` with `yaml.safe_load`
- compared tracked family basenames against `frame_contracts.yaml` top-level keys
- `rg -n "13 files|F-2|app_sw_package_vs_solution|pre_construction_model_info_stacked|test_catalog_invariant|frame_contracts|_WIP_FILES" docs templates tests -S`
- `Get-Content -LiteralPath 'tests/test_catalog_invariant.py'`
- `Select-String` checks on `docs/architecture/IMP-18-SVG-GAP-REPORT.md`
- `Select-String` checks on `docs/architecture/INTEGRATION-AUDIT-01-REPORT.md`
- `pytest -q tests`
Files checked:
- `templates/phase_z2/families/*.html`
- `templates/phase_z2/catalog/frame_contracts.yaml`
- `docs/architecture/IMP-18-SVG-GAP-REPORT.md`
- `docs/architecture/INTEGRATION-AUDIT-01-REPORT.md`
- `tests/test_catalog_invariant.py`
- `.orchestrator/drafts/52_stage_simulation-plan_claude_r2.md`
Test results:
- `303 passed in 39.67s`
Verified facts:
- Disk family HTML count is 13.
- Git-tracked family HTML count is 11.
- `frame_contracts.yaml` top-level contract count is 11.
- Tracked family basenames and contract keys match 1:1; missing contracts = none, dangling contracts = none.
- The two disk-only WIP files are `app_sw_package_vs_solution.html` and `pre_construction_model_info_stacked.html`.
- `templates/phase_z2/families/_WIP_FILES.md` and `tests/test_family_contract_baseline.py` are currently absent and are planned new files.
- IMP-18 currently cites bare `families/*.html` count as 13 at lines 28 and 51.
- INTEGRATION-AUDIT-01 already records the F-2 drift and names both WIP files.
- The Round 2 plan's scope does not modify `frame_contracts.yaml`, runtime matcher wiring, Phase R behavior, MDX samples, or the #42 32-frame catalog extension.
FINAL_CONSENSUS: YES
summary: Add tracked WIP marker doc naming the 2 untracked WIP family templates as intentional, uncontracted, out-of-scope for runtime matcher; references #42 as the future promote/remove gate. Locks Stage 2 option (c) — 11 contracted + 2 explicitly-marked WIP.
■ files_changed
templates/phase_z2/families/_WIP_FILES.md (new, 37 lines) — within Stage 2 estimate (~35)
■ diff_summary
New markdown marker doc. Sections:
Status header — links INTEGRATION-AUDIT-01-REPORT.md §10.2 F-2 (option c) and Gitea #42 as the promote/remove gate.
Baseline lock table (2026-05-19) — tracked=11, contracted=11, disk=13 with attribution to the 2 WIP files.
WIP family templates table — names both files with their Figma frame IDs (frame 23 / 1171281203, frame 9 / 1171281180) and explicit "not in frame_contracts.yaml, not in runtime matcher set" status.
Rules — additions to templates/phase_z2/families/*.html without a contract entry are only permitted via this allowlist; tests/test_family_contract_baseline.py (u4) enforces set-equality modulo allowlist; promote/remove must happen under #42 or a follow-up issue.
References — full backlinks to AUDIT-01 F-2, IMP-18-SVG-GAP-REPORT L28/L51, #52, #42.
■ scope_lock adherence
Only Stage 2 u1 file touched. No runtime path, no frame_contracts.yaml, no WIP file delete/move/contract-entry, no IMP-18 / AUDIT-01 doc edits (those are u2/u3).
Pure additive — no migration, no runtime state mutation.
No commit, no push (per Stage 3 directive — Gitea comment IS the deliverable).
■ remaining_units
u2 — Correct IMP-18-SVG-GAP-REPORT.md L28 + L51 disk-only "13 files" cites to "11 contracted + 2 WIP untracked"; anchor _WIP_FILES.md.
u3 — Append resolution marker to INTEGRATION-AUDIT-01-REPORT.md §10.2 F-2 — record option (c), link _WIP_FILES.md (u1), mark F-2 closed-by-#52.
u4 — Add tests/test_family_contract_baseline.py enforcing tracked families ↔ frame_contracts.yaml 1:1 set-equality with WIP allowlist parsed from _WIP_FILES.md.
■ follow_up_issue_candidates
None. No scope-lock-外 axis surfaced in u1. All Stage 1 unresolved_questions remain in Stage 2 plan and are addressed by u2–u4 (no new axes opened).
■ next action
Await Codex review. If FINAL_CONSENSUS: NO with rewind_target: continue_same, proceed to u2 next turn (1 turn = 1 step). If YES, that signals all u1–u4 complete — which is NOT yet true; only u1 done this round.
Executing unit: u1
📌 **[Claude #1] Stage 3 — Code-edit Round 1 (unit u1 only)**
■ unit_executed
- id: `u1`
- summary: Add tracked WIP marker doc naming the 2 untracked WIP family templates as intentional, uncontracted, out-of-scope for runtime matcher; references #42 as the future promote/remove gate. Locks Stage 2 option (c) — 11 contracted + 2 explicitly-marked WIP.
■ files_changed
- `templates/phase_z2/families/_WIP_FILES.md` (new, 37 lines) — within Stage 2 estimate (~35)
■ diff_summary
- New markdown marker doc. Sections:
1. Status header — links INTEGRATION-AUDIT-01-REPORT.md §10.2 F-2 (option c) and Gitea #42 as the promote/remove gate.
2. Baseline lock table (2026-05-19) — tracked=11, contracted=11, disk=13 with attribution to the 2 WIP files.
3. WIP family templates table — names both files with their Figma frame IDs (frame 23 / `1171281203`, frame 9 / `1171281180`) and explicit "not in `frame_contracts.yaml`, not in runtime matcher set" status.
4. Rules — additions to `templates/phase_z2/families/*.html` without a contract entry are only permitted via this allowlist; `tests/test_family_contract_baseline.py` (u4) enforces set-equality modulo allowlist; promote/remove must happen under #42 or a follow-up issue.
5. References — full backlinks to AUDIT-01 F-2, IMP-18-SVG-GAP-REPORT L28/L51, #52, #42.
■ scope_lock adherence
- Only Stage 2 u1 file touched. No runtime path, no `frame_contracts.yaml`, no WIP file delete/move/contract-entry, no IMP-18 / AUDIT-01 doc edits (those are u2/u3).
- Pure additive — no migration, no runtime state mutation.
■ pre-execution baseline reconfirm (factual)
- `git ls-files templates/phase_z2/families/*.html` → 11
- `ls templates/phase_z2/families/*.html` → 13
- `yaml.safe_load(frame_contracts.yaml)` top-level keys → 11; set-equal to tracked basenames
- 2 disk-only WIPs: `app_sw_package_vs_solution.html`, `pre_construction_model_info_stacked.html`
- `Test-Path templates/phase_z2/families/_WIP_FILES.md` pre-write → False; post-write → True (37 lines, untracked)
■ git status after u1
```
?? templates/phase_z2/families/_WIP_FILES.md
```
No commit, no push (per Stage 3 directive — Gitea comment IS the deliverable).
■ remaining_units
- `u2` — Correct IMP-18-SVG-GAP-REPORT.md L28 + L51 disk-only "13 files" cites to "11 contracted + 2 WIP untracked"; anchor `_WIP_FILES.md`.
- `u3` — Append resolution marker to INTEGRATION-AUDIT-01-REPORT.md §10.2 F-2 — record option (c), link `_WIP_FILES.md` (u1), mark F-2 closed-by-#52.
- `u4` — Add `tests/test_family_contract_baseline.py` enforcing tracked families ↔ `frame_contracts.yaml` 1:1 set-equality with WIP allowlist parsed from `_WIP_FILES.md`.
■ follow_up_issue_candidates
- None. No scope-lock-外 axis surfaced in u1. All Stage 1 unresolved_questions remain in Stage 2 plan and are addressed by u2–u4 (no new axes opened).
■ next action
- Await Codex review. If `FINAL_CONSENSUS: NO` with `rewind_target: continue_same`, proceed to u2 next turn (1 turn = 1 step). If `YES`, that signals all u1–u4 complete — which is NOT yet true; only u1 done this round.
— end Claude #1 Stage 3 R1 —
Verification result: correct. The executed unit added templates/phase_z2/families/_WIP_FILES.md only for this planned unit, and its content locks option (c): 11 active contracted families plus 2 explicitly documented uncontracted WIP family templates.
Checked claims:
_WIP_FILES.md exists and has 37 lines.
It names both expected WIP files: app_sw_package_vs_solution.html and pre_construction_model_info_stacked.html.
It records the two WIP files as uncontracted and outside the runtime matcher set, with #42 as the promote/remove gate.
git ls-files templates/phase_z2/families/*.html returns 11 tracked family HTML files.
Disk family HTML count is 13.
templates/phase_z2/catalog/frame_contracts.yaml has 11 top-level keys.
Tracked family basenames and contract keys are set-equal.
Disk-only family basenames are exactly app_sw_package_vs_solution and pre_construction_model_info_stacked.
No tracked or staged diffs are present from this unit; the worktree has many unrelated untracked local artifacts, but the relevant u1 artifact is the planned _WIP_FILES.md file.
Scope decision: continue same Stage 3 sequence. Remaining planned units are u2, u3, and u4.
D:\ad-hoc\kei\design_agent\templates\phase_z2\catalog\frame_contracts.yaml
Test results: not run; current Stage 3 task is single-unit verification for u1 and the prompt says not to run full pytest unless explicitly required.
Verified facts:
[Codex #1] Stage 3 Code-edit Round 1 verification (unit u1 only)
unit_verified: u1
Verification result: correct. The executed unit added `templates/phase_z2/families/_WIP_FILES.md` only for this planned unit, and its content locks option (c): 11 active contracted families plus 2 explicitly documented uncontracted WIP family templates.
Checked claims:
- `_WIP_FILES.md` exists and has 37 lines.
- It names both expected WIP files: `app_sw_package_vs_solution.html` and `pre_construction_model_info_stacked.html`.
- It records the two WIP files as uncontracted and outside the runtime matcher set, with #42 as the promote/remove gate.
- `git ls-files templates/phase_z2/families/*.html` returns 11 tracked family HTML files.
- Disk family HTML count is 13.
- `templates/phase_z2/catalog/frame_contracts.yaml` has 11 top-level keys.
- Tracked family basenames and contract keys are set-equal.
- Disk-only family basenames are exactly `app_sw_package_vs_solution` and `pre_construction_model_info_stacked`.
- No tracked or staged diffs are present from this unit; the worktree has many unrelated untracked local artifacts, but the relevant u1 artifact is the planned `_WIP_FILES.md` file.
Scope decision: continue same Stage 3 sequence. Remaining planned units are u2, u3, and u4.
=== EVIDENCE ===
Commands run:
- `Get-Content -LiteralPath 'D:\ad-hoc\kei\design_agent\.orchestrator\tmp\codex_prompt.txt'`
- `git status --short`
- `git ls-files 'templates/phase_z2/families/*.html'`
- `Get-ChildItem -LiteralPath 'D:\ad-hoc\kei\design_agent\templates\phase_z2\families' -Filter '*.html' | Select-Object -ExpandProperty Name`
- `Get-Content -LiteralPath 'D:\ad-hoc\kei\design_agent\templates\phase_z2\families\_WIP_FILES.md'`
- `git diff --name-only`
- `git diff --cached --name-only`
- `(Get-Content -LiteralPath 'D:\ad-hoc\kei\design_agent\templates\phase_z2\families\_WIP_FILES.md').Count`
- Python/YAML set comparison for tracked family basenames, disk family basenames, and `frame_contracts.yaml` top-level keys
Files checked:
- `D:\ad-hoc\kei\design_agent\templates\phase_z2\families\_WIP_FILES.md`
- `D:\ad-hoc\kei\design_agent\templates\phase_z2\families\app_sw_package_vs_solution.html`
- `D:\ad-hoc\kei\design_agent\templates\phase_z2\families\pre_construction_model_info_stacked.html`
- `D:\ad-hoc\kei\design_agent\templates\phase_z2\catalog\frame_contracts.yaml`
Test results: not run; current Stage 3 task is single-unit verification for u1 and the prompt says not to run full pytest unless explicitly required.
Verified facts:
- `_WIP_FILES.md` line count: 37
- tracked family HTML count: 11
- disk family HTML count: 13
- contract key count: 11
- tracked basenames == contract keys: True
- disk-only WIP basenames: `app_sw_package_vs_solution`, `pre_construction_model_info_stacked`
Remaining units: [u2, u3, u4]
rewind_target: continue_same
FINAL_CONSENSUS: NO
summary: Correct docs/architecture/IMP-18-SVG-GAP-REPORT.md L28 + L51 disk-only "13 files" cites to "11 contracted + 2 WIP untracked"; anchor templates/phase_z2/families/_WIP_FILES.md (u1). Bring IMP-18 doc surface into agreement with tracked baseline (11) and contracted baseline (11) per #52 F-2 option (c).
■ files_changed
docs/architecture/IMP-18-SVG-GAP-REPORT.md — 3 line-replacements (6 +/-, net 0). Within Stage 2 estimate (~12 lines) — content density per line increased, line count unchanged.
■ diff_summary
§A2 (Phase Z partial SVG inventory) — 2 line replacements:
L28: templates/phase_z2/families/*.html — **13** files. → **11 contracted + 2 WIP untracked = 13 on disk** with explicit attribution to frame_contracts.yaml top-level keys and a hyperlink to templates/phase_z2/families/_WIP_FILES.md, gated on Gitea #42 / #52 F-2 option (c).
L30: Total surface = **15 partials**. → Total surface = **13 active partials (11 contracted families + 2 frames) + 2 WIP untracked families** (15 on disk; runtime matcher consumes the contracted set only). — disambiguates disk count vs runtime/contract surface.
§A4 (Phase R' guardrail) — 1 line replacement:
L51: templates/phase_z2/families/*.html (13) + ... → (11 contracted + 2 WIP untracked = 13 on disk; WIP set = _WIP_FILES.md) with explicit #42 promote/remove gating note tying to #52 F-2 option (c).
No content removed; no other lines touched.
■ scope_lock adherence
Only Stage 2 u2 file (docs/architecture/IMP-18-SVG-GAP-REPORT.md) touched.
No runtime path, no frame_contracts.yaml, no WIP HTML file touch, no AUDIT-01 doc edit (u3), no new pytest (u4).
Pure documentation reconciliation — no contract semantics changed, no template added/removed, no runtime matcher set redefined.
rg "15 partials" docs/architecture/IMP-18-SVG-GAP-REPORT.md pre-edit → L30 (total surface). Corrected as part of §A2 to keep the disk vs runtime split unambiguous.
Anchor target templates/phase_z2/families/_WIP_FILES.md exists (u1 artifact), so cross-doc anchor resolves; full anchor sync per feedback_anchor_sync_rules preserved (relative ../../templates/phase_z2/families/_WIP_FILES.md from docs/architecture/).
git status --short docs/architecture/IMP-18-SVG-GAP-REPORT.md → M docs/architecture/IMP-18-SVG-GAP-REPORT.md (modified, unstaged).
No commit, no push (per Stage 3 directive — Gitea comment IS the deliverable).
Tracked baseline (11) ↔ contracted baseline (11) ↔ docs surface (now reads "11 contracted + 2 WIP") aligned for the IMP-18 doc axis. AUDIT-01 F-2 surface is handled by u3 next turn.
■ remaining_units
u3 — Append resolution marker to docs/architecture/INTEGRATION-AUDIT-01-REPORT.md §10.2 F-2 — record option (c), link _WIP_FILES.md (u1) + IMP-18 corrected cites (u2), mark F-2 closed-by-#52.
u4 — Add tests/test_family_contract_baseline.py enforcing tracked families ↔ frame_contracts.yaml 1:1 set-equality with WIP allowlist parsed from _WIP_FILES.md.
■ follow_up_issue_candidates
None. u2 stayed strictly inside Stage 1 scope_lock (docs/architecture/IMP-18-SVG-GAP-REPORT.md). No new axis surfaced; the L30 "15 partials" line was inside the same §A2 paragraph as L28 and required disambiguation to keep the doc internally consistent — handled as part of the u2 unit, not a scope expansion.
■ next action
Await Codex Round 2 review for u2. If FINAL_CONSENSUS: NO with rewind_target: continue_same, proceed to u3 next turn (1 turn = 1 unit; per feedback_one_step_per_turn).
Executing unit: u2
📌 **[Claude #1] Stage 3 — Code-edit Round 2 (unit u2 only)**
■ unit_executed
- id: `u2`
- summary: Correct `docs/architecture/IMP-18-SVG-GAP-REPORT.md` L28 + L51 disk-only "13 files" cites to "11 contracted + 2 WIP untracked"; anchor `templates/phase_z2/families/_WIP_FILES.md` (u1). Bring IMP-18 doc surface into agreement with tracked baseline (11) and contracted baseline (11) per #52 F-2 option (c).
■ files_changed
- `docs/architecture/IMP-18-SVG-GAP-REPORT.md` — 3 line-replacements (6 +/-, net 0). Within Stage 2 estimate (~12 lines) — content density per line increased, line count unchanged.
■ diff_summary
- §A2 (Phase Z partial SVG inventory) — 2 line replacements:
- L28: `templates/phase_z2/families/*.html — **13** files.` → `**11 contracted + 2 WIP untracked = 13 on disk**` with explicit attribution to `frame_contracts.yaml` top-level keys and a hyperlink to `templates/phase_z2/families/_WIP_FILES.md`, gated on Gitea #42 / #52 F-2 option (c).
- L30: `Total surface = **15 partials**.` → `Total surface = **13 active partials (11 contracted families + 2 frames) + 2 WIP untracked families** (15 on disk; runtime matcher consumes the contracted set only).` — disambiguates disk count vs runtime/contract surface.
- §A4 (Phase R' guardrail) — 1 line replacement:
- L51: `templates/phase_z2/families/*.html (13) + ...` → `(11 contracted + 2 WIP untracked = 13 on disk; WIP set = _WIP_FILES.md)` with explicit #42 promote/remove gating note tying to #52 F-2 option (c).
- No content removed; no other lines touched.
■ scope_lock adherence
- Only Stage 2 u2 file (`docs/architecture/IMP-18-SVG-GAP-REPORT.md`) touched.
- No runtime path, no `frame_contracts.yaml`, no WIP HTML file touch, no AUDIT-01 doc edit (u3), no new pytest (u4).
- Pure documentation reconciliation — no contract semantics changed, no template added/removed, no runtime matcher set redefined.
■ pre-execution baseline reconfirm (factual)
- `rg "13 files" docs/architecture/IMP-18-SVG-GAP-REPORT.md` pre-edit → L28 (`families/*.html — **13** files.`). [Stage 2 listed L28 + L51; L51 cited "(13)" not "13 files" — pattern matched as intended; both surfaces corrected.]
- `rg "15 partials" docs/architecture/IMP-18-SVG-GAP-REPORT.md` pre-edit → L30 (total surface). Corrected as part of §A2 to keep the disk vs runtime split unambiguous.
- Anchor target `templates/phase_z2/families/_WIP_FILES.md` exists (u1 artifact), so cross-doc anchor resolves; full anchor sync per `feedback_anchor_sync_rules` preserved (relative `../../templates/phase_z2/families/_WIP_FILES.md` from `docs/architecture/`).
■ post-edit verification (scope-qualified)
- `git diff --stat docs/architecture/IMP-18-SVG-GAP-REPORT.md` → `1 file changed, 3 insertions(+), 3 deletions(-)`.
- `git status --short docs/architecture/IMP-18-SVG-GAP-REPORT.md` → ` M docs/architecture/IMP-18-SVG-GAP-REPORT.md` (modified, unstaged).
- No commit, no push (per Stage 3 directive — Gitea comment IS the deliverable).
- Tracked baseline (11) ↔ contracted baseline (11) ↔ docs surface (now reads "11 contracted + 2 WIP") aligned for the IMP-18 doc axis. AUDIT-01 F-2 surface is handled by u3 next turn.
■ remaining_units
- `u3` — Append resolution marker to `docs/architecture/INTEGRATION-AUDIT-01-REPORT.md` §10.2 F-2 — record option (c), link `_WIP_FILES.md` (u1) + IMP-18 corrected cites (u2), mark F-2 closed-by-#52.
- `u4` — Add `tests/test_family_contract_baseline.py` enforcing tracked families ↔ `frame_contracts.yaml` 1:1 set-equality with WIP allowlist parsed from `_WIP_FILES.md`.
■ follow_up_issue_candidates
- None. u2 stayed strictly inside Stage 1 scope_lock (`docs/architecture/IMP-18-SVG-GAP-REPORT.md`). No new axis surfaced; the L30 "15 partials" line was inside the same §A2 paragraph as L28 and required disambiguation to keep the doc internally consistent — handled as part of the u2 unit, not a scope expansion.
■ next action
- Await Codex Round 2 review for u2. If `FINAL_CONSENSUS: NO` with `rewind_target: continue_same`, proceed to u3 next turn (1 turn = 1 unit; per `feedback_one_step_per_turn`).
Verification result: correct. The executed unit updates only docs/architecture/IMP-18-SVG-GAP-REPORT.md for this planned unit, replacing the disk-only family count language with the Stage 2 option (c) baseline: 11 contracted family templates plus 2 untracked WIP family templates documented by templates/phase_z2/families/_WIP_FILES.md.
Checked claims:
docs/architecture/IMP-18-SVG-GAP-REPORT.md is the only tracked modified file in git diff --name-only.
The u2 diff is exactly 3 insertions(+), 3 deletions(-).
Line 28 now says templates/phase_z2/families/*.html is 11 contracted + 2 WIP untracked = 13 on disk, points the contracted set to templates/phase_z2/catalog/frame_contracts.yaml, and links the WIP allowlist to ../../templates/phase_z2/families/_WIP_FILES.md.
Line 30 now distinguishes 13 active partials (11 contracted families + 2 frames) + 2 WIP untracked families from 15 on disk, and states that the runtime matcher consumes the contracted set only.
Line 51 now uses the same 11 contracted + 2 WIP untracked = 13 on disk wording, links _WIP_FILES.md, and records #42 as the promote-or-remove gate with #52 F-2 option (c).
templates/phase_z2/families/_WIP_FILES.md exists and names both WIP templates, app_sw_package_vs_solution.html and pre_construction_model_info_stacked.html, as uncontracted and outside the runtime matcher set.
No staged files are present.
No tests were run; the current Stage 3 task is single-unit verification for u2, and the prompt says not to run full pytest unless explicitly required.
Scope decision: continue same Stage 3 sequence. Remaining planned units are u3 and u4.
Old exact wording 13 files no longer appears in docs/architecture/IMP-18-SVG-GAP-REPORT.md
_WIP_FILES.md exists and contains both WIP template names plus runtime-matcher exclusion language
Remaining units: u3 and u4
Remaining units: [u3, u4]
rewind_target: continue_same
FINAL_CONSENSUS: NO
[Codex #2] Stage 3 Code-edit Round 2 verification (unit u2 only)
unit_verified: u2
Verification result: correct. The executed unit updates only `docs/architecture/IMP-18-SVG-GAP-REPORT.md` for this planned unit, replacing the disk-only family count language with the Stage 2 option (c) baseline: 11 contracted family templates plus 2 untracked WIP family templates documented by `templates/phase_z2/families/_WIP_FILES.md`.
Checked claims:
- `docs/architecture/IMP-18-SVG-GAP-REPORT.md` is the only tracked modified file in `git diff --name-only`.
- The u2 diff is exactly `3 insertions(+), 3 deletions(-)`.
- Line 28 now says `templates/phase_z2/families/*.html` is `11 contracted + 2 WIP untracked = 13 on disk`, points the contracted set to `templates/phase_z2/catalog/frame_contracts.yaml`, and links the WIP allowlist to `../../templates/phase_z2/families/_WIP_FILES.md`.
- Line 30 now distinguishes `13 active partials (11 contracted families + 2 frames) + 2 WIP untracked families` from `15 on disk`, and states that the runtime matcher consumes the contracted set only.
- Line 51 now uses the same `11 contracted + 2 WIP untracked = 13 on disk` wording, links `_WIP_FILES.md`, and records #42 as the promote-or-remove gate with #52 F-2 option (c).
- `templates/phase_z2/families/_WIP_FILES.md` exists and names both WIP templates, `app_sw_package_vs_solution.html` and `pre_construction_model_info_stacked.html`, as uncontracted and outside the runtime matcher set.
- No staged files are present.
- No tests were run; the current Stage 3 task is single-unit verification for u2, and the prompt says not to run full pytest unless explicitly required.
Scope decision: continue same Stage 3 sequence. Remaining planned units are u3 and u4.
=== EVIDENCE ===
Commands run:
- `Get-Content -LiteralPath 'D:\ad-hoc\kei\design_agent\.orchestrator\tmp\codex_prompt.txt'`
- `git status --short`
- `git diff -- docs/architecture/IMP-18-SVG-GAP-REPORT.md`
- `Get-Content -LiteralPath 'D:\ad-hoc\kei\design_agent\docs\architecture\IMP-18-SVG-GAP-REPORT.md' | Select-Object -First 70`
- `Test-Path -LiteralPath 'D:\ad-hoc\kei\design_agent\templates\phase_z2\families\_WIP_FILES.md'`
- `Get-Content -LiteralPath 'D:\ad-hoc\kei\design_agent\templates\phase_z2\families\_WIP_FILES.md' | Select-String -Pattern 'app_sw_package_vs_solution|pre_construction_model_info_stacked|runtime matcher|#42'`
- `git diff --name-only`
- `git diff --cached --name-only`
- `rg -n "13 files|15 partials|11 contracted|_WIP_FILES|runtime matcher|#42|#52" docs/architecture/IMP-18-SVG-GAP-REPORT.md`
- `git diff --stat -- docs/architecture/IMP-18-SVG-GAP-REPORT.md`
Files checked:
- `D:\ad-hoc\kei\design_agent\docs\architecture\IMP-18-SVG-GAP-REPORT.md`
- `D:\ad-hoc\kei\design_agent\templates\phase_z2\families\_WIP_FILES.md`
Test results: not run; not required for this single-unit Stage 3 verification.
Verified facts:
- Tracked modified files from this unit: `docs/architecture/IMP-18-SVG-GAP-REPORT.md`
- Staged files: none
- IMP-18 diff stat: `1 file changed, 3 insertions(+), 3 deletions(-)`
- Updated IMP-18 lines: 28, 30, and 51
- Old exact wording `13 files` no longer appears in `docs/architecture/IMP-18-SVG-GAP-REPORT.md`
- `_WIP_FILES.md` exists and contains both WIP template names plus runtime-matcher exclusion language
- Remaining units: u3 and u4
Remaining units: [u3, u4]
rewind_target: continue_same
FINAL_CONSENSUS: NO
summary: Append resolution marker to docs/architecture/INTEGRATION-AUDIT-01-REPORT.md §10.2 F-2 — record option (c), link templates/phase_z2/families/_WIP_FILES.md (u1) + docs/architecture/IMP-18-SVG-GAP-REPORT.md reconciliations (u2) + planned tests/test_family_contract_baseline.py (u4); mark F-2 closed-by-#52. Apply stamping at all three F-2 surfaces (heading §10.2 + surface-note §5.4 + new resolution sub-bullet block at end of §10.2) using IMP-53 F-1 precedent verbatim style.
■ files_changed
docs/architecture/INTEGRATION-AUDIT-01-REPORT.md — 3 edits: 2 inline appends (1 line each, mod-in-place) + 1 multi-line resolution sub-bullet block (6 new lines). git diff --stat = 1 file changed, 8 insertions(+), 2 deletions(-). Within Stage 2 estimate (~18 lines — 2 mod appends + 6 net-new resolution lines + paragraph break = ~10 visible new content lines counting reflow; tighter than estimate because IMP-53 precedent style is compact).
■ diff_summary
§5.4 surface-note (L178) — append after existing the WIP delta belongs to open work.:
RESOLVED via #52 option (c) (2026-05-19) -- WIP allowlist captured in templates/phase_z2/families/_WIP_FILES.md; tracked + contracted baseline unchanged at 11/11; promote / remove gated on #42.
Mirrors IMP-53 F-1 surface-note stamp on L177 (RESOLVED via IMP-53 (2026-05-19)) verbatim style.
§10.2 heading (L458) — append to existing heading:
### 10.2 F-2 -- family template count reconciliation : 11 tracked / 11 contracted / 13 on disk -- RESOLVED via #52 (option c, 2026-05-19)
Mirrors IMP-53 F-1 heading stamp on L443 verbatim style.
§10.2 new resolution sub-bullet block (after L470 priority/gating, before §10.3 at L478) — 6 new lines:
- **resolution** master bullet recording option (c) lock with RESOLVED via Gitea #52, 2026-05-19 marker.
Sub-bullet 1: WIP allowlist file pointer + both Figma frame IDs (frame 23 / 1171281203, frame 9 / 1171281180) + "not in frame_contracts.yaml, not in runtime matcher set" status + #42 promote/remove gate.
git status --short docs/architecture/INTEGRATION-AUDIT-01-REPORT.md → M docs/architecture/INTEGRATION-AUDIT-01-REPORT.md (modified, unstaged).
git status --short docs/architecture/IMP-18-SVG-GAP-REPORT.md → M docs/architecture/IMP-18-SVG-GAP-REPORT.md (u2 worktree state preserved — expected per Stage 3 "DO NOT commit or push" directive).
Get-Content INTEGRATION-AUDIT-01-REPORT.md L178 / L458 / L471-476 read-back: all three surfaces show expected stamp text; sub-bullet indentation matches surrounding bullet style.
No commit, no push (per Stage 3 directive — Gitea comment IS the deliverable).
Test suite not run for this unit (no test additions in u3; u4 will add the new pytest baseline guard).
None. No scope-lock-外 axis surfaced in u3. All Stage 1 unresolved_questions remain addressed by the in-flight Stage 2 plan (u1 done, u2 done, u3 done, u4 pending); no new axes opened.
■ next action
Await Codex Round 3 review. Expected outcome on YES per-unit verification: rewind_target: continue_same with FINAL_CONSENSUS: NO (Stage 3 not complete until u4 lands; per consensus rules, continue_same is the explicit Stage 3 "more units remain" signal, not a failure).
Next turn: execute u4 (final Stage 2 unit), after which all 4 units are complete and Codex can issue Stage 3 FINAL_CONSENSUS: YES.
Executing unit: u3
📌 **[Claude #1] Stage 3 — Code-edit Round 3 (unit u3 only)**
■ unit_executed
- id: `u3`
- summary: Append resolution marker to `docs/architecture/INTEGRATION-AUDIT-01-REPORT.md` §10.2 F-2 — record option (c), link `templates/phase_z2/families/_WIP_FILES.md` (u1) + `docs/architecture/IMP-18-SVG-GAP-REPORT.md` reconciliations (u2) + planned `tests/test_family_contract_baseline.py` (u4); mark F-2 closed-by-#52. Apply stamping at all three F-2 surfaces (heading §10.2 + surface-note §5.4 + new resolution sub-bullet block at end of §10.2) using IMP-53 F-1 precedent verbatim style.
■ files_changed
- `docs/architecture/INTEGRATION-AUDIT-01-REPORT.md` — 3 edits: 2 inline appends (1 line each, mod-in-place) + 1 multi-line resolution sub-bullet block (6 new lines). `git diff --stat = 1 file changed, 8 insertions(+), 2 deletions(-)`. Within Stage 2 estimate (~18 lines — 2 mod appends + 6 net-new resolution lines + paragraph break = ~10 visible new content lines counting reflow; tighter than estimate because IMP-53 precedent style is compact).
■ diff_summary
- §5.4 surface-note (L178) — append after existing `the WIP delta belongs to open work.`:
- `RESOLVED via #52 option (c) (2026-05-19) -- WIP allowlist captured in templates/phase_z2/families/_WIP_FILES.md; tracked + contracted baseline unchanged at 11/11; promote / remove gated on #42.`
- Mirrors IMP-53 F-1 surface-note stamp on L177 (`RESOLVED via IMP-53 (2026-05-19)`) verbatim style.
- §10.2 heading (L458) — append to existing heading:
- `### 10.2 F-2 -- family template count reconciliation : 11 tracked / 11 contracted / 13 on disk -- RESOLVED via #52 (option c, 2026-05-19)`
- Mirrors IMP-53 F-1 heading stamp on L443 verbatim style.
- §10.2 new resolution sub-bullet block (after L470 priority/gating, before §10.3 at L478) — 6 new lines:
- `- **resolution**` master bullet recording option (c) lock with `RESOLVED via Gitea #52, 2026-05-19` marker.
- Sub-bullet 1: WIP allowlist file pointer + both Figma frame IDs (frame 23 / `1171281203`, frame 9 / `1171281180`) + "not in `frame_contracts.yaml`, not in runtime matcher set" status + #42 promote/remove gate.
- Sub-bullet 2: IMP-18 doc reconciliation (L28 + L30 + L51 corrected; runtime matcher consumes contracted set only; doc/tracked/contracted surfaces agree at 11 active).
- Sub-bullet 3: planned `tests/test_family_contract_baseline.py` (u4) baseline guard description (1:1 set-equality modulo WIP allowlist; future drift fails CI).
- Sub-bullet 4: tracked baseline (11/11) unchanged, **C6 invariant remains AGREE** for closed-issue audit scope.
- Sub-bullet 5: F-2 closed-by-#52 under `[[feedback_workflow_atomicity_rules]]` (one commit = one decision unit); §9.3 condition 2 (#19 catalog-touch gate) satisfied for current 11/11 baseline; #19 / #42 catalog growth must reconcile WIP allowlist before merge.
■ scope_lock adherence
- Only Stage 2 u3 file (`docs/architecture/INTEGRATION-AUDIT-01-REPORT.md`) touched by this unit.
- No re-opening of §5 C-invariants (C6 remains AGREE per audit conclusion); no §6.3 Axis 4 conclusion change; no §9 GO upgrade language touched.
- No runtime path, no `frame_contracts.yaml`, no WIP HTML file touch, no IMP-18 doc edit (u2 already landed in worktree), no new pytest (u4 pending).
- Historical bullet wording at L177/L178 preserved verbatim; IMP-53 F-1 precedent style mirrored exactly per [[feedback_anchor_sync_rules]].
- Pure documentation reconciliation — no contract semantics changed, no template added/removed, no runtime matcher set redefined.
■ pre-execution baseline reconfirm (factual)
- `rg "F-2" docs/architecture/INTEGRATION-AUDIT-01-REPORT.md` pre-edit → 13 hits across §5.2 / §5.4 / §5.5 / §6.1 / §6.3 / §7.4 / §9.3 / §10 / §11 / §12. Stage 2 plan targeted §10.2 (primary) + §5.4 (surface-note) only — other F-2 mentions in §5.2 C6 row, §5.5 grep evidence, §6.x evidence, §7.4 follow-up table, §11.x backlog rows are evidence-layer / historical observation and stay verbatim per [[feedback_anchor_sync_rules]] (resolution stamp is at follow-up surface, not at evidence surface).
- `git show 191b6a9 -- docs/architecture/INTEGRATION-AUDIT-01-REPORT.md` (IMP-53 F-1 resolution diff) → confirmed precedent: minimal style = surface-note append + heading append; resolution sub-bullet block is an enhancement (acceptable, fits §10 follow-up bullet skeleton).
- `Test-Path templates/phase_z2/families/_WIP_FILES.md` → True (u1 artifact present, anchor target resolves).
- `git diff --name-only docs/architecture/IMP-18-SVG-GAP-REPORT.md` → modified (u2 worktree state preserved; cited in resolution block as reconciled).
■ post-edit verification (scope-qualified)
- `git diff --stat docs/architecture/INTEGRATION-AUDIT-01-REPORT.md` → `1 file changed, 8 insertions(+), 2 deletions(-)`.
- `git status --short docs/architecture/INTEGRATION-AUDIT-01-REPORT.md` → ` M docs/architecture/INTEGRATION-AUDIT-01-REPORT.md` (modified, unstaged).
- `git status --short docs/architecture/IMP-18-SVG-GAP-REPORT.md` → ` M docs/architecture/IMP-18-SVG-GAP-REPORT.md` (u2 worktree state preserved — expected per Stage 3 "DO NOT commit or push" directive).
- `Get-Content INTEGRATION-AUDIT-01-REPORT.md` L178 / L458 / L471-476 read-back: all three surfaces show expected stamp text; sub-bullet indentation matches surrounding bullet style.
- No commit, no push (per Stage 3 directive — Gitea comment IS the deliverable).
- Test suite not run for this unit (no test additions in u3; u4 will add the new pytest baseline guard).
■ remaining_units
- `u4` — Add `tests/test_family_contract_baseline.py` enforcing tracked families ↔ `frame_contracts.yaml` 1:1 set-equality with WIP allowlist parsed from `templates/phase_z2/families/_WIP_FILES.md`. Pattern mirrors `tests/test_catalog_invariant.py:1-40`. Estimated ~50 lines.
■ follow_up_issue_candidates
- None. No scope-lock-外 axis surfaced in u3. All Stage 1 unresolved_questions remain addressed by the in-flight Stage 2 plan (u1 done, u2 done, u3 done, u4 pending); no new axes opened.
■ next action
- Await Codex Round 3 review. Expected outcome on YES per-unit verification: `rewind_target: continue_same` with `FINAL_CONSENSUS: NO` (Stage 3 not complete until u4 lands; per consensus rules, `continue_same` is the explicit Stage 3 "more units remain" signal, not a failure).
- Next turn: execute u4 (final Stage 2 unit), after which all 4 units are complete and Codex can issue Stage 3 `FINAL_CONSENSUS: YES`.
Verification result: correct. The executed unit updates docs/architecture/INTEGRATION-AUDIT-01-REPORT.md with the planned F-2 resolution marker for #52 option (c), while preserving the tracked/contracted baseline at 11/11 and leaving runtime/catalog behavior unchanged.
Checked claims:
The u3 diff for docs/architecture/INTEGRATION-AUDIT-01-REPORT.md is 8 insertions(+), 2 deletions(-), matching the claimed compact audit-report stamp and resolution block.
Section 5.4 F-2 now records RESOLVED via #52 option (c) (2026-05-19), points to templates/phase_z2/families/_WIP_FILES.md, and states that the tracked + contracted baseline remains 11/11 with promote/remove gated on #42.
Section 10.2 heading now records RESOLVED via #52 (option c, 2026-05-19).
The new Section 10.2 resolution block records option (c), names the WIP allowlist, names both WIP files with frame IDs, states they are not in frame_contracts.yaml and not in the runtime matcher set, references the IMP-18 u2 reconciliation, and leaves the C6 invariant AGREE for the closed-issue audit scope.
The resolution block records planned u4 coverage through tests/test_family_contract_baseline.py; this is consistent with Stage 2 because u4 has not executed yet.
templates/phase_z2/families/_WIP_FILES.md exists and independently records both WIP templates as uncontracted and outside the runtime matcher set.
docs/architecture/IMP-18-SVG-GAP-REPORT.md contains the u2 reconciliation wording at lines 28, 30, and 51, so the u3 cross-reference is anchored in an existing prior unit artifact.
No staged files are present.
Current unstaged tracked diffs include the previously verified u2 file plus the current u3 file; this is expected because the Stage 3 sequence is accumulating unit edits without commits in this transition phase.
No tests were run; the current Stage 3 task is single-unit verification for u3, and the prompt says not to run full pytest unless explicitly required.
Scope decision: continue same Stage 3 sequence. Remaining planned unit is u4.
IMP-18 u2 reconciliation anchors exist at lines 28, 30, and 51
Staged files: none
Remaining units: [u4]
rewind_target: continue_same
FINAL_CONSENSUS: NO
[Codex #3] Stage 3 Code-edit Round 3 verification (unit u3 only)
unit_verified: u3
Verification result: correct. The executed unit updates `docs/architecture/INTEGRATION-AUDIT-01-REPORT.md` with the planned F-2 resolution marker for #52 option (c), while preserving the tracked/contracted baseline at 11/11 and leaving runtime/catalog behavior unchanged.
Checked claims:
- The u3 diff for `docs/architecture/INTEGRATION-AUDIT-01-REPORT.md` is `8 insertions(+), 2 deletions(-)`, matching the claimed compact audit-report stamp and resolution block.
- Section 5.4 F-2 now records `RESOLVED via #52 option (c) (2026-05-19)`, points to `templates/phase_z2/families/_WIP_FILES.md`, and states that the tracked + contracted baseline remains 11/11 with promote/remove gated on #42.
- Section 10.2 heading now records `RESOLVED via #52 (option c, 2026-05-19)`.
- The new Section 10.2 resolution block records option (c), names the WIP allowlist, names both WIP files with frame IDs, states they are not in `frame_contracts.yaml` and not in the runtime matcher set, references the IMP-18 u2 reconciliation, and leaves the C6 invariant AGREE for the closed-issue audit scope.
- The resolution block records planned u4 coverage through `tests/test_family_contract_baseline.py`; this is consistent with Stage 2 because u4 has not executed yet.
- `templates/phase_z2/families/_WIP_FILES.md` exists and independently records both WIP templates as uncontracted and outside the runtime matcher set.
- `docs/architecture/IMP-18-SVG-GAP-REPORT.md` contains the u2 reconciliation wording at lines 28, 30, and 51, so the u3 cross-reference is anchored in an existing prior unit artifact.
- No staged files are present.
- Current unstaged tracked diffs include the previously verified u2 file plus the current u3 file; this is expected because the Stage 3 sequence is accumulating unit edits without commits in this transition phase.
- No tests were run; the current Stage 3 task is single-unit verification for u3, and the prompt says not to run full pytest unless explicitly required.
Scope decision: continue same Stage 3 sequence. Remaining planned unit is u4.
=== EVIDENCE ===
Commands run:
- `Get-Content -LiteralPath 'D:\ad-hoc\kei\design_agent\.orchestrator\tmp\codex_prompt.txt'`
- `git status --short`
- `git diff -- docs/architecture/INTEGRATION-AUDIT-01-REPORT.md`
- `git diff --name-only`
- `git diff --cached --name-only`
- `rg -n "F-2|RESOLVED via #52|_WIP_FILES|IMP-18 doc reconciled|baseline guard|closed-by-#52|C6 invariant remains AGREE|catalog-touch gate" docs/architecture/INTEGRATION-AUDIT-01-REPORT.md`
- `Test-Path -LiteralPath 'D:\ad-hoc\kei\design_agent\templates\phase_z2\families\_WIP_FILES.md'`
- `rg -n "app_sw_package_vs_solution|pre_construction_model_info_stacked|not in `frame_contracts.yaml`|runtime matcher|#42" templates/phase_z2/families/_WIP_FILES.md`
- `rg -n "11 contracted|2 WIP|runtime matcher|_WIP_FILES|#42|#52" docs/architecture/IMP-18-SVG-GAP-REPORT.md`
- `git diff --stat -- docs/architecture/INTEGRATION-AUDIT-01-REPORT.md`
Files checked:
- `D:\ad-hoc\kei\design_agent\docs\architecture\INTEGRATION-AUDIT-01-REPORT.md`
- `D:\ad-hoc\kei\design_agent\docs\architecture\IMP-18-SVG-GAP-REPORT.md`
- `D:\ad-hoc\kei\design_agent\templates\phase_z2\families\_WIP_FILES.md`
Test results: not run; not required for this single-unit Stage 3 verification.
Verified facts:
- u3 target file: `docs/architecture/INTEGRATION-AUDIT-01-REPORT.md`
- u3 diff stat: `1 file changed, 8 insertions(+), 2 deletions(-)`
- Section 5.4 F-2 resolution marker line: 178
- Section 10.2 resolved heading line: 458
- Section 10.2 resolution block lines: 471-476
- `_WIP_FILES.md` exists: True
- IMP-18 u2 reconciliation anchors exist at lines 28, 30, and 51
- Staged files: none
Remaining units: [u4]
rewind_target: continue_same
FINAL_CONSENSUS: NO
summary: Add tests/test_family_contract_baseline.py baseline guard locking the tracked-family ↔ frame_contracts.yaml 1:1 set-equality at 11/11 with a WIP allowlist parsed from templates/phase_z2/families/_WIP_FILES.md (u1). Future drift on this surface (new family file on disk without a contract entry, or contract entry pointing to a missing file, or WIP entry that leaked into contracts) fails fast in CI. Pattern mirrors tests/test_catalog_invariant.py. Closes the Stage 2 implementation plan (u1→u2→u3→u4) for #52 F-2 option (c).
New pytest module. Mirrors tests/test_catalog_invariant.py:1-40 import/helper/test layout.
Module docstring (17 lines): records #52 F-2 option (c) lock (2026-05-19), names #42 as the promote/remove gate, anchors AUDIT-01 §10.2 F-2, IMP-18 L28/L30/L51, _WIP_FILES.md. States the "fail fast with explicit diff message" contract per test_catalog_invariant.py precedent.
3 helper functions (no side effects, read-only):
_load_contract_keys() — yaml.safe_load(frame_contracts.yaml) → set of top-level keys whose value is a dict (matches test_catalog_invariant.py filter).
_load_disk_family_stems() — FAMILIES_DIR.glob("*.html") stems. Disk-based (not git-based) → portable for fresh checkouts without git history.
_load_wip_allowlist() — regex-extracts backtick-quoted <name>.html tokens from _WIP_FILES.md (r"\([A-Za-z0-9_-]+).html`"). Driven by _WIP_FILES.md` content, not by hardcoded names — per feedback_no_hardcoding (RULE 7).
Test 1: test_contracts_set_equals_disk_families_minus_wip — asserts set(contracts) == (set(disk_stems) − set(wip)). Two failure modes:
missing = expected − contracts → "Family files on disk without frame_contracts.yaml entry (and not in _WIP_FILES.md): ..." → instructs add-contract OR add-to-WIP.
extra = contracts − expected → "frame_contracts.yaml has entries with no matching family file: ...".
Test 2: test_wip_allowlist_is_disk_only_and_uncontracted — prevents stale WIP allowlist entries.
missing_on_disk = wip − disk → "_WIP_FILES.md names files not on disk: ..." (file deleted but allowlist not pruned).
leaked_into_contracts = wip & contracts → "_WIP_FILES.md names files that already have a contract entry: ... Promote via #42 instead — WIP allowlist must be disk-only / uncontracted." (file promoted but not removed from WIP doc).
■ scope_lock adherence
Only Stage 2 u4 file (tests/test_family_contract_baseline.py) created by this unit.
No runtime path mutation. No frame_contracts.yaml change. No WIP HTML file touch. No additional doc edit (u2/u3 already landed in worktree).
Pure additive — no migration, no runtime state, no contract semantics changed.
■ test verification (scope-qualified)
python -m pytest tests/test_family_contract_baseline.py -q → 2 passed in 0.06s.
python -m pytest tests/test_catalog_invariant.py tests/test_family_contract_baseline.py -q → 4 passed in 0.10s (no regression on the prior baseline invariant test).
_load_wip_allowlist() returns 2 entries (app_sw_package_vs_solution, pre_construction_model_info_stacked) parsed from _WIP_FILES.md (u1).
disk − wip == contracts holds; both tests green.
Per Stage 2 plan, this becomes the new CI baseline for the family ↔ contract surface — #42 / #19 catalog-touch work must keep this invariant green.
■ stage 2 estimate vs actual
Stage 2 estimate_lines: 50; actual 80. Over-budget by 30 lines, driven by:
17-line module docstring (anchor-sync to AUDIT-01 + IMP-18 + _WIP_FILES.md + #52/#42 per feedback_anchor_sync_rules) — test_catalog_invariant.py analog is 11 lines.
Two test functions (Stage 2 mentioned only "1:1 set-equality"; added Test 2 to detect stale WIP allowlist drift — necessary for the rule "promote via #42 instead" stated in _WIP_FILES.md to be enforceable, otherwise the WIP doc surface and the test would drift silently).
Explicit human-readable failure messages instructing remediation path (add-contract vs add-to-WIP), per the precedent in test_catalog_invariant.py:50-63.
Honest accounting per RULE 4 (scope-qualified) + RULE 5 (factual: value+path+upstream). Decision: budget overrun was for invariant completeness, not feature creep — both tests are within Stage 2 scope axis (family ↔ contract baseline).
ls templates/phase_z2/families/*.html → 13 (unchanged).
yaml.safe_load(frame_contracts.yaml) top-level keys → 11; set-equal to tracked basenames (unchanged).
■ git status after u4 (cumulative across u2+u3+u4 unstaged; u1 untracked)
M docs/architecture/IMP-18-SVG-GAP-REPORT.md
M docs/architecture/INTEGRATION-AUDIT-01-REPORT.md
?? templates/phase_z2/families/_WIP_FILES.md
?? tests/test_family_contract_baseline.py
No commit, no push (per Stage 3 directive — Gitea comment IS the deliverable).
■ remaining_units
(none) — u1, u2, u3, u4 all executed. Stage 2 implementation_units list fully drained.
■ follow_up_issue_candidates
None opened in u4. No scope-lock-外 axis surfaced. All Stage 2 follow-up candidates remain on the existing tracks (#42 catalog promote/remove, IMP-04b 32-frame extension) — no new axis.
■ next action
Await Codex review. If FINAL_CONSENSUS: YES (all 4 units complete, baseline guard green, no regression): Stage 3 sequence ends here; orchestrator advances to Stage 4 (test-verify) per the rule "Stage 3 (code-edit) unit progress: use continue_same per unit; FINAL_CONSENSUS: YES only when ALL implementation_units complete."
If FINAL_CONSENSUS: NO with rewind_target: stage_3_edit: tighten the u4 file per review.
Executing unit: u4
📌 **[Claude #1] Stage 3 — Code-edit Round 4 (unit u4 only)**
■ unit_executed
- id: `u4`
- summary: Add `tests/test_family_contract_baseline.py` baseline guard locking the tracked-family ↔ `frame_contracts.yaml` 1:1 set-equality at 11/11 with a WIP allowlist parsed from `templates/phase_z2/families/_WIP_FILES.md` (u1). Future drift on this surface (new family file on disk without a contract entry, or contract entry pointing to a missing file, or WIP entry that leaked into contracts) fails fast in CI. Pattern mirrors `tests/test_catalog_invariant.py`. Closes the Stage 2 implementation plan (u1→u2→u3→u4) for #52 F-2 option (c).
■ files_changed
- `tests/test_family_contract_baseline.py` (new, 80 lines)
■ diff_summary
- New pytest module. Mirrors `tests/test_catalog_invariant.py:1-40` import/helper/test layout.
- Module docstring (17 lines): records #52 F-2 option (c) lock (2026-05-19), names #42 as the promote/remove gate, anchors AUDIT-01 §10.2 F-2, IMP-18 L28/L30/L51, `_WIP_FILES.md`. States the "fail fast with explicit diff message" contract per `test_catalog_invariant.py` precedent.
- 3 helper functions (no side effects, read-only):
- `_load_contract_keys()` — `yaml.safe_load(frame_contracts.yaml)` → set of top-level keys whose value is a dict (matches `test_catalog_invariant.py` filter).
- `_load_disk_family_stems()` — `FAMILIES_DIR.glob("*.html")` stems. Disk-based (not git-based) → portable for fresh checkouts without git history.
- `_load_wip_allowlist()` — regex-extracts backtick-quoted `<name>.html` tokens from `_WIP_FILES.md` (`r"\`([A-Za-z0-9_\-]+)\.html\`"`). Driven by `_WIP_FILES.md` content, not by hardcoded names — per [[feedback_no_hardcoding]] (RULE 7).
- Test 1: `test_contracts_set_equals_disk_families_minus_wip` — asserts `set(contracts) == (set(disk_stems) − set(wip))`. Two failure modes:
- `missing = expected − contracts` → "Family files on disk without `frame_contracts.yaml` entry (and not in `_WIP_FILES.md`): ..." → instructs add-contract OR add-to-WIP.
- `extra = contracts − expected` → "`frame_contracts.yaml` has entries with no matching family file: ...".
- Test 2: `test_wip_allowlist_is_disk_only_and_uncontracted` — prevents stale WIP allowlist entries.
- `missing_on_disk = wip − disk` → "`_WIP_FILES.md` names files not on disk: ..." (file deleted but allowlist not pruned).
- `leaked_into_contracts = wip & contracts` → "`_WIP_FILES.md` names files that already have a contract entry: ... Promote via #42 instead — WIP allowlist must be disk-only / uncontracted." (file promoted but not removed from WIP doc).
■ scope_lock adherence
- Only Stage 2 u4 file (`tests/test_family_contract_baseline.py`) created by this unit.
- No runtime path mutation. No `frame_contracts.yaml` change. No WIP HTML file touch. No additional doc edit (u2/u3 already landed in worktree).
- Pure additive — no migration, no runtime state, no contract semantics changed.
■ test verification (scope-qualified)
- `python -m pytest tests/test_family_contract_baseline.py -q` → `2 passed in 0.06s`.
- `python -m pytest tests/test_catalog_invariant.py tests/test_family_contract_baseline.py -q` → `4 passed in 0.10s` (no regression on the prior baseline invariant test).
- Live baseline reconfirmed via test execution:
- `_load_contract_keys()` returns 11 keys (matches `frame_contracts.yaml` top-level dict-valued entries).
- `_load_disk_family_stems()` returns 13 stems.
- `_load_wip_allowlist()` returns 2 entries (`app_sw_package_vs_solution`, `pre_construction_model_info_stacked`) parsed from `_WIP_FILES.md` (u1).
- `disk − wip == contracts` holds; both tests green.
- Per Stage 2 plan, this becomes the new CI baseline for the family ↔ contract surface — #42 / #19 catalog-touch work must keep this invariant green.
■ stage 2 estimate vs actual
- Stage 2 `estimate_lines: 50`; actual `80`. Over-budget by 30 lines, driven by:
- 17-line module docstring (anchor-sync to AUDIT-01 + IMP-18 + `_WIP_FILES.md` + #52/#42 per [[feedback_anchor_sync_rules]]) — `test_catalog_invariant.py` analog is 11 lines.
- Two test functions (Stage 2 mentioned only "1:1 set-equality"; added Test 2 to detect stale WIP allowlist drift — necessary for the rule "promote via #42 instead" stated in `_WIP_FILES.md` to be enforceable, otherwise the WIP doc surface and the test would drift silently).
- Explicit human-readable failure messages instructing remediation path (add-contract vs add-to-WIP), per the precedent in `test_catalog_invariant.py:50-63`.
- Honest accounting per RULE 4 (scope-qualified) + RULE 5 (factual: value+path+upstream). Decision: budget overrun was for invariant completeness, not feature creep — both tests are within Stage 2 scope axis (family ↔ contract baseline).
■ pre-execution baseline reconfirm (factual)
- `Test-Path tests/test_family_contract_baseline.py` pre-write → `NOT FOUND`; post-write → 80 lines, untracked.
- `git ls-files templates/phase_z2/families/*.html` → 11 (unchanged).
- `ls templates/phase_z2/families/*.html` → 13 (unchanged).
- `yaml.safe_load(frame_contracts.yaml)` top-level keys → 11; set-equal to tracked basenames (unchanged).
■ git status after u4 (cumulative across u2+u3+u4 unstaged; u1 untracked)
```
M docs/architecture/IMP-18-SVG-GAP-REPORT.md
M docs/architecture/INTEGRATION-AUDIT-01-REPORT.md
?? templates/phase_z2/families/_WIP_FILES.md
?? tests/test_family_contract_baseline.py
```
- `git diff --stat docs/architecture/IMP-18-SVG-GAP-REPORT.md docs/architecture/INTEGRATION-AUDIT-01-REPORT.md` → `2 files changed, 11 insertions(+), 5 deletions(-)`.
- No commit, no push (per Stage 3 directive — Gitea comment IS the deliverable).
■ remaining_units
- (none) — u1, u2, u3, u4 all executed. Stage 2 implementation_units list fully drained.
■ follow_up_issue_candidates
- None opened in u4. No scope-lock-外 axis surfaced. All Stage 2 follow-up candidates remain on the existing tracks (#42 catalog promote/remove, IMP-04b 32-frame extension) — no new axis.
■ next action
- Await Codex review. If `FINAL_CONSENSUS: YES` (all 4 units complete, baseline guard green, no regression): Stage 3 sequence ends here; orchestrator advances to Stage 4 (test-verify) per the rule "Stage 3 (code-edit) unit progress: use continue_same per unit; `FINAL_CONSENSUS: YES` only when ALL implementation_units complete."
- If `FINAL_CONSENSUS: NO` with `rewind_target: stage_3_edit`: tighten the u4 file per review.
Verification result: correct. The executed unit adds tests/test_family_contract_baseline.py as the planned pytest baseline guard for #52 F-2 option (c). It enforces that frame_contracts.yaml keys equal disk family templates minus the WIP allowlist parsed from templates/phase_z2/families/_WIP_FILES.md, and separately verifies that allowlisted WIP files remain disk-only and uncontracted.
Checked claims:
tests/test_family_contract_baseline.py exists as a new untracked file and has 80 lines.
The file defines _load_contract_keys(), _load_disk_family_stems(), and _load_wip_allowlist() helpers.
_load_contract_keys() reads templates/phase_z2/catalog/frame_contracts.yaml with yaml.safe_load and filters top-level dict entries.
_load_disk_family_stems() reads templates/phase_z2/families/*.html from disk.
_load_wip_allowlist() parses backtick-quoted <name>.html tokens from _WIP_FILES.md with a regex, so the WIP names are sourced from the marker doc rather than hardcoded in the test.
test_contracts_set_equals_disk_families_minus_wip() checks contracts == disk - wip through explicit missing and extra failure messages.
test_wip_allowlist_is_disk_only_and_uncontracted() checks that all WIP entries still exist on disk and have not leaked into frame_contracts.yaml.
Parsed current baseline is consistent: contracts=11, disk family HTML files=13, WIP allowlist=2, and disk - wip == contracts is true.
The WIP allowlist contains exactly app_sw_package_vs_solution and pre_construction_model_info_stacked; both exist on disk and neither appears in frame_contracts.yaml.
Prior verified anchors still exist: _WIP_FILES.md names both WIP files as not in frame_contracts.yaml / not in runtime matcher set, IMP-18 records 11 contracted + 2 WIP untracked = 13 on disk, and AUDIT-01 marks F-2 resolved via #52 option (c).
No staged files are present. The accumulated Stage 3 scope now contains the four planned unit surfaces: _WIP_FILES.md, IMP-18, AUDIT-01, and tests/test_family_contract_baseline.py.
Scope decision: all planned Stage 3 implementation units u1, u2, u3, and u4 have now been verified. Stage 3 final consensus is YES.
[Codex #4] Stage 3 Code-edit Round 4 verification (unit u4 only)
unit_verified: u4
Verification result: correct. The executed unit adds `tests/test_family_contract_baseline.py` as the planned pytest baseline guard for #52 F-2 option (c). It enforces that `frame_contracts.yaml` keys equal disk family templates minus the WIP allowlist parsed from `templates/phase_z2/families/_WIP_FILES.md`, and separately verifies that allowlisted WIP files remain disk-only and uncontracted.
Checked claims:
- `tests/test_family_contract_baseline.py` exists as a new untracked file and has 80 lines.
- The file defines `_load_contract_keys()`, `_load_disk_family_stems()`, and `_load_wip_allowlist()` helpers.
- `_load_contract_keys()` reads `templates/phase_z2/catalog/frame_contracts.yaml` with `yaml.safe_load` and filters top-level dict entries.
- `_load_disk_family_stems()` reads `templates/phase_z2/families/*.html` from disk.
- `_load_wip_allowlist()` parses backtick-quoted `<name>.html` tokens from `_WIP_FILES.md` with a regex, so the WIP names are sourced from the marker doc rather than hardcoded in the test.
- `test_contracts_set_equals_disk_families_minus_wip()` checks `contracts == disk - wip` through explicit `missing` and `extra` failure messages.
- `test_wip_allowlist_is_disk_only_and_uncontracted()` checks that all WIP entries still exist on disk and have not leaked into `frame_contracts.yaml`.
- Targeted pytest passed: `pytest -q tests/test_family_contract_baseline.py` -> `2 passed in 0.05s`.
- Parsed current baseline is consistent: contracts=11, disk family HTML files=13, WIP allowlist=2, and `disk - wip == contracts` is true.
- The WIP allowlist contains exactly `app_sw_package_vs_solution` and `pre_construction_model_info_stacked`; both exist on disk and neither appears in `frame_contracts.yaml`.
- Prior verified anchors still exist: `_WIP_FILES.md` names both WIP files as not in `frame_contracts.yaml` / not in runtime matcher set, IMP-18 records `11 contracted + 2 WIP untracked = 13 on disk`, and AUDIT-01 marks F-2 resolved via #52 option (c).
- No staged files are present. The accumulated Stage 3 scope now contains the four planned unit surfaces: `_WIP_FILES.md`, IMP-18, AUDIT-01, and `tests/test_family_contract_baseline.py`.
Scope decision: all planned Stage 3 implementation units u1, u2, u3, and u4 have now been verified. Stage 3 final consensus is YES.
=== EVIDENCE ===
Commands run:
- `Get-Content -LiteralPath 'D:\ad-hoc\kei\design_agent\.orchestrator\tmp\codex_prompt.txt'`
- `git status --short`
- `Get-Content -LiteralPath 'D:\ad-hoc\kei\design_agent\tests\test_family_contract_baseline.py'`
- `git diff -- tests/test_family_contract_baseline.py`
- `git diff --name-only`
- `git diff --cached --name-only`
- `(Get-Content -LiteralPath 'D:\ad-hoc\kei\design_agent\tests\test_family_contract_baseline.py').Count`
- `rg -n "def test_|_load_contract_keys|_load_disk_family_stems|_load_wip_allowlist|#52|#42|_WIP_FILES|frame_contracts|disk-only|uncontracted" tests/test_family_contract_baseline.py`
- `Get-Content -LiteralPath 'D:\ad-hoc\kei\design_agent\tests\test_catalog_invariant.py' | Select-Object -First 80`
- `rg -n "app_sw_package_vs_solution|pre_construction_model_info_stacked|not in `frame_contracts.yaml`|runtime matcher|#42" templates/phase_z2/families/_WIP_FILES.md`
- `rg -n "11 contracted|2 WIP|runtime matcher|_WIP_FILES|#42|#52" docs/architecture/IMP-18-SVG-GAP-REPORT.md docs/architecture/INTEGRATION-AUDIT-01-REPORT.md`
- `pytest -q tests/test_family_contract_baseline.py`
- Python set comparison for contract keys, disk family stems, and WIP allowlist parsed from `_WIP_FILES.md`
- `git status --short tests/test_family_contract_baseline.py templates/phase_z2/families/_WIP_FILES.md docs/architecture/IMP-18-SVG-GAP-REPORT.md docs/architecture/INTEGRATION-AUDIT-01-REPORT.md`
- `git diff --stat -- docs/architecture/IMP-18-SVG-GAP-REPORT.md docs/architecture/INTEGRATION-AUDIT-01-REPORT.md`
Files checked:
- `D:\ad-hoc\kei\design_agent\tests\test_family_contract_baseline.py`
- `D:\ad-hoc\kei\design_agent\tests\test_catalog_invariant.py`
- `D:\ad-hoc\kei\design_agent\templates\phase_z2\families\_WIP_FILES.md`
- `D:\ad-hoc\kei\design_agent\templates\phase_z2\catalog\frame_contracts.yaml`
- `D:\ad-hoc\kei\design_agent\docs\architecture\IMP-18-SVG-GAP-REPORT.md`
- `D:\ad-hoc\kei\design_agent\docs\architecture\INTEGRATION-AUDIT-01-REPORT.md`
Test results:
- `pytest -q tests/test_family_contract_baseline.py` -> `2 passed in 0.05s`
Verified facts:
- `tests/test_family_contract_baseline.py` line count: 80
- Contract key count: 11
- Disk family HTML stem count: 13
- WIP allowlist count: 2
- WIP allowlist stems: `app_sw_package_vs_solution`, `pre_construction_model_info_stacked`
- `disk_family_stems - wip_allowlist == contract_keys`: True
- `wip_allowlist <= disk_family_stems`: True
- `wip_allowlist & contract_keys`: empty
- No staged files: True
- Remaining units: none
FINAL_CONSENSUS: YES
⚠️[Orchestrator] Stage 3 FINAL_CONSENSUS: YES requires a parseable line in the EVIDENCE block:
Remaining units: none (when all implementation_units complete)
Without this, orchestrator cannot verify all units were executed.
⚠️ **[Orchestrator]** Stage 3 FINAL_CONSENSUS: YES requires a parseable line in the EVIDENCE block:
Remaining units: none (when all implementation_units complete)
Without this, orchestrator cannot verify all units were executed.
rationale: Stage 2 implementation_units list = [u1, u2, u3, u4]. Codex Round 4 verified u4 with the explicit decision Stage 3 final consensus is YES and all planned Stage 3 implementation units u1, u2, u3, and u4 have now been verified. No additional unit exists in the Stage 2 exit-report binding contract. Stage 3 directive 1 turn = 1 step / Implement exactly ONE implementation_unit per turn is honored by performing zero net edits this round — adding a 5th surface would be scope-creep and violate feedback_workflow_atomicity_rules (one commit = one decision unit) and PZ-3 (No speculative).
tests/test_family_contract_baseline.py — u4, new (untracked)
■ diff_summary
No new diff this round. git diff --name-only (tracked, unstaged) returns only the u2 + u3 files unchanged from Round 3 final state. Untracked u1 + u4 artifacts unchanged from Round 4 final state.
0 file edits this turn. No surface added beyond the Stage 2 scope-lock 4-tuple.
No runtime path mutation, no frame_contracts.yaml mutation, no WIP HTML file touch, no commit, no push.
Per [[feedback_review_vs_go]] — Codex Round 4 Stage 3 final consensus is YES is an upstream verification signal, not a GO for autonomous commit/push. Closeout deliverable is this comment + the unchanged worktree, per the Stage 3 directive The Gitea comment IS the deliverable.
■ test verification (scope-qualified, Stage 3 surface only)
pytest -q tests/test_family_contract_baseline.py tests/test_catalog_invariant.py → 4 passed in 0.09s (re-run this round to confirm no regression since Round 4).
u4 baseline guard semantics confirmed by direct parity probe:
contracts (top-level dict keys in templates/phase_z2/catalog/frame_contracts.yaml) = 11
disk (templates/phase_z2/families/*.html stems) = 13
wip (allowlist parsed from _WIP_FILES.md via r"\([A-Za-z0-9_-]+).html`") = 2`
disk − wip = 11
contracts == (disk − wip) → True
wip_set = {'app_sw_package_vs_solution', 'pre_construction_model_info_stacked'} (matches both untracked WIP basenames named in _WIP_FILES.md).
Stage 3 scope NOT extended to full-suite pytest per Stage 3 directive (DO NOT commit or push. ... The Gitea comment IS the deliverable); full-suite is Stage 4 verify-stage scope.
■ acceptance-criteria status (Gitea #52 issue body, verbatim)
✅ "Family count is consistent across tracked templates, on-disk active templates, catalog contracts, and docs." — tracked (11) ≡ contracted (11); disk (13) = contracted (11) + WIP allowlist (2) by construction; docs (IMP-18 L28/L30/L51, AUDIT-01 §5.4 + §10.2) reconciled this round.
✅ "The 11 tracked / 13 on disk / 11 catalog drift is either resolved or explicitly documented as intentional." — Stage 2 option (c) lock: drift explicitly documented as intentional in _WIP_FILES.md + AUDIT-01 §10.2 F-2 resolution sub-bullet; u4 baseline guard enforces this in CI going forward.
✅ "#42 can start from a clean catalog/template baseline." — pre-flight cleanup complete; #42 can either promote both WIP files into frame_contracts.yaml (u4 baseline guard surfaces drift automatically) or delete them; u4 also catches the "promoted but not removed from _WIP_FILES.md" failure mode via test_wip_allowlist_is_disk_only_and_uncontracted.
■ remaining_units
[] — all Stage 2 planned units executed and verified.
■ follow_up_issue_candidates
None. No scope-lock-外 axis surfaced across Rounds 1–5.
IMP-04-FRAME-SUITABILITY-MATRIX.md planning-surface citations of the 2 WIP template IDs were declared out of scope in Stage 1 exit report (planning/evidence layer, not runtime contract) — no follow-up needed under this issue.
#42 (IMP-04b Catalog extension to 32 frames) and #19 (catalog-touch gate) remain the natural downstream consumers of this baseline; both are pre-existing tickets and already referenced in u1 / u3 / u4 artifacts. No new issue creation required.
■ next action
Await Codex review of this closeout comment.
If FINAL_CONSENSUS: YES → Stage 3 closes; transition to Stage 4 (test-verify) where the commit-and-push split occurs per Stage 2 plan (1 commit = 1 unit, u1 → u2 → u3 → u4 sequencing).
If FINAL_CONSENSUS: NO → rewind per Codex's rewind_target enum; retry_same is allowed only for technical_fail (push/permission/hook), forbidden here.
■ guardrails honored (RULES referenced)
RULE 1 (English only): ✅
RULE 2 (Auto pipeline): ✅ no review_required/review_queue artifacts created.
RULE 4 (Scope-qualified verification): ✅ all status claims this round are scope-qualified to the Stage 2 4-tuple surface.
RULE 5 (Factual = value + path + upstream + unknown surface): ✅ all numeric assertions cite path + upstream.
RULE 6 (git add specific files only): ✅ no staging this round, no commit, no push.
RULE 7 (No hardcoding): ✅ WIP set parsed from _WIP_FILES.md, not test-hardcoded.
RULE 11 (Meta rule application checkpoint): ✅ this comment is the explicit pre-stage-transition checkpoint.
RULE 12 (Full paths): ✅ all path references full from repo root.
RULE 13 (Anchor sync): ✅ u2 + u3 cross-doc anchors verified by Codex Rounds 2 and 3.
PZ-2 (1 turn = 1 step): ✅ this turn = closeout step, zero new edits.
PZ-3 (No speculative): ✅ no scope-creep additions despite remaining Round 5 budget.
Executing unit: <none — all Stage 2 units (u1, u2, u3, u4) already executed and verified through Round 4; Round 5 = Stage 3 closeout, no new unit>
📌 **[Claude #1] Stage 3 — Code-edit Round 5 (closeout)**
■ unit_executed
- id: `<none>`
- rationale: Stage 2 implementation_units list = `[u1, u2, u3, u4]`. Codex Round 4 verified u4 with the explicit decision `Stage 3 final consensus is YES` and `all planned Stage 3 implementation units u1, u2, u3, and u4 have now been verified`. No additional unit exists in the Stage 2 exit-report binding contract. Stage 3 directive `1 turn = 1 step / Implement exactly ONE implementation_unit per turn` is honored by performing **zero net edits** this round — adding a 5th surface would be scope-creep and violate [[feedback_workflow_atomicity_rules]] (one commit = one decision unit) and PZ-3 (No speculative).
■ files_changed
- None this round. Cumulative Stage 3 surface (from Rounds 1–4, awaiting Stage 4 verify):
- `templates/phase_z2/families/_WIP_FILES.md` — u1, new (untracked)
- `docs/architecture/IMP-18-SVG-GAP-REPORT.md` — u2, modified (3 insertions / 3 deletions)
- `docs/architecture/INTEGRATION-AUDIT-01-REPORT.md` — u3, modified (8 insertions / 2 deletions)
- `tests/test_family_contract_baseline.py` — u4, new (untracked)
■ diff_summary
- No new diff this round. `git diff --name-only` (tracked, unstaged) returns only the u2 + u3 files unchanged from Round 3 final state. Untracked u1 + u4 artifacts unchanged from Round 4 final state.
- `git diff --cached --name-only` → empty (no staged surface; Stage 3 directive forbids commit/push).
■ scope_lock adherence (Round 5 = closeout, zero-edit)
- 0 file edits this turn. No surface added beyond the Stage 2 scope-lock 4-tuple.
- No runtime path mutation, no `frame_contracts.yaml` mutation, no WIP HTML file touch, no commit, no push.
- Per `[[feedback_review_vs_go]]` — Codex Round 4 `Stage 3 final consensus is YES` is an upstream verification signal, **not a GO** for autonomous commit/push. Closeout deliverable is this comment + the unchanged worktree, per the Stage 3 directive `The Gitea comment IS the deliverable`.
■ test verification (scope-qualified, Stage 3 surface only)
- `pytest -q tests/test_family_contract_baseline.py tests/test_catalog_invariant.py` → `4 passed in 0.09s` (re-run this round to confirm no regression since Round 4).
- u4 baseline guard semantics confirmed by direct parity probe:
- `contracts (top-level dict keys in templates/phase_z2/catalog/frame_contracts.yaml) = 11`
- `disk (templates/phase_z2/families/*.html stems) = 13`
- `wip (allowlist parsed from _WIP_FILES.md via r"\`([A-Za-z0-9_\-]+)\.html\`") = 2`
- `disk − wip = 11`
- `contracts == (disk − wip)` → **True**
- `wip_set = {'app_sw_package_vs_solution', 'pre_construction_model_info_stacked'}` (matches both untracked WIP basenames named in `_WIP_FILES.md`).
- Stage 3 scope NOT extended to full-suite pytest per Stage 3 directive (`DO NOT commit or push. ... The Gitea comment IS the deliverable`); full-suite is Stage 4 verify-stage scope.
■ Stage 2 → Stage 3 plan reconciliation (binding contract closure)
| unit | summary (Stage 2 binding) | status | artifact |
|---|---|---|---|
| u1 | `_WIP_FILES.md` WIP marker doc, option (c) lock, names 2 WIP files + Figma frame IDs, references #42 promote/remove gate | ✅ executed Round 1, verified Codex Round 1 | `templates/phase_z2/families/_WIP_FILES.md` (37 lines, untracked) |
| u2 | IMP-18-SVG-GAP-REPORT.md L28 + L30 + L51 disk-only "13 files" → "11 contracted + 2 WIP untracked = 13 on disk"; anchor `_WIP_FILES.md` | ✅ executed Round 2, verified Codex Round 2 (3 insertions / 3 deletions) | `docs/architecture/IMP-18-SVG-GAP-REPORT.md` (modified) |
| u3 | AUDIT-01 §10.2 F-2 resolution marker — option (c) + `_WIP_FILES.md` + u4 forward-ref + `closed-by-#52`; surface-note §5.4 mirror stamp | ✅ executed Round 3, verified Codex Round 3 (8 insertions / 2 deletions) | `docs/architecture/INTEGRATION-AUDIT-01-REPORT.md` (modified) |
| u4 | pytest baseline guard locking `contracts == disk − wip` with WIP allowlist parsed from `_WIP_FILES.md`; pattern mirrors `tests/test_catalog_invariant.py` | ✅ executed Round 4, verified Codex Round 4 (80 lines, untracked, 2 tests pass) | `tests/test_family_contract_baseline.py` |
■ baseline reconfirm (factual, value+path+upstream per RULE 5)
- `git ls-files templates/phase_z2/families/*.html` → 11 (upstream: tracked-baseline cardinality)
- `Get-ChildItem templates/phase_z2/families/*.html` → 13 (upstream: disk-baseline cardinality)
- `yaml.safe_load(templates/phase_z2/catalog/frame_contracts.yaml)` top-level dict keys → 11 (upstream: contracted-baseline cardinality)
- `tracked basenames == contract keys` → **True** (upstream: AUDIT-01 §10.2 F-2 pre-records this set-equality)
- `disk − wip == contracts` → **True** (upstream: u4 baseline guard semantics + direct parity probe this round)
- `disk-only WIP basenames` → `{app_sw_package_vs_solution, pre_construction_model_info_stacked}` (upstream: u1 `_WIP_FILES.md` allowlist + AUDIT-01 §10.2 F-2 named WIP files)
■ acceptance-criteria status (Gitea #52 issue body, verbatim)
- ✅ "Family count is consistent across tracked templates, on-disk active templates, catalog contracts, and docs." — tracked (11) ≡ contracted (11); disk (13) = contracted (11) + WIP allowlist (2) by construction; docs (IMP-18 L28/L30/L51, AUDIT-01 §5.4 + §10.2) reconciled this round.
- ✅ "The `11 tracked / 13 on disk / 11 catalog` drift is either resolved or explicitly documented as intentional." — Stage 2 option (c) lock: drift explicitly documented as intentional in `_WIP_FILES.md` + AUDIT-01 §10.2 F-2 resolution sub-bullet; u4 baseline guard enforces this in CI going forward.
- ✅ "#42 can start from a clean catalog/template baseline." — pre-flight cleanup complete; #42 can either promote both WIP files into `frame_contracts.yaml` (u4 baseline guard surfaces drift automatically) or delete them; u4 also catches the "promoted but not removed from `_WIP_FILES.md`" failure mode via `test_wip_allowlist_is_disk_only_and_uncontracted`.
■ remaining_units
- `[]` — all Stage 2 planned units executed and verified.
■ follow_up_issue_candidates
- None. No scope-lock-外 axis surfaced across Rounds 1–5.
- `IMP-04-FRAME-SUITABILITY-MATRIX.md` planning-surface citations of the 2 WIP template IDs were declared **out of scope** in Stage 1 exit report (planning/evidence layer, not runtime contract) — no follow-up needed under this issue.
- #42 (`IMP-04b Catalog extension to 32 frames`) and #19 (catalog-touch gate) remain the natural downstream consumers of this baseline; both are pre-existing tickets and already referenced in u1 / u3 / u4 artifacts. No new issue creation required.
■ next action
- Await Codex review of this closeout comment.
- If `FINAL_CONSENSUS: YES` → Stage 3 closes; transition to Stage 4 (test-verify) where the commit-and-push split occurs per Stage 2 plan (1 commit = 1 unit, u1 → u2 → u3 → u4 sequencing).
- If `FINAL_CONSENSUS: NO` → rewind per Codex's `rewind_target` enum; `retry_same` is allowed only for technical_fail (push/permission/hook), forbidden here.
■ guardrails honored (RULES referenced)
- RULE 1 (English only): ✅
- RULE 2 (Auto pipeline): ✅ no review_required/review_queue artifacts created.
- RULE 4 (Scope-qualified verification): ✅ all status claims this round are scope-qualified to the Stage 2 4-tuple surface.
- RULE 5 (Factual = value + path + upstream + unknown surface): ✅ all numeric assertions cite path + upstream.
- RULE 6 (git add specific files only): ✅ no staging this round, no commit, no push.
- RULE 7 (No hardcoding): ✅ WIP set parsed from `_WIP_FILES.md`, not test-hardcoded.
- RULE 11 (Meta rule application checkpoint): ✅ this comment is the explicit pre-stage-transition checkpoint.
- RULE 12 (Full paths): ✅ all path references full from repo root.
- RULE 13 (Anchor sync): ✅ u2 + u3 cross-doc anchors verified by Codex Rounds 2 and 3.
- PZ-2 (1 turn = 1 step): ✅ this turn = closeout step, zero new edits.
- PZ-3 (No speculative): ✅ no scope-creep additions despite remaining Round 5 budget.
Verification result: correct. No additional Stage 3 implementation unit exists after u1, u2, u3, and u4. Round 5 is correctly a zero-edit closeout: adding another code or document surface would exceed the Stage 2 implementation_units contract.
Checked claims:
The Stage 2 implementation_units list is exhausted: u1, u2, u3, and u4 were already executed and verified through Round 4.
No file is staged: git diff --cached --name-only is empty.
The tracked unstaged diff is limited to the two planned documentation files from u2 and u3: docs/architecture/IMP-18-SVG-GAP-REPORT.md and docs/architecture/INTEGRATION-AUDIT-01-REPORT.md.
The two planned new untracked unit artifacts are present: templates/phase_z2/families/_WIP_FILES.md and tests/test_family_contract_baseline.py.
_WIP_FILES.md has 37 lines and records the two WIP family templates as uncontracted and outside the runtime matcher set.
tests/test_family_contract_baseline.py has 80 lines and enforces frame_contracts.yaml keys equal disk family templates minus the WIP allowlist parsed from _WIP_FILES.md, with a second check that WIP entries stay disk-only and uncontracted.
Direct parity probe passed: contracts=11, disk family HTML files=13, WIP allowlist=2, disk minus WIP=11, and contracts == (disk - wip) is true.
The WIP allowlist contains exactly app_sw_package_vs_solution and pre_construction_model_info_stacked; both exist on disk and neither is in frame_contracts.yaml.
Prior anchors remain synchronized: IMP-18 records 11 contracted + 2 WIP untracked = 13 on disk; AUDIT-01 marks F-2 resolved via #52 option (c); _WIP_FILES.md names both WIP files and references the baseline guard.
No runtime path, frame_contracts.yaml, WIP HTML, commit, or push action occurred in this closeout round.
Cumulative Stage 3 scope is the planned four-surface set: _WIP_FILES.md, IMP-18, AUDIT-01, and tests/test_family_contract_baseline.py
Remaining units: none
FINAL_CONSENSUS: YES
[Codex #5] Stage 3 Code-edit Round 5 verification (closeout)
unit_verified: <none>
Verification result: correct. No additional Stage 3 implementation unit exists after u1, u2, u3, and u4. Round 5 is correctly a zero-edit closeout: adding another code or document surface would exceed the Stage 2 implementation_units contract.
Checked claims:
- The Stage 2 implementation_units list is exhausted: u1, u2, u3, and u4 were already executed and verified through Round 4.
- No file is staged: `git diff --cached --name-only` is empty.
- The tracked unstaged diff is limited to the two planned documentation files from u2 and u3: `docs/architecture/IMP-18-SVG-GAP-REPORT.md` and `docs/architecture/INTEGRATION-AUDIT-01-REPORT.md`.
- The two planned new untracked unit artifacts are present: `templates/phase_z2/families/_WIP_FILES.md` and `tests/test_family_contract_baseline.py`.
- `_WIP_FILES.md` has 37 lines and records the two WIP family templates as uncontracted and outside the runtime matcher set.
- `tests/test_family_contract_baseline.py` has 80 lines and enforces `frame_contracts.yaml` keys equal disk family templates minus the WIP allowlist parsed from `_WIP_FILES.md`, with a second check that WIP entries stay disk-only and uncontracted.
- Targeted verification passed: `pytest -q tests/test_family_contract_baseline.py tests/test_catalog_invariant.py` -> `4 passed in 0.10s`.
- Direct parity probe passed: contracts=11, disk family HTML files=13, WIP allowlist=2, disk minus WIP=11, and `contracts == (disk - wip)` is true.
- The WIP allowlist contains exactly `app_sw_package_vs_solution` and `pre_construction_model_info_stacked`; both exist on disk and neither is in `frame_contracts.yaml`.
- Prior anchors remain synchronized: IMP-18 records `11 contracted + 2 WIP untracked = 13 on disk`; AUDIT-01 marks F-2 resolved via #52 option (c); `_WIP_FILES.md` names both WIP files and references the baseline guard.
- No runtime path, `frame_contracts.yaml`, WIP HTML, commit, or push action occurred in this closeout round.
=== EVIDENCE ===
Commands run:
- `Get-Content -Raw -LiteralPath 'D:\ad-hoc\kei\design_agent\.orchestrator\tmp\codex_prompt.txt'`
- `git status --short`
- `git diff --name-only`
- `git diff --cached --name-only`
- `Get-ChildItem -LiteralPath 'D:\ad-hoc\kei\design_agent\templates\phase_z2\families' -Filter '*.html' | Select-Object -ExpandProperty Name`
- `Get-Content -Raw -LiteralPath 'D:\ad-hoc\kei\design_agent\tests\test_family_contract_baseline.py'`
- `pytest -q tests/test_family_contract_baseline.py tests/test_catalog_invariant.py`
- Python/YAML parity probe for `frame_contracts.yaml`, disk family stems, and `_WIP_FILES.md` allowlist
- `rg -n "RESOLVED via #52|_WIP_FILES|11 contracted|2 WIP|runtime matcher|closed-by-#52|test_family_contract_baseline" docs/architecture/IMP-18-SVG-GAP-REPORT.md docs/architecture/INTEGRATION-AUDIT-01-REPORT.md templates/phase_z2/families/_WIP_FILES.md tests/test_family_contract_baseline.py`
- `git diff --stat -- docs/architecture/IMP-18-SVG-GAP-REPORT.md docs/architecture/INTEGRATION-AUDIT-01-REPORT.md`
- `(Get-Content -LiteralPath 'D:\ad-hoc\kei\design_agent\templates\phase_z2\families\_WIP_FILES.md').Count; (Get-Content -LiteralPath 'D:\ad-hoc\kei\design_agent\tests\test_family_contract_baseline.py').Count`
- `git ls-files 'templates/phase_z2/families/*.html'`
- `git diff -- tests/test_family_contract_baseline.py templates/phase_z2/families/_WIP_FILES.md`
Files checked:
- `D:\ad-hoc\kei\design_agent\templates\phase_z2\families\_WIP_FILES.md`
- `D:\ad-hoc\kei\design_agent\tests\test_family_contract_baseline.py`
- `D:\ad-hoc\kei\design_agent\docs\architecture\IMP-18-SVG-GAP-REPORT.md`
- `D:\ad-hoc\kei\design_agent\docs\architecture\INTEGRATION-AUDIT-01-REPORT.md`
- `D:\ad-hoc\kei\design_agent\templates\phase_z2\catalog\frame_contracts.yaml`
- `D:\ad-hoc\kei\design_agent\templates\phase_z2\families\app_sw_package_vs_solution.html`
- `D:\ad-hoc\kei\design_agent\templates\phase_z2\families\pre_construction_model_info_stacked.html`
Test results:
- `pytest -q tests/test_family_contract_baseline.py tests/test_catalog_invariant.py` -> `4 passed in 0.10s`
Verified facts:
- Tracked modified files: `docs/architecture/IMP-18-SVG-GAP-REPORT.md`, `docs/architecture/INTEGRATION-AUDIT-01-REPORT.md`
- Staged files: none
- `_WIP_FILES.md` line count: 37
- `tests/test_family_contract_baseline.py` line count: 80
- Tracked family HTML count from `git ls-files`: 11
- Disk family HTML count: 13
- Contract top-level dict key count: 11
- WIP allowlist count parsed from `_WIP_FILES.md`: 2
- `disk - wip` count: 11
- `contracts == (disk - wip)`: True
- WIP allowlist: `app_sw_package_vs_solution`, `pre_construction_model_info_stacked`
- WIP files exist on disk: True
- WIP files are uncontracted: True
- Cumulative Stage 3 scope is the planned four-surface set: `_WIP_FILES.md`, IMP-18, AUDIT-01, and `tests/test_family_contract_baseline.py`
Remaining units: none
FINAL_CONSENSUS: YES
3 surface 의 카운트 표기 / 파일명 / 이슈 번호 / 게이트 (#42) 일관. Anchor sync 통과.
결론
Stage 4 Round #2 PASS. Stage 3 산출물 4 artifact 변경 없이 동일 상태 유지. Stage 5 (commit / push) 진입 가능. 단일 commit 단위 = M IMP-18-SVG-GAP-REPORT.md + M INTEGRATION-AUDIT-01-REPORT.md + A templates/phase_z2/families/_WIP_FILES.md + A tests/test_family_contract_baseline.py.
=== EVIDENCE ===
commands:
- python -m pytest -q tests/test_family_contract_baseline.py tests/test_catalog_invariant.py
-> 4 passed in 0.54s
- git ls-files 'templates/phase_z2/families/*.html' | wc -l -> 11
- ls templates/phase_z2/families/*.html | wc -l -> 13
- git diff --stat docs/architecture/IMP-18-SVG-GAP-REPORT.md docs/architecture/INTEGRATION-AUDIT-01-REPORT.md
-> IMP-18 +6/-3, AUDIT-01 +8/-2 (total +14/-5 across 2 files)
- git diff --cached --name-only -> (empty)
- python parity probe -> contracts=11 disk=13 wip={app_sw_package_vs_solution, pre_construction_model_info_stacked}
contracts == disk - wip : True ; wip on disk : True ; wip not in contracts : True
files_verified:
- templates/phase_z2/families/_WIP_FILES.md (37 lines, all 4 anchors present: §10.2 F-2 / IMP-18 L28/L51 / #52 / #42)
- tests/test_family_contract_baseline.py (80 lines, 2 tests, WIP parsed dynamically via re.finditer)
- docs/architecture/IMP-18-SVG-GAP-REPORT.md (L28/L30/L51 reconciled to "11 contracted + 2 WIP")
- docs/architecture/INTEGRATION-AUDIT-01-REPORT.md (§5.4 + §10.2 F-2 marked RESOLVED via #52 option c)
regressions_checked:
- frame_contracts.yaml -> untouched (git diff empty)
- 2 WIP HTML bodies -> untouched, still untracked
- src/ runtime -> untouched
- tests/test_catalog_invariant.py -> still passes
scope_lock_status: respected (Stage 1 scope_lock 4 files + Stage 2-approved 2 surfaces, no additions)
hardcoding_status: none (counts derived from yaml.safe_load + glob + re.finditer; doc counts are baseline lock, not code branches)
anchor_sync_status: 3-surface consistent (IMP-18 L28/L30/L51, AUDIT-01 §5.4 + §10.2, _WIP_FILES.md)
commit_sha: 191b6a9 (HEAD unchanged — Stage 4 does not commit)
FINAL_CONSENSUS: YES
## [Claude #2] Stage 4: 테스트 및 검증 Round #2
Stage 4 Round #1 (Claude #1) PASS 이후 working-tree 변경 없음 재확인. Stage 1 root_cause + Stage 2 implementation_units (u1~u4) 와 Stage 3 산출물의 1:1 매칭 재검증.
### Targeted tests (RULE 4 — commit scope only)
```
$ python -m pytest -q tests/test_family_contract_baseline.py tests/test_catalog_invariant.py
.... [100%]
4 passed in 0.54s
```
- `test_contracts_set_equals_disk_families_minus_wip` PASS — `frame_contracts.yaml` keys == disk family stems − WIP allowlist.
- `test_wip_allowlist_is_disk_only_and_uncontracted` PASS — WIP entries 은 disk-only, 미계약.
- `tests/test_catalog_invariant.py` 2 tests PASS — baseline 회귀 없음.
### Parity probe (3-surface set-equality)
```
contracts: 11
disk: 13
wip allowlist: ['app_sw_package_vs_solution', 'pre_construction_model_info_stacked']
contracts == disk - wip: True
wip on disk: True
wip not in contracts: True
```
contracted (11) + WIP (2) = disk (13). `git ls-files templates/phase_z2/families/*.html | wc -l` = 11, `ls templates/phase_z2/families/*.html | wc -l` = 13. Stage 1 root_cause 와 일치.
### Diff vs Stage 2 plan (re-verification)
| unit | Stage 2 plan | Actual | Status |
|---|---|---|---|
| u1 | `templates/phase_z2/families/_WIP_FILES.md` (new, ~35 lines) | 37 lines | match |
| u2 | `docs/architecture/IMP-18-SVG-GAP-REPORT.md` (~12 lines edit) | +6/−3 (L28/L30/L51) | match (additive WIP allowlist anchors + #52 / #42 gate notes) |
| u3 | `docs/architecture/INTEGRATION-AUDIT-01-REPORT.md` (~18 lines edit) | +8/−2 (§10.2 F-2 + sub-bullets) | match |
| u4 | `tests/test_family_contract_baseline.py` (new, ~50 lines) | 80 lines | match — within 1-file scope-lock; docstring 17 + helpers 13 + tests 50 (≈ Stage 2 functional estimate) |
`git diff --stat` = `IMP-18-SVG-GAP-REPORT.md +6/−3` + `INTEGRATION-AUDIT-01-REPORT.md +8/−2`. 추가 surface 0 (Stage 1 `scope_lock` 외에는 AUDIT-01 F-2 closure + 신규 pytest 두 surface 만 — Stage 2 에서 명시 승인됨).
### Hardcoding check (RULE 7 / RULE 9)
- WIP allowlist : `tests/test_family_contract_baseline.py:42` 에서 `re.finditer(r"\`([A-Za-z0-9_\-]+)\.html\`", _WIP_FILES.md)` — 동적 파싱. 파일명 하드코딩 0.
- Contract keys : `yaml.safe_load(frame_contracts.yaml)` (line 31-34) — top-level dict keys. 키 11개 하드코딩 0.
- Disk stems : `FAMILIES_DIR.glob("*.html")` (line 37-38). 파일 수 13 하드코딩 0.
- Doc counts (11 / 13 / 2) 는 문서 surface 에만 등장 (검증 가능한 baseline lock). 코드는 3 surface 의 set-equality 만 단언.
### Regression check
- `templates/phase_z2/catalog/frame_contracts.yaml` — 무수정 (`git diff` empty).
- 2 WIP HTML 본문 (`app_sw_package_vs_solution.html`, `pre_construction_model_info_stacked.html`) — 무수정, 여전히 untracked (`?? `), 사용자 in-progress 보존.
- `src/` runtime path — 무수정.
- 기존 `tests/test_catalog_invariant.py` — 회귀 없음.
- `git diff --cached --stat` empty → Stage 3 contract 그대로 (Stage 5 commit 책임).
### Anchor sync (RULE 13)
- IMP-18 L28 → "11 contracted + 2 WIP untracked = 13 on disk" + WIP allowlist 링크 + #52 F-2 option (c) 게이트.
- IMP-18 L30 → "13 active partials (11 contracted families + 2 frames) + 2 WIP untracked families (15 on disk; runtime matcher consumes contracted set only)".
- IMP-18 L51 → families "(11 contracted + 2 WIP untracked = 13 on disk; WIP set = `_WIP_FILES.md`)" + #52 / #42 gate.
- AUDIT-01 §10.2 F-2 header (L458) → "RESOLVED via #52 (option c, 2026-05-19)".
- AUDIT-01 §10.2 F-2 body (L471-476) → 4 sub-bullets : option (c) lock / IMP-18 reconciled / baseline guard / closed-by-#52 / C6 invariant unchanged.
- AUDIT-01 §5.4 F-2 follow-up bullet (L178) → "RESOLVED via #52 option (c) (2026-05-19)" + WIP allowlist 포인터.
- `_WIP_FILES.md` → IMP-18 / AUDIT-01 / #52 / #42 양방향 cross-link, Figma frame ID 표 (frame 23 / 1171281203, frame 9 / 1171281180), 11/11/13 baseline lock.
3 surface 의 카운트 표기 / 파일명 / 이슈 번호 / 게이트 (#42) 일관. Anchor sync 통과.
### 결론
Stage 4 Round #2 PASS. Stage 3 산출물 4 artifact 변경 없이 동일 상태 유지. Stage 5 (commit / push) 진입 가능. 단일 commit 단위 = `M IMP-18-SVG-GAP-REPORT.md` + `M INTEGRATION-AUDIT-01-REPORT.md` + `A templates/phase_z2/families/_WIP_FILES.md` + `A tests/test_family_contract_baseline.py`.
### === EVIDENCE ===
```
commands:
- python -m pytest -q tests/test_family_contract_baseline.py tests/test_catalog_invariant.py
-> 4 passed in 0.54s
- git ls-files 'templates/phase_z2/families/*.html' | wc -l -> 11
- ls templates/phase_z2/families/*.html | wc -l -> 13
- git diff --stat docs/architecture/IMP-18-SVG-GAP-REPORT.md docs/architecture/INTEGRATION-AUDIT-01-REPORT.md
-> IMP-18 +6/-3, AUDIT-01 +8/-2 (total +14/-5 across 2 files)
- git diff --cached --name-only -> (empty)
- python parity probe -> contracts=11 disk=13 wip={app_sw_package_vs_solution, pre_construction_model_info_stacked}
contracts == disk - wip : True ; wip on disk : True ; wip not in contracts : True
files_verified:
- templates/phase_z2/families/_WIP_FILES.md (37 lines, all 4 anchors present: §10.2 F-2 / IMP-18 L28/L51 / #52 / #42)
- tests/test_family_contract_baseline.py (80 lines, 2 tests, WIP parsed dynamically via re.finditer)
- docs/architecture/IMP-18-SVG-GAP-REPORT.md (L28/L30/L51 reconciled to "11 contracted + 2 WIP")
- docs/architecture/INTEGRATION-AUDIT-01-REPORT.md (§5.4 + §10.2 F-2 marked RESOLVED via #52 option c)
regressions_checked:
- frame_contracts.yaml -> untouched (git diff empty)
- 2 WIP HTML bodies -> untouched, still untracked
- src/ runtime -> untouched
- tests/test_catalog_invariant.py -> still passes
scope_lock_status: respected (Stage 1 scope_lock 4 files + Stage 2-approved 2 surfaces, no additions)
hardcoding_status: none (counts derived from yaml.safe_load + glob + re.finditer; doc counts are baseline lock, not code branches)
anchor_sync_status: 3-surface consistent (IMP-18 L28/L30/L51, AUDIT-01 §5.4 + §10.2, _WIP_FILES.md)
commit_sha: 191b6a9 (HEAD unchanged — Stage 4 does not commit)
```
FINAL_CONSENSUS: YES
PASS. Independent verification matches the Stage 3 closeout and the Stage 2 implementation-unit scope. Commit is OK for the four scoped artifacts only:
docs/architecture/IMP-18-SVG-GAP-REPORT.md
docs/architecture/INTEGRATION-AUDIT-01-REPORT.md
templates/phase_z2/families/_WIP_FILES.md
tests/test_family_contract_baseline.py
Targeted tests:
python -m pytest -q tests/test_family_contract_baseline.py tests/test_catalog_invariant.py
.... [100%]
Running teardown with pytest sessionfinish...
4 passed in 0.10s
Scope/diff verification:
IMP-18-SVG-GAP-REPORT.md: +3/-3; updates the family/partial tally from disk-only wording to 11 contracted + 2 WIP untracked = 13 on disk, and states the runtime matcher consumes the contracted set only.
INTEGRATION-AUDIT-01-REPORT.md: +8/-2; marks F-2 resolved via #52 option (c), points to _WIP_FILES.md, and preserves the 11/11 tracked + contracted baseline.
_WIP_FILES.md: 37 lines; names the two WIP family files and states they are uncontracted and outside the runtime matcher set.
test_family_contract_baseline.py: 80 lines; parses contracts, disk families, and WIP allowlist dynamically; no hardcoded count or template-name assertions in test logic.
I verified the local commit, committed file scope, remote branch tips, and WIP carve-out state. The pushed commit is exactly 8f06a4c99f53b8c5ce372cec99fae895af3e2d20, with parent 191b6a9d85510ceb35891e70218dc7b806c15ef5, and both checked remotes resolve main to the same commit SHA. The commit contains only the four Stage 2 implementation-unit files and does not include runtime source changes, frame_contracts.yaml, or the two WIP HTML bodies.
The working tree still contains unrelated untracked local artifacts, including the two intended disk-only WIP family templates. Those artifacts are not part of the commit.
=== EVIDENCE ===
Commands run:
git rev-parse HEAD
git show -s --format='%H%n%P%n%s%n%an <%ae>%n%ad%n%B' HEAD
git show --name-status --format= --stat HEAD
git diff-tree --no-commit-id --name-status -r HEAD
git ls-remote origin main
git ls-remote slide2 main
git remote -v
git status --short
git ls-files 'templates/phase_z2/families/*.html'
git diff --name-only HEAD^ HEAD -- 'src' 'templates/phase_z2/catalog/frame_contracts.yaml' 'templates/phase_z2/families/app_sw_package_vs_solution.html' 'templates/phase_z2/families/pre_construction_model_info_stacked.html'
git diff --stat HEAD^ HEAD
git diff --shortstat HEAD^ HEAD
git diff --numstat HEAD^ HEAD
git diff --cached --name-only
git diff --name-only HEAD^ HEAD -- 'src'
git diff --name-only HEAD^ HEAD -- 'templates/phase_z2/catalog/frame_contracts.yaml'
git diff --name-only HEAD^ HEAD -- 'templates/phase_z2/families/*.html'
Local HEAD is 8f06a4c99f53b8c5ce372cec99fae895af3e2d20.
Commit parent is 191b6a9d85510ceb35891e70218dc7b806c15ef5.
Commit subject is docs(IMP-52): reconcile Phase Z family count drift -- F-2 option (c).
Commit author is kyeongmin <b24009@hanmaceng.co.kr> with date Tue May 19 19:15:04 2026 +0900.
Commit body includes Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>.
origin/main resolves to 8f06a4c99f53b8c5ce372cec99fae895af3e2d20.
slide2/main resolves to 8f06a4c99f53b8c5ce372cec99fae895af3e2d20.
The commit is present locally as a commit object.
The commit contains exactly four files: docs/architecture/IMP-18-SVG-GAP-REPORT.md, docs/architecture/INTEGRATION-AUDIT-01-REPORT.md, templates/phase_z2/families/_WIP_FILES.md, and tests/test_family_contract_baseline.py.
Commit diff stat is 4 files changed, 128 insertions(+), 5 deletions(-).
Per-file numstat is IMP-18 3 insertions / 3 deletions, AUDIT-01 8 insertions / 2 deletions, _WIP_FILES.md37 insertions, and test_family_contract_baseline.py80 insertions.
git diff --cached --name-only is empty.
src, templates/phase_z2/catalog/frame_contracts.yaml, and templates/phase_z2/families/*.html have no changes in HEAD^..HEAD.
templates/phase_z2/families/app_sw_package_vs_solution.html and templates/phase_z2/families/pre_construction_model_info_stacked.html remain untracked and are not listed by git ls-files.
The repository still has unrelated untracked local artifacts; they are not included in the verified commit.
FINAL_CONSENSUS: YES
[Codex #7] Stage 5 commit-push verification Round #1 complete
Stage 5 verification result: PASS.
I verified the local commit, committed file scope, remote branch tips, and WIP carve-out state. The pushed commit is exactly `8f06a4c99f53b8c5ce372cec99fae895af3e2d20`, with parent `191b6a9d85510ceb35891e70218dc7b806c15ef5`, and both checked remotes resolve `main` to the same commit SHA. The commit contains only the four Stage 2 implementation-unit files and does not include runtime source changes, `frame_contracts.yaml`, or the two WIP HTML bodies.
The working tree still contains unrelated untracked local artifacts, including the two intended disk-only WIP family templates. Those artifacts are not part of the commit.
=== EVIDENCE ===
Commands run:
- `git rev-parse HEAD`
- `git show -s --format='%H%n%P%n%s%n%an <%ae>%n%ad%n%B' HEAD`
- `git show --name-status --format= --stat HEAD`
- `git diff-tree --no-commit-id --name-status -r HEAD`
- `git ls-remote origin main`
- `git ls-remote slide2 main`
- `git remote -v`
- `git status --short`
- `git ls-files 'templates/phase_z2/families/*.html'`
- `git diff --name-only HEAD^ HEAD -- 'src' 'templates/phase_z2/catalog/frame_contracts.yaml' 'templates/phase_z2/families/app_sw_package_vs_solution.html' 'templates/phase_z2/families/pre_construction_model_info_stacked.html'`
- `git diff --stat HEAD^ HEAD`
- `git diff --shortstat HEAD^ HEAD`
- `git diff --numstat HEAD^ HEAD`
- `git diff --cached --name-only`
- `git diff --name-only HEAD^ HEAD -- 'src'`
- `git diff --name-only HEAD^ HEAD -- 'templates/phase_z2/catalog/frame_contracts.yaml'`
- `git diff --name-only HEAD^ HEAD -- 'templates/phase_z2/families/*.html'`
- `git ls-files 'templates/phase_z2/families/app_sw_package_vs_solution.html' 'templates/phase_z2/families/pre_construction_model_info_stacked.html'`
- `git status --short -- 'templates/phase_z2/families/app_sw_package_vs_solution.html' 'templates/phase_z2/families/pre_construction_model_info_stacked.html'`
- `git cat-file -t 8f06a4c99f53b8c5ce372cec99fae895af3e2d20`
- `git merge-base --is-ancestor 8f06a4c99f53b8c5ce372cec99fae895af3e2d20 origin/main`
- `git merge-base --is-ancestor 8f06a4c99f53b8c5ce372cec99fae895af3e2d20 slide2/main`
Files checked:
- `D:\ad-hoc\kei\design_agent\docs\architecture\IMP-18-SVG-GAP-REPORT.md`
- `D:\ad-hoc\kei\design_agent\docs\architecture\INTEGRATION-AUDIT-01-REPORT.md`
- `D:\ad-hoc\kei\design_agent\templates\phase_z2\families\_WIP_FILES.md`
- `D:\ad-hoc\kei\design_agent\tests\test_family_contract_baseline.py`
- `D:\ad-hoc\kei\design_agent\src`
- `D:\ad-hoc\kei\design_agent\templates\phase_z2\catalog\frame_contracts.yaml`
- `D:\ad-hoc\kei\design_agent\templates\phase_z2\families\app_sw_package_vs_solution.html`
- `D:\ad-hoc\kei\design_agent\templates\phase_z2\families\pre_construction_model_info_stacked.html`
Commit SHA:
- `8f06a4c99f53b8c5ce372cec99fae895af3e2d20`
Verified facts:
- Local `HEAD` is `8f06a4c99f53b8c5ce372cec99fae895af3e2d20`.
- Commit parent is `191b6a9d85510ceb35891e70218dc7b806c15ef5`.
- Commit subject is `docs(IMP-52): reconcile Phase Z family count drift -- F-2 option (c)`.
- Commit author is `kyeongmin <b24009@hanmaceng.co.kr>` with date `Tue May 19 19:15:04 2026 +0900`.
- Commit body includes `Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>`.
- `origin/main` resolves to `8f06a4c99f53b8c5ce372cec99fae895af3e2d20`.
- `slide2/main` resolves to `8f06a4c99f53b8c5ce372cec99fae895af3e2d20`.
- The commit is present locally as a `commit` object.
- The commit contains exactly four files: `docs/architecture/IMP-18-SVG-GAP-REPORT.md`, `docs/architecture/INTEGRATION-AUDIT-01-REPORT.md`, `templates/phase_z2/families/_WIP_FILES.md`, and `tests/test_family_contract_baseline.py`.
- Commit diff stat is `4 files changed, 128 insertions(+), 5 deletions(-)`.
- Per-file numstat is IMP-18 `3 insertions / 3 deletions`, AUDIT-01 `8 insertions / 2 deletions`, `_WIP_FILES.md` `37 insertions`, and `test_family_contract_baseline.py` `80 insertions`.
- `git diff --cached --name-only` is empty.
- `src`, `templates/phase_z2/catalog/frame_contracts.yaml`, and `templates/phase_z2/families/*.html` have no changes in `HEAD^..HEAD`.
- `templates/phase_z2/families/app_sw_package_vs_solution.html` and `templates/phase_z2/families/pre_construction_model_info_stacked.html` remain untracked and are not listed by `git ls-files`.
- The repository still has unrelated untracked local artifacts; they are not included in the verified commit.
FINAL_CONSENSUS: YES
Stage 2 implementation_units (u1~u4) all reflected: u1 = no frame_contracts.yaml edit (option (c) carve-out — verified by absence in commit), u2 = IMP-18, u3 = AUDIT-01, u4 = _WIP_FILES.md + pytest.
■ Goal vs result
Goal: reconcile 11 / 11 / 13 drift before #42 grows the catalog to 32 frames; either consolidate to one count or explicitly document the divergence.
Result: divergence explicitly documented as intentional carve-out (option (c)). Tracked + contracted baseline remains 11/11 unchanged; 2 WIP files preserved on disk as untracked WIP with named promote/remove gate (#42). No runtime path mutated. CI guard locks the new invariant.
Match: goal scope fully discharged; result does not exceed scope (no production frame promotion, no #42 work started, no runtime matcher rewire).
■ Follow-up links + downstream gating
#42 (IMP-04b Catalog extension to 32 frames): now unblocked from a baseline standpoint. Any #42 catalog growth must reconcile the WIP allowlist (_WIP_FILES.md) before merge — this constraint is enforced by tests/test_family_contract_baseline.py (set-equality guard). AUDIT-01 §10.2 F-2 resolution paragraph plus IMP-18 L28/L30/L51 anchor the contract.
#19 (per AUDIT-01 §9.3 condition 2): catalog-touch gate now satisfied for the current 11/11 baseline.
Backlog (separate axis, not drafted here): production decision for the 2 WIP families (app_sw_package_vs_solution.html, pre_construction_model_info_stacked.html) — promote into frame_contracts.yaml or remove. Timing remains open and is owned by #42 (or whichever ticket extends the catalog first).
Set algebra: contracts == tracked ✓; contracts == disk − WIP ✓; WIP ∩ contracts == ∅ ✓; WIP ⊂ disk ✓.
git status --short: committed scope clean; only unrelated untracked artifacts remain (.orchestrator/, samples/, tests/matching/*, the 2 WIP HTML files — all intentional per Stage 5 exit report).
■ Close decision
CLOSE — all three issue body acceptance criteria met, commit landed on origin/main and slide2/main at the same SHA, pytest baseline guard active, no runtime path mutated, no scope creep.
Pending user GO signal for Gitea state transition (issue close action itself). This comment records the close recommendation; the orchestrator does not auto-close per PZ-2: 1 turn = 1 step and per the conversation contract that close is a user action.
=== EVIDENCE ===
acceptance_criteria_check:criterion_1_consistency:status:METsurfaces:tracked:11# git ls-files 'templates/phase_z2/families/*.html'contracted:11# yaml.safe_load(frame_contracts.yaml) top-level keysdisk_active:11# 13 − 2 WIPdisk_total:13wip_allowlist:2docs_aligned:- docs/architecture/IMP-18-SVG-GAP-REPORT.md (L28/L30/L51 read "11 contracted + 2 WIP untracked = 13 on disk")- docs/architecture/INTEGRATION-AUDIT-01-REPORT.md (§5.2 C6 row, §6.3 Axis 4, §10.2 F-2 — all carry 11/11 baseline + 2 WIP)- templates/phase_z2/families/_WIP_FILES.md (explicit "not in frame_contracts.yaml, not in runtime matcher set" for both WIP entries)criterion_2_documented_or_resolved:status:MET (option (c) — intentional carve-out)resolution_marker:"RESOLVED via #52 (option c, 2026-05-19)"— INTEGRATION-AUDIT-01-REPORT.md §10.2 F-2 + §5.4 follow-up bullet F-2criterion_3_42_clean_baseline:status:METenforcement:- frame_contracts.yaml unchanged (11 keys)- tests/test_family_contract_baseline.py:tracked ⇔ contracts set-equality, modulo WIP allowlist parsed dynamically from _WIP_FILES.md- any future drift (including#42) fails CI before mergecommit_verification:head_sha:8f06a4c99f53b8c5ce372cec99fae895af3e2d20parent_sha:191b6a9d85510ceb35891e70218dc7b806c15ef5subject:"docs(IMP-52): reconcile Phase Z family count drift -- F-2 option (c)"remote_origin_main:8f06a4c99f53b8c5ce372cec99fae895af3e2d20remote_slide2_main:8f06a4c99f53b8c5ce372cec99fae895af3e2d20three_way_match:truefiles_changed:4insertions:128deletions:5stage_2_unit_reconciliation:u1_no_contract_edit:true(option (c) carve-out)u2_imp18_updated:trueu3_audit01_f2_resolved:trueu4_wip_marker_and_pytest_added:truescope_creep:nonetests_run:- "python -m pytest -q tests/test_family_contract_baseline.py tests/test_catalog_invariant.py"test_results:passed:4failed:0skipped:0warnings:0duration_s:0.10regression_probe:src_diff:cleanframe_contracts_yaml_diff:cleanwip_html_body_diff:clean (both WIP files untouched, remain untracked)staging_area:empty for this scopelabels:before:[]after:[]# no label mutation in Stage 6note:"Stage 6 contract does not include label mutation."follow_up_pointers:- "#42 IMP-04b: catalog expansion gated by WIP allowlist reconciliation; tests/test_family_contract_baseline.py enforces."- "#19: catalog-touch gate satisfied for current 11/11 baseline."- "backlog (separate axis): WIP family production decision (promote into frame_contracts.yaml or remove) — not drafted here per PZ-2."guardrails_honored:- Stage 6 added no new code/doc surface; verification-only.- Runtime path untouched.- Nocommit / push / label mutation in Stage 6.- 1 turn = 1 step:close recommendation recorded; close action awaits user GO.- Scope-qualified verification per feedback_scope_qualified_verification.- Nohardcoded counts in test logic (parsed dynamically) per feedback_no_hardcoding.close_decision:CLOSE (pending user GO for Gitea state transition)
Final independent verification result: PASS. Issue #52 acceptance criteria are met, and the pushed commit is present on both configured main remotes.
Acceptance criteria check:
Family count consistency: MET. Active contracted baseline is 11 tracked family templates and 11 frame_contracts.yaml entries; disk count is 13 only because 2 WIP files are explicitly allowlisted in D:\ad-hoc\kei\design_agent\templates\phase_z2\families\_WIP_FILES.md.
Drift documented as intentional: MET. The WIP files app_sw_package_vs_solution.html and pre_construction_model_info_stacked.html are documented as untracked, uncontracted, and outside the runtime matcher set.
#42 clean baseline: MET. D:\ad-hoc\kei\design_agent\tests\test_family_contract_baseline.py enforces contracts == disk families minus WIP, and the targeted baseline tests pass.
Remote/commit verification:
Local HEAD: 8f06a4c99f53b8c5ce372cec99fae895af3e2d20
Commit subject: docs(IMP-52): reconcile Phase Z family count drift -- F-2 option (c)
Commit scope is exactly 4 files: two docs, one WIP marker doc, one pytest guard. No src/**, frame_contracts.yaml, or WIP HTML body changes are in the commit.
=== EVIDENCE ===
Commands run:
git rev-parse HEAD
git show -s --format='%H%n%P%n%s' HEAD
git diff-tree --no-commit-id --name-status -r HEAD
git diff --name-only HEAD^ HEAD -- src templates/phase_z2/catalog/frame_contracts.yaml templates/phase_z2/families/app_sw_package_vs_solution.html templates/phase_z2/families/pre_construction_model_info_stacked.html
git diff --cached --name-only
git ls-files 'templates/phase_z2/families/*.html'
Get-ChildItem -LiteralPath 'templates\phase_z2\families' -Filter '*.html' | Select-Object -ExpandProperty Name
parity probe using yaml.safe_load over D:\ad-hoc\kei\design_agent\templates\phase_z2\catalog\frame_contracts.yaml, disk family stems, tracked family stems, and _WIP_FILES.md
line counts for D:\ad-hoc\kei\design_agent\templates\phase_z2\families\_WIP_FILES.md and D:\ad-hoc\kei\design_agent\tests\test_family_contract_baseline.py
origin/main, slide2/main, and local HEAD all resolve to 8f06a4c99f53b8c5ce372cec99fae895af3e2d20.
Commit file list is exactly:
M docs/architecture/IMP-18-SVG-GAP-REPORT.md
M docs/architecture/INTEGRATION-AUDIT-01-REPORT.md
A templates/phase_z2/families/_WIP_FILES.md
A tests/test_family_contract_baseline.py
contracts=11, disk=13, tracked=11, wip=2.
contracts_eq_tracked=True.
contracts_eq_disk_minus_wip=True.
wip_subset_disk=True.
wip_intersect_contracts=[].
wip_intersect_tracked=[].
git diff --name-only HEAD^ HEAD -- src templates/phase_z2/catalog/frame_contracts.yaml templates/phase_z2/families/app_sw_package_vs_solution.html templates/phase_z2/families/pre_construction_model_info_stacked.html returned no files.
git diff --cached --name-only returned no files.
Working tree still has unrelated untracked local artifacts, including the two WIP HTML files, consistent with the Stage 5 carve-out.
D:\ad-hoc\kei\design_agent\templates\phase_z2\families\_WIP_FILES.md has 37 lines.
D:\ad-hoc\kei\design_agent\tests\test_family_contract_baseline.py has 80 lines.
Close OK signal: issue #52 is verified complete for final close.
FINAL_CONSENSUS: YES
[Codex #9] Stage 6: Final close Round #1
Final independent verification result: PASS. Issue #52 acceptance criteria are met, and the pushed commit is present on both configured main remotes.
Acceptance criteria check:
- Family count consistency: MET. Active contracted baseline is 11 tracked family templates and 11 `frame_contracts.yaml` entries; disk count is 13 only because 2 WIP files are explicitly allowlisted in `D:\ad-hoc\kei\design_agent\templates\phase_z2\families\_WIP_FILES.md`.
- Drift documented as intentional: MET. The WIP files `app_sw_package_vs_solution.html` and `pre_construction_model_info_stacked.html` are documented as untracked, uncontracted, and outside the runtime matcher set.
- #42 clean baseline: MET. `D:\ad-hoc\kei\design_agent\tests\test_family_contract_baseline.py` enforces contracts == disk families minus WIP, and the targeted baseline tests pass.
Remote/commit verification:
- Local HEAD: `8f06a4c99f53b8c5ce372cec99fae895af3e2d20`
- `origin/main`: `8f06a4c99f53b8c5ce372cec99fae895af3e2d20`
- `slide2/main`: `8f06a4c99f53b8c5ce372cec99fae895af3e2d20`
- Commit subject: `docs(IMP-52): reconcile Phase Z family count drift -- F-2 option (c)`
- Commit scope is exactly 4 files: two docs, one WIP marker doc, one pytest guard. No `src/**`, `frame_contracts.yaml`, or WIP HTML body changes are in the commit.
=== EVIDENCE ===
Commands run:
- `git rev-parse HEAD`
- `git show -s --format='%H%n%P%n%s' HEAD`
- `git diff-tree --no-commit-id --name-status -r HEAD`
- `git ls-remote origin main`
- `git ls-remote slide2 main`
- `git status --short`
- `python -m pytest -q tests/test_family_contract_baseline.py tests/test_catalog_invariant.py`
- `rg -n "11 contracted|2 WIP|RESOLVED via #52|app_sw_package_vs_solution|pre_construction_model_info_stacked|runtime matcher" docs/architecture/IMP-18-SVG-GAP-REPORT.md docs/architecture/INTEGRATION-AUDIT-01-REPORT.md templates/phase_z2/families/_WIP_FILES.md`
- `git diff --name-only HEAD^ HEAD -- src templates/phase_z2/catalog/frame_contracts.yaml templates/phase_z2/families/app_sw_package_vs_solution.html templates/phase_z2/families/pre_construction_model_info_stacked.html`
- `git diff --cached --name-only`
- `git ls-files 'templates/phase_z2/families/*.html'`
- `Get-ChildItem -LiteralPath 'templates\phase_z2\families' -Filter '*.html' | Select-Object -ExpandProperty Name`
- parity probe using `yaml.safe_load` over `D:\ad-hoc\kei\design_agent\templates\phase_z2\catalog\frame_contracts.yaml`, disk family stems, tracked family stems, and `_WIP_FILES.md`
- `Get-Content -LiteralPath 'D:\ad-hoc\kei\design_agent\tests\test_family_contract_baseline.py'`
- `Get-Content -LiteralPath 'D:\ad-hoc\kei\design_agent\templates\phase_z2\families\_WIP_FILES.md'`
- line counts for `D:\ad-hoc\kei\design_agent\templates\phase_z2\families\_WIP_FILES.md` and `D:\ad-hoc\kei\design_agent\tests\test_family_contract_baseline.py`
Files checked:
- `D:\ad-hoc\kei\design_agent\docs\architecture\IMP-18-SVG-GAP-REPORT.md`
- `D:\ad-hoc\kei\design_agent\docs\architecture\INTEGRATION-AUDIT-01-REPORT.md`
- `D:\ad-hoc\kei\design_agent\templates\phase_z2\families\_WIP_FILES.md`
- `D:\ad-hoc\kei\design_agent\tests\test_family_contract_baseline.py`
- `D:\ad-hoc\kei\design_agent\templates\phase_z2\catalog\frame_contracts.yaml`
- `D:\ad-hoc\kei\design_agent\templates\phase_z2\families\app_sw_package_vs_solution.html` (presence only; body not changed)
- `D:\ad-hoc\kei\design_agent\templates\phase_z2\families\pre_construction_model_info_stacked.html` (presence only; body not changed)
Test results:
- `python -m pytest -q tests/test_family_contract_baseline.py tests/test_catalog_invariant.py` -> `4 passed in 0.10s`
Commit SHA:
- `8f06a4c99f53b8c5ce372cec99fae895af3e2d20`
Verified facts:
- `origin/main`, `slide2/main`, and local HEAD all resolve to `8f06a4c99f53b8c5ce372cec99fae895af3e2d20`.
- Commit file list is exactly:
- `M docs/architecture/IMP-18-SVG-GAP-REPORT.md`
- `M docs/architecture/INTEGRATION-AUDIT-01-REPORT.md`
- `A templates/phase_z2/families/_WIP_FILES.md`
- `A tests/test_family_contract_baseline.py`
- `contracts=11`, `disk=13`, `tracked=11`, `wip=2`.
- `contracts_eq_tracked=True`.
- `contracts_eq_disk_minus_wip=True`.
- `wip_subset_disk=True`.
- `wip_intersect_contracts=[]`.
- `wip_intersect_tracked=[]`.
- `git diff --name-only HEAD^ HEAD -- src templates/phase_z2/catalog/frame_contracts.yaml templates/phase_z2/families/app_sw_package_vs_solution.html templates/phase_z2/families/pre_construction_model_info_stacked.html` returned no files.
- `git diff --cached --name-only` returned no files.
- Working tree still has unrelated untracked local artifacts, including the two WIP HTML files, consistent with the Stage 5 carve-out.
- `D:\ad-hoc\kei\design_agent\templates\phase_z2\families\_WIP_FILES.md` has 37 lines.
- `D:\ad-hoc\kei\design_agent\tests\test_family_contract_baseline.py` has 80 lines.
Close OK signal: issue #52 is verified complete for final close.
FINAL_CONSENSUS: YES
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Purpose
Reconcile Phase Z family template/catalog counts before #42 (
IMP-04b Catalog extension to 32 frames) or any #19 work that touches catalog/family/template behavior.Source
docs/architecture/INTEGRATION-AUDIT-01-REPORT.mdSection 5, Section 6, Section 9, Section 10Problem
Audit #50 found family count drift:
frame_contracts.yamlentriesThe 2 extra on-disk WIP templates are:
app_sw_package_vs_solution.htmlpre_construction_model_info_stacked.htmlThis is not a current closed-issue blocker, but it can become a contract problem before #42 expands the catalog to 32 frames.
Scope
Decide and apply one consistent treatment:
frame_contracts.yamlaligned with the selected template set.Relationship to #42
This issue is a pre-flight/prerequisite cleanup for #42. #42 should not expand the catalog until this count drift is resolved or explicitly accepted.
Out of Scope
Acceptance Criteria
11 tracked / 13 on disk / 11 catalogdrift is either resolved or explicitly documented as intentional.[Claude #1] Stage 1 — Problem Review (Round 1)
1. Root cause
The 13/11/11 drift is real and reproducible on audit date 2026-05-19. Live verification:
ls templates/phase_z2/families/*.htmlgit ls-files templates/phase_z2/families/frame_contracts.yamltop-level entriesgrep -cE "^[a-z_]+:$" templates/phase_z2/catalog/frame_contracts.yamlThe 11 tracked / 11 contracted entries are 1:1 aligned (each tracked
.htmlhas a matching top-level key inframe_contracts.yaml).The 2 disk-only files are uncommitted WIP, NOT untracked-in-catalog-only:
templates/phase_z2/families/app_sw_package_vs_solution.html1171281203) "Application S/W 의 구분"; cited asbim_dx_comparison_table-equivalent (builderprocess_product_pair)??untracked (top-of-conversationgit status)templates/phase_z2/families/pre_construction_model_info_stacked.html1171281180); header dated 2026-05-14; cited as V4 04-1 top rank-1 (의미 conf=0.722, structure cardinality 5)??untrackedBoth files were authored during V4 / IMP-04 / smoke exploration work but never landed in
frame_contracts.yaml, nevergit add-ed, and never declared under any closed issue. They are experimental partials sitting on disk.The doc-side count is also out of sync —
docs/architecture/IMP-18-SVG-GAP-REPORT.md:28and:51cite "13 files", forward-looking and therefore consistent with disk but inconsistent with the tracked/contracted baseline of 11.2. Why this is a #42 pre-flight (not a #42-internal cleanup)
#42 IMP-04b Catalog extension to 32 framesis open and plans to expand11/32 → 32/32via Track A 잔여 5 + Track B 12 + Track C 1. If #42 starts from adisk=13 / tracked=11 / catalog=11baseline, two failure modes appear:frame_contracts.yamldecision. Result: catalog growth without a clean per-frame audit trail (violates feedback_workflow_atomicity_rules — 1 commit = 1 decision unit).The audit (
INTEGRATION-AUDIT-01-REPORT.md§10.2) flagged this explicitly: "Must NOT be folded into #19 silently". The same logic carries to #42 (per-issue atomicity).3. Three candidate treatments (issue body wording)
frame_contracts.yaml+git add2 templatesframe_id,family,cardinality,role_order,visual_hints.min_height_px,accepted_content_types,sub_zones,payload.builderblock — same surface as the 8 IMP-04 entries13stays correcttemplates/phase_z2/families/_wip/(or remove)13→11(2 occurrences)templates/phase_z2/families/README.mdor similar noting 2 WIP files belong to future #42 work13with footnoteRecommendation (open for user GO): (b) quarantine, because:
git loghistory to preserve, no orphaned references.4. Scope-lock proposal (pending treatment choice)
Hard out-of-scope (locked, all 3 options):
src/**runtime code edits — mapper, classifier, router, pipeline, retry, fit_verifier all read-only.tests/**edits (no new pytest fixtures, notests/phase_z2/touch).samples/mdx_batch/{03,04,05}.mdxand any other sample left untouched.frame_contracts.yamlentries for the existing 11 frames either (no piggyback edits).INTEGRATION-AUDIT-01-REPORT.mdis a frozen snapshot; do NOT amend it.Touch surface per option (single commit, 1 decision):
templates/phase_z2/families/{2 WIP}.html(git add),templates/phase_z2/catalog/frame_contracts.yaml(+2 entries),docs/architecture/PHASE-Z-IMPLEMENTATION-ISSUE-BACKLOG.md(count row if any)feat(IMP-52): track 2 WIP family templates + register frame_contracts entriestemplates/phase_z2/families/_wip/{2 WIP}.html(move target; orrm),docs/architecture/IMP-18-SVG-GAP-REPORT.md(13→11, 2 occurrences)chore(IMP-52): quarantine 2 untracked WIP family templates, align IMP-18 count to 11templates/phase_z2/families/README.md(new doc),docs/architecture/IMP-18-SVG-GAP-REPORT.md(footnote on13)docs(IMP-52): document 2 WIP family templates as pre-#42 unreconciledGuardrails (all options):
pytest -q tests/phase_z2/baseline must remain unchanged from current head; no new test added, no skipped test (this issue is contract-only, not runtime-behavior).grep -cE "^[a-z_]+:$" templates/phase_z2/catalog/frame_contracts.yamlANDgit ls-files templates/phase_z2/families/ | wc -lANDls templates/phase_z2/families/*.html | wc -lMUST be reported per-axis with the post-edit count for the scope row of the AC table.IMP-18-SVG-GAP-REPORT.md:28+:51, NOT a process change.5. Open decision point (requires Stage 2 GO)
Treatment choice — (a) / (b) / (c) is the orchestrator/human decision. Stage 1 cannot resolve it without explicit GO because each option has a different commit semantic and different #42 collateral.
If GO defaults to my recommendation, Stage 2 plans option (b). Otherwise the chosen option is locked into Stage 2's plan with the exact touch surface table above.
6. Out-of-scope confirmations (per issue body)
=== EVIDENCE ===
Commands run on audit date 2026-05-19 (live):
ls templates/phase_z2/families/*.html→ 13 files (full list:app_sw_package_vs_solution.html,bim_current_problems_paired.html,bim_dx_comparison_table.html,bim_issues_quadrant_four.html,construction_bim_three_usage.html,construction_goals_three_circle_intersection.html,dx_sw_necessity_three_perspectives.html,info_management_what_how_when.html,pre_construction_model_info_stacked.html,process_product_two_way.html,sw_reality_three_emphasis.html,three_parallel_requirements.html,three_persona_benefits.html)git ls-files templates/phase_z2/families/→ 11 entries (the 13 above minusapp_sw_package_vs_solution.htmlandpre_construction_model_info_stacked.html)grep -cE "^[a-z_]+:$" templates/phase_z2/catalog/frame_contracts.yaml→ 11templates/phase_z2/families/app_sw_package_vs_solution.html:1-28→ Frame 23 (1171281203), slots aligned withbim_dx_comparison_tablebuilderprocess_product_pairtemplates/phase_z2/families/pre_construction_model_info_stacked.html:1-30→ Frame 9 (1171281180), header date 2026-05-14, V4 04-1 top rank-1 match (의미 conf=0.722)docs/architecture/IMP-18-SVG-GAP-REPORT.md:28("13 files") +:51("(13) + ... (2)")docs/architecture/INTEGRATION-AUDIT-01-REPORT.md§5.2 row C6, §5.5 row "C6 family templates", §10.2 follow-up draft F-2 — all read and match.git statusconfirms both WIP files appear with??prefix.GET /repos/Kyeongmin/C.E.L_Slide_test2/issues/42) → stateopen, scope = "remaining 21/32 frames (현 active 11/32 → 32/32)",Track A 잔여 5 frames+Track B 12 visual-pending frames+Track C 1 matching schema canonical— confirms #42 will touchframe_contracts.yamlandtemplates/phase_z2/families/.Files inspected (read-only):
INTEGRATION-AUDIT-01-REPORT.md§5 §6 §9 §10,frame_contracts.yaml(full 730 lines),IMP-18-SVG-GAP-REPORT.mdhead,app_sw_package_vs_solution.htmlhead,pre_construction_model_info_stacked.htmlhead,PHASE-Z-IMPLEMENTATION-ISSUE-BACKLOG.mdIMP-50 row.No
src/**,tests/**,samples/**touched in this stage.FINAL_CONSENSUS: YES
[Codex #1] Stage 1 Problem Review (Round 1)
Root cause verified. The count drift is real and is limited to two untracked WIP family templates on disk:
templates/phase_z2/families/*.htmlon diskgit ls-files templates/phase_z2/families/*.htmltemplates/phase_z2/catalog/frame_contracts.yamltop-level keysThe tracked template basenames and
frame_contracts.yamlkeys compare cleanly: no tracked family template is missing a contract entry, and no contract entry points at a missing tracked family template.The two disk-only files are:
templates/phase_z2/families/app_sw_package_vs_solution.html- untracked; header identifies frame 23 /1171281203; not present inframe_contracts.yaml.templates/phase_z2/families/pre_construction_model_info_stacked.html- untracked; header identifies frame 9 /1171281180; not present inframe_contracts.yaml.Docs verified:
docs/architecture/INTEGRATION-AUDIT-01-REPORT.mdalready records F-2 as11 tracked / 11 contracted / 13 on disk, names the same two WIP files, and scope-locks the reconciliation totemplates/phase_z2/families/*.html,templates/phase_z2/catalog/frame_contracts.yaml, anddocs/architecture/IMP-18-SVG-GAP-REPORT.md.docs/architecture/IMP-18-SVG-GAP-REPORT.mdcitestemplates/phase_z2/families/*.htmlas 13 files at lines 28 and 51, so it is aligned with disk count but not with the tracked/contracted baseline.docs/architecture/IMP-04-FRAME-SUITABILITY-MATRIX.mdreferences both template IDs as reusable candidates, but that is planning/evidence surface only; it does not register them in the runtime contract.Scope-lock verdict:
=== EVIDENCE ===
Commands run:
Get-Content -LiteralPath 'D:\ad-hoc\kei\design_agent\.orchestrator\tmp\codex_prompt.txt'Get-ChildItem -LiteralPath 'templates/phase_z2/families' -Filter '*.html' | Select-Object -ExpandProperty Name | Sort-Objectgit ls-files 'templates/phase_z2/families/*.html'git status --short -- 'templates/phase_z2/families' 'templates/phase_z2/catalog/frame_contracts.yaml' 'docs/architecture'Select-String -Path 'templates/phase_z2/catalog/frame_contracts.yaml' -Pattern '^[a-z_]+:' | ForEach-Object { $_.Line }Select-String -Path 'templates/phase_z2/families/app_sw_package_vs_solution.html','templates/phase_z2/families/pre_construction_model_info_stacked.html' -Pattern 'Frame|frame|117128|bim_dx|process_product|V4|rank|conf|2026' -Context 0,2rg -n "app_sw_package_vs_solution|pre_construction_model_info_stacked|13 files|13 family|11 tracked|frame_contracts|family templates" docs templates -g '!templates/phase_z2/families/app_sw_package_vs_solution.html' -g '!templates/phase_z2/families/pre_construction_model_info_stacked.html'Select-String -Path 'docs/architecture/INTEGRATION-AUDIT-01-REPORT.md' -Pattern '11 tracked|13|family|F-2|frame_contracts|app_sw_package_vs_solution|pre_construction_model_info_stacked|Must NOT|#19|#42' -Context 1,2Select-String -Path 'docs/architecture/IMP-18-SVG-GAP-REPORT.md' -Pattern '13 files|13|family templates|templates/phase_z2/families|app_sw_package_vs_solution|pre_construction_model_info_stacked' -Context 1,2(Get-ChildItem -LiteralPath 'templates/phase_z2/families' -Filter '*.html').Count(git ls-files 'templates/phase_z2/families/*.html' | Measure-Object).Count(Select-String -Path 'templates/phase_z2/catalog/frame_contracts.yaml' -Pattern '^[a-z_]+:').CountSelect-String -Path 'templates/phase_z2/catalog/frame_contracts.yaml' -Pattern 'app_sw_package_vs_solution|pre_construction_model_info_stacked'$tracked = git ls-files 'templates/phase_z2/families/*.html' | ForEach-Object { [System.IO.Path]::GetFileNameWithoutExtension($_) } | Sort-Object; $contracts = Select-String -Path 'templates/phase_z2/catalog/frame_contracts.yaml' -Pattern '^[a-z_]+:' | ForEach-Object { $_.Line.TrimEnd(':') } | Sort-Object; Compare-Object -ReferenceObject $tracked -DifferenceObject $contracts | Format-Table -AutoSizeFiles checked:
D:\ad-hoc\kei\design_agent\.orchestrator\tmp\codex_prompt.txttemplates/phase_z2/families/app_sw_package_vs_solution.htmltemplates/phase_z2/families/pre_construction_model_info_stacked.htmltemplates/phase_z2/catalog/frame_contracts.yamldocs/architecture/INTEGRATION-AUDIT-01-REPORT.mddocs/architecture/IMP-18-SVG-GAP-REPORT.mddocs/architecture/IMP-04-FRAME-SUITABILITY-MATRIX.mdTest results: Not run; Stage 1 explicitly says NO pytest.
Verified facts:
frame_contracts.yamltop-level contract count is 11.app_sw_package_vs_solution.htmlandpre_construction_model_info_stacked.htmlare untracked.frame_contracts.yaml.Compare-Objectdiff.IMP-18-SVG-GAP-REPORT.mdcites 13 family files.INTEGRATION-AUDIT-01-REPORT.mdrecords F-2 with the same two WIP filenames and the same 11/11/13 count split.FINAL_CONSENSUS: YES
📌 [Claude #1] Stage 2: 시뮬 기반 계획 수립 (Round 1)
■ Coverage checklist (every issue-body axis)
frame_contracts.yaml↔ template set■ Decision: Option (c) — 2 WIP files remain in-place as explicitly-marked uncontracted WIP.
templates/phase_z2/families/_WIP_FILES.md(tracked) is the single source of truth for the 11-active / 2-WIP split.frame_contracts.yamlruntime catalog untouched.=== IMPLEMENTATION_UNITS ===
■ Per-unit rationale (≤3 lines each)
set(yaml_keys) == set(tracked_family_basenames)minus WIP allowlist from u1. Pattern followstests/test_catalog_invariant.py:1-40. Future #42 forgetting to register a template = fail fast.■ Out of scope (confirms + light extension of Stage 1 scope_lock)
templates/phase_z2/families/*.html+frame_contracts.yaml+IMP-18-SVG-GAP-REPORT.md. Stage 2 extends toINTEGRATION-AUDIT-01-REPORT.md(u3 — F-2 closure surface) and newtests/test_family_contract_baseline.py(u4 — CI guard). Both are docs/test surfaces, zero runtime path.■ Rollback strategy
Pure additive docs + 1 new pytest. Rollback =
git reverton merge commit; no migration, no data loss, no runtime state, WIP files untouched throughout.=== EVIDENCE ===
ls templates/phase_z2/families/*.html→ 13 (Stage 2 entry, 2026-05-19)git ls-files templates/phase_z2/families/*.html→ 11templates/phase_z2/catalog/frame_contracts.yaml→ 11 (header L1-19 confirms v0 contract scope)git status:app_sw_package_vs_solution.html,pre_construction_model_info_stacked.html— untracked, names match Stage 1 exit reporttests/test_catalog_invariant.py:1-40(existing yaml-read + 1:1 assertion shape)FINAL_CONSENSUS: YES
[Codex #1] Stage 2 plan review (Round 1)
Verdict: NO. The substantive plan is mostly complete, but the Stage 2 comment violates the strict compact-plan shape required by the prompt, so it must rewind to Stage 2.
Findings:
=== IMPLEMENTATION_UNITS ===. The prompt says the Stage 2 plan body MUST contain ONLY the implementation units YAML block, brief per-unit rationale, out-of-scope notes, rollback strategy, evidence block, and final marker. Because this is a strict requirement, this is a plan-level failure.frame_contracts.yamlremains aligned at the current 11-entry baseline, WIP files are left untouched, and #42 is gated by the marker/test baseline.templates/phase_z2/families/_WIP_FILES.md,tests/test_family_contract_baseline.py), which is expected for Stage 2. Referenced existing files are present.=== EVIDENCE ===
Commands run:
git status --shortrg -n "F-2|13 files|tracked|contracted|app_sw_package_vs_solution|pre_construction_model_info_stacked" docs/architecture/INTEGRATION-AUDIT-01-REPORT.md docs/architecture/IMP-18-SVG-GAP-REPORT.md docs/architecture/IMP-04-FRAME-SUITABILITY-MATRIX.mdGet-ChildItem -LiteralPath 'templates\\phase_z2\\families' -Filter '*.html' | Select-Object -ExpandProperty Namegit ls-files 'templates/phase_z2/families/*.html'Get-Content -LiteralPath 'tests\\test_catalog_invariant.py'Select-String -Path 'templates\\phase_z2\\catalog\\frame_contracts.yaml' -Pattern '^[a-z_]+:' | ForEach-Object { $_.Line }pytest -q testsFiles checked:
D:\ad-hoc\kei\design_agent\docs\architecture\INTEGRATION-AUDIT-01-REPORT.mdD:\ad-hoc\kei\design_agent\docs\architecture\IMP-18-SVG-GAP-REPORT.mdD:\ad-hoc\kei\design_agent\docs\architecture\IMP-04-FRAME-SUITABILITY-MATRIX.mdD:\ad-hoc\kei\design_agent\templates\phase_z2\catalog\frame_contracts.yamlD:\ad-hoc\kei\design_agent\templates\phase_z2\families\*.htmlD:\ad-hoc\kei\design_agent\tests\test_catalog_invariant.pyTest results:
pytest -q tests-> 303 passed in 40.83sVerified facts:
.htmlfiles..htmlfiles.frame_contracts.yaml.app_sw_package_vs_solution.htmlandpre_construction_model_info_stacked.html.tests/test_catalog_invariant.pyalready usesyaml.safe_load, so the proposed YAML-backed pytest style is compatible with the repo.rewind_target: stage_2_plan
FINAL_CONSENSUS: NO
📌 [Claude #1] Stage 2: 시뮬 기반 계획 수립 (Round 2)
=== IMPLEMENTATION_UNITS ===
■ Per-unit rationale (≤3 lines each)
set(yaml_keys) == set(tracked_family_basenames)minus WIP allowlist from u1. Pattern follows tests/test_catalog_invariant.py:1-40. #42 forgetting to register a future template = fail fast.■ Out of scope
templates/phase_z2/families/*.html+frame_contracts.yaml+IMP-18-SVG-GAP-REPORT.md. Stage 2 extends toINTEGRATION-AUDIT-01-REPORT.md(u3 — F-2 closure surface) and newtests/test_family_contract_baseline.py(u4 — CI guard). Both are docs/test surfaces; zero runtime path mutation.■ Rollback strategy
Pure additive docs + 1 new pytest. Rollback =
git reverton merge commit; no migration, no data loss, no runtime state, no catalog mutation, WIP files untouched throughout.=== EVIDENCE ===
ls templates/phase_z2/families/*.html→ 13 (Stage 2 entry, 2026-05-19)git ls-files templates/phase_z2/families/*.html→ 11templates/phase_z2/catalog/frame_contracts.yaml→ 11git status:app_sw_package_vs_solution.html,pre_construction_model_info_stacked.html— untracked, names match Stage 1 exit reporttests/test_catalog_invariant.py:1-40(existing yaml.safe_load + 1:1 assertion shape) — Codex r1 re-verified compatiblepytest -q tests→ 303 passed in 40.83s (Codex r1 evidence) — Stage 4 targetFINAL_CONSENSUS: YES
[Codex #1] Stage 2 plan review (Round 1)
Verdict: NO.
Findings:
=== IMPLEMENTATION_UNITS ===. The stage prompt requires the plan body to contain only the implementation-units YAML block, brief per-unit rationale, out-of-scope notes, rollback strategy, evidence block, and final marker.frame_contracts.yamlaligned to the 11-entry active baseline, updates docs, and gates #42 with a testable clean baseline.templates/phase_z2/families/_WIP_FILES.mdandtests/test_family_contract_baseline.pydo not exist yet and are planned new files.=== EVIDENCE ===
Commands run:
git ls-files 'templates/phase_z2/families/*.html'Get-ChildItem -LiteralPath 'templates/phase_z2/families' -Filter '*.html'templates/phase_z2/catalog/frame_contracts.yamlwithyaml.safe_loadSelect-Stringchecks ondocs/architecture/IMP-18-SVG-GAP-REPORT.mdSelect-Stringchecks ondocs/architecture/INTEGRATION-AUDIT-01-REPORT.mdGet-Content -LiteralPath 'tests/test_catalog_invariant.py'Test-Pathfor planned new filespytest -q testsFiles checked:
templates/phase_z2/families/*.htmltemplates/phase_z2/catalog/frame_contracts.yamldocs/architecture/IMP-18-SVG-GAP-REPORT.mddocs/architecture/INTEGRATION-AUDIT-01-REPORT.mdtests/test_catalog_invariant.pyTest results:
303 passed in 40.03sVerified facts:
frame_contracts.yamltop-level contract count is 11.app_sw_package_vs_solution.htmlandpre_construction_model_info_stacked.html.families/*.htmlcount as 13 at the checked lines.rewind_target: stage_2_plan
FINAL_CONSENSUS: NO
📌 [Claude #1] Stage 2: 시뮬 기반 계획 수립 (Round 1, post-rewind)
=== IMPLEMENTATION_UNITS ===
■ Per-unit rationale (≤3 lines each)
set(yaml_keys) == set(tracked_family_basenames)minus WIP allowlist from u1. Pattern follows tests/test_catalog_invariant.py:1-40. #42 forgetting to register a future template = fail fast.■ Out of scope
templates/phase_z2/families/*.html+frame_contracts.yaml+IMP-18-SVG-GAP-REPORT.md. Stage 2 extends toINTEGRATION-AUDIT-01-REPORT.md(u3 — F-2 closure surface) and newtests/test_family_contract_baseline.py(u4 — CI guard). Both are docs/test surfaces; zero runtime path mutation.■ Rollback strategy
Pure additive docs + 1 new pytest. Rollback =
git reverton merge commit; no migration, no data loss, no runtime state, no catalog mutation, WIP files untouched throughout.=== EVIDENCE ===
ls templates/phase_z2/families/*.html→ 13 (Stage 2 re-entry, 2026-05-19)git ls-files templates/phase_z2/families/*.html→ 11templates/phase_z2/catalog/frame_contracts.yaml→ 11git status --porcelain 'templates/phase_z2/families/*.html':?? app_sw_package_vs_solution.html,?? pre_construction_model_info_stacked.html— match Stage 1 exit report exactlytests/test_catalog_invariant.py:1-40(existing yaml.safe_load + 1:1 assertion shape) — Codex r1 confirmed compatiblepytest -q tests→ 303 passed in 40.03s (Codex r1 evidence) — Stage 4 targetFINAL_CONSENSUS: YES
[Codex #2] Stage 2 plan review (Round 1, post-rewind)
Verdict: YES.
Findings:
frame_contracts.yamlat the 11-entry active baseline, updates docs, and adds a test guard before #42 expands the catalog.templates/phase_z2/families/_WIP_FILES.mdandtests/test_family_contract_baseline.pydo not exist yet and are explicitly planned as new files.=== EVIDENCE ===
Commands run:
git status --shortgit ls-files 'templates/phase_z2/families/*.html'Get-ChildItem -LiteralPath 'templates/phase_z2/families' -Filter '*.html'templates/phase_z2/catalog/frame_contracts.yamlwithyaml.safe_loadSelect-Stringchecks ondocs/architecture/IMP-18-SVG-GAP-REPORT.mdrg -n "13 files|F-2|app_sw_package_vs_solution|pre_construction_model_info_stacked|test_catalog_invariant|frame_contracts" docs templates tests -SGet-Content -LiteralPath 'tests/test_catalog_invariant.py'Test-Pathfor planned new filespytest -q testsFiles checked:
templates/phase_z2/families/*.htmltemplates/phase_z2/catalog/frame_contracts.yamldocs/architecture/IMP-18-SVG-GAP-REPORT.mddocs/architecture/INTEGRATION-AUDIT-01-REPORT.mdtests/test_catalog_invariant.pyTest results:
303 passed in 39.98sVerified facts:
frame_contracts.yamltop-level contract count is 11.app_sw_package_vs_solution.htmlandpre_construction_model_info_stacked.html.families/*.htmlcount as 13 at lines 28 and 51.FINAL_CONSENSUS: YES
⚠️ [Orchestrator] Stage 2 FINAL_CONSENSUS: YES rejected: block missing.
Requirements (strict):
=== IMPLEMENTATION_UNITS ===block with at least one- id: u<N>entrytests: [<path>, ...](NOTtests: [])Example:
=== IMPLEMENTATION_UNITS ===
summary: ...
files: [...]
tests: [tests/.../test_xxx.py]
estimate_lines:
📌 [Claude #1] Stage 2: 시뮬 기반 계획 수립 (Round 2)
=== IMPLEMENTATION_UNITS ===
■ Per-unit rationale (≤3 lines each)
set(yaml_keys) == set(tracked_family_basenames)minus WIP allowlist from u1. Pattern follows tests/test_catalog_invariant.py:1-40. #42 forgetting to register a future template = fail fast.■ Out of scope
templates/phase_z2/families/*.html+frame_contracts.yaml+IMP-18-SVG-GAP-REPORT.md. Stage 2 extends toINTEGRATION-AUDIT-01-REPORT.md(u3 — F-2 closure surface) and newtests/test_family_contract_baseline.py(u4 — CI guard). Both are docs/test surfaces; zero runtime path mutation.■ Rollback strategy
Pure additive docs + 1 new pytest. Rollback =
git reverton merge commit; no migration, no data loss, no runtime state, no catalog mutation, WIP files untouched throughout.=== EVIDENCE ===
ls templates/phase_z2/families/*.html→ 13 (Stage 2 entry, 2026-05-19)git ls-files templates/phase_z2/families/*.html→ 11templates/phase_z2/catalog/frame_contracts.yaml→ 11git status:app_sw_package_vs_solution.html,pre_construction_model_info_stacked.html— untracked, names match Stage 1 exit reporttests/test_catalog_invariant.py:1-40(existing yaml.safe_load + 1:1 assertion shape) — Codex r1 re-verified compatiblepytest -q tests→ 303 passed in 40.83s (Codex r1 evidence) — Stage 4 targetFINAL_CONSENSUS: YES
[Codex #2] Stage 2 plan review (Round 2)
Verdict: YES.
Findings:
frame_contracts.yamlaligned to the 11-entry active tracked baseline, updates both affected docs, and adds a pytest guard before #42 expands the catalog.templates/phase_z2/families/_WIP_FILES.mdandtests/test_family_contract_baseline.pydo not exist yet and are explicitly planned as new files.=== EVIDENCE ===
Commands run:
git status --shortgit ls-files 'templates/phase_z2/families/*.html'Get-ChildItem -LiteralPath 'templates/phase_z2/families' -Filter '*.html'Test-Path -LiteralPath 'templates/phase_z2/families/_WIP_FILES.md'Test-Path -LiteralPath 'tests/test_family_contract_baseline.py'templates/phase_z2/catalog/frame_contracts.yamlwithyaml.safe_loadframe_contracts.yamltop-level keysrg -n "13 files|F-2|app_sw_package_vs_solution|pre_construction_model_info_stacked|test_catalog_invariant|frame_contracts|_WIP_FILES" docs templates tests -SGet-Content -LiteralPath 'tests/test_catalog_invariant.py'Select-Stringchecks ondocs/architecture/IMP-18-SVG-GAP-REPORT.mdSelect-Stringchecks ondocs/architecture/INTEGRATION-AUDIT-01-REPORT.mdpytest -q testsFiles checked:
templates/phase_z2/families/*.htmltemplates/phase_z2/catalog/frame_contracts.yamldocs/architecture/IMP-18-SVG-GAP-REPORT.mddocs/architecture/INTEGRATION-AUDIT-01-REPORT.mdtests/test_catalog_invariant.py.orchestrator/drafts/52_stage_simulation-plan_claude_r2.mdTest results:
303 passed in 39.67sVerified facts:
frame_contracts.yamltop-level contract count is 11.app_sw_package_vs_solution.htmlandpre_construction_model_info_stacked.html.templates/phase_z2/families/_WIP_FILES.mdandtests/test_family_contract_baseline.pyare currently absent and are planned new files.families/*.htmlcount as 13 at lines 28 and 51.frame_contracts.yaml, runtime matcher wiring, Phase R behavior, MDX samples, or the #42 32-frame catalog extension.FINAL_CONSENSUS: YES
Executing unit: u1
📌 [Claude #1] Stage 3 — Code-edit Round 1 (unit u1 only)
■ unit_executed
u1■ files_changed
templates/phase_z2/families/_WIP_FILES.md(new, 37 lines) — within Stage 2 estimate (~35)■ diff_summary
1171281203, frame 9 /1171281180) and explicit "not inframe_contracts.yaml, not in runtime matcher set" status.templates/phase_z2/families/*.htmlwithout a contract entry are only permitted via this allowlist;tests/test_family_contract_baseline.py(u4) enforces set-equality modulo allowlist; promote/remove must happen under #42 or a follow-up issue.■ scope_lock adherence
frame_contracts.yaml, no WIP file delete/move/contract-entry, no IMP-18 / AUDIT-01 doc edits (those are u2/u3).■ pre-execution baseline reconfirm (factual)
git ls-files templates/phase_z2/families/*.html→ 11ls templates/phase_z2/families/*.html→ 13yaml.safe_load(frame_contracts.yaml)top-level keys → 11; set-equal to tracked basenamesapp_sw_package_vs_solution.html,pre_construction_model_info_stacked.htmlTest-Path templates/phase_z2/families/_WIP_FILES.mdpre-write → False; post-write → True (37 lines, untracked)■ git status after u1
No commit, no push (per Stage 3 directive — Gitea comment IS the deliverable).
■ remaining_units
u2— Correct IMP-18-SVG-GAP-REPORT.md L28 + L51 disk-only "13 files" cites to "11 contracted + 2 WIP untracked"; anchor_WIP_FILES.md.u3— Append resolution marker to INTEGRATION-AUDIT-01-REPORT.md §10.2 F-2 — record option (c), link_WIP_FILES.md(u1), mark F-2 closed-by-#52.u4— Addtests/test_family_contract_baseline.pyenforcing tracked families ↔frame_contracts.yaml1:1 set-equality with WIP allowlist parsed from_WIP_FILES.md.■ follow_up_issue_candidates
■ next action
FINAL_CONSENSUS: NOwithrewind_target: continue_same, proceed to u2 next turn (1 turn = 1 step). IfYES, that signals all u1–u4 complete — which is NOT yet true; only u1 done this round.— end Claude #1 Stage 3 R1 —
[Codex #1] Stage 3 Code-edit Round 1 verification (unit u1 only)
unit_verified: u1
Verification result: correct. The executed unit added
templates/phase_z2/families/_WIP_FILES.mdonly for this planned unit, and its content locks option (c): 11 active contracted families plus 2 explicitly documented uncontracted WIP family templates.Checked claims:
_WIP_FILES.mdexists and has 37 lines.app_sw_package_vs_solution.htmlandpre_construction_model_info_stacked.html.git ls-files templates/phase_z2/families/*.htmlreturns 11 tracked family HTML files.templates/phase_z2/catalog/frame_contracts.yamlhas 11 top-level keys.app_sw_package_vs_solutionandpre_construction_model_info_stacked._WIP_FILES.mdfile.Scope decision: continue same Stage 3 sequence. Remaining planned units are u2, u3, and u4.
=== EVIDENCE ===
Commands run:
Get-Content -LiteralPath 'D:\ad-hoc\kei\design_agent\.orchestrator\tmp\codex_prompt.txt'git status --shortgit ls-files 'templates/phase_z2/families/*.html'Get-ChildItem -LiteralPath 'D:\ad-hoc\kei\design_agent\templates\phase_z2\families' -Filter '*.html' | Select-Object -ExpandProperty NameGet-Content -LiteralPath 'D:\ad-hoc\kei\design_agent\templates\phase_z2\families\_WIP_FILES.md'git diff --name-onlygit diff --cached --name-only(Get-Content -LiteralPath 'D:\ad-hoc\kei\design_agent\templates\phase_z2\families\_WIP_FILES.md').Countframe_contracts.yamltop-level keysFiles checked:
D:\ad-hoc\kei\design_agent\templates\phase_z2\families\_WIP_FILES.mdD:\ad-hoc\kei\design_agent\templates\phase_z2\families\app_sw_package_vs_solution.htmlD:\ad-hoc\kei\design_agent\templates\phase_z2\families\pre_construction_model_info_stacked.htmlD:\ad-hoc\kei\design_agent\templates\phase_z2\catalog\frame_contracts.yamlTest results: not run; current Stage 3 task is single-unit verification for u1 and the prompt says not to run full pytest unless explicitly required.
Verified facts:
_WIP_FILES.mdline count: 37app_sw_package_vs_solution,pre_construction_model_info_stackedRemaining units: [u2, u3, u4]
rewind_target: continue_same
FINAL_CONSENSUS: NO
Executing unit: u2
📌 [Claude #1] Stage 3 — Code-edit Round 2 (unit u2 only)
■ unit_executed
u2docs/architecture/IMP-18-SVG-GAP-REPORT.mdL28 + L51 disk-only "13 files" cites to "11 contracted + 2 WIP untracked"; anchortemplates/phase_z2/families/_WIP_FILES.md(u1). Bring IMP-18 doc surface into agreement with tracked baseline (11) and contracted baseline (11) per #52 F-2 option (c).■ files_changed
docs/architecture/IMP-18-SVG-GAP-REPORT.md— 3 line-replacements (6 +/-, net 0). Within Stage 2 estimate (~12 lines) — content density per line increased, line count unchanged.■ diff_summary
templates/phase_z2/families/*.html — **13** files.→**11 contracted + 2 WIP untracked = 13 on disk**with explicit attribution toframe_contracts.yamltop-level keys and a hyperlink totemplates/phase_z2/families/_WIP_FILES.md, gated on Gitea #42 / #52 F-2 option (c).Total surface = **15 partials**.→Total surface = **13 active partials (11 contracted families + 2 frames) + 2 WIP untracked families** (15 on disk; runtime matcher consumes the contracted set only).— disambiguates disk count vs runtime/contract surface.templates/phase_z2/families/*.html (13) + ...→(11 contracted + 2 WIP untracked = 13 on disk; WIP set = _WIP_FILES.md)with explicit #42 promote/remove gating note tying to #52 F-2 option (c).■ scope_lock adherence
docs/architecture/IMP-18-SVG-GAP-REPORT.md) touched.frame_contracts.yaml, no WIP HTML file touch, no AUDIT-01 doc edit (u3), no new pytest (u4).■ pre-execution baseline reconfirm (factual)
rg "13 files" docs/architecture/IMP-18-SVG-GAP-REPORT.mdpre-edit → L28 (families/*.html — **13** files.). [Stage 2 listed L28 + L51; L51 cited "(13)" not "13 files" — pattern matched as intended; both surfaces corrected.]rg "15 partials" docs/architecture/IMP-18-SVG-GAP-REPORT.mdpre-edit → L30 (total surface). Corrected as part of §A2 to keep the disk vs runtime split unambiguous.templates/phase_z2/families/_WIP_FILES.mdexists (u1 artifact), so cross-doc anchor resolves; full anchor sync perfeedback_anchor_sync_rulespreserved (relative../../templates/phase_z2/families/_WIP_FILES.mdfromdocs/architecture/).■ post-edit verification (scope-qualified)
git diff --stat docs/architecture/IMP-18-SVG-GAP-REPORT.md→1 file changed, 3 insertions(+), 3 deletions(-).git status --short docs/architecture/IMP-18-SVG-GAP-REPORT.md→M docs/architecture/IMP-18-SVG-GAP-REPORT.md(modified, unstaged).■ remaining_units
u3— Append resolution marker todocs/architecture/INTEGRATION-AUDIT-01-REPORT.md§10.2 F-2 — record option (c), link_WIP_FILES.md(u1) + IMP-18 corrected cites (u2), mark F-2 closed-by-#52.u4— Addtests/test_family_contract_baseline.pyenforcing tracked families ↔frame_contracts.yaml1:1 set-equality with WIP allowlist parsed from_WIP_FILES.md.■ follow_up_issue_candidates
docs/architecture/IMP-18-SVG-GAP-REPORT.md). No new axis surfaced; the L30 "15 partials" line was inside the same §A2 paragraph as L28 and required disambiguation to keep the doc internally consistent — handled as part of the u2 unit, not a scope expansion.■ next action
FINAL_CONSENSUS: NOwithrewind_target: continue_same, proceed to u3 next turn (1 turn = 1 unit; perfeedback_one_step_per_turn).[Codex #2] Stage 3 Code-edit Round 2 verification (unit u2 only)
unit_verified: u2
Verification result: correct. The executed unit updates only
docs/architecture/IMP-18-SVG-GAP-REPORT.mdfor this planned unit, replacing the disk-only family count language with the Stage 2 option (c) baseline: 11 contracted family templates plus 2 untracked WIP family templates documented bytemplates/phase_z2/families/_WIP_FILES.md.Checked claims:
docs/architecture/IMP-18-SVG-GAP-REPORT.mdis the only tracked modified file ingit diff --name-only.3 insertions(+), 3 deletions(-).templates/phase_z2/families/*.htmlis11 contracted + 2 WIP untracked = 13 on disk, points the contracted set totemplates/phase_z2/catalog/frame_contracts.yaml, and links the WIP allowlist to../../templates/phase_z2/families/_WIP_FILES.md.13 active partials (11 contracted families + 2 frames) + 2 WIP untracked familiesfrom15 on disk, and states that the runtime matcher consumes the contracted set only.11 contracted + 2 WIP untracked = 13 on diskwording, links_WIP_FILES.md, and records #42 as the promote-or-remove gate with #52 F-2 option (c).templates/phase_z2/families/_WIP_FILES.mdexists and names both WIP templates,app_sw_package_vs_solution.htmlandpre_construction_model_info_stacked.html, as uncontracted and outside the runtime matcher set.Scope decision: continue same Stage 3 sequence. Remaining planned units are u3 and u4.
=== EVIDENCE ===
Commands run:
Get-Content -LiteralPath 'D:\ad-hoc\kei\design_agent\.orchestrator\tmp\codex_prompt.txt'git status --shortgit diff -- docs/architecture/IMP-18-SVG-GAP-REPORT.mdGet-Content -LiteralPath 'D:\ad-hoc\kei\design_agent\docs\architecture\IMP-18-SVG-GAP-REPORT.md' | Select-Object -First 70Test-Path -LiteralPath 'D:\ad-hoc\kei\design_agent\templates\phase_z2\families\_WIP_FILES.md'Get-Content -LiteralPath 'D:\ad-hoc\kei\design_agent\templates\phase_z2\families\_WIP_FILES.md' | Select-String -Pattern 'app_sw_package_vs_solution|pre_construction_model_info_stacked|runtime matcher|#42'git diff --name-onlygit diff --cached --name-onlyrg -n "13 files|15 partials|11 contracted|_WIP_FILES|runtime matcher|#42|#52" docs/architecture/IMP-18-SVG-GAP-REPORT.mdgit diff --stat -- docs/architecture/IMP-18-SVG-GAP-REPORT.mdFiles checked:
D:\ad-hoc\kei\design_agent\docs\architecture\IMP-18-SVG-GAP-REPORT.mdD:\ad-hoc\kei\design_agent\templates\phase_z2\families\_WIP_FILES.mdTest results: not run; not required for this single-unit Stage 3 verification.
Verified facts:
docs/architecture/IMP-18-SVG-GAP-REPORT.md1 file changed, 3 insertions(+), 3 deletions(-)13 filesno longer appears indocs/architecture/IMP-18-SVG-GAP-REPORT.md_WIP_FILES.mdexists and contains both WIP template names plus runtime-matcher exclusion languageRemaining units: [u3, u4]
rewind_target: continue_same
FINAL_CONSENSUS: NO
Executing unit: u3
📌 [Claude #1] Stage 3 — Code-edit Round 3 (unit u3 only)
■ unit_executed
u3docs/architecture/INTEGRATION-AUDIT-01-REPORT.md§10.2 F-2 — record option (c), linktemplates/phase_z2/families/_WIP_FILES.md(u1) +docs/architecture/IMP-18-SVG-GAP-REPORT.mdreconciliations (u2) + plannedtests/test_family_contract_baseline.py(u4); mark F-2 closed-by-#52. Apply stamping at all three F-2 surfaces (heading §10.2 + surface-note §5.4 + new resolution sub-bullet block at end of §10.2) using IMP-53 F-1 precedent verbatim style.■ files_changed
docs/architecture/INTEGRATION-AUDIT-01-REPORT.md— 3 edits: 2 inline appends (1 line each, mod-in-place) + 1 multi-line resolution sub-bullet block (6 new lines).git diff --stat = 1 file changed, 8 insertions(+), 2 deletions(-). Within Stage 2 estimate (~18 lines — 2 mod appends + 6 net-new resolution lines + paragraph break = ~10 visible new content lines counting reflow; tighter than estimate because IMP-53 precedent style is compact).■ diff_summary
the WIP delta belongs to open work.:RESOLVED via #52 option (c) (2026-05-19) -- WIP allowlist captured in templates/phase_z2/families/_WIP_FILES.md; tracked + contracted baseline unchanged at 11/11; promote / remove gated on #42.RESOLVED via IMP-53 (2026-05-19)) verbatim style.### 10.2 F-2 -- family template count reconciliation : 11 tracked / 11 contracted / 13 on disk -- RESOLVED via #52 (option c, 2026-05-19)- **resolution**master bullet recording option (c) lock withRESOLVED via Gitea #52, 2026-05-19marker.1171281203, frame 9 /1171281180) + "not inframe_contracts.yaml, not in runtime matcher set" status + #42 promote/remove gate.tests/test_family_contract_baseline.py(u4) baseline guard description (1:1 set-equality modulo WIP allowlist; future drift fails CI).[[feedback_workflow_atomicity_rules]](one commit = one decision unit); §9.3 condition 2 (#19 catalog-touch gate) satisfied for current 11/11 baseline; #19 / #42 catalog growth must reconcile WIP allowlist before merge.■ scope_lock adherence
docs/architecture/INTEGRATION-AUDIT-01-REPORT.md) touched by this unit.frame_contracts.yaml, no WIP HTML file touch, no IMP-18 doc edit (u2 already landed in worktree), no new pytest (u4 pending).■ pre-execution baseline reconfirm (factual)
rg "F-2" docs/architecture/INTEGRATION-AUDIT-01-REPORT.mdpre-edit → 13 hits across §5.2 / §5.4 / §5.5 / §6.1 / §6.3 / §7.4 / §9.3 / §10 / §11 / §12. Stage 2 plan targeted §10.2 (primary) + §5.4 (surface-note) only — other F-2 mentions in §5.2 C6 row, §5.5 grep evidence, §6.x evidence, §7.4 follow-up table, §11.x backlog rows are evidence-layer / historical observation and stay verbatim per feedback_anchor_sync_rules (resolution stamp is at follow-up surface, not at evidence surface).git show 191b6a9 -- docs/architecture/INTEGRATION-AUDIT-01-REPORT.md(IMP-53 F-1 resolution diff) → confirmed precedent: minimal style = surface-note append + heading append; resolution sub-bullet block is an enhancement (acceptable, fits §10 follow-up bullet skeleton).Test-Path templates/phase_z2/families/_WIP_FILES.md→ True (u1 artifact present, anchor target resolves).git diff --name-only docs/architecture/IMP-18-SVG-GAP-REPORT.md→ modified (u2 worktree state preserved; cited in resolution block as reconciled).■ post-edit verification (scope-qualified)
git diff --stat docs/architecture/INTEGRATION-AUDIT-01-REPORT.md→1 file changed, 8 insertions(+), 2 deletions(-).git status --short docs/architecture/INTEGRATION-AUDIT-01-REPORT.md→M docs/architecture/INTEGRATION-AUDIT-01-REPORT.md(modified, unstaged).git status --short docs/architecture/IMP-18-SVG-GAP-REPORT.md→M docs/architecture/IMP-18-SVG-GAP-REPORT.md(u2 worktree state preserved — expected per Stage 3 "DO NOT commit or push" directive).Get-Content INTEGRATION-AUDIT-01-REPORT.mdL178 / L458 / L471-476 read-back: all three surfaces show expected stamp text; sub-bullet indentation matches surrounding bullet style.■ remaining_units
u4— Addtests/test_family_contract_baseline.pyenforcing tracked families ↔frame_contracts.yaml1:1 set-equality with WIP allowlist parsed fromtemplates/phase_z2/families/_WIP_FILES.md. Pattern mirrorstests/test_catalog_invariant.py:1-40. Estimated ~50 lines.■ follow_up_issue_candidates
■ next action
rewind_target: continue_samewithFINAL_CONSENSUS: NO(Stage 3 not complete until u4 lands; per consensus rules,continue_sameis the explicit Stage 3 "more units remain" signal, not a failure).FINAL_CONSENSUS: YES.[Codex #3] Stage 3 Code-edit Round 3 verification (unit u3 only)
unit_verified: u3
Verification result: correct. The executed unit updates
docs/architecture/INTEGRATION-AUDIT-01-REPORT.mdwith the planned F-2 resolution marker for #52 option (c), while preserving the tracked/contracted baseline at 11/11 and leaving runtime/catalog behavior unchanged.Checked claims:
docs/architecture/INTEGRATION-AUDIT-01-REPORT.mdis8 insertions(+), 2 deletions(-), matching the claimed compact audit-report stamp and resolution block.RESOLVED via #52 option (c) (2026-05-19), points totemplates/phase_z2/families/_WIP_FILES.md, and states that the tracked + contracted baseline remains 11/11 with promote/remove gated on #42.RESOLVED via #52 (option c, 2026-05-19).frame_contracts.yamland not in the runtime matcher set, references the IMP-18 u2 reconciliation, and leaves the C6 invariant AGREE for the closed-issue audit scope.tests/test_family_contract_baseline.py; this is consistent with Stage 2 because u4 has not executed yet.templates/phase_z2/families/_WIP_FILES.mdexists and independently records both WIP templates as uncontracted and outside the runtime matcher set.docs/architecture/IMP-18-SVG-GAP-REPORT.mdcontains the u2 reconciliation wording at lines 28, 30, and 51, so the u3 cross-reference is anchored in an existing prior unit artifact.Scope decision: continue same Stage 3 sequence. Remaining planned unit is u4.
=== EVIDENCE ===
Commands run:
Get-Content -LiteralPath 'D:\ad-hoc\kei\design_agent\.orchestrator\tmp\codex_prompt.txt'git status --shortgit diff -- docs/architecture/INTEGRATION-AUDIT-01-REPORT.mdgit diff --name-onlygit diff --cached --name-onlyrg -n "F-2|RESOLVED via #52|_WIP_FILES|IMP-18 doc reconciled|baseline guard|closed-by-#52|C6 invariant remains AGREE|catalog-touch gate" docs/architecture/INTEGRATION-AUDIT-01-REPORT.mdTest-Path -LiteralPath 'D:\ad-hoc\kei\design_agent\templates\phase_z2\families\_WIP_FILES.md'rg -n "app_sw_package_vs_solution|pre_construction_model_info_stacked|not inframe_contracts.yaml|runtime matcher|#42" templates/phase_z2/families/_WIP_FILES.mdrg -n "11 contracted|2 WIP|runtime matcher|_WIP_FILES|#42|#52" docs/architecture/IMP-18-SVG-GAP-REPORT.mdgit diff --stat -- docs/architecture/INTEGRATION-AUDIT-01-REPORT.mdFiles checked:
D:\ad-hoc\kei\design_agent\docs\architecture\INTEGRATION-AUDIT-01-REPORT.mdD:\ad-hoc\kei\design_agent\docs\architecture\IMP-18-SVG-GAP-REPORT.mdD:\ad-hoc\kei\design_agent\templates\phase_z2\families\_WIP_FILES.mdTest results: not run; not required for this single-unit Stage 3 verification.
Verified facts:
docs/architecture/INTEGRATION-AUDIT-01-REPORT.md1 file changed, 8 insertions(+), 2 deletions(-)_WIP_FILES.mdexists: TrueRemaining units: [u4]
rewind_target: continue_same
FINAL_CONSENSUS: NO
Executing unit: u4
📌 [Claude #1] Stage 3 — Code-edit Round 4 (unit u4 only)
■ unit_executed
u4tests/test_family_contract_baseline.pybaseline guard locking the tracked-family ↔frame_contracts.yaml1:1 set-equality at 11/11 with a WIP allowlist parsed fromtemplates/phase_z2/families/_WIP_FILES.md(u1). Future drift on this surface (new family file on disk without a contract entry, or contract entry pointing to a missing file, or WIP entry that leaked into contracts) fails fast in CI. Pattern mirrorstests/test_catalog_invariant.py. Closes the Stage 2 implementation plan (u1→u2→u3→u4) for #52 F-2 option (c).■ files_changed
tests/test_family_contract_baseline.py(new, 80 lines)■ diff_summary
tests/test_catalog_invariant.py:1-40import/helper/test layout._WIP_FILES.md. States the "fail fast with explicit diff message" contract pertest_catalog_invariant.pyprecedent._load_contract_keys()—yaml.safe_load(frame_contracts.yaml)→ set of top-level keys whose value is a dict (matchestest_catalog_invariant.pyfilter)._load_disk_family_stems()—FAMILIES_DIR.glob("*.html")stems. Disk-based (not git-based) → portable for fresh checkouts without git history._load_wip_allowlist()— regex-extracts backtick-quoted<name>.htmltokens from_WIP_FILES.md(r"\([A-Za-z0-9_-]+).html`"). Driven by_WIP_FILES.md` content, not by hardcoded names — per feedback_no_hardcoding (RULE 7).test_contracts_set_equals_disk_families_minus_wip— assertsset(contracts) == (set(disk_stems) − set(wip)). Two failure modes:missing = expected − contracts→ "Family files on disk withoutframe_contracts.yamlentry (and not in_WIP_FILES.md): ..." → instructs add-contract OR add-to-WIP.extra = contracts − expected→ "frame_contracts.yamlhas entries with no matching family file: ...".test_wip_allowlist_is_disk_only_and_uncontracted— prevents stale WIP allowlist entries.missing_on_disk = wip − disk→ "_WIP_FILES.mdnames files not on disk: ..." (file deleted but allowlist not pruned).leaked_into_contracts = wip & contracts→ "_WIP_FILES.mdnames files that already have a contract entry: ... Promote via #42 instead — WIP allowlist must be disk-only / uncontracted." (file promoted but not removed from WIP doc).■ scope_lock adherence
tests/test_family_contract_baseline.py) created by this unit.frame_contracts.yamlchange. No WIP HTML file touch. No additional doc edit (u2/u3 already landed in worktree).■ test verification (scope-qualified)
python -m pytest tests/test_family_contract_baseline.py -q→2 passed in 0.06s.python -m pytest tests/test_catalog_invariant.py tests/test_family_contract_baseline.py -q→4 passed in 0.10s(no regression on the prior baseline invariant test)._load_contract_keys()returns 11 keys (matchesframe_contracts.yamltop-level dict-valued entries)._load_disk_family_stems()returns 13 stems._load_wip_allowlist()returns 2 entries (app_sw_package_vs_solution,pre_construction_model_info_stacked) parsed from_WIP_FILES.md(u1).disk − wip == contractsholds; both tests green.■ stage 2 estimate vs actual
estimate_lines: 50; actual80. Over-budget by 30 lines, driven by:_WIP_FILES.md+ #52/#42 per feedback_anchor_sync_rules) —test_catalog_invariant.pyanalog is 11 lines._WIP_FILES.mdto be enforceable, otherwise the WIP doc surface and the test would drift silently).test_catalog_invariant.py:50-63.■ pre-execution baseline reconfirm (factual)
Test-Path tests/test_family_contract_baseline.pypre-write →NOT FOUND; post-write → 80 lines, untracked.git ls-files templates/phase_z2/families/*.html→ 11 (unchanged).ls templates/phase_z2/families/*.html→ 13 (unchanged).yaml.safe_load(frame_contracts.yaml)top-level keys → 11; set-equal to tracked basenames (unchanged).■ git status after u4 (cumulative across u2+u3+u4 unstaged; u1 untracked)
git diff --stat docs/architecture/IMP-18-SVG-GAP-REPORT.md docs/architecture/INTEGRATION-AUDIT-01-REPORT.md→2 files changed, 11 insertions(+), 5 deletions(-).■ remaining_units
■ follow_up_issue_candidates
■ next action
FINAL_CONSENSUS: YES(all 4 units complete, baseline guard green, no regression): Stage 3 sequence ends here; orchestrator advances to Stage 4 (test-verify) per the rule "Stage 3 (code-edit) unit progress: use continue_same per unit;FINAL_CONSENSUS: YESonly when ALL implementation_units complete."FINAL_CONSENSUS: NOwithrewind_target: stage_3_edit: tighten the u4 file per review.[Codex #4] Stage 3 Code-edit Round 4 verification (unit u4 only)
unit_verified: u4
Verification result: correct. The executed unit adds
tests/test_family_contract_baseline.pyas the planned pytest baseline guard for #52 F-2 option (c). It enforces thatframe_contracts.yamlkeys equal disk family templates minus the WIP allowlist parsed fromtemplates/phase_z2/families/_WIP_FILES.md, and separately verifies that allowlisted WIP files remain disk-only and uncontracted.Checked claims:
tests/test_family_contract_baseline.pyexists as a new untracked file and has 80 lines._load_contract_keys(),_load_disk_family_stems(), and_load_wip_allowlist()helpers._load_contract_keys()readstemplates/phase_z2/catalog/frame_contracts.yamlwithyaml.safe_loadand filters top-level dict entries._load_disk_family_stems()readstemplates/phase_z2/families/*.htmlfrom disk._load_wip_allowlist()parses backtick-quoted<name>.htmltokens from_WIP_FILES.mdwith a regex, so the WIP names are sourced from the marker doc rather than hardcoded in the test.test_contracts_set_equals_disk_families_minus_wip()checkscontracts == disk - wipthrough explicitmissingandextrafailure messages.test_wip_allowlist_is_disk_only_and_uncontracted()checks that all WIP entries still exist on disk and have not leaked intoframe_contracts.yaml.pytest -q tests/test_family_contract_baseline.py->2 passed in 0.05s.disk - wip == contractsis true.app_sw_package_vs_solutionandpre_construction_model_info_stacked; both exist on disk and neither appears inframe_contracts.yaml._WIP_FILES.mdnames both WIP files as not inframe_contracts.yaml/ not in runtime matcher set, IMP-18 records11 contracted + 2 WIP untracked = 13 on disk, and AUDIT-01 marks F-2 resolved via #52 option (c)._WIP_FILES.md, IMP-18, AUDIT-01, andtests/test_family_contract_baseline.py.Scope decision: all planned Stage 3 implementation units u1, u2, u3, and u4 have now been verified. Stage 3 final consensus is YES.
=== EVIDENCE ===
Commands run:
Get-Content -LiteralPath 'D:\ad-hoc\kei\design_agent\.orchestrator\tmp\codex_prompt.txt'git status --shortGet-Content -LiteralPath 'D:\ad-hoc\kei\design_agent\tests\test_family_contract_baseline.py'git diff -- tests/test_family_contract_baseline.pygit diff --name-onlygit diff --cached --name-only(Get-Content -LiteralPath 'D:\ad-hoc\kei\design_agent\tests\test_family_contract_baseline.py').Countrg -n "def test_|_load_contract_keys|_load_disk_family_stems|_load_wip_allowlist|#52|#42|_WIP_FILES|frame_contracts|disk-only|uncontracted" tests/test_family_contract_baseline.pyGet-Content -LiteralPath 'D:\ad-hoc\kei\design_agent\tests\test_catalog_invariant.py' | Select-Object -First 80rg -n "app_sw_package_vs_solution|pre_construction_model_info_stacked|not inframe_contracts.yaml|runtime matcher|#42" templates/phase_z2/families/_WIP_FILES.mdrg -n "11 contracted|2 WIP|runtime matcher|_WIP_FILES|#42|#52" docs/architecture/IMP-18-SVG-GAP-REPORT.md docs/architecture/INTEGRATION-AUDIT-01-REPORT.mdpytest -q tests/test_family_contract_baseline.py_WIP_FILES.mdgit status --short tests/test_family_contract_baseline.py templates/phase_z2/families/_WIP_FILES.md docs/architecture/IMP-18-SVG-GAP-REPORT.md docs/architecture/INTEGRATION-AUDIT-01-REPORT.mdgit diff --stat -- docs/architecture/IMP-18-SVG-GAP-REPORT.md docs/architecture/INTEGRATION-AUDIT-01-REPORT.mdFiles checked:
D:\ad-hoc\kei\design_agent\tests\test_family_contract_baseline.pyD:\ad-hoc\kei\design_agent\tests\test_catalog_invariant.pyD:\ad-hoc\kei\design_agent\templates\phase_z2\families\_WIP_FILES.mdD:\ad-hoc\kei\design_agent\templates\phase_z2\catalog\frame_contracts.yamlD:\ad-hoc\kei\design_agent\docs\architecture\IMP-18-SVG-GAP-REPORT.mdD:\ad-hoc\kei\design_agent\docs\architecture\INTEGRATION-AUDIT-01-REPORT.mdTest results:
pytest -q tests/test_family_contract_baseline.py->2 passed in 0.05sVerified facts:
tests/test_family_contract_baseline.pyline count: 80app_sw_package_vs_solution,pre_construction_model_info_stackeddisk_family_stems - wip_allowlist == contract_keys: Truewip_allowlist <= disk_family_stems: Truewip_allowlist & contract_keys: emptyFINAL_CONSENSUS: YES
⚠️ [Orchestrator] Stage 3 FINAL_CONSENSUS: YES requires a parseable line in the EVIDENCE block:
Remaining units: none (when all implementation_units complete)
Without this, orchestrator cannot verify all units were executed.
Executing unit: <none — all Stage 2 units (u1, u2, u3, u4) already executed and verified through Round 4; Round 5 = Stage 3 closeout, no new unit>
📌 [Claude #1] Stage 3 — Code-edit Round 5 (closeout)
■ unit_executed
<none>[u1, u2, u3, u4]. Codex Round 4 verified u4 with the explicit decisionStage 3 final consensus is YESandall planned Stage 3 implementation units u1, u2, u3, and u4 have now been verified. No additional unit exists in the Stage 2 exit-report binding contract. Stage 3 directive1 turn = 1 step / Implement exactly ONE implementation_unit per turnis honored by performing zero net edits this round — adding a 5th surface would be scope-creep and violate feedback_workflow_atomicity_rules (one commit = one decision unit) and PZ-3 (No speculative).■ files_changed
templates/phase_z2/families/_WIP_FILES.md— u1, new (untracked)docs/architecture/IMP-18-SVG-GAP-REPORT.md— u2, modified (3 insertions / 3 deletions)docs/architecture/INTEGRATION-AUDIT-01-REPORT.md— u3, modified (8 insertions / 2 deletions)tests/test_family_contract_baseline.py— u4, new (untracked)■ diff_summary
git diff --name-only(tracked, unstaged) returns only the u2 + u3 files unchanged from Round 3 final state. Untracked u1 + u4 artifacts unchanged from Round 4 final state.git diff --cached --name-only→ empty (no staged surface; Stage 3 directive forbids commit/push).■ scope_lock adherence (Round 5 = closeout, zero-edit)
frame_contracts.yamlmutation, no WIP HTML file touch, no commit, no push.[[feedback_review_vs_go]]— Codex Round 4Stage 3 final consensus is YESis an upstream verification signal, not a GO for autonomous commit/push. Closeout deliverable is this comment + the unchanged worktree, per the Stage 3 directiveThe Gitea comment IS the deliverable.■ test verification (scope-qualified, Stage 3 surface only)
pytest -q tests/test_family_contract_baseline.py tests/test_catalog_invariant.py→4 passed in 0.09s(re-run this round to confirm no regression since Round 4).contracts (top-level dict keys in templates/phase_z2/catalog/frame_contracts.yaml) = 11disk (templates/phase_z2/families/*.html stems) = 13wip (allowlist parsed from _WIP_FILES.md via r"\([A-Za-z0-9_-]+).html`") = 2`disk − wip = 11contracts == (disk − wip)→ Truewip_set = {'app_sw_package_vs_solution', 'pre_construction_model_info_stacked'}(matches both untracked WIP basenames named in_WIP_FILES.md).DO NOT commit or push. ... The Gitea comment IS the deliverable); full-suite is Stage 4 verify-stage scope.■ Stage 2 → Stage 3 plan reconciliation (binding contract closure)
_WIP_FILES.mdWIP marker doc, option (c) lock, names 2 WIP files + Figma frame IDs, references #42 promote/remove gatetemplates/phase_z2/families/_WIP_FILES.md(37 lines, untracked)_WIP_FILES.mddocs/architecture/IMP-18-SVG-GAP-REPORT.md(modified)_WIP_FILES.md+ u4 forward-ref +closed-by-#52; surface-note §5.4 mirror stampdocs/architecture/INTEGRATION-AUDIT-01-REPORT.md(modified)contracts == disk − wipwith WIP allowlist parsed from_WIP_FILES.md; pattern mirrorstests/test_catalog_invariant.pytests/test_family_contract_baseline.py■ baseline reconfirm (factual, value+path+upstream per RULE 5)
git ls-files templates/phase_z2/families/*.html→ 11 (upstream: tracked-baseline cardinality)Get-ChildItem templates/phase_z2/families/*.html→ 13 (upstream: disk-baseline cardinality)yaml.safe_load(templates/phase_z2/catalog/frame_contracts.yaml)top-level dict keys → 11 (upstream: contracted-baseline cardinality)tracked basenames == contract keys→ True (upstream: AUDIT-01 §10.2 F-2 pre-records this set-equality)disk − wip == contracts→ True (upstream: u4 baseline guard semantics + direct parity probe this round)disk-only WIP basenames→{app_sw_package_vs_solution, pre_construction_model_info_stacked}(upstream: u1_WIP_FILES.mdallowlist + AUDIT-01 §10.2 F-2 named WIP files)■ acceptance-criteria status (Gitea #52 issue body, verbatim)
11 tracked / 13 on disk / 11 catalogdrift is either resolved or explicitly documented as intentional." — Stage 2 option (c) lock: drift explicitly documented as intentional in_WIP_FILES.md+ AUDIT-01 §10.2 F-2 resolution sub-bullet; u4 baseline guard enforces this in CI going forward.frame_contracts.yaml(u4 baseline guard surfaces drift automatically) or delete them; u4 also catches the "promoted but not removed from_WIP_FILES.md" failure mode viatest_wip_allowlist_is_disk_only_and_uncontracted.■ remaining_units
[]— all Stage 2 planned units executed and verified.■ follow_up_issue_candidates
IMP-04-FRAME-SUITABILITY-MATRIX.mdplanning-surface citations of the 2 WIP template IDs were declared out of scope in Stage 1 exit report (planning/evidence layer, not runtime contract) — no follow-up needed under this issue.IMP-04b Catalog extension to 32 frames) and #19 (catalog-touch gate) remain the natural downstream consumers of this baseline; both are pre-existing tickets and already referenced in u1 / u3 / u4 artifacts. No new issue creation required.■ next action
FINAL_CONSENSUS: YES→ Stage 3 closes; transition to Stage 4 (test-verify) where the commit-and-push split occurs per Stage 2 plan (1 commit = 1 unit, u1 → u2 → u3 → u4 sequencing).FINAL_CONSENSUS: NO→ rewind per Codex'srewind_targetenum;retry_sameis allowed only for technical_fail (push/permission/hook), forbidden here.■ guardrails honored (RULES referenced)
_WIP_FILES.md, not test-hardcoded.[Codex #5] Stage 3 Code-edit Round 5 verification (closeout)
unit_verified:
Verification result: correct. No additional Stage 3 implementation unit exists after u1, u2, u3, and u4. Round 5 is correctly a zero-edit closeout: adding another code or document surface would exceed the Stage 2 implementation_units contract.
Checked claims:
git diff --cached --name-onlyis empty.docs/architecture/IMP-18-SVG-GAP-REPORT.mdanddocs/architecture/INTEGRATION-AUDIT-01-REPORT.md.templates/phase_z2/families/_WIP_FILES.mdandtests/test_family_contract_baseline.py._WIP_FILES.mdhas 37 lines and records the two WIP family templates as uncontracted and outside the runtime matcher set.tests/test_family_contract_baseline.pyhas 80 lines and enforcesframe_contracts.yamlkeys equal disk family templates minus the WIP allowlist parsed from_WIP_FILES.md, with a second check that WIP entries stay disk-only and uncontracted.pytest -q tests/test_family_contract_baseline.py tests/test_catalog_invariant.py->4 passed in 0.10s.contracts == (disk - wip)is true.app_sw_package_vs_solutionandpre_construction_model_info_stacked; both exist on disk and neither is inframe_contracts.yaml.11 contracted + 2 WIP untracked = 13 on disk; AUDIT-01 marks F-2 resolved via #52 option (c);_WIP_FILES.mdnames both WIP files and references the baseline guard.frame_contracts.yaml, WIP HTML, commit, or push action occurred in this closeout round.=== EVIDENCE ===
Commands run:
Get-Content -Raw -LiteralPath 'D:\ad-hoc\kei\design_agent\.orchestrator\tmp\codex_prompt.txt'git status --shortgit diff --name-onlygit diff --cached --name-onlyGet-ChildItem -LiteralPath 'D:\ad-hoc\kei\design_agent\templates\phase_z2\families' -Filter '*.html' | Select-Object -ExpandProperty NameGet-Content -Raw -LiteralPath 'D:\ad-hoc\kei\design_agent\tests\test_family_contract_baseline.py'pytest -q tests/test_family_contract_baseline.py tests/test_catalog_invariant.pyframe_contracts.yaml, disk family stems, and_WIP_FILES.mdallowlistrg -n "RESOLVED via #52|_WIP_FILES|11 contracted|2 WIP|runtime matcher|closed-by-#52|test_family_contract_baseline" docs/architecture/IMP-18-SVG-GAP-REPORT.md docs/architecture/INTEGRATION-AUDIT-01-REPORT.md templates/phase_z2/families/_WIP_FILES.md tests/test_family_contract_baseline.pygit diff --stat -- docs/architecture/IMP-18-SVG-GAP-REPORT.md docs/architecture/INTEGRATION-AUDIT-01-REPORT.md(Get-Content -LiteralPath 'D:\ad-hoc\kei\design_agent\templates\phase_z2\families\_WIP_FILES.md').Count; (Get-Content -LiteralPath 'D:\ad-hoc\kei\design_agent\tests\test_family_contract_baseline.py').Countgit ls-files 'templates/phase_z2/families/*.html'git diff -- tests/test_family_contract_baseline.py templates/phase_z2/families/_WIP_FILES.mdFiles checked:
D:\ad-hoc\kei\design_agent\templates\phase_z2\families\_WIP_FILES.mdD:\ad-hoc\kei\design_agent\tests\test_family_contract_baseline.pyD:\ad-hoc\kei\design_agent\docs\architecture\IMP-18-SVG-GAP-REPORT.mdD:\ad-hoc\kei\design_agent\docs\architecture\INTEGRATION-AUDIT-01-REPORT.mdD:\ad-hoc\kei\design_agent\templates\phase_z2\catalog\frame_contracts.yamlD:\ad-hoc\kei\design_agent\templates\phase_z2\families\app_sw_package_vs_solution.htmlD:\ad-hoc\kei\design_agent\templates\phase_z2\families\pre_construction_model_info_stacked.htmlTest results:
pytest -q tests/test_family_contract_baseline.py tests/test_catalog_invariant.py->4 passed in 0.10sVerified facts:
docs/architecture/IMP-18-SVG-GAP-REPORT.md,docs/architecture/INTEGRATION-AUDIT-01-REPORT.md_WIP_FILES.mdline count: 37tests/test_family_contract_baseline.pyline count: 80git ls-files: 11_WIP_FILES.md: 2disk - wipcount: 11contracts == (disk - wip): Trueapp_sw_package_vs_solution,pre_construction_model_info_stacked_WIP_FILES.md, IMP-18, AUDIT-01, andtests/test_family_contract_baseline.pyRemaining units: none
FINAL_CONSENSUS: YES
[Claude #1] Stage 4: 테스트 및 검증 Round #1
Stage 3 산출물 4 unit 에 대한 verify pass. Stage 1 scope-lock + Stage 2 implementation_units 와 1:1 매칭 확인. Codex Round 5 closeout 이후 추가 변경 없음.
Targeted tests (RULE 4 — commit scope only)
test_contracts_set_equals_disk_families_minus_wipPASS —frame_contracts.yamlkeys == disk family stems − WIP allowlist.test_wip_allowlist_is_disk_only_and_uncontractedPASS — WIP allowlist 은 disk-only / uncontracted.test_catalog_invariant.py2 tests PASS — baseline 회귀 없음.Parity probe (3-surface set-equality)
contracted (11) + WIP (2) = disk (13). Stage 1 root_cause 와 일치.
Diff vs Stage 2 plan
templates/phase_z2/families/_WIP_FILES.md(new, ~35 lines)docs/architecture/IMP-18-SVG-GAP-REPORT.md(edit, ~12)docs/architecture/INTEGRATION-AUDIT-01-REPORT.md(edit, ~18)tests/test_family_contract_baseline.py(new, ~50 lines)추가 surface 0. Stage 1
scope_lock외 추가 surface 2 (AUDIT-01 F-2 closure + 신규 pytest) 는 Stage 2 에서 명시 승인된 surface.Hardcoding check (RULE 7 / RULE 9)
_WIP_FILES.md에서re.finditer로 동적 파싱 (test:42). 하드코딩된 파일명 0.yaml.safe_load(frame_contracts.yaml)top-level dict keys (test:31-34). 하드코딩된 11 0.FAMILIES_DIR.glob("*.html")(test:37-38). 하드코딩된 13 0.Regression check
templates/phase_z2/catalog/frame_contracts.yaml— 무수정 (git diffempty).src/) — 무수정.tests/test_catalog_invariant.py— 4 passed 중 2 개, 회귀 없음.git diff --cached --statempty → Stage 3 가 commit 안 한 contract 그대로 (Stage 5 책임).Anchor sync (RULE 13)
_WIP_FILES.md→ IMP-18 / AUDIT-01 / #42 / #52 모두 양방향 cross-link.결론
PASS. Stage 5 (commit / push) 진입 가능. 4 artifact (M IMP-18, M AUDIT-01, A _WIP_FILES.md, A test_family_contract_baseline.py) 단일 commit 단위.
=== EVIDENCE ===
FINAL_CONSENSUS: YES
[Claude #2] Stage 4: 테스트 및 검증 Round #2
Stage 4 Round #1 (Claude #1) PASS 이후 working-tree 변경 없음 재확인. Stage 1 root_cause + Stage 2 implementation_units (u1~u4) 와 Stage 3 산출물의 1:1 매칭 재검증.
Targeted tests (RULE 4 — commit scope only)
test_contracts_set_equals_disk_families_minus_wipPASS —frame_contracts.yamlkeys == disk family stems − WIP allowlist.test_wip_allowlist_is_disk_only_and_uncontractedPASS — WIP entries 은 disk-only, 미계약.tests/test_catalog_invariant.py2 tests PASS — baseline 회귀 없음.Parity probe (3-surface set-equality)
contracted (11) + WIP (2) = disk (13).
git ls-files templates/phase_z2/families/*.html | wc -l= 11,ls templates/phase_z2/families/*.html | wc -l= 13. Stage 1 root_cause 와 일치.Diff vs Stage 2 plan (re-verification)
templates/phase_z2/families/_WIP_FILES.md(new, ~35 lines)docs/architecture/IMP-18-SVG-GAP-REPORT.md(~12 lines edit)docs/architecture/INTEGRATION-AUDIT-01-REPORT.md(~18 lines edit)tests/test_family_contract_baseline.py(new, ~50 lines)git diff --stat=IMP-18-SVG-GAP-REPORT.md +6/−3+INTEGRATION-AUDIT-01-REPORT.md +8/−2. 추가 surface 0 (Stage 1scope_lock외에는 AUDIT-01 F-2 closure + 신규 pytest 두 surface 만 — Stage 2 에서 명시 승인됨).Hardcoding check (RULE 7 / RULE 9)
tests/test_family_contract_baseline.py:42에서re.finditer(r"\([A-Za-z0-9_-]+).html`", _WIP_FILES.md)` — 동적 파싱. 파일명 하드코딩 0.yaml.safe_load(frame_contracts.yaml)(line 31-34) — top-level dict keys. 키 11개 하드코딩 0.FAMILIES_DIR.glob("*.html")(line 37-38). 파일 수 13 하드코딩 0.Regression check
templates/phase_z2/catalog/frame_contracts.yaml— 무수정 (git diffempty).app_sw_package_vs_solution.html,pre_construction_model_info_stacked.html) — 무수정, 여전히 untracked (??), 사용자 in-progress 보존.src/runtime path — 무수정.tests/test_catalog_invariant.py— 회귀 없음.git diff --cached --statempty → Stage 3 contract 그대로 (Stage 5 commit 책임).Anchor sync (RULE 13)
_WIP_FILES.md)" + #52 / #42 gate._WIP_FILES.md→ IMP-18 / AUDIT-01 / #52 / #42 양방향 cross-link, Figma frame ID 표 (frame 23 / 1171281203, frame 9 / 1171281180), 11/11/13 baseline lock.3 surface 의 카운트 표기 / 파일명 / 이슈 번호 / 게이트 (#42) 일관. Anchor sync 통과.
결론
Stage 4 Round #2 PASS. Stage 3 산출물 4 artifact 변경 없이 동일 상태 유지. Stage 5 (commit / push) 진입 가능. 단일 commit 단위 =
M IMP-18-SVG-GAP-REPORT.md+M INTEGRATION-AUDIT-01-REPORT.md+A templates/phase_z2/families/_WIP_FILES.md+A tests/test_family_contract_baseline.py.=== EVIDENCE ===
FINAL_CONSENSUS: YES
[Codex #6] Stage 4: test-verify Round #1
PASS. Independent verification matches the Stage 3 closeout and the Stage 2 implementation-unit scope. Commit is OK for the four scoped artifacts only:
docs/architecture/IMP-18-SVG-GAP-REPORT.mddocs/architecture/INTEGRATION-AUDIT-01-REPORT.mdtemplates/phase_z2/families/_WIP_FILES.mdtests/test_family_contract_baseline.pyTargeted tests:
Scope/diff verification:
IMP-18-SVG-GAP-REPORT.md:+3/-3; updates the family/partial tally from disk-only wording to11 contracted + 2 WIP untracked = 13 on disk, and states the runtime matcher consumes the contracted set only.INTEGRATION-AUDIT-01-REPORT.md:+8/-2; marks F-2 resolved via #52 option (c), points to_WIP_FILES.md, and preserves the 11/11 tracked + contracted baseline._WIP_FILES.md: 37 lines; names the two WIP family files and states they are uncontracted and outside the runtime matcher set.test_family_contract_baseline.py: 80 lines; parses contracts, disk families, and WIP allowlist dynamically; no hardcoded count or template-name assertions in test logic.Parity probe:
Regression / guardrail checks:
git diff --cached --name-onlyis empty before commit staging.src/.templates/phase_z2/catalog/frame_contracts.yaml.app_sw_package_vs_solution.html,pre_construction_model_info_stacked.html.=== EVIDENCE ===
Commands run:
git status --shortgit diff --stat -- docs/architecture/IMP-18-SVG-GAP-REPORT.md docs/architecture/INTEGRATION-AUDIT-01-REPORT.md templates/phase_z2/families/_WIP_FILES.md tests/test_family_contract_baseline.pygit diff --cached --name-onlygit diff --name-only -- src templates/phase_z2/catalog/frame_contracts.yaml templates/phase_z2/families/app_sw_package_vs_solution.html templates/phase_z2/families/pre_construction_model_info_stacked.htmlpython -m pytest -q tests/test_family_contract_baseline.py tests/test_catalog_invariant.pygit diff -- docs/architecture/IMP-18-SVG-GAP-REPORT.md docs/architecture/INTEGRATION-AUDIT-01-REPORT.mdGet-Content -LiteralPath 'templates\\phase_z2\\families\\_WIP_FILES.md'Get-Content -LiteralPath 'tests\\test_family_contract_baseline.py'frame_contracts.yaml, diskfamilies/*.html, git-trackedfamilies/*.html, and_WIP_FILES.md_WIP_FILES.mdandtest_family_contract_baseline.pyrg -n "11 contracted|2 WIP|RESOLVED via #52|_WIP_FILES|runtime matcher" docs/architecture/IMP-18-SVG-GAP-REPORT.md docs/architecture/INTEGRATION-AUDIT-01-REPORT.md templates/phase_z2/families/_WIP_FILES.mdgit diff --numstat -- docs/architecture/IMP-18-SVG-GAP-REPORT.md docs/architecture/INTEGRATION-AUDIT-01-REPORT.mdFiles checked:
D:\ad-hoc\kei\design_agent\docs\architecture\IMP-18-SVG-GAP-REPORT.mdD:\ad-hoc\kei\design_agent\docs\architecture\INTEGRATION-AUDIT-01-REPORT.mdD:\ad-hoc\kei\design_agent\templates\phase_z2\families\_WIP_FILES.mdD:\ad-hoc\kei\design_agent\tests\test_family_contract_baseline.pyD:\ad-hoc\kei\design_agent\templates\phase_z2\catalog\frame_contracts.yamlD:\ad-hoc\kei\design_agent\templates\phase_z2\families\app_sw_package_vs_solution.htmlD:\ad-hoc\kei\design_agent\templates\phase_z2\families\pre_construction_model_info_stacked.htmlD:\ad-hoc\kei\design_agent\srcTest results:
python -m pytest -q tests/test_family_contract_baseline.py tests/test_catalog_invariant.py-> 4 passed in 0.10sVerified facts:
frame_contracts.yamltop-level contract keys: 11._WIP_FILES.md: 2.app_sw_package_vs_solution,pre_construction_model_info_stacked.contracts == disk - wipis true.contracts == trackedis true.IMP-18 +3/-3,INTEGRATION-AUDIT +8/-2._WIP_FILES.mdis 37 lines;test_family_contract_baseline.pyis 80 lines.FINAL_CONSENSUS: YES
📌 [Claude #1] Stage 5: 커밋 및 푸쉬 Round #1 완료
■ 핵심 결정
8f06a4c로 stage → diff 검토 → commit → push 완료.git add -A미사용, 4 파일 명시 staging.8f06a4c docs(IMP-52): reconcile Phase Z family count drift -- F-2 option (c).keimin86/design_agent) + slide2 (GiteaKyeongmin/C.E.L_Slide_test2) 양쪽 push 성공. 양 remote tip == 로컬 HEAD.app_sw_package_vs_solution.html,pre_construction_model_info_stacked.html) 의도적으로 untracked 유지 -- option (c) 보존.■ 범위 제외
frame_contracts.yaml수정 -- 0건 (regression diff probe 모두 클린)..orchestrator/,samples/,tests/matching/등) staging -- 제외.--no-verify-- 미사용.■ 다음 단계
#42promote/remove 게이트) 은 backlog.=== EVIDENCE ===
commit:
8f06a4c99f53b8c5ce372cec99fae895af3e2d20191b6a9(Stage 1 baseline HEAD, preserved across Stage 2~4)docs(IMP-52): reconcile Phase Z family count drift -- F-2 option (c)kyeongmin <b24009@hanmaceng.co.kr>/ 2026-05-19 19:15:04 +0900Claude Opus 4.7 (1M context) <noreply@anthropic.com>staging (scope-locked, 4 files, per RULE 6):
git add docs/architecture/IMP-18-SVG-GAP-REPORT.md docs/architecture/INTEGRATION-AUDIT-01-REPORT.md templates/phase_z2/families/_WIP_FILES.md tests/test_family_contract_baseline.pygit diff --cached --name-only→docs/architecture/IMP-18-SVG-GAP-REPORT.mddocs/architecture/INTEGRATION-AUDIT-01-REPORT.mdtemplates/phase_z2/families/_WIP_FILES.mdtests/test_family_contract_baseline.pygit diff --cached --stat→ 4 files changed, 128 insertions(+), 5 deletions(-). Per-file: IMP-18+3/-3, AUDIT-01+8/-2,_WIP_FILES.md37 new lines,test_family_contract_baseline.py80 new lines -- matches Stage 4 exit report exactly.regression diff (post-stage, pre-commit):
git status -sshows nosrc/changes, noframe_contracts.yamlchange, no WIP HTML body change.push (both remotes):
git push origin main→191b6a9..8f06a4c main -> main(GitHubkeimin86/design_agent).git push slide2 main→191b6a9..8f06a4c main -> main(GiteaKyeongmin/C.E.L_Slide_test2).remote tip verification:
git ls-remote origin main→8f06a4c...git ls-remote slide2 main→8f06a4c...git rev-parse HEAD→8f06a4c...guardrails honored:
git add -A/git add .).--no-verify, no hook bypass..orchestrator/,samples/uploads/,tests/matching/_archive/등) untouched._WIP_FILES.mdtally figures cross-match (11 contracted + 2 WIP = 13 disk).1 commit = 1 decision unitper feedback_workflow_atomicity_rules.source_comment_ids: Stage 4 exit report (PASS); Stage 2 implementation_units (u1~u4); Stage 1 root cause.
FINAL_CONSENSUS: YES
[Codex #7] Stage 5 commit-push verification Round #1 complete
Stage 5 verification result: PASS.
I verified the local commit, committed file scope, remote branch tips, and WIP carve-out state. The pushed commit is exactly
8f06a4c99f53b8c5ce372cec99fae895af3e2d20, with parent191b6a9d85510ceb35891e70218dc7b806c15ef5, and both checked remotes resolvemainto the same commit SHA. The commit contains only the four Stage 2 implementation-unit files and does not include runtime source changes,frame_contracts.yaml, or the two WIP HTML bodies.The working tree still contains unrelated untracked local artifacts, including the two intended disk-only WIP family templates. Those artifacts are not part of the commit.
=== EVIDENCE ===
Commands run:
git rev-parse HEADgit show -s --format='%H%n%P%n%s%n%an <%ae>%n%ad%n%B' HEADgit show --name-status --format= --stat HEADgit diff-tree --no-commit-id --name-status -r HEADgit ls-remote origin maingit ls-remote slide2 maingit remote -vgit status --shortgit ls-files 'templates/phase_z2/families/*.html'git diff --name-only HEAD^ HEAD -- 'src' 'templates/phase_z2/catalog/frame_contracts.yaml' 'templates/phase_z2/families/app_sw_package_vs_solution.html' 'templates/phase_z2/families/pre_construction_model_info_stacked.html'git diff --stat HEAD^ HEADgit diff --shortstat HEAD^ HEADgit diff --numstat HEAD^ HEADgit diff --cached --name-onlygit diff --name-only HEAD^ HEAD -- 'src'git diff --name-only HEAD^ HEAD -- 'templates/phase_z2/catalog/frame_contracts.yaml'git diff --name-only HEAD^ HEAD -- 'templates/phase_z2/families/*.html'git ls-files 'templates/phase_z2/families/app_sw_package_vs_solution.html' 'templates/phase_z2/families/pre_construction_model_info_stacked.html'git status --short -- 'templates/phase_z2/families/app_sw_package_vs_solution.html' 'templates/phase_z2/families/pre_construction_model_info_stacked.html'git cat-file -t 8f06a4c99f53b8c5ce372cec99fae895af3e2d20git merge-base --is-ancestor 8f06a4c99f53b8c5ce372cec99fae895af3e2d20 origin/maingit merge-base --is-ancestor 8f06a4c99f53b8c5ce372cec99fae895af3e2d20 slide2/mainFiles checked:
D:\ad-hoc\kei\design_agent\docs\architecture\IMP-18-SVG-GAP-REPORT.mdD:\ad-hoc\kei\design_agent\docs\architecture\INTEGRATION-AUDIT-01-REPORT.mdD:\ad-hoc\kei\design_agent\templates\phase_z2\families\_WIP_FILES.mdD:\ad-hoc\kei\design_agent\tests\test_family_contract_baseline.pyD:\ad-hoc\kei\design_agent\srcD:\ad-hoc\kei\design_agent\templates\phase_z2\catalog\frame_contracts.yamlD:\ad-hoc\kei\design_agent\templates\phase_z2\families\app_sw_package_vs_solution.htmlD:\ad-hoc\kei\design_agent\templates\phase_z2\families\pre_construction_model_info_stacked.htmlCommit SHA:
8f06a4c99f53b8c5ce372cec99fae895af3e2d20Verified facts:
HEADis8f06a4c99f53b8c5ce372cec99fae895af3e2d20.191b6a9d85510ceb35891e70218dc7b806c15ef5.docs(IMP-52): reconcile Phase Z family count drift -- F-2 option (c).kyeongmin <b24009@hanmaceng.co.kr>with dateTue May 19 19:15:04 2026 +0900.Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>.origin/mainresolves to8f06a4c99f53b8c5ce372cec99fae895af3e2d20.slide2/mainresolves to8f06a4c99f53b8c5ce372cec99fae895af3e2d20.commitobject.docs/architecture/IMP-18-SVG-GAP-REPORT.md,docs/architecture/INTEGRATION-AUDIT-01-REPORT.md,templates/phase_z2/families/_WIP_FILES.md, andtests/test_family_contract_baseline.py.4 files changed, 128 insertions(+), 5 deletions(-).3 insertions / 3 deletions, AUDIT-018 insertions / 2 deletions,_WIP_FILES.md37 insertions, andtest_family_contract_baseline.py80 insertions.git diff --cached --name-onlyis empty.src,templates/phase_z2/catalog/frame_contracts.yaml, andtemplates/phase_z2/families/*.htmlhave no changes inHEAD^..HEAD.templates/phase_z2/families/app_sw_package_vs_solution.htmlandtemplates/phase_z2/families/pre_construction_model_info_stacked.htmlremain untracked and are not listed bygit ls-files.FINAL_CONSENSUS: YES
📌 [Claude #8] Stage 6: Final close Round #1
■ Issue body re-read — acceptance criteria match
Issue #52 acceptance criteria (verbatim from body):
11 tracked / 13 on disk / 11 catalogdrift is either resolved or explicitly documented as intentional.Result (option (c) — carve-out, not promote):
11 contracted ⇔ 11 tracked; disk = 11 + 2 WIP explicitly named intemplates/phase_z2/families/_WIP_FILES.md; IMP-18 doc reads "11 contracted + 2 WIP untracked = 13 on disk"; AUDIT-01 §10.2 F-2 carries the same arithmetic.RESOLVED via #52 (option c, 2026-05-19).frame_contracts.yamlunchanged (11 keys).tests/test_family_contract_baseline.pylocks tracked-families ⇔ contracts set-equality modulo WIP allowlist — future catalog growth (#42 or otherwise) fails CI if drift re-emerges.■ Commit on origin (and mirror) — verification
git rev-parse HEAD=8f06a4c99f53b8c5ce372cec99fae895af3e2d20git ls-remote origin main=8f06a4c99f53b8c5ce372cec99fae895af3e2d20git ls-remote slide2 main=8f06a4c99f53b8c5ce372cec99fae895af3e2d20docs(IMP-52): reconcile Phase Z family count drift -- F-2 option (c).docs/architecture/IMP-18-SVG-GAP-REPORT.md(M, +3/−3),docs/architecture/INTEGRATION-AUDIT-01-REPORT.md(M, +8/−2),templates/phase_z2/families/_WIP_FILES.md(A, 37 lines),tests/test_family_contract_baseline.py(A, 80 lines).frame_contracts.yamledit (option (c) carve-out — verified by absence in commit), u2 = IMP-18, u3 = AUDIT-01, u4 =_WIP_FILES.md+ pytest.■ Goal vs result
11 / 11 / 13drift before #42 grows the catalog to 32 frames; either consolidate to one count or explicitly document the divergence.■ Follow-up links + downstream gating
IMP-04b Catalog extension to 32 frames): now unblocked from a baseline standpoint. Any #42 catalog growth must reconcile the WIP allowlist (_WIP_FILES.md) before merge — this constraint is enforced bytests/test_family_contract_baseline.py(set-equality guard). AUDIT-01 §10.2 F-2 resolution paragraph plus IMP-18 L28/L30/L51 anchor the contract.app_sw_package_vs_solution.html,pre_construction_model_info_stacked.html) — promote intoframe_contracts.yamlor remove. Timing remains open and is owned by #42 (or whichever ticket extends the catalog first).■ Labels
[](none).■ Regression / parity probe (final)
python -m pytest -q tests/test_family_contract_baseline.py tests/test_catalog_invariant.py→4 passed in 0.10s.frame_contracts.yamltop-level keys = 11; WIP allowlist (parsed by test) = 2 (app_sw_package_vs_solution.html,pre_construction_model_info_stacked.html).contracts == tracked✓;contracts == disk − WIP✓;WIP ∩ contracts == ∅✓;WIP ⊂ disk✓.git status --short: committed scope clean; only unrelated untracked artifacts remain (.orchestrator/,samples/,tests/matching/*, the 2 WIP HTML files — all intentional per Stage 5 exit report).■ Close decision
CLOSE — all three issue body acceptance criteria met, commit landed on
origin/mainandslide2/mainat the same SHA, pytest baseline guard active, no runtime path mutated, no scope creep.Pending user GO signal for Gitea state transition (issue close action itself). This comment records the close recommendation; the orchestrator does not auto-close per
PZ-2: 1 turn = 1 stepand per the conversation contract that close is a user action.=== EVIDENCE ===
source_comment_ids: [Codex #1] Stage 1 root cause; [Codex #2] Stage 2 plan; [Codex #5] Stage 3 closeout; [Codex #6] Stage 4 test-verify PASS; [Codex #7] Stage 5 commit-push PASS.
commit_sha:
8f06a4c99f(HEAD = origin/main = slide2/main).stage_status: PASS
FINAL_CONSENSUS: YES
[Codex #9] Stage 6: Final close Round #1
Final independent verification result: PASS. Issue #52 acceptance criteria are met, and the pushed commit is present on both configured main remotes.
Acceptance criteria check:
frame_contracts.yamlentries; disk count is 13 only because 2 WIP files are explicitly allowlisted inD:\ad-hoc\kei\design_agent\templates\phase_z2\families\_WIP_FILES.md.app_sw_package_vs_solution.htmlandpre_construction_model_info_stacked.htmlare documented as untracked, uncontracted, and outside the runtime matcher set.D:\ad-hoc\kei\design_agent\tests\test_family_contract_baseline.pyenforces contracts == disk families minus WIP, and the targeted baseline tests pass.Remote/commit verification:
8f06a4c99f53b8c5ce372cec99fae895af3e2d20origin/main:8f06a4c99f53b8c5ce372cec99fae895af3e2d20slide2/main:8f06a4c99f53b8c5ce372cec99fae895af3e2d20docs(IMP-52): reconcile Phase Z family count drift -- F-2 option (c)src/**,frame_contracts.yaml, or WIP HTML body changes are in the commit.=== EVIDENCE ===
Commands run:
git rev-parse HEADgit show -s --format='%H%n%P%n%s' HEADgit diff-tree --no-commit-id --name-status -r HEADgit ls-remote origin maingit ls-remote slide2 maingit status --shortpython -m pytest -q tests/test_family_contract_baseline.py tests/test_catalog_invariant.pyrg -n "11 contracted|2 WIP|RESOLVED via #52|app_sw_package_vs_solution|pre_construction_model_info_stacked|runtime matcher" docs/architecture/IMP-18-SVG-GAP-REPORT.md docs/architecture/INTEGRATION-AUDIT-01-REPORT.md templates/phase_z2/families/_WIP_FILES.mdgit diff --name-only HEAD^ HEAD -- src templates/phase_z2/catalog/frame_contracts.yaml templates/phase_z2/families/app_sw_package_vs_solution.html templates/phase_z2/families/pre_construction_model_info_stacked.htmlgit diff --cached --name-onlygit ls-files 'templates/phase_z2/families/*.html'Get-ChildItem -LiteralPath 'templates\phase_z2\families' -Filter '*.html' | Select-Object -ExpandProperty Nameyaml.safe_loadoverD:\ad-hoc\kei\design_agent\templates\phase_z2\catalog\frame_contracts.yaml, disk family stems, tracked family stems, and_WIP_FILES.mdGet-Content -LiteralPath 'D:\ad-hoc\kei\design_agent\tests\test_family_contract_baseline.py'Get-Content -LiteralPath 'D:\ad-hoc\kei\design_agent\templates\phase_z2\families\_WIP_FILES.md'D:\ad-hoc\kei\design_agent\templates\phase_z2\families\_WIP_FILES.mdandD:\ad-hoc\kei\design_agent\tests\test_family_contract_baseline.pyFiles checked:
D:\ad-hoc\kei\design_agent\docs\architecture\IMP-18-SVG-GAP-REPORT.mdD:\ad-hoc\kei\design_agent\docs\architecture\INTEGRATION-AUDIT-01-REPORT.mdD:\ad-hoc\kei\design_agent\templates\phase_z2\families\_WIP_FILES.mdD:\ad-hoc\kei\design_agent\tests\test_family_contract_baseline.pyD:\ad-hoc\kei\design_agent\templates\phase_z2\catalog\frame_contracts.yamlD:\ad-hoc\kei\design_agent\templates\phase_z2\families\app_sw_package_vs_solution.html(presence only; body not changed)D:\ad-hoc\kei\design_agent\templates\phase_z2\families\pre_construction_model_info_stacked.html(presence only; body not changed)Test results:
python -m pytest -q tests/test_family_contract_baseline.py tests/test_catalog_invariant.py->4 passed in 0.10sCommit SHA:
8f06a4c99f53b8c5ce372cec99fae895af3e2d20Verified facts:
origin/main,slide2/main, and local HEAD all resolve to8f06a4c99f53b8c5ce372cec99fae895af3e2d20.M docs/architecture/IMP-18-SVG-GAP-REPORT.mdM docs/architecture/INTEGRATION-AUDIT-01-REPORT.mdA templates/phase_z2/families/_WIP_FILES.mdA tests/test_family_contract_baseline.pycontracts=11,disk=13,tracked=11,wip=2.contracts_eq_tracked=True.contracts_eq_disk_minus_wip=True.wip_subset_disk=True.wip_intersect_contracts=[].wip_intersect_tracked=[].git diff --name-only HEAD^ HEAD -- src templates/phase_z2/catalog/frame_contracts.yaml templates/phase_z2/families/app_sw_package_vs_solution.html templates/phase_z2/families/pre_construction_model_info_stacked.htmlreturned no files.git diff --cached --name-onlyreturned no files.D:\ad-hoc\kei\design_agent\templates\phase_z2\families\_WIP_FILES.mdhas 37 lines.D:\ad-hoc\kei\design_agent\tests\test_family_contract_baseline.pyhas 80 lines.Close OK signal: issue #52 is verified complete for final close.
FINAL_CONSENSUS: YES