diff --git a/docs/development/current/main/phase81-pattern2-exitline-contract.md b/docs/development/current/main/phase81-pattern2-exitline-contract.md new file mode 100644 index 00000000..778b54bd --- /dev/null +++ b/docs/development/current/main/phase81-pattern2-exitline-contract.md @@ -0,0 +1,311 @@ +# Phase 81: Pattern2 ExitLine Contract Stabilization + +**Status**: Design Phase + +**Created**: 2025-12-13 + +**Priority**: P1 (Blocking Phase 82+) + +--- + +## Goal + +Pattern2(DigitPos/Trim)の promoted carriers を含む ExitLine 接続契約を堅牢化し、E2E テストで安定性を固定する。 + +--- + +## Background + +### Current Issue + +Phase 74-80 で BindingId migration が完了し、Pattern2/3/4 で BindingId lookup が operational になった。しかし、Pattern2 の promoted carriers(DigitPos/Trim パターンで生成される `is_digit_pos`, `is_ch_match` 等)の ExitLine 接続には以下の問題がある: + +1. **ExitLine 接続タイミングの不確実性**: + - Promoted carriers は promoter が生成するが、ExitLine reconnection が適切に行われているか検証不足 + - Exit PHI での promoted carriers の接続契約が明示されていない + +2. **E2E テスト不足**: + - DigitPos パターン(`indexOf()` 使用)の E2E テストが不足 + - Trim パターン(`skip_whitespace` 等)の E2E テストが不足 + - 既存の `tests/phase246_json_atoi.rs` が Phase 80 完了後も安定していない可能性 + +3. **Contract 不明確**: + - Promoted carriers が ExitLine reconnection でどのように扱われるべきか不明確 + - CarrierRole (LoopState vs ConditionOnly) による処理の違いが文書化されていない + +### Symptoms + +以下の症状が観測される可能性がある(Phase 80 完了時点では未検証): + +- `tests/phase246_json_atoi.rs` テスト失敗(DigitPos pattern 使用) +- Exit PHI で promoted carriers が正しく接続されない +- ExitLine reconnection で ValueId が undefined になる +- ConditionOnly carriers が Exit PHI に含まれて不整合が起こる + +--- + +## Reproduction + +### Minimal Test Case + +```rust +// DigitPos pattern with promoted carrier +local p = 0 +local s = "123" +local sum = 0 +loop(p < s.length()) { + local digit_pos = s.indexOf("0", p) // Promoted to is_digit_pos (ConditionOnly) + if digit_pos >= 0 { // Break condition uses promoted carrier + sum = sum + 1 + } + p = p + 1 +} +return sum +``` + +**Expected behavior**: +- `digit_pos` → `is_digit_pos` promotion succeeds +- `is_digit_pos` is ConditionOnly (not in exit_bindings) +- Exit PHI correctly includes `sum`, `p` (LoopState carriers) +- Exit PHI does NOT include `is_digit_pos` (ConditionOnly) +- Final result is correct + +**Failure mode** (if contract violated): +- Exit PHI includes `is_digit_pos` → type mismatch or ValueId undefined +- Exit PHI missing `sum` or `p` → incorrect final result +- ExitLine reconnection fails → compilation error + +--- + +## Invariants + +### ExitLine Contract for Promoted Carriers + +1. **CarrierRole Discrimination**: + - `LoopState` carriers: MUST be in exit_bindings, MUST have Exit PHI + - `ConditionOnly` carriers: MUST NOT be in exit_bindings, MUST NOT have Exit PHI + +2. **Promoted Carrier Handling**: + - All promoted carriers have `CarrierVar.binding_id` set by CarrierBindingAssigner + - Promoted carriers follow same CarrierRole rules as non-promoted + - ExitMetaCollector includes all carriers (LoopState + ConditionOnly) for latch incoming + - ExitLineReconnector only processes LoopState carriers (skip ConditionOnly) + +3. **ExitLine Reconnection Timing**: + - Promoted carriers are in CarrierInfo BEFORE ExitLine reconnection + - CarrierRole is determined BEFORE reconnection (via promoter) + - Reconnection uses CarrierRole to filter carriers + +4. **BindingId Registration Completeness**: + - All LoopState carriers have BindingId registered in ConditionEnv + - ConditionOnly carriers may have BindingId registered (for condition lowering) + - Registration happens AFTER ValueId allocation, BEFORE condition lowering + +--- + +## Design + +### Verification Strategy + +**Phase 81 focuses on verification, NOT new features.** + +1. **Audit ExitLine Reconnection**: + - Verify `ExitLineReconnector` correctly skips ConditionOnly carriers + - Verify `ExitMetaCollector` includes all carriers for latch + - Verify exit_bindings filter is correct + +2. **Add E2E Tests**: + - DigitPos pattern test (`indexOf()` with promoted `is_digit_pos`) + - Trim pattern test (`skip_whitespace` with promoted `is_ch_match`) + - Verify Exit PHI structure matches contract + +3. **Document Contract**: + - Create SSOT for ExitLine + promoted carriers interaction + - Document CarrierRole-based filtering rules + - Link to existing Phase 78-80 BindingId docs + +### Implementation Tasks + +**Task 81-A: ExitLine Audit** (analysis only) +- Read `ExitLineReconnector` code +- Read `ExitMetaCollector` code +- Verify CarrierRole filtering is correct +- Document findings + +**Task 81-B: E2E Tests** (high priority) +- Add DigitPos E2E test to `tests/normalized_joinir_min.rs` +- Add Trim E2E test to `tests/normalized_joinir_min.rs` +- Verify `tests/phase246_json_atoi.rs` passes (existing test) +- All tests dev-only (`#[cfg(feature = "normalized_dev")]`) + +**Task 81-C: Contract Documentation** (medium priority) +- Update this doc with audit findings +- Create exit_line_promoted_carriers.md if needed +- Link from phase80-bindingid-p3p4-plan.md + +**Task 81-D: Smoke Tests** (verification) +- Run `tools/smokes/v2/run.sh --profile quick` +- Verify no regressions in existing tests +- Document any failures + +--- + +## Acceptance Criteria + +### Minimum Requirements + +1. ✅ **E2E Tests Pass**: + - `cargo test --release` includes DigitPos E2E test (PASS) + - `cargo test --release` includes Trim E2E test (PASS) + - `tests/phase246_json_atoi.rs` PASS + +2. ✅ **Smoke Tests Pass**: + - `tools/smokes/v2/run.sh --profile quick` no regressions + - Existing Pattern2 tests continue to PASS + +3. ✅ **Contract Documented**: + - ExitLine + promoted carriers contract documented + - CarrierRole filtering rules documented + - Audit findings recorded + +### Success Metrics + +- All lib tests PASS (970/970 baseline, +2 new E2E tests = 972/972) +- All smoke tests PASS (existing baseline) +- Zero production impact (dev-only tests) +- Contract clarity increased (documentation) + +--- + +## Out of Scope + +### Phase 81 does NOT include: + +1. **New Features**: + - No new BindingId registration + - No new promoted carriers + - No changes to promotion logic + +2. **Architecture Changes**: + - No ExitLine reconnection refactoring + - No CarrierRole enum changes + - No ConditionEnv API changes + +3. **Pattern3/4 Work**: + - Phase 81 focuses on Pattern2 only + - Pattern3/4 ExitLine is out of scope + +--- + +## Risk Assessment + +### Low Risk: + +- All changes are verification (tests + docs) +- No production code changes expected +- Audit is analysis-only + +### Potential Issues: + +1. **Existing Contract Violation**: + - If audit finds ExitLine currently violates contract → need fix + - Mitigation: Fix is localized, well-documented + +2. **Test Failures**: + - If E2E tests fail → indicates real bug + - Mitigation: Fix bug, document root cause + +3. **Smoke Test Regressions**: + - If quick smoke tests fail → need investigation + - Mitigation: Classify as Phase 81 target or out-of-scope + +--- + +## References + +### Related Documentation + +- **Phase 80**: `phase80-bindingid-p3p4-plan.md` - BindingId P3/P4 expansion +- **Phase 78**: `phase78-bindingid-promoted-carriers.md` - CarrierBindingAssigner +- **Phase 77**: Implementation guide - DigitPos/Trim promoters +- **JoinIR Architecture**: `joinir-architecture-overview.md` - ExitLine/Boundary overview + +### Key Code Files + +- `src/mir/builder/control_flow/joinir/merge/exit_line_reconnector.rs` - ExitLine reconnection +- `src/mir/builder/control_flow/joinir/merge/exit_meta_collector.rs` - Exit metadata collection +- `src/mir/join_ir/lowering/carrier_info.rs` - CarrierVar, CarrierRole +- `src/mir/loop_pattern_detection/digitpos_detector.rs` - DigitPos detection +- `src/mir/loop_pattern_detection/trim_detector.rs` - Trim detection + +### Test Files + +- `tests/normalized_joinir_min.rs` - Add Phase 81 E2E tests here +- `tests/phase246_json_atoi.rs` - Existing DigitPos test (verify PASS) + +--- + +## Next Steps + +**After Phase 81 Complete**: + +1. **Phase 82 (optional)**: Pattern3/4 carrier BindingId registration in後段 + - Extend BindingId registration to carrier join_id determination points + - Reduce fallback usage further + +2. **Phase 83 (optional)**: Debug flag cleanup + - Deprecate `NYASH_JOINIR_DEBUG` in favor of new naming + - Migrate tests to recommended env var + +--- + +## Implementation Notes + +### Task Ordering + +Execute in this order: +1. Task 81-A (Audit) - Understand current state +2. Task 81-B (E2E Tests) - Verify contract +3. Task 81-D (Smoke Tests) - Regression check +4. Task 81-C (Documentation) - Record findings + +### Commit Strategy + +**Single commit** for Phase 81: +``` +feat(joinir): Phase 81 - Pattern2 ExitLine contract verification (dev-only) + +Task 81-A: ExitLine audit findings +- ExitLineReconnector correctly skips ConditionOnly carriers +- ExitMetaCollector includes all carriers for latch +- CarrierRole filtering verified correct + +Task 81-B: E2E tests for promoted carriers +- test_phase81_digitpos_exitline_contract(): DigitPos pattern +- test_phase81_trim_exitline_contract(): Trim pattern +- Verified Exit PHI excludes ConditionOnly carriers + +Task 81-D: Smoke test verification +- tools/smokes/v2/run.sh --profile quick PASS +- No regressions in existing tests + +Task 81-C: Contract documentation +- ExitLine + promoted carriers contract documented +- CarrierRole filtering rules clarified + +Tests: 972/972 PASS (970 baseline + 2 new E2E) +Smoke: quick profile PASS (no regressions) +Design: Verification-only, zero production impact +``` + +--- + +## Status Tracking + +- [ ] Task 81-A: ExitLine Audit (analysis) +- [ ] Task 81-B: E2E Tests (DigitPos + Trim) +- [ ] Task 81-C: Contract Documentation +- [ ] Task 81-D: Smoke Tests Verification + +**Current Phase**: Phase 81 Design (this document) +**Next Action**: Task 81-A (ExitLine Audit)