Files
C.E.L_Slide_test2/docs/architecture/PHASE-Z-OVERLAY-SCHEMA.md
kyeongmin 7762f6766a Lock Phase Z overlay schema for Option E migration
- categorize F13/F29/F16 frame_contracts fields as overlay-only, templates_v1-derived, or validation duplicate
- lock duplicate hard-error, 1:1 keyspace, manual trigger, semantic-identical rollback
- defer analysis.md direction inversion and 32-frame audit as separate axes
2026-05-07 11:19:52 +09:00

11 KiB
Raw Permalink Blame History

Phase Z Overlay Schema (Option E first migration)

Status: Step 0 schema lock — pre-execution spec. Scope: F13 / F29 / F16 only (3 active Phase Z frames). Last updated: 2026-05-07.


0. Why this doc exists

templates/phase_z2/catalog/frame_contracts.yaml is currently a hand-curated island. It must be hand-edited whenever a Phase Z frame's slot/sub_zone/payload structure changes, even though most of its sibling Phase Z artifacts (V4 matching results, structure_ontology.yaml templates_v1 section, figma_to_html_agent/blocks/{frame_id}/analysis.md) are auto-generated from upstream sources.

Option E first migration converts frame_contracts.yaml to a generated artifact:

runtime_overlay/{template_id}.yaml  (per-template Phase Z fields, hand-edited)
  +
templates_v1[frame_id]              (cross-validation only in first migration)
  ↓
build_phase_z2_frame_contracts.py   (generator)
  ↓
templates/phase_z2/catalog/frame_contracts.yaml  (committed, generated)
  ↓
Phase Z runtime (unchanged — reads frame_contracts.yaml the same way)

This doc locks the schema/keyspace/trigger/rollback rules before any overlay file or generator code is written.


0-1. Field owner table

Each field in current frame_contracts.yaml is classified as one of:

  • (a) templates_v1-derived — generator looks up from tests/matching/structure_ontology.yaml templates_v1 section. Not declared in overlay.
  • (b) overlay-only — Phase Z 전용 operational config. Declared in runtime_overlay/{template_id}.yaml.
  • (c) validation duplicate — generator cross-checks overlay value against templates_v1. Disagreement → hard error.

F13 — three_parallel_requirements (frame_id 1171281190)

Field Current value Category Note
template_id three_parallel_requirements (c) overlay filename = template_id; cross-check templates_v1['1171281190'].template_id
frame_id 1171281190 (b) overlay declares; generator confirms it exists as a templates_v1 key
family three_parallel (b) Phase Z categorization. Not the same as templates_v1.visual_pattern.family (= list) — different semantic axis. Name overlap is incidental.
source_shape top_bullets (b) Phase Z B1 extractor signal. Not in templates_v1.
cardinality.strict 3 (c) cross-check against templates_v1.visual_pattern.cardinality — must equal min (and max if min==max).
cardinality.overflow_policy abort_or_review (b) Phase Z fallback policy.
role_order [tech, people, nature] (b) F13-specific visual role mapping. Not in templates_v1.
visual_hints.min_height_px 230 (b) Phase Z layout calculation. Not in templates_v1.
accepted_content_types [text_block] (b) SPEC v1 §3 Layer A→B input. Not in templates_v1.
sub_zones [pillar_1, pillar_2, pillar_3] (with partial_target_path) (b) Phase Z Frame Slot declaration. Conceptually overlaps with templates_v1.slots (pillar_*_label/body) but different shape (sub_zones = column units; slots = label+body pairs).
payload.* {title, builder, builder_options} (b) Phase Z mapper directives. Not in templates_v1.

F29 — process_product_two_way (frame_id 1171281210)

Field Current value Category Note
template_id process_product_two_way (c) filename = template_id; cross-check
frame_id 1171281210 (b)
family two_column_h3 (b) templates_v1.visual_pattern.family = compare; intentionally different
source_shape h3_subsections (b) F29-specific B1 path
cardinality.strict 2 (c) cross-check against templates_v1.visual_pattern.cardinality.{ideal:2, min:2, max:2}
cardinality.overflow_policy abort_or_review (b)
visual_hints.min_height_px 345 (b)
accepted_content_types [text_block, transform_table] (b) F29 process column accepts AS-IS/TO-BE table
sub_zones [process_column, product_column] (each cardinality.strict: 3) (b) 2 column × 3 sections; sub_zone unit = column
payload.* {title, builder=process_product_pair, builder_options} (b)

F16 — bim_issues_quadrant_four (frame_id 1171281193)

Field Current value Category Note
template_id bim_issues_quadrant_four (c)
frame_id 1171281193 (b)
family bim_issues_quadrant (b) templates_v1.visual_pattern.family = cards
source_shape top_bullets (b)
cardinality.strict (not declared) n/a F16 intentionally omits — uses pad_to=4 + truncate>4 policy in payload.builder_options. templates_v1.cardinality has {ideal:4, min:4, max:4} but Phase Z does not enforce strict here. Generator must NOT auto-derive this from templates_v1.
accepted_content_types [text_block] (b)
sub_zones [quadrant_1, quadrant_2, quadrant_3, quadrant_4] (each cardinality.strict: 1) (b) sub_zone-level cardinality = capacity; not the same as frame-level
payload.* {title, builder=quadrant_flat_slots, builder_options.{item_parser, pad_to, truncate_at, label_key_pattern, body_key_pattern, empty_label, empty_body}} (b)

Summary

  • (a) templates_v1-derived: none in first migration. Overlay declares all operational config.
  • (b) overlay-only: ~all fields. Overlay file is essentially a per-template extract of the current frame_contracts.yaml entry.
  • (c) validation duplicate: 2 fields per template — template_id (overlay filename matches templates_v1[frame_id].template_id) and cardinality.strict when present (must match templates_v1.visual_pattern.cardinality.min).

Implication: first migration is mostly a split-and-concatenate refactor with light cross-validation. Migration value is (i) per-template editing isolation, (ii) templates_v1 consistency check at build time. Heavier derivation (e.g., generating cardinality.strict from templates_v1 automatically) is 별 axis — defer until a concrete need surfaces.


0-2. Duplicate rule — hard error

If an overlay file declares a field that is classified as (a) templates_v1-derived, generator fails immediately with a clear message. No silent override semantics.

Currently no fields are in (a), so this rule is dormant for first migration. It exists to prevent regression: a future overlay author cannot quietly duplicate a templates_v1-owned field without removing the (a) classification first.

For (c) validation duplicate fields, the rule is:

  • Overlay declares the value.
  • Generator looks up the corresponding value in templates_v1.
  • If the two disagree, hard error with both values printed and a pointer to this doc.

This preserves the lock-layer "overlay = single source of truth for declared values" while making templates_v1 drift visible.


0-3. Keyspace rule

  • Source ref = frame_id (Figma origin).
  • Overlay identity = template_id (filename: runtime_overlay/{template_id}.yaml).
  • First-migration assumption: frame_idtemplate_id is 1:1 for all active Phase Z frames (F13/F29/F16).
  • Generator verification: for each overlay, the generator looks up templates_v1[overlay.frame_id].template_id and asserts it equals the overlay filename's {template_id}. Mismatch → hard error.
  • Multi-variant (one frame ↔ multiple templates) = 별 axis. When that case appears, this doc is updated and the keyspace becomes a composite key. Until then, 1:1 is locked.

0-4. Trigger

  • Manual run for first migration:
    python scripts/build_phase_z2_frame_contracts.py
    
  • Verification (semantic-identical) is required after each run. Generator should refuse to write output if the result differs semantically from current frame_contracts.yaml during first migration.
  • CI / pre-commit automation = 별 axis. Will be considered after first migration ships and a drift incident actually occurs. Adding it now is over-engineering for 3 templates.

0-5. Rollback / failure path

If semantic-identical verification fails (yaml.safe_load(current) != yaml.safe_load(generated)):

  1. Generated artifact is NOT adopted. No write to frame_contracts.yaml.
  2. Current frame_contracts.yaml remains canonical (status quo preserved).
  3. Diff source: overlay schema, generator implementation, or templates_v1 cross-check rule. Identify root cause.
  4. Fix overlay/schema/generator. Retry from Step 1.
  5. Migration is incomplete: 3 active templates partially migrated count as failure — either all 3 ship or none.

The migration commit (Step 5) is only made after all 3 templates pass both (a) semantic-identical and (b) Phase Z runtime regression (final.html identical).


0-6. Scope boundary

Option E first migration solves:

  • frame_contracts.yaml island problem (hand-curated → generated).
  • Per-template editing isolation.
  • Light templates_v1 consistency check at build time.

Option E first migration does NOT solve (= 별 axis, NOT addressed by this migration):

  • analysis.mdstructure_ontology.yaml ownership direction conflict. Specifically: figma_to_html_agent/CLAUDE.md implies forward direction (agent owns analysis.md), while tests/matching/sync_analysis_from_ontology.py enforces reverse direction (structure_ontology.yaml is source, analysis.md is mirror). This is a separate architectural decision and is out of scope here.
  • templates/blocks/structures legacy retirement.
  • legacy templates/catalog/blocks.yaml removal.
  • zone_extract rule formalization (long-term zone_application policy).
  • 32-frame full audit (only active F13/F29/F16 in first migration).

When the user resumes work on the direction inversion axis, this doc is not invalidated — overlay schema and generator continue to work because they read templates_v1 (not analysis.md).


Migration steps (post-Step 0)

  1. Create templates/phase_z2/catalog/runtime_overlay/{F13,F29,F16}.yaml files. Each contains the (b) overlay-only fields + (c) validation duplicate values for one template.
  2. Write scripts/build_phase_z2_frame_contracts.py generator. Reads overlays + templates_v1, applies 0-2 / 0-3 rules, writes generated frame_contracts.yaml.
  3. Run generator. Verify yaml.safe_load(current) == yaml.safe_load(generated). List order preserved (sub_zones especially). On disagreement → 0-5 rollback.
  4. Run Phase Z pipeline once (regression MDX) — confirm final.html is byte-identical to current run.
  5. Commit Option E migration (overlay files + generator + new generated frame_contracts.yaml with header). Separate commit from Step 0 schema doc.

Out of scope for this doc

  • Generator implementation details (parsing, emit format, error message templates) — captured in the script itself.
  • Overlay file format details beyond field categorization — captured in the overlay files themselves.
  • Direction inversion fixes — see future axis docs.