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

9.7 KiB
Raw Blame History

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

// 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_posis_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

  • 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)