Files
hakorune/docs/development/current/main/phase81-pattern2-exitline-contract.md
nyash-codex 0e3b825a52 docs(joinir): Phase 81 design - Pattern2 ExitLine contract verification
Phase 81 SSOT 設計文書作成(P1 優先度)

Goal: Pattern2(DigitPos/Trim)promoted carriers の ExitLine 接続契約を堅牢化

Key sections:
- Background: Phase 74-80 完了後の ExitLine 契約不明確問題
- Invariants: CarrierRole discrimination, ExitLine reconnection timing
- Design: Verification-only strategy (no new features)
- Tasks:
  - 81-A: ExitLine Audit (analysis)
  - 81-B: E2E Tests (DigitPos + Trim)
  - 81-C: Contract Documentation
  - 81-D: Smoke Tests Verification

Acceptance criteria:
- 972/972 lib tests PASS (970 + 2 new E2E)
- tools/smokes/v2/run.sh --profile quick no regressions
- Contract documented

Out of scope: New features, architecture changes, Pattern3/4 work

Next: Task 81-A (ExitLine Audit)
Future: Phase 82 (P3/P4 後段 BindingId), Phase 83 (debug flag cleanup) - optional
2025-12-13 18:18:44 +09:00

312 lines
9.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Phase 81: Pattern2 ExitLine Contract Stabilization
**Status**: Design Phase
**Created**: 2025-12-13
**Priority**: P1 (Blocking Phase 82+)
---
## Goal
Pattern2DigitPos/Trimの promoted carriers を含む ExitLine 接続契約を堅牢化し、E2E テストで安定性を固定する。
---
## Background
### Current Issue
Phase 74-80 で BindingId migration が完了し、Pattern2/3/4 で BindingId lookup が operational になった。しかし、Pattern2 の promoted carriersDigitPos/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)