wip: phase_z2 evidence 파이프라인 + matching 실험(phase2~26) + 프론트 trace 패널 진행분 스냅샷
- src: phase_z2 composition/mapper/pipeline/placement_planner/retry, ai_fallback(prompts/schema/validate), mdx_text_atoms 신규 - Front: PipelineTracePanel 신규, FramePanel/SlideCanvas/Home/designAgentApi 등 갱신 + 테스트 4종 추가 - templates/phase_z2: catalog(component_expansion_registry, node_slot_mapping 신규), frames, families, slide_base 갱신 - tests/matching: phase2~26 매칭 실험 스크립트·리포트·온톨로지 전체 (미커밋 진행분) - tests: b4_v4 evidence, task5~28.5 시리즈, regression(imp95 baseline) 등 신규 테스트 대량 추가 - docs/reference: MDX 구조 인벤토리, MDX→Frame 구조 계약 문서 - scripts: mdx 계약/parity/coverage/viewport 체크, gitea comment, run sync 유틸 - .gitignore: tmp*.json, chromedriver, .orchestrator, *.pkl, Front_test* 등 임시/스냅샷 제외 미완성 작업의 보존용 스냅샷 커밋 (2026-07-02) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,119 @@
|
||||
# Five-MDX Structure Inventory
|
||||
|
||||
Issue: #98
|
||||
|
||||
Purpose: establish the empirical ground truth for T22-T30 before changing
|
||||
the parser, matcher, layout planner, slot mapper, frontend override path, or
|
||||
AI adaptation path.
|
||||
|
||||
This inventory intentionally compares three layers:
|
||||
|
||||
| Column | Meaning | Gap type exposed |
|
||||
|---|---|---|
|
||||
| A. Original MDX contains | What the source file actually expresses | Source structure |
|
||||
| B. Current pipeline sees | What the current `task21d_*` runs expose in Step 02 / Step 06 / Step 20 | Parser, normalizer, component, and planner behavior |
|
||||
| C. Expected result | What the slide pipeline should preserve and render | Layout, matching, slot mapping, override, and adaptation behavior |
|
||||
|
||||
Source files inspected:
|
||||
|
||||
- `samples/mdx/01. ... .mdx`
|
||||
- `samples/mdx/02. ... .mdx`
|
||||
- `samples/mdx/03. ... .mdx`
|
||||
- `samples/mdx/04. ... .mdx`
|
||||
- `samples/mdx/05. ... .mdx`
|
||||
|
||||
Observed pipeline runs:
|
||||
|
||||
- `data/runs/task21d_01`
|
||||
- `data/runs/task21d_02`
|
||||
- `data/runs/task21d_03`
|
||||
- `data/runs/task21d_04`
|
||||
- `data/runs/task21d_05`
|
||||
|
||||
## MDX 01
|
||||
|
||||
| A. Original MDX contains | B. Current pipeline sees | C. Expected result | Gap owner |
|
||||
|---|---|---|---|
|
||||
| A pre-intro block before the first numbered `##` heading. It includes a details/popup block and is user-visible content. | Step 02 only emits `01-1` and `01-2`. The pre-intro has no unit id. Existing `data/user_overrides/01.json` references `01-3`, but that id is orphaned. | Promote the pre-intro into a first-class unit such as `01-intro`, or define a documented alias/migration path for the existing `01-3` override. | T22 parser/normalizer and override migration |
|
||||
| `## 1` and `## 2` numbered sections. | Step 06 selects two units: `01-1 -> construction_bim_three_usage`, `01-2 -> bim_dx_comparison_table`. | Body zones should be based on the normalized section tree after the pre-intro policy is decided. | T24 layout policy |
|
||||
| An image reference in section 2 and details/popup content. | Recent asset handling removes broken image icons, but popup/details semantics remain only partially represented. | Image and popup/details nodes must be explicit node types, not raw markdown leftovers. | T22 node taxonomy and T25 slot mapping |
|
||||
|
||||
## MDX 02
|
||||
|
||||
| A. Original MDX contains | B. Current pipeline sees | C. Expected result | Gap owner |
|
||||
|---|---|---|---|
|
||||
| `## 1` with goal content and one image. | Step 02 emits `02-1`. Step 06 selects `construction_goals_three_circle_intersection`. A user override exists for `02-1`, but frontend/runtime override behavior is not proven end-to-end. | Section `02-1` must remain independently addressable, and selected/overridden frames must render without stale preview or silent fallback. | T28 frontend override E2E |
|
||||
| `## 2`, with `### 2.1` and `### 2.2`. | Step 02 emits only parent `02-2`; child headings are raw content inside the section. | `2.1` and `2.2` should become frame-internal groups under the `02-2` unit, not separate slide zones unless a layout policy explicitly asks for that. | T22/T25 |
|
||||
| `<DxEffect />`, which represents the stakeholder/persona effect table in `samples/src/components/dx.astro`. | The pipeline sees an opaque component tag; persona columns are not expanded into semantic nodes. | Register `DxEffect` in a component expansion registry and expand it into persona/table nodes before matching and slot mapping. | T23 component expansion |
|
||||
|
||||
## MDX 03
|
||||
|
||||
| A. Original MDX contains | B. Current pipeline sees | C. Expected result | Gap owner |
|
||||
|---|---|---|---|
|
||||
| `## 1` with three conceptual groups: technology, people, and environment/nature. | Step 06 selects `three_parallel_requirements` for `03-1`. Technical text coverage is currently PASS. | Child groups should populate the internal pillar labels and body slots of the selected frame. They must not become external slide titles. | T25 slot mapping |
|
||||
| `## 2` with `### 2.1` process and `### 2.2` product, including table-like content. | Step 06 selects `process_product_two_way` for `03-2`. | Process/product child groups should map to the selected two-way frame with all source atoms preserved. | T25/T27 |
|
||||
| Dense content in two zones. | Presentation can still become visually dense even when technical coverage is PASS. | Fit must be solved through zone sizing, frame expansion, or layout choice, not font shrinking or text truncation. | T27 and T30 |
|
||||
|
||||
## MDX 04
|
||||
|
||||
| A. Original MDX contains | B. Current pipeline sees | C. Expected result | Gap owner |
|
||||
|---|---|---|---|
|
||||
| `## 1` with several perception/problem groups. | Step 06 selects `pre_construction_model_info_stacked` with a reject/provisional path. Step 20 marks design readiness as `needs_review`. | Reject/provisional candidates must remain visible as candidates, but the slide should surface that adaptation is required. | T26 candidate policy |
|
||||
| `## 2` with `### 2.1` and `### 2.2`, plus details blocks. | Step 06 keeps parent `04-2` and selects `bim_issues_quadrant_four`; earlier runs showed child handling instability. | Child groups under `04-2` should become internal quadrant/list items in source order. | T25 slot mapping |
|
||||
| Content is larger than the currently chosen zones in some layouts. | Technical PASS does not guarantee presentation readiness. | The system should resize/replan zones or expand frame structure. It must not shrink font size to hide overflow. | T24/T27/T30 |
|
||||
|
||||
## MDX 05
|
||||
|
||||
| A. Original MDX contains | B. Current pipeline sees | C. Expected result | Gap owner |
|
||||
|---|---|---|---|
|
||||
| Two top-level numbered sections, `05-1` and `05-2`. | Step 06 now emits two units, but both use `three_parallel_requirements` through `generic_fallback`. Step 20 marks design readiness as `not_ready`. | Sections must stay separated, and fallback/generic frames must be visible as not ready unless a real matching/adaptation path is used. | T24/T26 |
|
||||
| `05-2` uses numeric `### 1` and `### 2` headings, not decimal `### 2.1` style headings. | These child headings are raw section content. | The contract must decide whether numeric child headings are allowed input or require MDX standardization. | T21.6/T22 |
|
||||
| User-selected alternative frames can work through CLI override, but UI selection has not been proven. | `data/user_overrides/05.json` contains zone assignment but no `frames` override. | Frontend frame selection must persist `frames` and backend must apply the selected frame without stale preview or silent no-op. | T28 frontend override E2E |
|
||||
|
||||
## Aggregate Node Inventory
|
||||
|
||||
| Node type | Found in | Current state | Contract decision needed |
|
||||
|---|---|---|---|
|
||||
| `pre_intro` | MDX 01 | Not promoted to a unit | Allow as first-class unit or require source standardization |
|
||||
| `numbered_section` | MDX 01-05 | Parsed as top-level units | Keep as the main slide-zone unit type |
|
||||
| `subsection_decimal` | MDX 02, 03, 04 | Usually raw content under parent | Map to frame-internal groups unless explicitly split |
|
||||
| `subsection_numeric` | MDX 05 | Raw content under parent | Decide whether allowed or normalized to decimal form |
|
||||
| `component_ref` | MDX 02 `<DxEffect />` | Opaque tag | Registry-based component expansion |
|
||||
| `image_ref` | MDX 01, MDX 02 | Asset copy now works for known frame images; content images still need typed handling | Explicit image node and image slot policy |
|
||||
| `details_popup` | MDX 01, MDX 04 | Raw markdown/html-like content | Explicit popup/details node and presentation policy |
|
||||
| `table_like_content` | MDX 01 details, MDX 02 component, MDX 03 table | Partly raw content | Explicit table/comparison nodes |
|
||||
| `summary_footer` | All five MDX samples conceptually | Must stay outside body frame zones | Fixed base-slide region, not a body layout zone |
|
||||
|
||||
## Aggregate Gap List
|
||||
|
||||
| Gap | Evidence | Next task |
|
||||
|---|---|---|
|
||||
| Pre-intro content lacks stable unit identity | MDX 01 source has visible content before the first `##`; Step 02 emits only `01-1` and `01-2`; override references orphan `01-3` | T22 |
|
||||
| Registered component expansion does not exist | MDX 02 uses `<DxEffect />`; current parser sees only the component tag | T23 |
|
||||
| Child headings need frame-internal mapping | MDX 02/03/04/05 child headings remain raw content or map inconsistently | T25 |
|
||||
| Generic fallback can be technically PASS but design-not-ready | MDX 05 uses `generic_fallback` for both units | T26/T30 |
|
||||
| Frontend override persistence is not proven | MDX 05 override JSON has no `frames`; CLI override works separately | T28 |
|
||||
| Fit is still a structure/layout problem, not a font problem | MDX 03/04 can be dense; policy forbids font shrinking | T24/T27/T30 |
|
||||
|
||||
## Immediate Contract Decisions For T21.6
|
||||
|
||||
1. Unit identity policy:
|
||||
- Prefer stable explicit ids such as `01-intro`, not implicit renumbering.
|
||||
- Existing user override aliases such as `01-3` need a tested migration or compatibility rule.
|
||||
2. Component registry:
|
||||
- Start with `DxEffect`.
|
||||
- New components must be added through registry entries, not one-off parser branches.
|
||||
3. Child-section policy:
|
||||
- Top-level `## n.` sections map to body zones.
|
||||
- Child headings map to internal frame slots by default.
|
||||
4. Allowed input policy:
|
||||
- `## n. Title` is allowed.
|
||||
- Registered component tags are allowed.
|
||||
- Unregistered component tags are unsupported.
|
||||
- Raw JSX/style blobs are disallowed in rendered text and must be sanitized or rejected.
|
||||
5. Coverage-state policy:
|
||||
- `covered_native`: current frame and builder can render source atoms verbatim.
|
||||
- `covered_via_expand`: current frame can render after deterministic repeat/expand.
|
||||
- `requires_adaptation`: visual motif is usable, but an adapted schema is needed.
|
||||
- `unsupported`: no current contract path; must be surfaced honestly.
|
||||
|
||||
@@ -0,0 +1,189 @@
|
||||
# MDX-to-Frame Structure Contract
|
||||
|
||||
Issue: #98
|
||||
|
||||
Status: draft contract for T22-T30.
|
||||
|
||||
This document converts `5_MDX_STRUCTURE_INVENTORY.md` into a shared
|
||||
contract for parser normalization, component expansion, layout selection,
|
||||
frame candidate ranking, slot mapping, frontend override behavior, and AI
|
||||
adaptation.
|
||||
|
||||
The contract is deliberately process-first. It must not introduce MDX-id
|
||||
special cases, generated text, font shrinking, or silent fallback.
|
||||
|
||||
## 1. Non-Negotiable Policies
|
||||
|
||||
| Policy | Rule |
|
||||
|---|---|
|
||||
| Source text preservation | MDX source atoms are copied verbatim into rendered slots. No omission, summary, inference, or rewriting. |
|
||||
| AI isolation | AI may propose adapted frame structure only. AI must not output new or modified MDX text. |
|
||||
| Unit separation | Top-level content units must not be silently merged. |
|
||||
| Child mapping | Child headings and groups usually map to frame-internal labels/body slots, not independent slide titles. |
|
||||
| Summary/footer | Summary/footer content belongs to the fixed base-slide region, not body layout zones. |
|
||||
| Fit policy | Do not reduce font size to force fit. Use layout, zone sizing, frame expansion, or needs-review state. |
|
||||
| Candidate honesty | Reject/provisional candidates remain visible with status. They are not deleted and not treated as ready. |
|
||||
| No silent swap | If selected frame and rendered frame differ, record a failure or explicit adaptation state. |
|
||||
| No debug leakage | Internal ids, counters, and pipeline labels must not appear in presentation output. |
|
||||
|
||||
## 2. Node Taxonomy
|
||||
|
||||
| Node type | Definition | Unit role | Examples from inventory |
|
||||
|---|---|---|---|
|
||||
| `pre_intro` | Visible content before the first numbered `##` heading | Optional top-level unit | MDX 01 intro/details before `## 1` |
|
||||
| `numbered_section` | `## n. Title` top-level section | Default slide body unit | MDX 01-05 |
|
||||
| `subsection_decimal` | `### n.m Title` child section | Frame-internal group by default | MDX 02, 03, 04 |
|
||||
| `subsection_numeric` | `### n Title` child section without parent decimal prefix | Allowed only if normalized to parent-scoped child id | MDX 05 |
|
||||
| `bullet_group` | Consecutive bullet lines under a unit or child heading | Slot body group | MDX 01-05 |
|
||||
| `table_like_content` | Markdown table, component-expanded table, or details table | Table/comparison slot group | MDX 01 details, MDX 02 `DxEffect`, MDX 03 |
|
||||
| `image_ref` | Markdown image reference with alt text and src | Image slot | MDX 01, MDX 02 |
|
||||
| `component_ref` | Registered MDX/Astro component tag | Expanded node tree | MDX 02 `<DxEffect />` |
|
||||
| `details_popup` | `<details>` block or equivalent collapsible detail source | Popup/detail body slot or auxiliary note | MDX 01, MDX 04 |
|
||||
| `summary_footer` | Closing summary or key message outside body frame zones | Fixed footer/base-slide region | All five samples conceptually |
|
||||
|
||||
## 3. Unit Identity Rules
|
||||
|
||||
| Input pattern | Unit id policy | Notes |
|
||||
|---|---|---|
|
||||
| `pre_intro` before first numbered section | `<mdx_id>-intro` | Existing orphan overrides such as `01-3` need alias migration to this id. |
|
||||
| `## n. Title` | `<mdx_id>-<n>` | This remains the stable primary unit id. |
|
||||
| `### n.m Title` under parent `n` | `<mdx_id>-<n>-sub-<m>` if materialized, otherwise child node under parent | Materialization must be explicit; default is internal child node. |
|
||||
| `### k Title` under parent `n` | `<mdx_id>-<n>-sub-<k>` after parent-scoped normalization | This covers MDX 05 numeric child headings. |
|
||||
| Registered component | Stays under containing unit unless registry declares child units | `DxEffect` should expand under `02-2`. |
|
||||
|
||||
Override compatibility:
|
||||
|
||||
- Existing overrides that reference missing ids must not be silently ignored.
|
||||
- A compatibility alias table must be emitted during T22 when a prior id can be
|
||||
mapped safely, such as `01-3 -> 01-intro` if that is confirmed as user
|
||||
intent.
|
||||
- If an override id cannot be resolved, the frontend and pipeline trace must
|
||||
show `override_unresolved`.
|
||||
|
||||
## 4. Slot Taxonomy
|
||||
|
||||
| Slot type | Meaning | Text source |
|
||||
|---|---|---|
|
||||
| `title` | Top-level frame title | Unit title only |
|
||||
| `label` | Short internal group label | Child heading or source label atom only |
|
||||
| `body_text_lines` | Paragraph or bullet text | Source atoms only |
|
||||
| `pillar` | Generic repeated vertical group with label/body | Child heading plus child body |
|
||||
| `persona_column` | Stakeholder/persona column | Component-expanded table/persona node |
|
||||
| `comparison_cell` | Cell in two-column or multi-column comparison | Source table cell or bullet group |
|
||||
| `table_row` | Repeated row in a table-like frame | Source row or key/value atom |
|
||||
| `image_target` | Frame image slot | Source image_ref, never decorative generated image |
|
||||
| `popup_body` | Detail/popup auxiliary content | Source details content |
|
||||
| `footer_summary` | Fixed summary/footer region | Summary source only |
|
||||
|
||||
`pillar` is a generic repeated group concept. `three_parallel_requirements`
|
||||
uses it as one concrete family implementation, but the slot type itself is not
|
||||
limited to that frame.
|
||||
|
||||
## 5. Node-to-Slot Mapping Matrix
|
||||
|
||||
| Node type | Allowed target slots | Default behavior | Disallowed behavior |
|
||||
|---|---|---|---|
|
||||
| `pre_intro` | `title`, `label`, `body_text_lines`, `popup_body` | Treat as a top-level unit when visible and substantial | Dropping it because it precedes `## 1` |
|
||||
| `numbered_section` | `title`, `body_text_lines`, `image_target`, `table_row` | One body zone unit by default | Merging with another top-level section without explicit user action |
|
||||
| `subsection_decimal` | `label`, `body_text_lines`, `pillar`, `comparison_cell`, `table_row` | Internal frame group | Using child title as the whole slide title when parent is the unit |
|
||||
| `subsection_numeric` | `label`, `body_text_lines`, `pillar` | Normalize under current parent | Treating it as a new top-level section |
|
||||
| `bullet_group` | `body_text_lines`, `comparison_cell`, `table_row` | Preserve bullet text verbatim | Rewriting or summarizing |
|
||||
| `table_like_content` | `table_row`, `comparison_cell`, `persona_column` | Preserve cells verbatim | Flattening into prose without trace |
|
||||
| `image_ref` | `image_target` | Resolve source image path and alt text | Broken image icon or decorative replacement |
|
||||
| `component_ref` | Registry-defined expanded nodes | Expand before matching | Passing opaque tag into rendered text |
|
||||
| `details_popup` | `popup_body`, optional note slot | Preserve hidden/detail text in trace and supported frames | Leaking raw `<details>` markup as prose |
|
||||
| `summary_footer` | `footer_summary` | Fixed base-slide region | Consuming a body layout zone |
|
||||
|
||||
## 6. Component Expansion Registry Contract
|
||||
|
||||
Registry file:
|
||||
|
||||
- `templates/phase_z2/catalog/component_expansion_registry.yaml`
|
||||
|
||||
Initial required entry:
|
||||
|
||||
- `DxEffect`
|
||||
|
||||
Rules:
|
||||
|
||||
- Registered components expand into typed nodes before matching.
|
||||
- Unregistered component tags are `unsupported`, not silently rendered as text.
|
||||
- Component expansion is data-driven through the registry, not a one-off parser
|
||||
branch.
|
||||
- Expanded text still follows source preservation: copied from component source,
|
||||
not generated.
|
||||
|
||||
## 7. Coverage-State Taxonomy
|
||||
|
||||
The same state labels must be used by Step 05/06/20, frontend candidate panel,
|
||||
and AI adaptation routing.
|
||||
|
||||
| State | Meaning | User-facing behavior | AI behavior |
|
||||
|---|---|---|---|
|
||||
| `covered_native` | Existing frame and builder can render all required source atoms verbatim | Candidate is selectable and renderable | No AI |
|
||||
| `covered_via_expand` | Existing frame can render after deterministic repeat/expand | Candidate is selectable with expansion note | No AI |
|
||||
| `requires_adaptation` | Visual motif is usable, but slot schema/repeat structure must be adapted | Candidate is selectable with AI-adaptation badge | AI may propose adapted schema only |
|
||||
| `unsupported` | No current contract path | Show unsupported / needs design asset | No automatic AI text or hidden fallback |
|
||||
|
||||
Reject/provisional V4 labels are not deleted. They map to
|
||||
`requires_adaptation` or `unsupported` depending on whether the frame motif can
|
||||
be structurally reused.
|
||||
|
||||
## 8. Allowed And Disallowed Input Rules
|
||||
|
||||
| Input | Contract status | Action |
|
||||
|---|---|---|
|
||||
| `## n. Title` | Allowed | Parse as `numbered_section`. |
|
||||
| Visible content before first `##` | Allowed if non-empty | Parse as `pre_intro`. |
|
||||
| `### n.m Title` under current parent | Allowed | Parse as `subsection_decimal`. |
|
||||
| `### k Title` under current parent | Allowed with normalization | Parse as `subsection_numeric`; emit normalized id. |
|
||||
| Registered component tag | Allowed | Expand through registry. |
|
||||
| Unregistered component tag | Unsupported | Surface unsupported with trace. |
|
||||
| Raw JSX style object or event handler in source text | Disallowed in rendered text | Sanitize or fail coverage gate. |
|
||||
| Raw HTML details block | Allowed with typed handling | Parse as `details_popup`. |
|
||||
|
||||
## 9. Frame Coverage Priority
|
||||
|
||||
T27 must not attempt to migrate all 32 contracts at once. The priority is:
|
||||
|
||||
1. Frames actually selected or requested by the five MDX samples.
|
||||
2. Frames with existing family partials under `templates/phase_z2/families`.
|
||||
3. Remaining catalog-only frames, tracked separately as a family/variant mapping
|
||||
axis. This remains separate from the #98 immediate readiness work.
|
||||
|
||||
Initial frame families in scope:
|
||||
|
||||
- `construction_bim_three_usage`
|
||||
- `bim_dx_comparison_table`
|
||||
- `construction_goals_three_circle_intersection`
|
||||
- `three_persona_benefits`
|
||||
- `three_parallel_requirements`
|
||||
- `process_product_two_way`
|
||||
- `pre_construction_model_info_stacked`
|
||||
- `bim_issues_quadrant_four`
|
||||
|
||||
## 10. Task Mapping
|
||||
|
||||
| Task | Contract responsibility |
|
||||
|---|---|
|
||||
| T22 | Implement node taxonomy and unit identity rules. |
|
||||
| T23 | Implement component expansion registry, starting with `DxEffect`. |
|
||||
| T24 | Select layout from normalized top-level units and fixed summary/footer policy. |
|
||||
| T25 | Implement node-to-slot mapping and builder coverage checks. |
|
||||
| T26 | Carry candidate pools and coverage states through backend and frontend. |
|
||||
| T27 | Add deterministic repeat/expand rules without font shrinking. |
|
||||
| T28 | Verify frontend override persistence, stale-preview prevention, and backend application. |
|
||||
| T29 | Implement AI structure-plan path only for `requires_adaptation`. |
|
||||
| T30 | Run five-MDX technical, design-readiness, and presentation-readiness gates. |
|
||||
|
||||
## 11. Acceptance Checks For This Contract
|
||||
|
||||
- The contract defines node taxonomy, slot taxonomy, node-to-slot mapping,
|
||||
coverage states, allowed/disallowed input rules, and task mapping.
|
||||
- The contract explicitly covers all five MDX samples from the inventory.
|
||||
- The contract does not permit AI text generation or font shrinking.
|
||||
- The contract defines how reject/provisional candidates are surfaced without
|
||||
silent deletion.
|
||||
- The contract identifies registry files that later implementation tasks can
|
||||
read.
|
||||
|
||||
Reference in New Issue
Block a user