INTEGRATION-AUDIT-01 (#50) §10.4 / §10.5 housekeeping carry-over. F-4: annotate 14 remaining legacy Phase R'/Q sample-text hits across 10 src/ files with inline marker `# [legacy Phase R'/Q example -- INTEGRATION-AUDIT-01 §10.4]`. Comment-only. No string-literal / regex / sample dict value mutated. fit_verifier.py L612 marker keeps Phase Z partial-live import graph (FitAnalysis / RoleFit / redistribute / salvage) byte-precise. F-5: docs-only addendum -- §10.5.1 in INTEGRATION-AUDIT-01-REPORT.md + tests/CLAUDE.md fixture convention note. No root tests/fixtures/ dir created; existing tests/phase_z2/fixtures/ convention preserved. Documents test-only sample-reference allowance vs src/** runtime prohibition. Out of scope: Phase Z source 11 hits (phase_z2_content_extractor / failure_router / mapper / retry), production behavior change, #19 work. Verified: pytest -q tests/phase_z2/ = 157 PASS. git diff +210/-0 (35 src/docs lines + 175 new tests/CLAUDE.md). No behavioral delta. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
548 lines
80 KiB
Markdown
548 lines
80 KiB
Markdown
# INTEGRATION-AUDIT-01 -- Phase Z closed-issue cumulative consistency review
|
|
|
|
## Section 1. Audit anchor
|
|
|
|
**Anchor (cited verbatim per Stage 1 exit report)** :
|
|
> This audit verifies pipeline contracts. It does not optimize any single MDX sample.
|
|
|
|
**Scope** : 22 closed Gitea issues `#2-#18 + #45-#49` on `Kyeongmin/C.E.L_Slide_test2` against the 22-step Phase Z pipeline (`docs/architecture/PHASE-Z-PIPELINE-OVERVIEW.md`, Steps 1-22 plus Step 0 precondition).
|
|
|
|
**Mode** : audit-only -- no source code changes. Report-only file changes under `docs/architecture/INTEGRATION-AUDIT-*.md` and one row in `docs/architecture/PHASE-Z-IMPLEMENTATION-ISSUE-BACKLOG.md` (u7).
|
|
|
|
**Parent / child relationship** : Gitea `#15` = parent (IMP-15 Step 14 visual_check reinforcement). Execution children = `#45 / #46 / #47 / #48 / #49`. Locked child SHAs (Stage 1 exit report) :
|
|
- `#45` -> `e9b3d2e` (execution-1, image_aspect_mismatch detection)
|
|
- `#46` -> `2827622` (execution-2, table_self_overflow detection; commit message label says `IMP-16` but the closed Gitea issue is `#46`; flagged in Section 3)
|
|
- `#47` -> `535c484` (execution-3, classifier consumes image+table events)
|
|
- `#48` -> `614c533` (execution-4, debug.json event surfacing + spec taxonomy)
|
|
- `#49` -> no new SHA (verification-only per `#15` body; re-uses `614c533` evidence)
|
|
|
|
**Close timestamp anomaly** (Stage 1 lock, recorded; NOT reopened) :
|
|
- `#15` closed `2026-05-19T02:35:05+09:00`
|
|
- `#45 / #46 / #47 / #48` all closed BEFORE `#15` (correct ordering)
|
|
- `#49` closed `2026-05-19T02:49:56+09:00` -- about 15 minutes AFTER `#15` close (anomaly)
|
|
- Disposition : record-only in Section 3 / Section 6 finding column; no remediation row in backlog beyond the existing audit completion row (u7).
|
|
|
|
**Excluded (open / not in audit)** : `#1, #19, #20, #21, #22, #23, #24, #25, #26, #27, #28, #38, #39, #40, #41, #42, #43, #44`.
|
|
|
|
**Sample budget** : `samples/mdx_batch/03.mdx` (smoke) plus `samples/mdx_batch/04.mdx` (details + images). Pipeline runs captured in Section 7.
|
|
|
|
---
|
|
|
|
## Section 2. Baseline pytest
|
|
|
|
**Method** : `pytest -q tests` is the project regression suite. The audit captures it twice -- once before any u5 / u6 / u7 edits, once after Section 7 / 8 grep + render evidence is collected. Equality of both runs proves the audit-only work surface (`docs/architecture/INTEGRATION-AUDIT-*.md` + backlog row in u7) did not perturb production code.
|
|
|
|
**Command** : `pytest -q tests` (working dir = repo root `D:\ad-hoc\kei\design_agent\`).
|
|
|
|
**Pytest BEFORE audit u5 edits (audit date 2026-05-19)** :
|
|
- Result : `303 passed in 40.80s`
|
|
- Last 5 progress dots aggregated to `[100%]` then `Running teardown with pytest sessionfinish...` -- expected suite teardown banner.
|
|
|
|
**Pytest AFTER audit u5 edits (post §7 / §8 evidence collection, same audit date)** :
|
|
- Result : `303 passed in 40.54s`
|
|
- 303 == 303 ; 0 new failures, 0 skipped, 0 errored. Test count parity proves no test discovery side-effect from new audit docs.
|
|
|
|
**Verdict** : OK. Audit-only edits under `docs/architecture/INTEGRATION-AUDIT-*.md` introduce no regression. Baseline stable across u5 assembly.
|
|
|
|
---
|
|
|
|
## Section 3. Axis 1 -- Scope myopia (22 issues x adjacent-contract cross-reference)
|
|
|
|
**Method** : per closed issue, list (a) its own scope as declared in body / backlog row / closing commits, (b) adjacent pipeline contracts the change could have leaked into, (c) downstream consumers of its outputs, (d) finding label `OK` / `Warning` / `Blocker`. Each row cites `src/`, `tests/`, `docs/`, or `templates/` paths.
|
|
|
|
**De-dup convention** : `#15` is treated as the *integration parent*; the actual code/test changes are owned by execution children `#45-#49`. `#15` row records integration glue only (parent close evidence + cross-child reconciliation). No change is double-counted across parent + child.
|
|
|
|
**Pipeline step shorthand (per `PHASE-Z-PIPELINE-OVERVIEW.md`, full 22-step list)** :
|
|
- Step 0 precondition / 1 MDX upload / 2 normalize / 3 content_object / 4 internal composition planning / 5 V4 evidence / 6 composition planning / 7 layout vocabulary / 8 zone+region ratio / 9 region-level frame/display / 10 frame contract / 11 region-to-slot mapping / 12 slot payload / 13 render / 14 visual_check / 15 fit_classification / 16 router / 17 action / 18 failure_classify / 19 next_action / 20 slide_status / 21 debug.json / 22 user UI.
|
|
|
|
### Section 3 table -- 22 rows
|
|
|
|
| # | issue (title) | declared own_scope | adjacent contracts (potential leak surface) | downstream consumers | finding | evidence path |
|
|
|---|---|---|---|---|---|---|
|
|
| 1 | `#2` IMP-02 A-1 Stage 0 normalize chained adapter | Step 2 -- chained `normalize_mdx_content` + `extract_major_sections` + `extract_conclusion_text` with dual-write, preserve raw MDX | Step 3 content_object input shape (raw chunk handoff); Step 21 debug.json schema (`step02_*` keys) | Step 3 (IMP-03 ContentObject extractor); Step 21 trace writer; Step 7/8 layout planner (consumes normalized section list) | OK -- additive; preserves prior `extract_*` semantics via dual-write; no AI in path | `src/phase_z2_pipeline.py` (commit `bac13c0`, +165/-3) |
|
|
| 2 | `#3` IMP-03 A-1 popup/image/table trace | Step 3 -- normalize popups/images/tables into ContentObject (B1 v0 extension); slide-level rich ContentObject trace | Step 2 normalize output shape (consumer); Step 4 internal composition planning (Step 4 itself still not implemented, so this row only emits trace); Step 21 debug.json schema | Step 4 (not yet implemented; receives data only via trace); Step 21 debug.json (`content_objects` field) | OK -- emits trace without coupling to downstream Step 4 (Step 4 still pending); raw content preserved (no AI summarization; satisfies `feedback_ai_isolation_contract`) | `src/phase_z2_content_extractor.py` + `src/phase_z2_pipeline.py` (commit `fc3f7d8`) |
|
|
| 3 | `#4` IMP-04 A-2 catalog expansion | Step 0 + Step 9 -- register/expand 16 frame_partials + `frame_contracts.yaml` schema; F17 paired_rows_4x2 + pill alternation + theme | Step 5 V4 evidence (catalog size affects evidence pool); Step 10 frame contract validator (consumes new contracts); Step 12 mapper PAYLOAD_BUILDERS (consumes new schema); Step 13 render template surface (16 new `templates/phase_z2/families/*.html`) | Step 5/9/10/12/13; smoke tests `scripts/smoke_frame_render.py` | OK -- pre-render planning only; catalog is read-only data for V4; frame DB extension matches Step 0 contract; commit `73a98b8` corrected F17 schema after first land (factual_verification path active) | `templates/phase_z2/catalog/frame_contracts.yaml`; `templates/phase_z2/families/*.html`; `src/phase_z2_mapper.py`; `docs/architecture/IMP-04-FRAME-SUITABILITY-MATRIX.md` |
|
|
| 4 | `#5` IMP-05 A-5 V4 fallback | Step 9 + Step 16/17 -- deterministic V4 candidate bridge (pre-render rank-2/3 fallback); trace schema; dedup invariant test; new `PASS_WITH_FALLBACK` status semantics in Step 20 | Step 5 evidence (candidate dedup must agree with rank-1 path); Step 6 composition (candidates[0] backward-compat); Step 9 application_plan; Step 20 status enum; debug.json trace | Step 9/16/17/20; `tests/test_phase_z2_v4_fallback.py`; `tests/test_catalog_invariant.py` | OK -- pre-render bridge (Block A); deterministic (no AI); rank-1 path unchanged (backward compat per backlog guardrail); dedup invariant test guards collision with `#4` catalog expansion | `src/phase_z2_pipeline.py` + `src/phase_z2_composition.py` + `src/phase_z2_router.py` (commits `15c5b9a`, `21476ae`, `23d1b25`) |
|
|
| 5 | `#6` IMP-06 B-1 zone-section override | Step 6 + Step 1/22 input -- CLI arg + composition planner override (`replaced_auto_unit`, `render_records`, plan-aware traces, units rebuild, empty zone) | Step 1 CLI surface; Step 6 `plan_composition` schema (CompositionUnit); Step 7/8/9 downstream (units rebuild forces re-planning); Step 13 render (Catch K render-path) | Step 7/8/9/13; debug.json render_records; `Front/` (later wired via `#8` U3) | Warning -- wide blast radius (4 commits + Stage 4 blocker-fix `52ccb7f`); units-rebuild touches Step 7/8/9 implicitly; verified by `tests/test_phase_z2_section_assignment_override.py` (285 + 42 + 228 lines). No AI; deterministic. Risk = override path widens Step 6 surface where Step 4 is still pending | `src/phase_z2_pipeline.py` (commits `d596fab` `b81e564` `1f15495` `52ccb7f`) |
|
|
| 6 | `#7` IMP-07 B-2 edited HTML to MDX reverse path | Step 22 + Step 1/2 input -- Vite/React `Front/` plus reverse path glue; pipeline re-entry | Step 1 MDX upload; Step 2 normalize (must accept reverse-path MDX); CLI plus service API; `feedback_ai_isolation_contract` (reverse must not invoke AI rewrite) | Step 2 (reverse-path consumer); `Front/client/src/services/designAgentApi.ts`; pipeline CLI | OK -- frontend-shipped (`0f0d3fa`); reverse path schema aligned with `#2` Stage 0 normalize via hard-link declared in backlog. AI isolation preserved (no normal-path LLM in reverse). | `Front/`; `src/phase_z2_pipeline.py`; backlog row IMP-07 |
|
|
| 7 | `#8` IMP-08 B-3 sub-section drag-drop | Step 3 schema -- sub_sections schema + V4 alias resolver + aligner canonical sub-id + decimal alias guard (N-R5) + frontend wire | Step 3 ContentObject schema (extends `#3`); Step 5 V4 alias surface; Step 6 composition planner (consumer); Step 9 application_plan; `Front/` zoneSections override (U3) | Step 5/6/9/13; `tests/test_phase_z2_subsection_schema.py` (82+100+61 lines) | OK -- additive schema with explicit backward-compat guard (alias resolver at 4 lookup sites); Stage 5 R2 blocker-fix `8f6cffc` force-drills aligner only on override targets (scope contained) | `src/phase_z2_pipeline.py` + `src/phase_z2_composition.py` (commits `a422d72` `5191aca` `ab2764c` `8f6cffc`) |
|
|
| 8 | `#9` IMP-09 B-4 non-default layout zone-geometry | Step 8 -- col-axis solver + per-zone geometry mapper + retry gate; 2-D dynamic dispatch for 5 preset families (single + horizontal-2 + vertical-2 + top-1-bottom-2 + top-2-bottom-1 + left-1-right-2 + left-2-right-1 + grid-2x2) | Step 7 layout vocabulary (consumer); Step 9 region-level (zone geometry feeds region ratios; Step 9 region-level still warning); Step 17 zone_ratio_retry (`#12` IMP-12 retry path); Step 13 render `build_layout_css` | Step 9/13/17; `tests/phase_z2/fixtures/build_layout_css/*.yaml` (16 fixtures); `tests/phase_z2/fixtures/retry_gate/*.yaml` | OK -- all 8 vocabulary entries enabled in build_layout_css; fixtures supply provable diff per preset; no Kei/Phase R' regression (existing `build_containers_type_b` untouched) | `src/phase_z2_pipeline.py` (commits `201099e` PR1, `1fb9732` PR2) |
|
|
| 9 | `#10` IMP-10 D-1 filtered_section_reasons UI | Step 20/22 -- frontend read-only display of `filtered_section_reasons` artifact | Step 20 slide_status enum (read-only consumer); `Front/` service API; no backend mutation | `Front/client/src/pages/Home.tsx`; `Front/client/src/services/designAgentApi.ts` | OK -- frontend-only; backend artifact strictly read-only per backlog guardrail | `Front/` (commit `0fb168b`, +45 lines) |
|
|
| 10 | `#11` IMP-11 D-2 Frame min_height display | Step 22 -- `min_height_px` hint exposed backend to UI; resize hint read-only; Step 9 v4 all-judgments min_height test | Step 0 frame contract (`min_height_px` field); Step 9 region-level (consumer); `Front/` SlideCanvas | Step 9; `Front/client/src/components/SlideCanvas.tsx`; `tests/test_phase_z2_step9_v4_all_judgments_min_height.py` | OK -- contract read-only; backend exposure is additive payload field (`src/phase_z2_pipeline.py` +32/-12 in `a79bd8b`) | `src/phase_z2_pipeline.py` + `Front/client/src/components/SlideCanvas.tsx`; `tests/test_phase_z2_step9_v4_all_judgments_min_height.py` |
|
|
| 11 | `#12` IMP-12 Step 16/17 retry refinement | Step 16 + Step 17 -- multi-donor + 3-stage salvage cascade; `redistribute` + glue + font compression; new router action; new failure_router taxonomy | Step 14 visual_check (donor selection consumes overflow events); Step 18 failure_classify (cascade adds new failure types); Step 19 next_action (downstream router consumer); Step 20 status semantics; `feedback_phase_z_spacing_direction` (cross-zone redistribute is grant-changing, not common-shrink) | Step 18/19/20; `tests/phase_z2/test_phase_z2_*` (cross_zone, font_step, glue, multi_donor, step17_salvage_chain -- 5 new test modules) | Warning -- large blast radius (4 src files + 5 test modules in `56619a0`); multi-donor introduces cross-zone state in Step 17; verified by 5 dedicated test modules. Risk = cascade may interact with `#5` V4 fallback path in Step 20 status enum (mitigated by separate status enums per `#5` exit report) | `src/phase_z2_failure_router.py` + `src/phase_z2_pipeline.py` + `src/phase_z2_retry.py` + `src/phase_z2_router.py` (commit `56619a0`) |
|
|
| 12 | `#13` IMP-13 A-3 frame preview consistency | Step 0 + Step 14/21 -- build-time frame preview generator (salvage of `capture_slide_screenshot`) | Step 0 catalog frame_partials (consumer for snapshot); Step 14 visual_check (uses preview for sanity, read-only); no Phase R' regression | `scripts/generate_frame_previews.py`; `tests/test_generate_frame_previews.py` | OK -- build-time only (not in runtime pipeline); deterministic; no Phase R' coupling (script lives in `scripts/`) | `scripts/generate_frame_previews.py` (commit `7d5639a`, 239 LOC + 50 LOC test) |
|
|
| 13 | `#14` IMP-14 A-4 slide-base iframe mode | Step 13 render -- `slide-base.html` conditional CSS (embedded vs standalone); Step 0 contract bit | Step 0 slide_base template; Step 13 Jinja2 deterministic render; `Front/` SlideCanvas (consumer) | Step 13; `Front/client/src/components/SlideCanvas.tsx`; `tests/phase_z2/test_slide_base_embedded_mode.py` | OK -- render-time contract only; Jinja2 deterministic; embedded mode reduces SlideCanvas friction (34 LOC simplified) | `templates/phase_z2/slide_base.html` + `src/phase_z2_pipeline.py` (commit `7a52ceb`) |
|
|
| 14 | `#15` IMP-15 Step 14 visual_check reinforcement (PARENT -- execution children `#45-#49`) | Integration glue only -- *no direct code* under #15; closure depends on `#45-#49` SHAs. De-duped against children (real change attribution = #45-#49 rows below) | Step 14 (parent contract); Step 15 fit_classification consumer; Step 21 debug.json trace; `PHASE-Z-FIT-CLASSIFIER-ROUTER-SPEC.md` (taxonomy row added by `#48`) | Step 15/21; spec doc | Warning -- close-timestamp anomaly only : `#49` closed at `2026-05-19T02:49:56+09:00`, about 15 minutes AFTER `#15` close `02:35:05+09:00`. All other children (#45-#48) close BEFORE #15. `#49` body declares verification-only path (no new SHA; re-uses `614c533`), so post-close `#49` close does not leak code into `#15`. Disposition : record-only, no reopen. | `docs/architecture/PHASE-Z-PIPELINE-OVERVIEW.md` Step 14/15; child rows below |
|
|
| 15 | `#16` IMP-16 B-2 verification helper axis | Step 1/2/14/21/22 -- `phase_z2_verification_utils.py` port + 8 verification test modules + U2 wiring design doc | Step 22 reverse path verification (consumer is `#7` IMP-07 once activated); no normal-path coupling | Step 14/21 trace consumers (utility); future `#7` reverse-path verification | OK -- utility module plus design doc only; no normal-path coupling (gated by `#7` activation); commit `23ba8b6` is design + utility port (335 LOC utility + 8 test modules + wiring doc) | `src/phase_z2_verification_utils.py`; `docs/architecture/IMP-16-U2-WIRING-DESIGN.md` (commit `23ba8b6`) |
|
|
| 16 | `#17` IMP-17 AI repair fallback infra (carve-out -- outside normal path) | Design-only boundary + 3-cond AND gate (User GO AND B4 frame_selection evidence AND IMP-04/05 live); `httpx` + SSE + retry + JSON parse pattern reference | Step 12 (AI position contract; carve-out body asserts normal path AI = 0); Step 16/17 fallback path (gated activation); `feedback_ai_isolation_contract` (foundational rule); backlog row + INSIGHT-MAP cross-ref | Step 12 (design boundary); future activation gated by 3-cond AND | OK -- design-only carve-out; `src/phase_z2_pipeline.py` change = 1 line (comment anchor for orchestrator test); no runtime AI added | `docs/architecture/IMP-17-CARVE-OUT.md` + `tests/orchestrator_unit/test_imp17_comment_anchor.py` (commit `e10ec36`) |
|
|
| 17 | `#18` IMP-18 I3 SVG coordinate reinforcement | Doc-only carve-out -- SVG gap report; `renderer._preprocess_svg_data` pattern reference | Step 0 frame_partials SVG geometry (reference); Phase R' (renderer.py) read-only | doc consumers; backlog row | OK -- doc-only (`docs/architecture/IMP-18-SVG-GAP-REPORT.md` + 1-line backlog status flip from `pending` to `documented`); no code touched | `docs/architecture/IMP-18-SVG-GAP-REPORT.md` (commit `cbbc163`) |
|
|
| 18 | `#45` (`#15` execution-1) image_aspect_mismatch detection + runtime test | Step 14 -- `image_aspect_mismatch` detection in visual_check; runtime test `test_phase_z2_step14_image_check.py` | Step 15 fit_classification consumer; Step 21 debug.json event surfacing (delegated to `#48`); `#15` parent close evidence | Step 15 (consumer via classifier event); `#47` (classifier integration) | OK -- Step 14 detection only (no Step 15 wiring yet; delegated to `#47`). Test scope local. | `src/phase_z2_pipeline.py` + `tests/phase_z2/test_phase_z2_step14_image_check.py` (commit `e9b3d2e`) |
|
|
| 19 | `#46` (`#15` execution-2) table overflow + element-identity dedup + Selenium test | Step 14 -- `table_self_overflow` detection; element-identity dedup; Selenium integration test | Step 14 dedup logic (must agree with image events from `#45`); Step 15 consumer (delegated to `#47`); `#15` parent | Step 15 (consumer); `#47` | Warning -- commit-message label drift only (Step 14 scope-discipline pattern itself matches `#45`). Commit `2827622` message reads `feat(IMP-16): ...`, which mis-labels the closing Gitea issue (actually closes `#46` = `#15` execution-2; IMP-16 backlog row is the verification utility carved out separately). Audit attribution corrected here; SHA `2827622` is the authoritative anchor. No code/contract leak; risk is record-keeping only. | `src/phase_z2_pipeline.py` + `tests/phase_z2/test_phase_z2_step14_table_check.py` (commit `2827622`) |
|
|
| 20 | `#47` (`#15` execution-3) classifier consumer (image + table) + pure-dict test | Step 15 -- classifier consumes image+table events from Step 14; pure-dict test (no Selenium) | Step 14 producers (`#45` + `#46`); Step 15 `CONTENT_TYPE_PATTERNS` taxonomy; Step 16 router (consumer) | Step 16; `tests/phase_z2/test_phase_z2_visual_classifier.py` | OK -- classifier wiring with pure-dict tests isolates Step 15 from Selenium dependency; aligns Step 14 producer to Step 15 consumer (Axis 3 invariant -- to be re-verified in Section 5) | `src/phase_z2_classifier.py` (commit `535c484`) |
|
|
| 21 | `#48` (`#15` execution-4) debug.json event surfacing + spec doc trace + regression | Step 21 debug.json event surfacing + `PHASE-Z-FIT-CLASSIFIER-ROUTER-SPEC.md` taxonomy row + regression test | Step 21 trace schema (additive); spec doc; regression guard | spec doc consumers; debug.json consumers (Front/, audit tooling) | OK -- 3-line pipeline change + 2 test modules + 1-line spec doc row; smallest blast radius of #15 children | `src/phase_z2_pipeline.py` + `docs/architecture/PHASE-Z-FIT-CLASSIFIER-ROUTER-SPEC.md` (commit `614c533`) |
|
|
| 22 | `#49` (`#15` execution-5) final integration + parent close | Verification-only -- re-uses `#48` `614c533` evidence; no new SHA per `#15` body | `#15` parent close; integration-only | `#15` parent | Warning -- close-timestamp anomaly (closed `2026-05-19T02:49:56+09:00`, about 15 minutes AFTER `#15` close `02:35:05+09:00`). Verification-only path has no code change, so anomaly is administrative only; no contract leak. | `#15` body + `614c533` (re-used) |
|
|
|
|
### Section 3 finding summary
|
|
|
|
- **OK** rows : `#2 #3 #4 #5 #7 #8 #9 #10 #11 #13 #14 #16 #17 #18 #45 #47 #48` (17)
|
|
- **Warning** rows : `#6` (wide override blast radius, contained by tests); `#12` (multi-donor + cascade, contained by 5 test modules); `#15` (close-timestamp anomaly via `#49`); `#46` (commit-message label drift only, SHA correct); `#49` (close-timestamp anomaly, verification-only) -- 5 rows
|
|
- **Blocker** rows : 0
|
|
- **Total** : 17 OK + 5 Warning + 0 Blocker = 22 rows (matches 22 closed issues under audit).
|
|
- **De-dup audit** : `#15` row carries no code attribution; all code/test work attributed to `#45-#48` (and `#49` = verification-only). No double-count.
|
|
|
|
### Section 3 cross-issue scope-myopia adjacency check
|
|
|
|
Adjacent-contract pairs flagged for Section 5 Axis 3 re-verification (producer to consumer continuity) :
|
|
- `#2` Step 2 normalize output -> `#3` Step 3 content_object input
|
|
- `#3` content_object schema -> `#8` sub_sections schema extension
|
|
- `#4` catalog expansion -> `#5` V4 fallback candidate pool dedup
|
|
- `#4` catalog expansion -> `#10`-`#11` `min_height_px` exposure
|
|
- `#9` layout vocabulary -> `#12` retry zone-ratio donor selection
|
|
- `#9` layout vocabulary -> `#11` Step 9 min_height v4-all-judgments test
|
|
- `#45 + #46` Step 14 events -> `#47` Step 15 classifier -> Step 16 router
|
|
- `#48` debug.json event surfacing -> `#21` (Step 21 debug consumer; open, excluded)
|
|
- `#17` AI carve-out -> `#5 + #4` activation 3-cond AND gate (gated, not active)
|
|
|
|
Axis 3 (Section 5) will verify each pair has agreeing producer-line / consumer-line on the live code.
|
|
|
|
---
|
|
|
|
## Section 4. Axis 2 -- 22 issues x 22 steps pipeline matrix
|
|
|
|
**Split rationale** : at u1 completion the combined REPORT was 21,070 bytes / 136 lines -- over the 10 KB readability threshold defined in the Stage 2 plan. Per the split rule (`combined REPORT >= 10 KB grid moves to MATRIX.md + back-pointer`), the 22 x 22 grid lives in the companion file :
|
|
|
|
- `docs/architecture/INTEGRATION-AUDIT-01-MATRIX.md`
|
|
|
|
**What MATRIX.md contains** :
|
|
- Step 0 precondition NOTE (NOT a grid column) -- 5 issues (`#4 #11 #13 #14 #18`) recorded with scope summary + evidence path.
|
|
- 22 x 22 grid (Step 1 through Step 22 columns x 22 issue rows). Cell legend : `P` = primary touch, `A` = adjacent contract, `.` = no touch. ASCII-only.
|
|
- Row footer (touched-step count) and column footer (touching-issue count + `H` HOTSPOT marker for col total >= 4).
|
|
- HOTSPOT enumeration (9 steps : `S2 S9 S13 S14 S15 S16 S17 S21 S22`).
|
|
- Cross-check against the 9 adjacent-contract pairs flagged in Section 3.
|
|
- Empty / low-touch column notes (Step 4 and Step 11 are `missing` per PHASE-Z-PIPELINE-OVERVIEW -- 0 touches expected).
|
|
- Parent/child de-dup sum check : `#15` row carries 3 adjacencies and zero `P` cells ; only `#45 #46 #47 #48` carry the 4 primary cells for the `#15` family ; `#49` is verification-only with all-`A`.
|
|
|
|
**Section 4 summary (for readers staying in REPORT)** :
|
|
- 9 hotspot steps (col total >= 4) : Step 2 (4), Step 9 (6), Step 13 (5), Step 14 (9 highest), Step 15 (6), Step 16 (4), Step 17 (4), Step 21 (8), Step 22 (7).
|
|
- 2 empty columns : Step 4 + Step 11. Consistent with master pipeline `missing` status -- no audit gap.
|
|
- Total grid cells filled = 77 (row sum = col sum, cross-checked).
|
|
- Top row-total issues : `#6` (7), `#5` (6), `#8` (6), `#12` (6) -- the 2 `Warning` rows (`#6 #12`) sit at the top, consistent with Section 3 wide-blast-radius finding.
|
|
|
|
---
|
|
|
|
## Section 5. Axis 3 -- Cross-issue conflict per invariant category
|
|
|
|
**Method** : 6 invariant categories listed in the issue body. Per category, identify producer file:line, consumer file:line, the named state key / contract, the closed issues that touch it, agree-or-conflict verdict, plus grep evidence path. Categories are evaluated against the live tracked code at audit time, not against historical snapshots.
|
|
|
|
### 5.1 Invariant category roster (from issue body)
|
|
|
|
| # | category | issue-body wording |
|
|
|---|---|---|
|
|
| C1 | `debug.json` schema | phase_z2 debug payload paths; no conflicting key type / semantics |
|
|
| C2 | `visual_check_passed` | `src/phase_z2_pipeline.py` Step 14 / 17; set-site <-> read-site agree |
|
|
| C3 | `fit_classification` / router | `src/phase_z2_mapper.py` + consumers; labels consistent producer -> consumer (charter mis-cite; live producer = `src/phase_z2_classifier.py` -- see §10 F-1) |
|
|
| C4 | Step 14 / 17 / 21 interactions | expected state values stay aligned across the trio |
|
|
| C5 | Phase R vs Phase Z boundary | no R regression, Z additions don't leak into R |
|
|
| C6 | template / catalog / frame count | all docs / code use same numbers (family = 13) |
|
|
|
|
### 5.2 Producer / consumer / agreement table
|
|
|
|
| C# | invariant key | producer (file : line) | consumer(s) (file : line) | touching closed issues | verdict | grep evidence |
|
|
|---|---|---|---|---|---|---|
|
|
| C1 | per-step JSON schema = `step_num`, `step_name`, `step_status`, `pipeline_path_connected`, `input`, `output`, `note`, `data` (locked) | `src/phase_z2_pipeline.py:2593` `_write_step_artifact` definition; locked schema docstring at `2605-2611` (Locked schema lines `2607-2610`) | every step writer in `src/phase_z2_pipeline.py` -- 24 call sites at lines `2782, 2812, 2857, 2934, 3184, 3619, 3652, 3674, 3793, 3804, 3826, 3881, 4056, 4308, 4481, 4507, 4527, 4549, 4658, 4677, 4688, 4706, 4761, 4780`; `Front/` reads `data/runs/.../steps/*.json`; audit tooling | `#2 step02_*`; `#3 content_objects`; `#5 v4_fallback_summary` + `selection_paths` + `fallback_selection_count`; `#6 render_records`; `#11 min_height_px` payload; `#48 image_events` / `table_events` event surfacing | AGREE -- all step writers go through the single `_write_step_artifact` site with the locked field set; additive `data` payload only; no conflicting key types observed | `Grep _write_step_artifact src/phase_z2_pipeline.py` = 1 definition (line 2593) + 24 call sites = 25 total occurrences (all 24 call sites enumerated in consumer column); all share the same `_write_step_artifact(run_dir, step_num, name, data, *, step_status, pipeline_path_connected, inputs, outputs, note)` kwargs surface |
|
|
| C2 | `visual_check_passed: bool` set at Step 14 / read at Step 17 | `src/phase_z2_classifier.py:495` `visual_check_passed = bool(overflow.get("passed", False)) and not classifications` returned at `497` | `src/phase_z2_router.py:128` `if fit_classification.get("visual_check_passed", True): ... router_active = False`; `src/phase_z2_pipeline.py:2560` sets `slide_status["visual_check_passed"] = visual_passed`; pipeline summary reads at `4800`, `4804`, `4830` | `#15` parent; `#45` (image_events flip the flag); `#46` (table_events flip the flag); `#47` (classifier widens semantic to `passed AND no classifications`) | AGREE -- single set-site (classifier.py:495) + slide_status mirror (pipeline.py:2560); router.py:128 + pipeline.py:4800/4804/4830 read the same key. Default `.get(..., True)` at router.py:128 is safe because absent key = no classification = pass | `Grep visual_check_passed src` = 14 hits across `classifier.py` + `router.py` + `pipeline.py` -- producer / consumer line set matches |
|
|
| C3 | `fit_classification` dict keys = `visual_check_passed`, `classifications`, `summary`, `categories_seen`, `unclassified_signals`, `placement_diagnostics`; classifier <-> router consumer | `src/phase_z2_classifier.py:496-506` `classify_visual_runtime_check` return dict | `src/phase_z2_router.py:109` `route_fit_classification(fit_classification)`; `src/phase_z2_pipeline.py:4524` `fit_classification = classify_visual_runtime_check(overflow, debug_zones)`; pipeline re-classify after retry at `4582 / 4643`; router decision call at `4540 / 4583 / 4644`; retry consumer `src/phase_z2_retry.py:47` reads `fit_classification` | `#5` (V4 fallback PASS_WITH_FALLBACK semantics); `#12` (retry router multi-donor + cascade); `#15` parent; `#47` (classifier feed); `#48` (debug surfacing) | AGREE -- producer key set is the exact set consumed downstream. NOTE : the issue body says `src/phase_z2_mapper.py` for invariant C3, but the live producer is `src/phase_z2_classifier.py` (`mapper.py` owns slot payload, not fit classification). This is a record-keeping mismatch in the issue body, not a code conflict. Recorded as Section 10 follow-up candidate F-1 | `Grep fit_classification src` = 30 total occurrences across 4 files (`classifier.py` 3 hits incl. docstring/comments; `pipeline.py` 20 hits; `router.py` 5 hits; `retry.py` 2 hits). Active code use sites = producer at `classifier.py:497`; consumers at `router.py:128 / 139` + `pipeline.py 2732 / 4524 / 4540 / 4571 / 4582 / 4583 / 4643 / 4644 / 4754 / 4804 / 4805` + `retry.py:47 / 67`. Remaining occurrences are imports / function-parameter declarations / docstring references |
|
|
| C4 | Step 14 visual_check overflow events (`image_events`, `table_events`, `passed`) -> Step 15/16 (fit + router) -> Step 17 retry action -> Step 21 debug surface | Step 14 emit sites `src/phase_z2_pipeline.py:2236` (`image_events`), `2282` (`table_events`), `2367 / 2386` (aggregation); Step 15 classifier consumes both event lists at `src/phase_z2_classifier.py:429 / 453`; Step 16 router at `src/phase_z2_router.py:142`; Step 17 retry orchestration at `src/phase_z2_pipeline.py:4571 / 4583 / 4644`; Step 21 trace producer at `src/phase_z2_pipeline.py:4762-4777` (`step21_debug_index.json` + `debug.json` outputs) | Step 21 `debug.json` index reader (`Front/` + audit tooling); pipeline summary 4791-4841 | `#12` (retry cascade Step 17 multi-donor + glue + font compression); `#15 / #45 / #46 / #47 / #48` (Step 14 producer / Step 15 classifier consumer / Step 21 surface); `#10` filtered_section_reasons (Step 22 read-only, Step 21 source) | AGREE with one DOCUMENTED PARTIAL -- Step 21 writer at `pipeline.py:4772` is `step_status="partial"` with note `region marker partial 미주입 -- Step 21 ⚠ partial`. This is an *acknowledged* partial state recorded in trace, not a contract conflict between issues. Recorded as Section 6 status row | `Grep step_num.*=.*21\|outputs.*debug\.json src/phase_z2_pipeline.py` = single producer at line 4762-4777 |
|
|
| C5 | Phase R' (`src/renderer.py`, `src/content_editor.py`, `src/html_validator.py`, `src/block_selector.py`) <-> Phase Z (`src/phase_z2_*.py`) module boundary; no cross-import | `src/phase_z2_pipeline.py` (Phase Z entry) has zero imports of Phase R' modules; verified via `Grep "from renderer\|import renderer\|from phase_q\|from src\.renderer" src/phase_z2_pipeline.py` = `No matches found` | inverse direction `src/renderer.py` and `src/block_selector.py` have zero references to `phase_z2`; verified via `Grep phase_z2 src/renderer.py` = 0 and `Grep phase_z2 src/block_selector.py` = 0 | `#13` (build-time frame preview generator, scripts/ only); `#14` (slide-base iframe mode -- Phase Z only); `#16` (verification utility for Phase Z, no Phase R coupling); `#17` (AI carve-out, design-only no R coupling); `#18` (SVG gap report doc-only) | AGREE -- boundary clean both directions for the closed-issue scope. No Phase R' regression observed; Phase Z additions stay in `phase_z2_*.py` modules | `Grep` results above |
|
|
| C6 | family templates count vs frame_contracts.yaml count (= 11 in tracked baseline); docs cite "family = 13" including 2 in-progress untracked files | `templates/phase_z2/families/*.html` tracked = 11 (`git ls-files templates/phase_z2/families/` produces 11 entries); `templates/phase_z2/catalog/frame_contracts.yaml` top-level entries = 11 (`grep -cE "^[a-z_]+:$"` = 11) | `src/phase_z2_mapper.py` PAYLOAD_BUILDERS / ITEM_PARSERS / COLUMN_BODY_PARSERS registries (mapper.py:10-16 docstring + 262 / 306 / 332 / 369 / 414 / 424 / 471 registry sites); render surface `templates/phase_z2/families/*.html` | `#4` (16 frame_partials + F17 paired_rows_4x2 schema + theme); `#5` (V4 fallback candidate pool dedup); `#13` (frame preview generator); `#18` (SVG gap report cites `families/*.html (13)`) | AGREE FOR TRACKED BASELINE -- 11 tracked family templates <-> 11 frame_contracts entries. SURFACE NOTE : 2 untracked WIP family templates (`app_sw_package_vs_solution.html`, `pre_construction_model_info_stacked.html`) exist on disk but are NOT in any closed issue and NOT yet contracted. IMP-18 doc "families/*.html (13)" is forward-looking, includes the 2 WIP files. No closed-issue contract is broken; documentation drift is recorded as Section 10 follow-up candidate F-2 | `git ls-files templates/phase_z2/families/` = 11; `ls templates/phase_z2/families/*.html` = 13 (2 untracked); `grep -cE "^[a-z_]+:$" frame_contracts.yaml` = 11 |
|
|
|
|
### 5.3 Cross-issue adjacency continuity (Section 3 pairs re-verified)
|
|
|
|
| Section 3 adjacent pair | invariant carrying the contract | live continuity verdict |
|
|
|---|---|---|
|
|
| `#2` Step 2 normalize -> `#3` Step 3 content_object input | C1 (debug.json `step02_*` + content_objects) | OK -- additive payload, schema preserved via `_write_step_artifact` |
|
|
| `#3` content_object schema -> `#8` sub_sections schema | C1 + C4 (alias resolver state) | OK -- alias resolver covers 4 lookup sites (REPORT Section 3 row #8 evidence) |
|
|
| `#4` catalog -> `#5` V4 fallback dedup | C3 + C6 (frame count + classifier consumer) | OK -- candidates[0] backward-compat verified by `tests/test_catalog_invariant.py` (REPORT Section 3 row #5) |
|
|
| `#4` catalog -> `#10 / #11` `min_height_px` exposure | C1 + C6 | OK -- `min_height_px` is additive read-only field |
|
|
| `#9` layout vocabulary -> `#12` retry donor selection | C3 + C4 (Step 17 cascade) | OK -- multi-donor cross-zone state lives inside Step 17 retry; spacing direction matches `feedback_phase_z_spacing_direction` (no common-shrink) |
|
|
| `#9` layout vocabulary -> `#11` Step 9 min_height v4-all-judgments | C6 | OK -- guarded by `tests/test_phase_z2_step9_v4_all_judgments_min_height.py` |
|
|
| `#45 + #46` Step 14 events -> `#47` Step 15 classifier -> Step 16 router | C2 + C3 + C4 | OK -- live trace `image_events` / `table_events` enter classifier at `classifier.py:429 / 453`, flow into router at `router.py:142` |
|
|
| `#48` debug.json event surfacing -> `#21` (open, excluded) | C1 | OK for closed scope -- open consumer `#21` is outside audit window |
|
|
| `#17` AI carve-out -> `#5 / #4` activation 3-cond AND gate | C5 (boundary not yet crossed) | OK -- gate is *closed* (`User GO AND B4 frame_selection evidence AND IMP-04/05 live`); no normal-path AI active |
|
|
|
|
### 5.4 Axis 3 summary
|
|
|
|
- 6 invariant categories evaluated. All AGREE for the closed-issue audit scope.
|
|
- 2 surface notes recorded as Section 10 follow-up candidates :
|
|
- **F-1** : issue body cites `src/phase_z2_mapper.py` for invariant C3 (`fit_classification`), but the live producer is `src/phase_z2_classifier.py`. Record-keeping correction needed in any future audit charter, not a code conflict. RESOLVED via IMP-53 (2026-05-19)
|
|
- **F-2** : 2 untracked family templates exist on disk without `frame_contracts.yaml` entries; IMP-18 doc cites "families/*.html (13)" forward-looking. Tracked baseline (11 / 11) is consistent. Contract drift is *not* present for any closed issue; 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.
|
|
- 1 documented partial recorded :
|
|
- Step 21 `_write_step_artifact` at `pipeline.py:4772` carries `step_status="partial"` with note `region marker partial 미주입 -- Step 21 ⚠ partial`. This is *self-honest acknowledged* per `feedback_artifact_status_naming`; no cross-issue conflict.
|
|
- Phase R' <-> Phase Z boundary clean both directions for the 22 closed issues.
|
|
- 0 Blocker findings in Axis 3.
|
|
|
|
### 5.5 Live-grep re-verification stamp (audit date 2026-05-19)
|
|
|
|
All numerical claims in Section 5.2 re-verified against live source on the audit date. Commands and results :
|
|
|
|
| Claim | Command | Live result | Status |
|
|
|---|---|---|---|
|
|
| C1 producer + consumer count | `Grep _write_step_artifact src/phase_z2_pipeline.py -n` | 1 definition (`pipeline.py:2593`) + 24 call sites at lines `2782, 2812, 2857, 2934, 3184, 3619, 3652, 3674, 3793, 3804, 3826, 3881, 4056, 4308, 4481, 4507, 4527, 4549, 4658, 4677, 4688, 4706, 4761, 4780` = 25 total occurrences | MATCH (Section 5.2 C1 row already lists all 24 call sites) |
|
|
| C2 consumer scan | `Grep visual_check_passed src` | 14 hits across 3 files (`classifier.py:5`, `pipeline.py:6`, `router.py:3`) | MATCH (Section 5.2 C2 row says "14 hits across `classifier.py` + `router.py` + `pipeline.py`") |
|
|
| C3 consumer scan | `Grep fit_classification src` | 30 hits across 4 files (`classifier.py:3`, `pipeline.py:20`, `retry.py:2`, `router.py:5`) | MATCH (Section 5.2 C3 row says "30 total occurrences across 4 files") |
|
|
| C6 family templates -- tracked | `git ls-files templates/phase_z2/families/` | 11 entries | MATCH (Section 5.2 C6 row says "tracked = 11") |
|
|
| C6 family templates -- on disk | `ls templates/phase_z2/families/*.html | wc -l` | 13 files (11 tracked + 2 WIP untracked : `app_sw_package_vs_solution.html`, `pre_construction_model_info_stacked.html`) | MATCH (Section 5.2 C6 row + F-2 follow-up candidate) |
|
|
| C6 frame_contracts entries | `grep -cE "^[a-z_]+:$" templates/phase_z2/catalog/frame_contracts.yaml` | 11 | MATCH (Section 5.2 C6 row says "= 11") |
|
|
|
|
No discrepancy between Section 5.2 grep evidence and live code. Re-verification re-confirms u3 Axis 3 conclusion : 6 invariant categories all AGREE; 2 record-keeping follow-up candidates (F-1, F-2); 1 documented partial (Step 21); 0 Blocker findings.
|
|
|
|
---
|
|
|
|
## Section 6. Axis 4 -- Backlog vs code reality status matrix
|
|
|
|
**Method** : per closed issue, compare (a) `docs/architecture/PHASE-Z-IMPLEMENTATION-ISSUE-BACKLOG.md` status column at audit time (live read 2026-05-19), (b) live src/ + templates/ + tests/ + docs/ evidence (grep hits + file existence), (c) the audit-allowed status enum `implemented | documented (deferred) | pending`, (d) mismatch flag.
|
|
|
|
**Per issue-body rule set** :
|
|
- `implemented` -> live grep on `src/**` MUST show wired call site(s); not just a single declaration with no consumer.
|
|
- `documented (deferred)` -> live grep on `src/**` MUST NOT show a production code path that assumes the feature is active (carve-out only).
|
|
- `pending` -> live grep on `src/**` MUST NOT show wired implementation (or evidence shows incomplete).
|
|
- `pending -> documented` flip -> reason cited in backlog row must match what `src/**` actually contains.
|
|
|
|
### 6.1 Backlog status legend (live read on audit date)
|
|
|
|
| backlog status | IMP rows under audit | meaning |
|
|
|---|---|---|
|
|
| `documented` | `IMP-18` (1 row) | doc-only carve-out, no production path |
|
|
| `pending` | `IMP-02` through `IMP-17` (16 rows) | backlog status column has NOT been flipped, despite Gitea issue being closed |
|
|
| (no backlog row) | `#45 / #46 / #47 / #48 / #49` (5 rows) | execution children of `#15`; backlog tracks the parent `IMP-15` only -- and `IMP-15` is itself still marked `pending` in §2 row |
|
|
|
|
**Headline Axis 4 finding** : `PHASE-Z-IMPLEMENTATION-ISSUE-BACKLOG.md` status column is **stale across the entire closed-issue audit scope** -- 16 of 22 audited issues are flagged `BACKLOG_STALE` (backlog `pending` vs Gitea closed + live code wired); additionally 5 of 22 carry `NO_BACKLOG_ROW` for the `#15` execution children (`#45-#49`), and only 1 of 22 (`#18`) is `AGREE`. Reconciliation: 16 `BACKLOG_STALE` + 5 `NO_BACKLOG_ROW` + 1 `AGREE` = 22 (matches Section 6.3 summary and the 15+1=16 flip plan in §6.3 follow-up reference). This is documentation drift, not a code-side contract conflict; recorded as Section 10 follow-up candidate `F-3`.
|
|
|
|
### 6.2 Axis 4 -- 22 row backlog vs code reality matrix
|
|
|
|
Status meaning (audit verdict column) :
|
|
- `implemented_live` = backlog should be flipped to `implemented`; live src/ wiring proves it (grep evidence below).
|
|
- `documented_live` = backlog `documented` matches code reality (doc-only carve-out; no prod path).
|
|
- `child_of_parent` = no backlog row by design (execution child of parent IMP-15); status tracked via parent row.
|
|
|
|
Mismatch flag :
|
|
- `BACKLOG_STALE` = backlog says `pending` but code is wired live. Documentation drift only; no code conflict.
|
|
- `AGREE` = backlog status matches live code reality.
|
|
- `NO_BACKLOG_ROW` = execution child, child not represented in backlog; not an error, but parent `IMP-15` row is itself stale.
|
|
|
|
| # | issue (title) | backlog status (live read) | audit verdict | mismatch flag | live grep evidence |
|
|
|---|---|---|---|---|---|
|
|
| 1 | `#2` IMP-02 A-1 Stage 0 normalize chained adapter | `pending` (§1 row 2) | `implemented_live` | BACKLOG_STALE | `Grep "normalize_mdx_content\|extract_major_sections\|extract_conclusion_text" src/` = 24 hits across 6 files (`mdx_normalizer.py`, `phase_z2_content_extractor.py`, `phase_z2_pipeline.py` 9 hits, `pipeline.py`, `pipeline_v2.py`, `section_parser.py`); commit `bac13c0` +165/-3 |
|
|
| 2 | `#3` IMP-03 A-1 popup/image/table trace | `pending` (§1 row 3) | `implemented_live` | BACKLOG_STALE | `src/phase_z2_content_extractor.py` file exists (Glob hit); commit `fc3f7d8` |
|
|
| 3 | `#4` IMP-04 A-2 catalog expansion | `pending` (§1 row 4) | `implemented_live` | BACKLOG_STALE | `git ls-files templates/phase_z2/families/` = 11 tracked; `frame_contracts.yaml` top-level entries = 11; commit `73a98b8` corrects F17 schema; matches Axis 3 C6 |
|
|
| 4 | `#5` IMP-05 A-5 V4 fallback | `pending` (§1 row 5) | `implemented_live` | BACKLOG_STALE | `Grep "PASS_WITH_FALLBACK\|v4_fallback\|fallback_selection" src/` = 28 hits in `phase_z2_pipeline.py`; commits `15c5b9a`, `21476ae`, `23d1b25` |
|
|
| 5 | `#6` IMP-06 B-1 Zone-section override | `pending` (§1 row 6) | `implemented_live` | BACKLOG_STALE | `Grep "replaced_auto_unit\|render_records\|zone_section_override" src/` = 33 hits in `phase_z2_pipeline.py`; commits `d596fab` / `b81e564` / `1f15495` / `52ccb7f` |
|
|
| 6 | `#7` IMP-07 B-2 edited HTML to MDX reverse path | `pending` (§1 row 7) | `implemented_live` | BACKLOG_STALE | `Front/client/src/services/designAgentApi.ts` file exists (Glob hit); commit `0f0d3fa` |
|
|
| 7 | `#8` IMP-08 B-3 sub-section drag-drop | `pending` (§1 row 8) | `implemented_live` | BACKLOG_STALE | `Grep "sub_sections\|sub_section_id\|subsection_alias" src/` = 14 hits across `block_assembler.py` (12) + `phase_z2_pipeline.py` (2); commits `a422d72` / `5191aca` / `ab2764c` / `8f6cffc` |
|
|
| 8 | `#9` IMP-09 B-4 non-default layout zone-geometry | `pending` (§1 row 9) | `implemented_live` | BACKLOG_STALE | `Grep "build_layout_css\|preset_layout\|zone_geometry" src/` = 11 hits in `phase_z2_pipeline.py`; commits `201099e` / `1fb9732` |
|
|
| 9 | `#10` IMP-10 D-1 filtered_section_reasons UI | `pending` (§1 row 10) | `implemented_live` | BACKLOG_STALE | `Grep "filtered_section_reasons" Front/` = 4 hits (`Home.tsx`, `designAgentApi.ts`); + `src/phase_z2_pipeline.py` 6 hits (read-only consumer); commit `0fb168b` +45 lines |
|
|
| 10 | `#11` IMP-11 D-2 Frame min_height display | `pending` (§1 row 11) | `implemented_live` | BACKLOG_STALE | `Grep "min_height_px" src/` = 50 hits across 6 files (`block_reference.py`, `block_selector.py`, `fit_verifier.py`, `phase_z2_pipeline.py` 21 hits, `phase_z2_retry.py`, `space_allocator.py`); + Front/ 21 hits across 7 files including `SlideCanvas.tsx` (8); commit `a79bd8b` |
|
|
| 11 | `#12` IMP-12 Step 16/17 retry refinement | `pending` (§2 row 12 IMP-12) | `implemented_live` | BACKLOG_STALE | `Grep "phase_z2_failure_router\|phase_z2_retry\|redistribute\|font_compression" src/` = 63 hits across 7 files (incl. `phase_z2_failure_router.py` 17, `phase_z2_retry.py` 16, `phase_z2_router.py` 6, `phase_z2_pipeline.py` 17); commit `56619a0` |
|
|
| 12 | `#13` IMP-13 A-3 frame preview consistency | `pending` (§2 row 13) | `implemented_live` | BACKLOG_STALE | `scripts/generate_frame_previews.py` file exists (Glob hit); build-time only (scripts/, not runtime src/) -- matches `documented (deferred)` semantics for *runtime* path but verdict here = implemented_live because the script is the deliverable per issue body; commit `7d5639a` |
|
|
| 13 | `#14` IMP-14 A-4 slide-base iframe mode | `pending` (§2 row 14) | `implemented_live` | BACKLOG_STALE | `templates/phase_z2/slide_base.html` file exists (Glob hit); `Grep "slide_base\|embedded_mode\|standalone_mode" src/` = 25 hits across 5 files (incl. `block_assembler.py` 8, `phase_z2_pipeline.py` 11); commit `7a52ceb` |
|
|
| 14 | `#15` IMP-15 Step 14 visual_check reinforcement (PARENT) | `pending` (§2 row 15) | `implemented_live` (via children `#45-#49`) | BACKLOG_STALE | parent integration only; live code attribution belongs to child rows below (Stage 1 de-dup rule). All 4 child SHAs present in repo (`e9b3d2e` / `2827622` / `535c484` / `614c533`) |
|
|
| 15 | `#16` IMP-16 B-2 verification helper axis | `pending` (§2 row 16) | `implemented_live` | BACKLOG_STALE | `src/phase_z2_verification_utils.py` file exists (Glob hit); `docs/architecture/IMP-16-U2-WIRING-DESIGN.md` exists; commit `23ba8b6` |
|
|
| 16 | `#17` IMP-17 AI repair fallback infra (carve-out) | `pending` (§2 row 17) | `documented_live` | BACKLOG_STALE (status semantics) | `docs/architecture/IMP-17-CARVE-OUT.md` file exists (Glob hit); src/ runtime AI = 0 (verified Axis 3 C5 boundary); 3-cond AND gate closed; commit `e10ec36` -- 1 line in `src/phase_z2_pipeline.py` is comment anchor only, not a runtime path. Mismatch FLAG semantics : backlog says `pending`, but reality = `documented (deferred)`. The flag is BACKLOG_STALE *with status-class shift*, distinguished from rows above. |
|
|
| 17 | `#18` IMP-18 I3 SVG coordinate reinforcement | `documented` (§2 row 18) | `documented_live` | AGREE | `docs/architecture/IMP-18-SVG-GAP-REPORT.md` file exists (Glob hit); pure doc carve-out; no `src/**` touched; commit `cbbc163` -- the ONLY closed audited issue whose backlog status already reflects code reality |
|
|
| 18 | `#45` (`#15` execution-1) image_aspect_mismatch detection | no backlog row | `child_of_parent` | NO_BACKLOG_ROW | `tests/phase_z2/test_phase_z2_step14_image_check.py` file exists (Glob hit); `Grep "image_aspect_mismatch" src/` = 6 hits across `phase_z2_classifier.py` (2 : lines 426, 435) + `phase_z2_pipeline.py` (4 : lines 131, 2236, 2367, 4517); commit `e9b3d2e` |
|
|
| 19 | `#46` (`#15` execution-2) table_self_overflow detection | no backlog row | `child_of_parent` | NO_BACKLOG_ROW | `tests/phase_z2/test_phase_z2_step14_table_check.py` file exists (Glob hit); `Grep "table_self_overflow" src/` = 3 hits all in `phase_z2_pipeline.py` (lines 136, 2282, 2386); commit `2827622` (commit-message label drift `feat(IMP-16)` flagged in Section 3 row 19) |
|
|
| 20 | `#47` (`#15` execution-3) classifier consumer (image + table) | no backlog row | `child_of_parent` | NO_BACKLOG_ROW | `tests/phase_z2/test_phase_z2_visual_classifier.py` file exists (Glob hit); `Grep "classify_visual_runtime_check\|CONTENT_TYPE_PATTERNS" src/` = 8 hits across `phase_z2_classifier.py` (4) + `phase_z2_pipeline.py` (4); commit `535c484` |
|
|
| 21 | `#48` (`#15` execution-4) debug.json event surfacing + spec doc + regression | no backlog row | `child_of_parent` | NO_BACKLOG_ROW | `Grep "step21_debug_index\|step21_debug" src/` = 1 hit (`phase_z2_pipeline.py`); `docs/architecture/PHASE-Z-FIT-CLASSIFIER-ROUTER-SPEC.md` has taxonomy row (Section 3 row 21 evidence); commit `614c533`; Axis 3 C4 confirms `image_events` / `table_events` end-to-end |
|
|
| 22 | `#49` (`#15` execution-5) final integration + parent close | no backlog row | `child_of_parent` (verification-only) | NO_BACKLOG_ROW + close-timestamp anomaly (recorded Section 3 row 22) | verification-only per `#15` body; no new SHA; re-uses `614c533` evidence; no fresh grep needed |
|
|
|
|
### 6.3 Axis 4 summary
|
|
|
|
- **BACKLOG_STALE** rows : `#2 #3 #4 #5 #6 #7 #8 #9 #10 #11 #12 #13 #14 #15 #16 #17` = 16 rows (status column reads `pending` but live code is wired; for `#17` the right target status is `documented (deferred)` while for the other 15 it is `implemented`).
|
|
- **AGREE** rows : `#18` = 1 row (the only issue whose backlog status truthfully reflects code reality).
|
|
- **NO_BACKLOG_ROW** rows : `#45 #46 #47 #48 #49` = 5 rows (execution children, by-design no backlog row; parent `IMP-15` row exists but is itself BACKLOG_STALE).
|
|
- **Total** : 16 + 1 + 5 = 22 rows (matches 22 closed issues under audit).
|
|
- **Implementation-vs-documented split** (audit verdict, ignoring backlog wording) :
|
|
- `implemented_live` (runtime path wired) : `#2 #3 #4 #5 #6 #7 #8 #9 #10 #11 #12 #13 #14 #15(via children) #16` = 15 rows
|
|
- `documented_live` (doc-only / design-only carve-out, no runtime path) : `#17 #18` = 2 rows
|
|
- `child_of_parent` (no backlog row, attribution via parent) : `#45-#49` = 5 rows
|
|
- **0 Blocker findings in Axis 4.** No closed issue is `pending` *and* unimplemented; the only mismatches are documentation drift in the backlog status column.
|
|
- **Cross-axis consistency** :
|
|
- Axis 3 C6 frame count `11 tracked / 11 contract entries / 13 on disk (2 WIP)` matches the IMP-04 evidence in Axis 4 row 3 (BACKLOG_STALE but live code present).
|
|
- Axis 3 C5 boundary (Phase R' <-> Phase Z) clean both ways re-confirms `#17 #18` as documented_live (no R' leak).
|
|
- Axis 1 (Section 3) `Warning` rows `#6 #12 #15 #46 #49` are all still `implemented_live` in Axis 4 -- the warnings are about *blast radius* and *administrative drift*, not implementation absence.
|
|
- **Follow-up candidate F-3** (Section 10) : `PHASE-Z-IMPLEMENTATION-ISSUE-BACKLOG.md` status column needs a sweep to flip 15 rows `pending` -> `implemented`, 1 row `pending` -> `documented (deferred)` for `IMP-17`, and either add child-row stubs for `#45-#49` or add a footnote on the `IMP-15` row pointing at the 5 execution children. This is a single-file documentation-only edit; orthogonal to source-code Stage 3 work; safe under audit-only scope (deferred to a separate follow-up issue, NOT this audit's u7 backlog row).
|
|
|
|
---
|
|
|
|
## Section 7. Representative pipeline runs
|
|
|
|
**Method** : run the Phase Z runtime entry (`python -m src.phase_z2_pipeline <mdx_path> <run_id>`) on the two locked samples (`samples/mdx_batch/03.mdx` smoke + `samples/mdx_batch/04.mdx` details+images). Per run capture (from `data/runs/<run_id>/phase_z2/debug.json`) : top-level keys, `slide_status.visual_check_passed`, `slide_status.overall`, zone count, per-zone frame template + slot keys + slot key count, `slide_status.visual_fail_reasons`, `slide_status.filtered_section_reasons`, `selection_paths`, `image_events` / `table_events` count. Compare invariants across both runs.
|
|
|
|
**Audit date** : 2026-05-19. Both runs are fresh on this audit pass (run_ids `audit50_run_03_smoke` + `audit50_run_04_details`).
|
|
|
|
### 7.1 Run #1 -- `samples/mdx_batch/03.mdx` (smoke baseline)
|
|
|
|
| field | value |
|
|
|---|---|
|
|
| `run_id` | `audit50_run_03_smoke` |
|
|
| MDX title parsed | `DX 실행 체계 구축 방안` |
|
|
| sections parsed | 2 (`03-1`, `03-2`) |
|
|
| layout preset | `horizontal-2` (composition v0 count-based) |
|
|
| mode | `composition_v0_layout_8preset` |
|
|
| debug.json top-level keys | `composition_planner_debug`, `fit_classification`, `image_events`, `layout_css`, `layout_preset`, `mode`, `mode_note`, `mvp1_allowed_statuses`, `retry_trace`, `router_decision`, `slide_status`, `table_events`, `v4_label_to_phase_z_status`, `v4_source`, `visual_runtime_check`, `zone_geometries_px`, `zones` (17 keys) |
|
|
| `slide_status.visual_check_passed` | `True` |
|
|
| `slide_status.full_mdx_coverage` | `True` |
|
|
| `slide_status.rendered` | `True` |
|
|
| `slide_status.overall` | `PASS` |
|
|
| `slide_status.visual_fail_reasons` | `[]` (empty) |
|
|
| `slide_status.filtered_section_reasons` | `[]` (empty) |
|
|
| `slide_status.fallback_selection_count` | `0` |
|
|
| `fit_classification.visual_check_passed` | `True` (mirrors slide_status) |
|
|
| `fit_classification.classifications` | `[]` |
|
|
| `fit_classification.categories_seen` | `[]` |
|
|
| `router_decision.action` | `None` (no retry path triggered) |
|
|
| `image_events` count | `0` |
|
|
| `table_events` count | `0` |
|
|
| zone count | `2` |
|
|
| zone[0] (top) | template `three_parallel_requirements` (frame 13), contract `three_parallel_requirements`, label `use_as_is`, slot keys `['pillars', 'title']` (2), sections `['03-1']`, `height_px=228`, `width_px=1180` |
|
|
| zone[1] (bottom) | template `process_product_two_way` (frame 29), contract `process_product_two_way`, label `use_as_is`, slot keys `['banner_left', 'banner_right', 'process', 'product', 'title']` (5), sections `['03-2']`, `height_px=343`, `width_px=1180` |
|
|
| `selection_paths` | both `rank_1` (no fallback) |
|
|
| fail / overflow events | none |
|
|
|
|
### 7.2 Run #2 -- `samples/mdx_batch/04.mdx` (details + images)
|
|
|
|
| field | value |
|
|
|---|---|
|
|
| `run_id` | `audit50_run_04_details` |
|
|
| MDX title parsed | `DX 지연 요인` |
|
|
| sections parsed | 2 (`04-1`, `04-2`) |
|
|
| sections aligned | 3 (`04-1`, `04-2-sub-1`, `04-2-sub-2`) -- IMP-08 sub_section schema active |
|
|
| layout preset | `single` (composition v0 count-based; only 1 unit survived filtering) |
|
|
| mode | `composition_v0_layout_8preset` |
|
|
| debug.json top-level keys | identical 17 keys as Run #1 (`composition_planner_debug`, `fit_classification`, `image_events`, `layout_css`, `layout_preset`, `mode`, `mode_note`, `mvp1_allowed_statuses`, `retry_trace`, `router_decision`, `slide_status`, `table_events`, `v4_label_to_phase_z_status`, `v4_source`, `visual_runtime_check`, `zone_geometries_px`, `zones`) |
|
|
| `slide_status.visual_check_passed` | `True` |
|
|
| `slide_status.full_mdx_coverage` | `False` |
|
|
| `slide_status.rendered` | `True` (partial artifact -- viable units only) |
|
|
| `slide_status.overall` | `PARTIAL_COVERAGE` |
|
|
| `slide_status.visual_fail_reasons` | `[]` (visual side OK; coverage failure is upstream of visual_check) |
|
|
| `slide_status.filtered_section_reasons` | `[]` (filtering recorded via `selection_paths` chain_exhausted / no_v4_candidate, not via `filtered_section_reasons`) |
|
|
| `slide_status.fallback_selection_count` | `0` |
|
|
| `fit_classification.visual_check_passed` | `True` |
|
|
| `fit_classification.classifications` | `[]` |
|
|
| `fit_classification.categories_seen` | `[]` |
|
|
| `router_decision.action` | `None` |
|
|
| `image_events` count | `0` |
|
|
| `table_events` count | `0` |
|
|
| zone count | `1` (single preset) |
|
|
| zone[0] (primary) | template `bim_issues_quadrant_four` (frame 16), contract `bim_issues_quadrant_four`, label `light_edit`, slot keys `['quadrant_1_body', 'quadrant_1_label', 'quadrant_2_body', 'quadrant_2_label', 'quadrant_3_body', 'quadrant_3_label', 'quadrant_4_body', 'quadrant_4_label', 'title']` (9), sections `['04-2-sub-2']`, `height_px=585`, `width_px=1180` |
|
|
| `selection_paths` | `04-1=chain_exhausted`, `04-2-sub-1=chain_exhausted`, `04-2-sub-2=rank_1`, `04-2=no_v4_candidate` |
|
|
| fail / overflow events | none |
|
|
|
|
### 7.3 Cross-run invariants
|
|
|
|
| invariant | run #1 (03.mdx) | run #2 (04.mdx) | verdict |
|
|
|---|---|---|---|
|
|
| debug.json top-level key set | 17 keys (above) | identical 17 keys | AGREE -- Step 21 schema stable across both runs (Axis 3 C1) |
|
|
| `slide_status` schema keys | 19 keys (`visual_check_passed`, `full_mdx_coverage`, `rendered`, `overall`, `visual_fail_reasons`, `filtered_section_ids`, `filtered_section_reasons`, `aligned_section_ids`, `covered_section_ids`, `adapter_needed_count`, `adapter_needed_units`, `content_truncated_count`, `content_truncated_units`, `fallback_selection_count`, `fallback_selections`, `fallback_used`, `selection_path`, `selection_paths`, `note`) | identical 19 keys | AGREE -- slide_status surface stable (Axis 3 C2 + C4) |
|
|
| `fit_classification` shape | `{visual_check_passed, classifications, summary, categories_seen, ...}` -- matches Axis 3 C3 row | identical shape | AGREE -- classifier output schema invariant |
|
|
| `visual_check_passed` semantic | `True` AND `classifications=[]` -> overall `PASS` | `True` AND `classifications=[]` AND `full_mdx_coverage=False` -> overall `PARTIAL_COVERAGE` | AGREE -- visual side passing under both runs; `PARTIAL_COVERAGE` is composition-planner side (upstream of Step 14), so visual_check_passed does NOT contradict overall status (Axis 3 C2 verdict re-confirmed) |
|
|
| zone count vs layout preset | `horizontal-2` -> 2 zones (top + bottom) | `single` -> 1 zone (primary) | AGREE -- preset-to-zone arity matches IMP-09 B-4 vocabulary (Axis 1 row 8) |
|
|
| frame contract resolution | both zones resolved to a contract id (rank_1 path) | only 1 of 4 selection paths resolved (3 `chain_exhausted` / `no_v4_candidate`) | DIFF EXPECTED -- 04.mdx exhibits v4 candidate gap; this is the composition-planner maturity gap (not in any closed-issue scope). Not a contract conflict. |
|
|
| `image_events` / `table_events` arity | both = 0 | both = 0 | AGREE -- neither sample triggers Step 14 image/table self-overflow; `#45` `image_aspect_mismatch` and `#46` `table_self_overflow` event-arrays exist in the schema and are *correctly empty* when no overflow is detected |
|
|
| router action triggered | `None` | `None` | AGREE -- Step 16 router is dormant when classifications=[] (Axis 3 C3 verdict re-confirmed; `#12` retry cascade not exercised by these samples) |
|
|
| pipeline final banner | `PASS` (full MDX coverage + visual OK) | `PARTIAL_COVERAGE` (visual OK + composition-planner filter) | self-honest status naming per [[feedback_artifact_status_naming]] |
|
|
|
|
### 7.4 Run-level findings
|
|
|
|
- Both runs pass the visual_check axis (Axis 3 C2 contract). `visual_check_passed=True` agrees between `fit_classification` and `slide_status` mirror in both runs.
|
|
- 04.mdx `PARTIAL_COVERAGE` is a composition-planner side filter (3 sections drop to `chain_exhausted` / `no_v4_candidate` before reaching Step 14). This is NOT an audit Blocker because (a) no closed issue under audit targets composition-planner coverage, (b) the status field is self-honestly named `PARTIAL_COVERAGE` rather than misnamed `PASS` (matches [[feedback_artifact_status_naming]]).
|
|
- Step 21 `debug.json` writer surfaces a stable 17-key top-level surface across both runs; Axis 3 C1 invariant re-confirmed at runtime.
|
|
- Zero Blocker findings in Section 7.
|
|
|
|
---
|
|
|
|
## Section 8. Anti-hardcoding grep checklist
|
|
|
|
**Method** : run the 6 anti-hardcoding patterns enumerated in the Issue #50 body. For each, capture the live hit set, classify hits (Phase Z scope vs. legacy Phase R'/Q out-of-scope vs. docstring/comment vs. test fixture), then return a verdict. Raw output preserved at `D:\ad-hoc\kei\design_agent\.orchestrator\tmp\50_grep_checklist_raw.txt` (evidence-only, not staged for commit per Stage 3 directive).
|
|
|
|
**Audit date** : 2026-05-19. Searched against tracked source on this date.
|
|
|
|
### 8.1 Checklist
|
|
|
|
| # | pattern (issue body) | expected | live hit count (src/) | hit classification | verdict |
|
|
|---|---|---|---|---|---|
|
|
| G1 | `grep -E 'if .* == ["'\\''].*\.mdx' src/` | 0 hits | 0 | none | PASS |
|
|
| G2 | `grep -E 'OVERRIDES\s*=\s*\{' src/` | each match sample-agnostic | 0 | none | PASS (vacuously sample-agnostic) |
|
|
| G3 | `grep -E '재구성\|건설산업 DX\|BIM' src/` -- sample text leak | 0 hits | 31 source hits across 14 `.py` files (binary `.pyc` matches ignored) | (a) 20 hits in legacy Phase R'/Q files (`block_assembler_b2.py` 1, `block_matcher_tfidf.py` 1, `block_reference.py` 3, `content_editor.py` 3, `design_director.py` 2, `design_tokens.py` 1, `fit_verifier.py` 1, `frame_extractor.py` 1, `kei_client.py` 4, `pipeline.py` 3) -- pre-Phase-Z; not in audit window; (b) 11 hits in Phase Z files (`phase_z2_content_extractor.py` 7 -- all inside `if __name__ == "__main__"` self-test data blocks at lines 466/493/511/556/565/573/591; `phase_z2_failure_router.py:123` 1 -- internal taxonomy string `"topology 부터 재구성. frame_reselect 는 그 다음 단계"`; `phase_z2_mapper.py:519/529` 2 -- docstring examples; `phase_z2_retry.py:59` 1 -- docstring). Per-file count sum = 20 + 11 = 31, matching the live total. | PASS for the audit scope -- **0 closed-issue (#2-#18 + #45-#49)** introduces new sample-specific hardcoded BIM/재구성/건설산업 string literals into runtime code paths. All 11 Phase Z hits are docstring/taxonomy/self-test fixtures, none injected into runtime contracts. Legacy 20 hits are out of audit window. Recorded as Section 10 follow-up candidate `F-4` for future cleanup (doc-only, optional). |
|
|
| G4 | `grep -E 'height\s*=\s*720\|aspect\s*=\s*0\.5' src/` -- magic literal pinning | 0 hits | 0 | none | PASS |
|
|
| G5 | sample paths come from CLI args / config, not hardcoded | sample-agnostic | 4 occurrences across 2 files (`src/block_assembler.py:1390/1393` + `src/image_utils.py:62/65`) | all 4 hits use `samples/mdx_batch` as one of several **generic asset search directories** alongside `samples/images` (image asset discovery fallback). The directory is treated as a discovery namespace, not as a path to a specific MDX file. CLI entry (`src/phase_z2_pipeline.py:4861`) takes `mdx_path` as positional arg -- no hardcoded MDX path on the runtime entry. | PASS -- sample-agnostic asset discovery default; not a per-sample pin. |
|
|
| G6 | `tests/` : sample-specific fixtures only under `tests/fixtures/`, not in production pipeline | fixtures isolated | `tests/fixtures/` directory does not exist; closest hits = `tests/phase_z2/test_pz2_vu_integration.py:6, 82` referencing `samples/mdx_batch/02.mdx` as smoke-coverage MDX | the references in `test_pz2_vu_integration.py` are inside a verification-utility integration test (`#16` IMP-16 scope). The test file is named with the test prefix and lives in `tests/phase_z2/`, so pytest discovery treats it as a test, not as a production module. No production pipeline file imports a sample MDX path literal. | PASS WITH NOTE -- no `tests/fixtures/` directory exists today; the existing integration tests already keep sample references inside `tests/phase_z2/test_*.py`, which discharges the spirit of the rule. Optional follow-up: formalize a `tests/fixtures/` directory if sample inventory grows. Recorded as Section 10 follow-up candidate `F-5` (low priority, doc-only). |
|
|
|
|
### 8.2 Anti-hardcoding verdict
|
|
|
|
- 4 patterns PASS cleanly with 0 hits (G1, G2, G4) and 1 PASS with sample-agnostic hits (G5).
|
|
- 1 pattern PASS-for-audit-scope with classification (G3) : 11 Phase Z hits are all docstrings/taxonomy/self-test fixtures; 20 legacy hits are out of the 22-closed-issue audit window. Per-file counts sum to 31, matching the live grep total. No closed issue introduces new hardcoded sample text into a runtime code path.
|
|
- 1 pattern PASS WITH NOTE (G6) : `tests/fixtures/` directory not yet established; existing integration test references stay inside `tests/phase_z2/`. Already aligned with the spirit of the rule.
|
|
- **0 Blocker findings in Section 8.**
|
|
- Cross-axis : the F-4 / F-5 follow-up candidates are doc-only optional cleanup; they do not alter any closed-issue contract.
|
|
|
|
---
|
|
|
|
## Section 9. Final decision
|
|
|
|
**Decision** : **CONDITIONAL GO for #19**.
|
|
|
|
### 9.1 Summary across all 4 audit axes + supporting sections
|
|
|
|
| section | axis | Blocker | Warning | OK | follow-up candidates |
|
|
|---|---|---|---|---|---|
|
|
| §3 | Axis 1 -- scope myopia | 0 | 5 (`#6 #12 #15 #46 #49`) | 17 | none Blocker; warnings are blast-radius + administrative drift |
|
|
| §4 + MATRIX.md | Axis 2 -- 22 x 22 pipeline matrix | 0 | (9 hotspot steps, 2 expected-empty cols) | 22 issues mapped | none Blocker; hotspots match expected Step 14 / 21 attention |
|
|
| §5 | Axis 3 -- cross-issue conflict (6 invariants) | 0 | 0 | 6 categories AGREE | F-1 (body cites mapper.py; live producer is classifier.py for `fit_classification`); F-2 (13 family templates on disk vs. 11 tracked / contracted -- 2 WIP outside any closed issue) |
|
|
| §6 | Axis 4 -- backlog vs code reality | 0 | -- | 1 AGREE, 16 BACKLOG_STALE (doc drift), 5 NO_BACKLOG_ROW (by design for `#45-#49`) | F-3 (backlog status sweep : flip 15 rows `pending` -> `implemented`, 1 row `pending` -> `documented (deferred)` for IMP-17, footnote `IMP-15` row with 5 children) |
|
|
| §7 | representative runs (03.mdx + 04.mdx) | 0 | -- | both runs visual_check_passed = True; debug.json schema stable; 04.mdx PARTIAL_COVERAGE is composition-planner side (no audit-window contract conflict) | none new |
|
|
| §8 | grep checklist (6 patterns from issue body) | 0 | -- | G1/G2/G4/G5 PASS; G3/G6 PASS WITH NOTE | F-4 (legacy Phase R'/Q BIM literals -- optional cleanup); F-5 (formalize `tests/fixtures/` -- optional) |
|
|
| §2 | baseline pytest | -- | -- | 303 passed BEFORE + 303 passed AFTER audit | none |
|
|
|
|
### 9.2 Blocker tally
|
|
|
|
- **0 Blocker** findings across all four axes and all supporting sections.
|
|
- 5 Warning rows in §3 are about blast radius (`#6 #12`), administrative commit-label drift (`#46`), and parent/child close-timestamp anomaly (`#15 #49`). None of them indicate broken code contracts.
|
|
- All BACKLOG_STALE rows in §6 are documentation drift, not implementation absence. Live grep on `src/**` confirms each closed issue is wired (or carved-out as designed for `#17 #18`).
|
|
- 5 follow-up candidates (F-1 .. F-5) are all doc-only. None require source code changes.
|
|
|
|
### 9.3 Why CONDITIONAL GO, not unconditional GO
|
|
|
|
Audit found zero Blocker, but the conditions for upgrading to unconditional GO are not met because:
|
|
|
|
1. **F-3 (backlog sweep)** is the largest doc-drift surface (16 of 22 audited rows mislabeled). Issue #19 will read the backlog when scoping next-step coverage; running #19 against a stale backlog risks a planner who treats already-implemented features as still pending. The F-3 follow-up should be filed and merged before -- or at minimum in parallel with -- #19 Stage 2 planning.
|
|
2. **F-2 (family template count drift)** matters if #19 touches the catalog / `frame_contracts.yaml` (likely). The audit confirms 11 tracked entries are consistent today, but #19 should reconcile the 2 WIP files (`app_sw_package_vs_solution.html`, `pre_construction_model_info_stacked.html`) before adding any new family templates.
|
|
3. **F-1 (record-keeping for invariant C3 producer file path)** -- a small but real mismatch between the issue body wording (`src/phase_z2_mapper.py`) and the live producer (`src/phase_z2_classifier.py`). Should be fixed in the audit charter / spec doc before the next integration audit so future audits do not repeat the same drift check.
|
|
|
|
F-4 / F-5 are optional and do not gate #19.
|
|
|
|
### 9.4 Conditions to satisfy for #19 progression
|
|
|
|
- File F-1 / F-2 / F-3 as Section 10 follow-up issues (text-only drafts produced in u6).
|
|
- F-3 backlog sweep should land before #19 Stage 2 (so #19 plans against accurate status).
|
|
- F-2 family template reconciliation should land before #19 introduces new family templates (whichever comes first).
|
|
- F-1 is a one-line spec-doc edit, can land any time before the next INTEGRATION-AUDIT issue is opened.
|
|
|
|
### 9.5 Decision sentence
|
|
|
|
> **Issue #19 is approved for entry under CONDITIONAL GO**, with the explicit dependency that follow-up F-3 (backlog status sweep) must land before #19 Stage 2 planning consumes the backlog, and F-2 (family template reconciliation) must land before any #19 work that extends the catalog. No production source code change is required from this audit. Pytest baseline stable (303 passed BEFORE + AFTER).
|
|
|
|
---
|
|
|
|
## Section 10. Follow-up issue drafts (text-only, not auto-posted)
|
|
|
|
**Scope rule (Stage 2 u6 contract)** : per-draft fields = `title` + `source_axis` (1-4) + `scope` (what files / what change) + `evidence_link` (REPORT section that produced the finding). **No Gitea post.** Final disposition of each candidate is the orchestrator / human triage decision after #50 closes; this REPORT only records the audit-side text.
|
|
|
|
Five candidates were produced by Axes 1-4. F-3 + F-2 + F-1 are blocking conditions for upgrading §9 CONDITIONAL GO -> unconditional GO for #19; F-4 + F-5 are optional housekeeping. None require source-code changes inside this audit.
|
|
|
|
### 10.1 F-1 -- audit charter record-keeping : invariant C3 producer file path -- RESOLVED via IMP-53 (2026-05-19)
|
|
|
|
- **title** : `[AUDIT-CHARTER-FIX] invariant C3 (fit_classification) producer cited as src/phase_z2_mapper.py; live producer is src/phase_z2_classifier.py`
|
|
- **source_axis** : Axis 3 (cross-issue conflict, invariant category C3) -- recorded in §5.2 C3 row + §5.4 follow-up bullet F-1.
|
|
- **scope** :
|
|
- one-line fix in any future INTEGRATION-AUDIT-* issue body or in `docs/architecture/PHASE-Z-PIPELINE-OVERVIEW.md` if it cites the wrong file for `fit_classification` producer.
|
|
- replace text `src/phase_z2_mapper.py` -> `src/phase_z2_classifier.py` *only in the context of `fit_classification` invariant* (mapper.py legitimately owns slot payload and registries, so do not blanket-rename).
|
|
- update audit charter template (if one exists) so the next integration audit does not repeat the drift check.
|
|
- **scope-lock** : **doc-only**, zero `src/**` / `templates/**` / `tests/**` edits.
|
|
- **evidence_link** :
|
|
- REPORT §5.2 row C3 (issue body wording vs. live producer).
|
|
- REPORT §5.4 follow-up bullet F-1.
|
|
- Live producer site : `src/phase_z2_classifier.py:495-497` (return dict with `visual_check_passed`, `classifications`, `summary`, `categories_seen`, `unclassified_signals`, `placement_diagnostics`).
|
|
- **priority / gating** : low priority on its own; required for charter cleanliness; **not** a blocker for #19 Stage 2.
|
|
|
|
### 10.2 F-2 -- family template count reconciliation : 11 tracked / 11 contracted / 13 on disk -- RESOLVED via #52 (option c, 2026-05-19)
|
|
|
|
- **title** : `[FAMILY-TEMPLATE-RECONCILE] templates/phase_z2/families/ has 13 .html files on disk but 11 tracked + 11 frame_contracts entries; 2 WIP files (app_sw_package_vs_solution.html, pre_construction_model_info_stacked.html) untracked`
|
|
- **source_axis** : Axis 3 (invariant category C6 template / catalog / frame count) -- recorded in §5.2 C6 row + §5.4 follow-up bullet F-2 + §6.3 Axis 4 cross-axis consistency bullet.
|
|
- **scope** :
|
|
- decide whether the 2 untracked WIP family templates (`app_sw_package_vs_solution.html`, `pre_construction_model_info_stacked.html`) should be (a) tracked + contracted (add to `frame_contracts.yaml`, add to `git ls-files`), (b) removed if abandoned, or (c) explicitly noted as in-progress with a parent issue.
|
|
- reconcile the IMP-18 SVG-gap report doc citation `families/*.html (13)` against whichever decision is chosen (so the doc count matches code reality).
|
|
- **scope-lock** : touches `templates/phase_z2/families/*.html`, `templates/phase_z2/catalog/frame_contracts.yaml`, `docs/architecture/IMP-18-SVG-GAP-REPORT.md`. **Must NOT be folded into #19 silently**: any catalog growth needs a dedicated issue per [[feedback_workflow_atomicity_rules]] (one commit = one decision).
|
|
- **evidence_link** :
|
|
- REPORT §5.2 row C6 ("AGREE FOR TRACKED BASELINE -- 11 tracked family templates <-> 11 frame_contracts entries").
|
|
- REPORT §5.5 row "C6 family templates -- on disk" (`ls templates/phase_z2/families/*.html` = 13).
|
|
- REPORT §6.3 Axis 4 cross-axis consistency bullet (matches IMP-04 evidence).
|
|
- **priority / gating** : **must land before #19 introduces any new family template** (per §9.3 condition 2). Until #19's catalog touch surface is known, this can be filed independently.
|
|
- **resolution** : option (c) -- 2 WIP family templates explicitly noted as in-progress and tracked outside `frame_contracts.yaml` (RESOLVED via Gitea #52, 2026-05-19) :
|
|
- WIP allowlist : `templates/phase_z2/families/_WIP_FILES.md` (added by #52 u1) -- names both files with Figma frame IDs (`app_sw_package_vs_solution.html` -> frame 23 / `1171281203`; `pre_construction_model_info_stacked.html` -> frame 9 / `1171281180`) and explicit "not in `frame_contracts.yaml`, not in runtime matcher set" status; promote / remove gated on Gitea #42.
|
|
- IMP-18 doc reconciled : `docs/architecture/IMP-18-SVG-GAP-REPORT.md` L28 + L30 + L51 corrected from disk-only "13 files" / "15 partials" wording to "11 contracted + 2 WIP untracked = 13 on disk" (#52 u2) -- runtime matcher consumes the contracted set only; doc / tracked / contracted surfaces agree at 11 active.
|
|
- baseline guard (planned by #52 u4) : `tests/test_family_contract_baseline.py` will enforce tracked families <-> `frame_contracts.yaml` 1:1 set-equality modulo WIP allowlist parsed from `_WIP_FILES.md`; future drift (#42 or otherwise) fails CI.
|
|
- tracked baseline (11 contracted families <-> 11 `frame_contracts.yaml` entries) unchanged; no contract entries added or removed; no runtime matcher mutation; **C6 invariant remains AGREE** for the closed-issue audit scope.
|
|
- **F-2 closed-by-#52** under [[feedback_workflow_atomicity_rules]] (one commit = one decision unit), without re-opening any §5 C-invariant or §6.3 Axis 4 conclusion. #19 catalog-touch gate (per §9.3 condition 2) is now satisfied for the current 11/11 baseline; any #19 / #42 catalog growth must reconcile the WIP allowlist before merge.
|
|
|
|
### 10.3 F-3 -- backlog status sweep : 15 rows pending->implemented + 1 row pending->documented(deferred) + IMP-15 children footnote
|
|
|
|
- **title** : `[BACKLOG-STATUS-SWEEP] PHASE-Z-IMPLEMENTATION-ISSUE-BACKLOG.md has 16 of 22 audited rows mislabeled as pending; flip 15 to implemented, 1 (IMP-17) to documented (deferred), footnote IMP-15 with 5 execution children`
|
|
- **source_axis** : Axis 4 (backlog vs code reality) -- recorded in §6.1 headline finding + §6.2 22-row matrix + §6.3 follow-up candidate F-3 + §9.1 §6 row + §9.3 condition 1.
|
|
- **scope** :
|
|
- **15 rows** to flip `pending` -> `implemented` : IMP-02, IMP-03, IMP-04, IMP-05, IMP-06, IMP-07, IMP-08, IMP-09, IMP-10, IMP-11, IMP-12, IMP-13, IMP-14, IMP-15 (parent), IMP-16.
|
|
- **1 row** to flip `pending` -> `documented (deferred)` : IMP-17 (status-class shift; runtime AI = 0, 3-cond AND gate closed; matches §6.2 row 16).
|
|
- **IMP-15 row** : add inline footnote citing the 5 execution children commits `#45 (e9b3d2e)`, `#46 (2827622)`, `#47 (535c484)`, `#48 (614c533)`, `#49 (verification-only, re-uses 614c533)`. Either as a footnote on the IMP-15 row or as 5 child stub rows -- pick one and apply consistently.
|
|
- **IMP-18 row** : leave as `documented` (already AGREE per §6.2 row 17).
|
|
- **scope-lock** : single-file edit to `docs/architecture/PHASE-Z-IMPLEMENTATION-ISSUE-BACKLOG.md`. **Doc-only**, zero `src/**` / `templates/**` / `tests/**` edits. Must be filed as a separate Gitea issue with its own Stage 5 commit (not merged into #19 or any other improvement issue).
|
|
- **evidence_link** :
|
|
- REPORT §6.1 headline finding (16 BACKLOG_STALE + 5 NO_BACKLOG_ROW + 1 AGREE = 22).
|
|
- REPORT §6.2 22-row matrix (per-row grep evidence + commit SHAs).
|
|
- REPORT §6.3 follow-up reference.
|
|
- REPORT §9.1 / §9.3 condition 1 ("F-3 backlog sweep should land before #19 Stage 2 planning consumes the backlog").
|
|
- **priority / gating** : **highest of the 5 candidates**. **Must land before #19 Stage 2 planning** (per §9.3 condition 1) so that #19's planner reads accurate `implemented` / `documented (deferred)` status and does not treat already-wired features as still pending.
|
|
|
|
### 10.4 F-4 -- legacy Phase R' / Q sample-literal cleanup (OPTIONAL)
|
|
|
|
- **title** : `[LEGACY-LITERAL-CLEANUP] 20 hits of 재구성 / 건설산업 DX / BIM across 10 legacy Phase R'/Q files (block_assembler_b2.py, block_matcher_tfidf.py, block_reference.py, content_editor.py, design_director.py, design_tokens.py, fit_verifier.py, frame_extractor.py, kei_client.py, pipeline.py)`
|
|
- **source_axis** : Axis-supporting Section 8 (anti-hardcoding grep checklist) -- recorded in §8.1 row G3 + §8.2 third bullet + §9.1 §8 row.
|
|
- **scope** :
|
|
- per-file review of the 20 legacy hits to determine which are docstrings / comments (keep), legacy taxonomy (keep with annotation), or true sample-literal pins (remove or generalize).
|
|
- per-file counts to triage : `block_assembler_b2.py` 1, `block_matcher_tfidf.py` 1, `block_reference.py` 3, `content_editor.py` 3, `design_director.py` 2, `design_tokens.py` 1, `fit_verifier.py` 1, `frame_extractor.py` 1, `kei_client.py` 4, `pipeline.py` 3.
|
|
- **NOT** touching the 11 Phase Z hits (`phase_z2_content_extractor.py` 7 self-test data, `phase_z2_failure_router.py:123` taxonomy, `phase_z2_mapper.py:519/529` docstring examples, `phase_z2_retry.py:59` docstring) -- those passed audit verdict G3.
|
|
- **scope-lock** : potentially touches legacy `src/**` files NOT in the Phase Z 22-step pipeline. Must be filed as a deliberate cleanup issue with its own scope-lock. If any file flagged here turns out to be on a live Phase Z code path on review, demote the candidate or split it.
|
|
- **evidence_link** :
|
|
- REPORT §8.1 row G3 (per-file count breakdown, audit date 2026-05-19).
|
|
- REPORT §8.2 third bullet (20 legacy + 11 Phase Z = 31, reconciliation).
|
|
- Raw grep output : `D:\ad-hoc\kei\design_agent\.orchestrator\tmp\50_grep_checklist_raw.txt`.
|
|
- **priority / gating** : **optional, low priority, doc-only follow-up note**. Does NOT gate #19; §8 verdict already PASS for audit scope. Recorded for completeness so future audits do not re-discover the same 20-hit baseline.
|
|
|
|
### 10.5 F-5 -- formalize tests/fixtures/ directory (OPTIONAL)
|
|
|
|
- **title** : `[TESTS-FIXTURES-FORMALIZE] tests/fixtures/ directory does not exist; sample MDX references currently live in tests/phase_z2/test_pz2_vu_integration.py`
|
|
- **source_axis** : Axis-supporting Section 8 (anti-hardcoding grep checklist G6) -- recorded in §8.1 row G6 + §8.2 fourth bullet.
|
|
- **scope** :
|
|
- if-and-only-if sample inventory grows beyond what fits inside `tests/phase_z2/test_*.py` files, formalize a `tests/fixtures/` directory holding sample-specific fixtures.
|
|
- migrate existing `samples/mdx_batch/02.mdx` references in `tests/phase_z2/test_pz2_vu_integration.py:6, 82` only if migration is part of a broader test-fixture refactor (otherwise leave them as integration smoke).
|
|
- update the issue-body rule wording to acknowledge that `tests/phase_z2/test_*.py` already discharges the spirit of "no sample-specific fixtures in production pipeline".
|
|
- **scope-lock** : touches `tests/fixtures/` (new directory if filed) + the cited test files. Must NOT be folded into any unrelated test refactor.
|
|
- **evidence_link** :
|
|
- REPORT §8.1 row G6 verdict "PASS WITH NOTE".
|
|
- REPORT §8.2 fourth bullet (`tests/fixtures/` not yet established).
|
|
- **priority / gating** : **optional, very low priority**. Filing is only justified when sample inventory grows; the current state is already aligned with the spirit of the rule.
|
|
|
|
#### 10.5.1 F-5 docs-only resolution addendum (#54 Stage 3 u5, 2026-05-19)
|
|
|
|
Per issue #54 Stage 2 plan, F-5 is closed as **docs-only**; no root `tests/fixtures/` directory is created in this work. The current fixture inventory does not justify migration, and the existing convention is sufficient. The convention is recorded here so future anti-hardcoding audits can distinguish fixture / test-only paths from production paths without re-discovering the §8 G6 PASS-WITH-NOTE baseline.
|
|
|
|
- **Existing convention (DO NOT CHANGE)** : `tests/phase_z2/fixtures/` exists as a YAML regression fixture root (loaded by `tests/phase_z2/test_fixtures_loader.py`). Subdirectories present at audit time : `tests/phase_z2/fixtures/build_layout_css/`, `tests/phase_z2/fixtures/retry_gate/`. This is the canonical home for Phase Z regression fixtures.
|
|
- **Root `tests/fixtures/` (ABSENT)** : not created in #54. If a future change requires a non-Phase-Z, non-YAML fixture corpus (for example, multi-file MDX golden inputs that grow beyond what `tests/phase_z2/test_*.py` can hold inline), the migration must be filed as its own Gitea issue with its own scope-lock per §10.5.
|
|
- **Allowed sample references** : `samples/mdx_batch/**` and `samples/mdx/**` may be referenced from `tests/**` (test-only paths) for integration smoke -- e.g. the existing `samples/mdx_batch/02.mdx` references in `tests/phase_z2/test_pz2_vu_integration.py`. These do not violate the §8 anti-hardcoding rule because the spirit of the rule targets production pipeline code, not test runners.
|
|
- **Forbidden sample references** : production pipeline code (`src/**` runtime path) must NOT hardcode sample-specific MDX filenames or content (e.g. `02.mdx`, `03.mdx`, frame-specific labels keyed to a sample). The 20 legacy Phase R'/Q hits annotated under F-4 (#54 Stage 3 u1-u4) are intentional documented examples in docstrings / comments / glossary regex / sample-data dicts, not runtime input pins; they are out of scope for this rule by §10.4 verdict.
|
|
- **AI-isolation contract** : this addendum is text-only. No production behavior change, no runtime sample-path mutation, no new fixture file. Compatible with PZ-1 (AI = 0 on normal path) and [[feedback_ai_isolation_contract]].
|
|
- **Cross-reference** : `tests/CLAUDE.md` fixture convention note (#54 Stage 3 u5) mirrors the test-only / production rule split documented here.
|
|
|
|
### 10.6 Follow-up summary
|
|
|
|
| candidate | source axis | doc-only? | gates #19? | priority |
|
|
|---|---|---|---|---|
|
|
| F-1 audit-charter producer file path | Axis 3 (§5) | YES | NO | low (charter cleanup) |
|
|
| F-2 family template count reconcile | Axis 3 (§5) | NO -- touches templates / catalog / docs | gate IF #19 extends catalog | medium |
|
|
| F-3 backlog status sweep | Axis 4 (§6) | YES | YES -- must land before #19 Stage 2 plan | **highest** |
|
|
| F-4 legacy R'/Q literal cleanup | §8 (anti-hardcoding) | NO -- legacy src/ touch surface | NO | low (optional) |
|
|
| F-5 tests/fixtures/ formalize | §8 (anti-hardcoding) | NO -- tests/ migration | NO | very low (optional) |
|
|
|
|
- **Counts** : 5 candidates total. 3 are blocking conditions for upgrading §9 CONDITIONAL GO to unconditional GO for #19 (F-3 hard-gates, F-2 conditional-gates on catalog touch, F-1 nice-to-have before next audit). 2 are optional housekeeping (F-4, F-5).
|
|
- **Compliance with Stage 2 u6 contract** : per-draft fields (title / source_axis / scope / evidence_link) populated for each of F-1 .. F-5. **Zero auto-posts** -- this section is text-only. Filing decisions = orchestrator / human after #50 closes.
|
|
- **AI-isolation contract** : none of the 5 follow-up candidates require AI on a normal path. F-2 / F-4 / F-5 are scope decisions to be made by a human reviewer. Compatible with [[feedback_ai_isolation_contract]] and PZ-1 (AI = 0 on normal path).
|