docs(edgecfg): Phase 280 - Frag Composition SSOT Positioning (A→B→C)
## Purpose Stop pattern number enumeration proliferation by establishing Frag composition API as the Single Source of Truth (SSOT) for structured control flow → CFG lowering. Pattern numbers (1-9+) are **symptom labels** for regression tests, NOT architectural concepts. The architectural SSOT is **Frag composition rules** (seq/if/loop/cleanup). ## Changes Summary **Phase A (Docs-only, no code)**: SSOT Positioning - edgecfg-fragments.md: Status Draft → Active SSOT (+243 lines) - Added 5 sections: Composition SSOT, Rules, Laws, Fail-Fast, Ownership - Documented 3-tier ownership model (Normalizer/Composition/Lowerer) - Established composition as pattern absorption destination - joinir-architecture-overview.md: Pattern absorption documentation (+90 lines) - Added Section 0.2: Pattern Number Absorption Destination - JoinIR vs Plan comparison (different extraction, same SSOT) - Pattern absorption status table (Pattern6/7 as Phase 280 targets) - phase-280/README.md: Full roadmap (new) **Phase B (API solidification)**: Contract Verification - compose.rs: Module-level + function-level Phase 280 docs (+149 lines) - Documented composition SSOT, ownership model, usage example - Added constraint/composition law sections to seq/if/loop/cleanup - Contract verification: All seq/if/loop contracts verified (no gaps) - Test gap analysis: No missing tests (wires/exits separation explicitly tested) **Phase C (Pattern preparation)**: Documentation-only - normalizer.rs: Pattern6/7 TODO comments (+10 lines) - Pattern6: Early exit doesn't fit compose::if_() → cleanup() target - Pattern7: 挙動不変保証難 → compose::if_() migration deferred to Phase 281 ## Impact - **Net +460 lines** (docs-heavy, minimal code) - **4 files modified**, 1 directory created - **SSOT established**: Frag composition is now THE absorption destination - **導線固定**: Clear migration path for Pattern6/7 (Phase 281+) - **No behavior change**: Documentation-only for Phase C (tests not run) ## Phase 280 Goal Achieved ✅ SSOT positioning + 導線固定 (NOT full migration - that's Phase 281) ✅ Phase A complete: Docs updated to "Active SSOT" ✅ Phase B complete: API contract verified and documented ✅ Phase C complete: Pattern6/7 hand-rolled locations documented ## Next Phase (Phase 281+) - Phase 281: Full Pattern6/7 absorption (replace hand-rolled with compose_*) - Phase 282: Router shrinkage (pattern numbers → test labels) - Phase 283+: Pattern8 and beyond 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@ -136,6 +136,96 @@ NYASH_JOINIR_DEBUG=1 cargo test --release --lib
|
||||
実装: `src/config/env/joinir_flags.rs::is_joinir_debug()` が両者をチェック。
|
||||
詳細: `docs/development/current/main/phase82-83-debug-flag-ssot-summary.md`
|
||||
|
||||
## 0.2 Pattern Number Absorption Destination (Phase 280)
|
||||
|
||||
**Status**: Active (2025-12-23)
|
||||
**Purpose**: Stop pattern enumeration proliferation by establishing Frag composition as SSOT
|
||||
|
||||
### The Problem: Pattern Enumeration Proliferation
|
||||
|
||||
Pattern numbers (1-9+) became architectural decision points:
|
||||
- Router branches exploded (17+ patterns across JoinIR/Plan routes)
|
||||
- Each pattern duplicated CFG construction logic (block allocation, PHI insertion, terminator emission)
|
||||
- "Pattern-specific" knowledge leaked into lowering layers
|
||||
- Adding new loop shapes required full-stack pattern additions
|
||||
|
||||
**Symptom**: Pattern numbers drove architecture instead of being test labels
|
||||
|
||||
### The Solution: Frag Composition SSOT
|
||||
|
||||
**Key Insight**: Pattern numbers → symptom labels (test names), CFG construction → Frag composition API
|
||||
|
||||
**Architecture shift**:
|
||||
- **Before Phase 280**: Pattern number → entire lowering pipeline (extractor + allocator + emitter)
|
||||
- **After Phase 280**: Pattern number → extractor only, all lowering uses Frag composition SSOT
|
||||
|
||||
**Composition API as absorption destination**:
|
||||
- `seq(a, b)`: Sequential composition (Normal wiring)
|
||||
- `if_(header, cond, t, e, join)`: Conditional composition (Branch wiring)
|
||||
- `loop_(loop_id, header, after, body)`: Loop composition (Break/Continue wiring)
|
||||
- `cleanup(body, cleanup)`: Cleanup composition (planned, Phase 280+)
|
||||
|
||||
**Reference**: `docs/development/current/main/design/edgecfg-fragments.md` (Active SSOT)
|
||||
|
||||
### JoinIR vs Plan: Different Extraction, Same SSOT
|
||||
|
||||
Both routes converge on the same Frag composition SSOT:
|
||||
|
||||
| Route | Extraction Source | Pattern Knowledge | Composition SSOT |
|
||||
|-------|-------------------|-------------------|------------------|
|
||||
| **JoinIR** | cf_loop structure (Structured JoinIR) | JoinIR-specific (cf_loop DSL) | **Frag API** (seq/if/loop) |
|
||||
| **Plan** | DomainPlan (Pattern6/7 extractors) | Domain-specific (ScanWithInit/SplitScan) | **Frag API** (same) |
|
||||
|
||||
**Key principle**: Different extraction strategies, converged CFG construction
|
||||
|
||||
**Why separate routes?**:
|
||||
- JoinIR route: Handles cf_loop-based patterns (Pattern1-5, 8-9) via Structured JoinIR
|
||||
- Plan route: Handles complex scan patterns (Pattern6/7) via DomainPlan → CorePlan → Frag
|
||||
- Both routes use same Frag composition API for CFG lowering (no duplication)
|
||||
|
||||
### Pattern Absorption Status (Phase 280)
|
||||
|
||||
| Pattern | Structure | Status | Absorption Target |
|
||||
|---------|-----------|--------|-------------------|
|
||||
| **Pattern6** | ScanWithInit (forward scan) | Plan-based (Phase 273) | **Phase 280 C: Frag refactor target** |
|
||||
| **Pattern7** | SplitScan (conditional split) | Plan-based (Phase 273) | **Phase 280 C: Frag refactor target** |
|
||||
| Pattern8 | BoolPredicateScan (is_integer) | JoinIR-based | Phase 281+ (migration planned) |
|
||||
| Pattern9 | AccumConstLoop (bridge) | JoinIR-based (Phase 271) | 撤去条件 defined (minimal loop SSOT) |
|
||||
| Pattern1-5 | Legacy (SimpleWhile, Break, IfPhi, Continue, InfiniteEarlyExit) | JoinIR-based | Test/error stubs (not absorbed) |
|
||||
|
||||
**Phase 280 Focus**: Pattern6/7 preparation (documentation of hand-rolled locations, defer refactor to Phase 281)
|
||||
|
||||
**Absorption criteria** (Pattern6/7 → Frag composition):
|
||||
1. Hand-rolled Frag construction identified (function name + 識別コメント)
|
||||
2. TODO comments documenting future compose_* migration path
|
||||
3. Behavior-preserving refactor deferred to Phase 281 (Phase 280 = SSOT positioning only)
|
||||
|
||||
### Absorption Timeline
|
||||
|
||||
**Phase 280 (Current)**: SSOT positioning + 導線固定
|
||||
- A: Documentation (edgecfg-fragments.md → Active SSOT)
|
||||
- B: API solidification (compose.rs contract verification)
|
||||
- C: Pattern preparation (Pattern6/7 hand-rolled locations documented)
|
||||
- **Goal**: Establish Frag composition as THE absorption destination
|
||||
- **Non-Goal**: Full Pattern6/7 migration (deferred to Phase 281)
|
||||
|
||||
**Phase 281 (Planned)**: Full Pattern6/7 absorption
|
||||
- Replace hand-rolled Frag construction with compose_* calls
|
||||
- Behavior-preserving verification (smoke tests)
|
||||
- Goal: Pattern6/7 use compose::if_/loop_ exclusively
|
||||
|
||||
**Phase 282 (Planned)**: Router shrinkage
|
||||
- Pattern numbers → test labels only
|
||||
- Router uses Frag composition for all CFG construction
|
||||
- Pattern extractors remain as thin detection layer
|
||||
|
||||
**Phase 283+ (Future)**: Pattern8 and beyond
|
||||
- Migrate Pattern8 to Plan route or Frag-based JoinIR
|
||||
- Evaluate Pattern9 撤去 (if minimal loop SSOT achieved)
|
||||
- Continue pattern number reduction
|
||||
|
||||
---
|
||||
|
||||
## 1. 不変条件(Invariants)
|
||||
|
||||
JoinIR ラインで守るべきルールを先に書いておくよ:
|
||||
|
||||
Reference in New Issue
Block a user