# πŸ“‘ Issue #5 Phase 2b β€” μžλ™μ™„λ£Œ 운영 λ…ΈνŠΈ (Flag-Gated / Opt-In) - **λ¬Έμ„œ 버전**: Rev.1 - **μƒνƒœ**: κ΅¬ν˜„ μ™„λ£Œ, **κΈ°λ³Έ λΉ„ν™œμ„±(`MAM_AUTO_COMPLETE=0`)** --- ## 1. ν•œ λ¬Έμž₯ μš”μ•½ **λλ‚¬λ‹€λŠ” 사싀을 μ•„λŠ” μͺ½(μ—μ΄μ „νŠΈ)이 확정을 μ„ μ–Έν•˜κ³ , μ½λŠ” μͺ½μ€ κ·Έ 선언을 λ―Ώμ§€ μ•Šκ³  ν•΄μ‹œλ₯Ό λ‹€μ‹œ κ³„μ‚°ν•œλ‹€.** μ›Œμ²˜κ°€ 슀슀둜 ν•΄μ‹œλ₯Ό 계산해 λ§€λ‹ˆνŽ˜μŠ€νŠΈλ₯Ό λ§Œλ“€λ©΄ 그것은 "μ›Œμ²˜κ°€ μ•ˆμ •λœ νŒŒμΌμ„ λ΄€λ‹€"λŠ” 자기 증λͺ…일 뿐이닀. 이 이슈의 μ•žμ„  λΌμš΄λ“œμ—μ„œ 리뷰어가 κΈ°κ°ν•œ 증거 ν˜•νƒœμ΄λ©°, 같은 μ‹€μˆ˜λ₯Ό λ°˜λ³΅ν•˜μ§€ μ•ŠκΈ° μœ„ν•œ 섀계 결정이닀. ## 2. κ·Έλž˜μ„œ 미지원 μ—μ΄μ „νŠΈλŠ” μžλ™μœΌλ‘œ μ•ˆμ „ν•˜λ‹€ 확정을 μ„ μ–Έν•˜μ§€ μ•Šμ€ μ—μ΄μ „νŠΈλŠ” λ§€λ‹ˆνŽ˜μŠ€νŠΈλ₯Ό 남기지 μ•ŠλŠ”λ‹€. λ§€λ‹ˆνŽ˜μŠ€νŠΈκ°€ μ—†μœΌλ©΄ 정책이 이미 `hold`ν•œλ‹€(Phase 2aμ—μ„œ κ΅¬ν˜„Β·ν…ŒμŠ€νŠΈ μ™„λ£Œ). **"미지원 경둜 100% 보쑴"은 μƒˆ λΆ„κΈ°κ°€ μ•„λ‹ˆλΌ κΈ°μ‘΄ λ™μž‘μ˜ 귀결이닀.** ## 2-1. ⚠️ 아직 λ°°μ„ λ˜μ§€ μ•Šμ•˜λ‹€ (μ •μ§ν•œ ν˜„ν™©) **`autocomplete.evaluate`와 `notifier.recover`λ₯Ό ν˜ΈμΆœν•˜λŠ” ν”„λ‘œλ•μ…˜ κ²½λ‘œλŠ” 아직 μ—†λ‹€.** `daemon.py`/`job_subscriber.py`/`cli.py`/`service.py` 어디도 이듀을 μž„ν¬νŠΈν•˜μ§€ μ•ŠμœΌλ©°, `register`에 `auto_complete` opt-in μ˜΅μ…˜λ„ μ—†λ‹€. 즉 **ν˜„μž¬ 라이브 μ…Έ λ£¨ν”„μ—μ„œ `MAM_AUTO_COMPLETE=1`은 λ¬΄λ™μž‘(no-op)이닀.** Phase 2bκ°€ μ œκ³΅ν•˜λŠ” 것은 **κ²€μ¦λœ λΌμ΄λΈŒλŸ¬λ¦¬μ™€ 게이트**이며, 이λ₯Ό κ°μ‹œ 루프에 μ—°κ²°ν•˜λŠ” 배선은 Phase 3의 λͺ«μ΄λ‹€. 초기 λ¬Έμ„œκ°€ "기동 μ‹œ μž¬λ°œν–‰μ΄ κ΅¬λ…μžμ—μ„œ μˆ˜ν–‰λœλ‹€"κ³  μ μ—ˆλ˜ 것은 사싀이 μ•„λ‹ˆμ—ˆμœΌλ©° μ—¬κΈ°μ„œ μ •μ •ν•œλ‹€(ꡐ차 리뷰 `3fa76e08` O-1, `a0de0e5e` μž”μ—¬ 1Β·2). λ°°μ„  μ‹œ ν•„μš”ν•œ 것: 1. κ°μ‹œ λ£¨ν”„μ—μ„œ `evaluate(...)` 호좜 β€” **`report_dir`λŠ” ν•„μˆ˜ μΈμžλ‹€.** 2. 컀밋 ν›„ `notifier.flush(...)` 호좜 β€” `evaluate`λŠ” intentλ₯Ό 남길 뿐 λ°œν–‰ν•˜μ§€ μ•ŠλŠ”λ‹€. 3. 기동 μ‹œ `notifier.recover(...)` 호좜. 4. `register`에 μž‘λ³„ opt-in 경둜 μΆ”κ°€. ## 3. 3쀑 게이트 (μ „λΆ€ 참일 λ•Œλ§Œ 컀밋) | 게이트 | κΈ°λ³Έκ°’ | κ·Όκ±° | |---|---|---| | `MAM_AUTO_COMPLETE=1` | **`0` (OFF)** | μ „μ—­ 킬 μŠ€μœ„μΉ˜ | | `MAM_ENGINE_CAS=1` | `1` | `0`이면 μžλ™μ™„λ£Œλ„ ν•¨κ»˜ μ€‘λ‹¨λœλ‹€. μΆ”λ‘  μ™„λ£ŒλŠ” CAS 경계 μœ„μ— μ„œ μžˆμœΌλ―€λ‘œ, 경계가 둀백된 μƒνƒœμ˜ 컀밋은 κ·Έ 경계λ₯Ό μš°νšŒν•˜λŠ” 것이닀 | | λ°±μ—”λ“œ ν—ˆμš©λͺ©λ‘ | `claude,grok,codex` (+ `-code`/`-build`/`-cli` 정식 ν‚€) | μ •μ§€ μƒνƒœ(`idle`/`done`) **κ΄€μΈ‘ 증거가 μžˆλŠ” λ°±μ—”λ“œλ§Œ**. `agy`λŠ” `working`만 κ΄€μΈ‘, `hermes`Β·`opencode`λŠ” κ΄€μΈ‘ 0건. **μ •ν™• 일치**둜 λΉ„κ΅ν•œλ‹€ β€” 접두 일치라면 미래의 `claude-experimental`이 μˆ˜μ§‘λœ 적 μ—†λŠ” 증거λ₯Ό λ¬Όλ €λ°›λŠ”λ‹€ | | μž‘λ³„ opt-in | λ ˆμ½”λ“œ `auto_complete: true` | 작 λ‹¨μœ„ λ™μ˜ | `MAM_AUTO_COMPLETE_BACKENDS`둜 λͺ©λ‘μ„ **쒁힐 수만** μžˆλ‹€. κ΄€μΈ‘λœ 적 μ—†λŠ” 이름은 λ¬΄μ‹œλœλ‹€ β€” λ„“νžˆλ €λ©΄ 섀정이 μ•„λ‹ˆλΌ 증거가 ν•„μš”ν•˜λ‹€. ## 4. ν™•μ • 계약 (P2B-01) ``` μ—μ΄μ „νŠΈ: publish_event.py --job --event completed \ --finalize-report [--side-effect =] ... β‘  .tmp β†’ μ›μžμ  rename (반쯀 쓰인 리포트λ₯Ό μ΅œμ’…λ³ΈμœΌλ‘œ λ³Ό 수 μ—†κ²Œ) β‘‘ SHA-256 계산 β‘’ report-manifest.json μ›μžμ  기둝 (job_id, attempt_id, sha256, side_effects, declared_by) ``` - **리포트λ₯Ό λ‹€μ‹œ μ“°λ©΄ 선언은 μ¦‰μ‹œ 무효**κ°€ λœλ‹€. ν•΄μ‹œλ₯Ό λ‹€μ‹œ 계산해 λŒ€μ‘°ν•˜κΈ° λ•Œλ¬Έμ΄λ‹€. μƒˆ λ³Έλ¬Έμ—λŠ” μƒˆ 확정이 ν•„μš”ν•˜λ‹€. - **μ„ μ–Έν•œ λΆ€μˆ˜νš¨κ³ΌλŠ” μ „λΆ€ 증거가 μžˆμ–΄μ•Ό ν•œλ‹€.** μΌλΆ€λ§Œ μžˆλŠ” 것은 μ—†λŠ” κ²ƒμœΌλ‘œ μ·¨κΈ‰ν•œλ‹€ β€” μž‘μ—…μ΄ 끝났닀고 μ•Œ 수 μ—†κΈ° λ•Œλ¬Έμ΄λ‹€. - 확정은 λ°œν–‰ **μ•žμ—** μΌμ–΄λ‚œλ‹€. 리포트λ₯Ό 아직 μ“°λŠ” 쀑인 `completed` μ΄λ²€νŠΈλŠ” 계약이 κΈˆμ§€ν•˜λŠ” λΆ€λΆ„ 리포트 채택을 λΆ€λ₯Έλ‹€. ## 5. μ§€μ—° μ•Œλ¦Ό (P2B-02) ``` 락 μ•ˆ: μƒνƒœ 컀밋 + pending_notification 기둝 ← ν•˜λ‚˜μ˜ μ›μžμ  μ“°κΈ° 락 λ°–: λ°œν–‰ β†’ 성곡 μ‹œ notification_settled μ „μ΄λ‘œ 정리 기동 μ‹œ: pending_notification이 남은 λ ˆμ½”λ“œλ₯Ό μž¬λ°œν–‰ (λ©±λ“±: κ΅¬λ…μžκ°€ seq둜 쀑볡 제거) ``` - **독립 Outbox μ €μž₯μ†Œλ₯Ό λ§Œλ“€μ§€ μ•ŠλŠ”λ‹€**(`state-transitions.md` Β§5 λͺ…μ‹œ). 이미 μ“°λŠ” λ ˆμ½”λ“œμ— ν•„λ“œ ν•˜λ‚˜λ₯Ό 더 μ“΄λ‹€. - **λ°œν–‰ μ‹€νŒ¨λŠ” μ˜λ„μ μœΌλ‘œ intentλ₯Ό 남긴닀.** 보내지 μ•Šμ€ μ•Œλ¦Όμ΄ 보낸 κ²ƒμ²˜λŸΌ λ³΄μ΄λŠ” 편이, μž¬μ‹œλ„λ˜λŠ” νŽΈλ³΄λ‹€ λ‚˜μ˜λ‹€. - `notification_settled`λŠ” **μƒνƒœλ₯Ό λ°”κΎΈμ§€ μ•ŠλŠ” bookkeeping μš”μ²­**이라 terminal μƒνƒœμ—μ„œλ„ ν—ˆμš©λ˜λ©°, **`pending_notification` μ™Έμ˜ ν•„λ“œλŠ” μ“Έ 수 μ—†λ‹€**(κ²½κ³„μ—μ„œ κ±°λΆ€ β€” ν˜„μž¬ ν˜ΈμΆœμžκ°€ κ·Έκ²ƒλ§Œ λ„˜κΈ΄λ‹€λŠ” 사싀에 μ˜μ‘΄ν•˜μ§€ μ•ŠλŠ”λ‹€). - **μ†ŒλΉ„μž 쀑볡 제거**: μž¬λ°œν–‰μ€ **μƒˆ wire seq**λ₯Ό λ°›μœΌλ―€λ‘œ κ΅¬λ…μžμ˜ 단쑰 seq κ°€λ“œλŠ” μž¬μ‹œλ„λ₯Ό μ•Œμ•„λ³΄μ§€ λͺ»ν•œλ‹€(κ°€λ“œ μž…μž₯μ—μ„œλŠ” μƒˆ μ΄λ²€νŠΈλ‹€). κ·Έλž˜μ„œ `job_subscriber`κ°€ `data.notification_intent`의 μ•ˆμ •λœ μ‹ μ›μœΌλ‘œ 쀑볡을 μ œκ±°ν•œλ‹€. μž¬μ‹œμž‘ ν›„μ—λŠ” λ””μŠ€ν¬ 폴백이 λ ˆμ§€μŠ€νŠΈλ¦¬μ—μ„œ terminal을 ν™•μΈν•˜κ³ , 쀑볡 terminal은 전이 경계가 λ©±λ“± ACK둜 κ±°λΆ€ν•˜λ―€λ‘œ 이쀑 적용이 λ°œμƒν•˜μ§€ μ•ŠλŠ”λ‹€(ꡐ차 리뷰 Round 2 R4). - μ •λ¦¬λŠ” **μ‹€μ œλ‘œ 보낸 intent와 μΌμΉ˜ν•  λ•Œλ§Œ** 이루어진닀. λ°œν–‰μ€ 락 λ°–μ—μ„œ μΌμ–΄λ‚˜λ―€λ‘œ κ·Έ 사이에 μƒˆ intentκ°€ μ •λ‹Ήν•˜κ²Œ λ“€μ–΄μ˜¬ 수 있고, 무쑰건 μ§€μš°λ©΄ 아무도 보내지 μ•Šμ€ μ•Œλ¦Όμ΄ 사라진닀. - λ°œν–‰ payload에 intent의 `seq`/`event`/`timestamp`λ₯Ό μ‹€μ–΄ 보낸닀. **전솑 계측 seqλŠ” 같은 intent의 μž¬μ‹œλ„λ₯Ό μ‹λ³„ν•˜μ§€ λͺ»ν•˜λ―€λ‘œ**, μ†ŒλΉ„μžλŠ” `notification_intent`둜 쀑볡을 μ œκ±°ν•œλ‹€. μ•Œλ¦Όμ€ terminal에 *κ΄€ν•œ* κ²ƒμ΄λ―€λ‘œ, terminal이 κ±°λΆ€ν•˜λŠ” μš”μ²­μœΌλ‘œλŠ” μ˜μ›νžˆ 정리할 수 μ—†λ‹€. ## 5-1. ν•„μˆ˜ 검증 (ꡐ차 리뷰 반영, μ „λΆ€ λ―ΈμΆ©μ‘± μ‹œ `hold`) | 검증 | μ—†μœΌλ©΄ | |---|---| | `report_dir` 인자 | `hold` β€” **선택이 μ•„λ‹ˆλ‹€.** μƒλž΅ν•˜λ©΄ λ””μŠ€ν¬ λŒ€μ‘°κ°€ ν†΅μ§Έλ‘œ κ±΄λ„ˆλ›°μ–΄μ Έ μˆ˜μ§‘κΈ°μ˜ 자기 μ‹ κ³ κ°€ λ‹€μ‹œ νŒλ‹¨ 주체가 λœλ‹€ | | 기둝된 dispatch | `hold` β€” κ·€μ†μ‹œν‚¬ λŒ€μƒμ΄ μ—†λ‹€ | | 증거의 **λŒ€μƒ 일치** | `hold` β€” μ‹œλ‚˜λ¦¬μ˜€μ˜ `job_id`Β·attemptΒ·sessionΒ·pane이 기둝된 dispatch와 μΌμΉ˜ν•΄μ•Ό ν•œλ‹€. 정책은 μ‹œλ‚˜λ¦¬μ˜€ **λ‚΄λΆ€**의 dispatch_contextμ™€λ§Œ λΉ„κ΅ν•˜λ―€λ‘œ ꡬ쑰상 항상 자기 일관적이닀 | | λ§€λ‹ˆνŽ˜μŠ€νŠΈ μž¬κ³„μ‚° λŒ€μ‘° | `hold` | | Reviewer μ—­ν• μ˜ νŒμ • 토큰 | `hold` β€” Phase 0 μ•ˆμ „ 계약. νŒμ •μ„ 아직 μ“°μ§€ μ•Šμ€ λ¦¬λ·°μ–΄λŠ” κ²€ν† λ₯Ό 끝내지 μ•Šμ€ 것이닀 | ## 6. λ¬΄νŒμ • fail-closed λ§€λ‹ˆνŽ˜μŠ€νŠΈλ₯Ό 읽지 λͺ»ν•¨, 정책이 μ˜ˆμ™Έλ₯Ό 던짐, μ•Œ 수 μ—†λŠ” κ²°μ • β€” μ „λΆ€ `hold`λ‹€. **"νŒμ •ν•˜μ§€ λͺ»ν•¨"은 κ²°μ½” "μ™„λ£Œ"κ°€ μ•„λ‹ˆλ‹€.** 늦게 λ„μ°©ν•œ λͺ…μ‹œ terminal이 있으면 전이 경계가 μΆ”λ‘  μ™„λ£Œλ₯Ό κ±°λΆ€ν•˜λ©°, 그것은 경계가 제 일을 ν•œ 것이지 게이트의 였λ₯˜κ°€ μ•„λ‹ˆλ‹€. ## 7. 감사 ν‘œμ‹ μžλ™μ™„λ£Œλ‘œ λ“€μ–΄κ°„ terminalμ—λŠ” `completed_by: "auto_complete"`와 νŒμ • μ‚¬μœ κ°€ λ‚¨λŠ”λ‹€. κ΅¬λ…μžμ™€ λž˜νΌλŠ” μžλ™/λͺ…μ‹œ μ™„λ£Œλ₯Ό κ΅¬λ³„ν•˜μ§€ λͺ»ν•˜λ―€λ‘œ(`job_subscriber._check_disk_fallback`은 λ ˆμ§€μŠ€νŠΈλ¦¬ status만 λ³Έλ‹€), **사후에 ꡬ별할 수 μžˆλŠ” μœ μΌν•œ μˆ˜λ‹¨**이닀. ## 8. λ‘€λ°± 1. `MAM_AUTO_COMPLETE=0` β€” μ‹ κ·œ μžλ™μ™„λ£Œλ§Œ 쀑단. **이미 ν™•μ •λœ terminal λ ˆμ½”λ“œλŠ” 보쑴**ν•œλ‹€. 2. `MAM_ENGINE_CAS=0` β€” Phase 2a κ²½λ‘œκΉŒμ§€ λ˜λŒλ¦°λ‹€(μžλ™μ™„λ£ŒλŠ” κ·Έ μœ„μ— μžˆμœΌλ―€λ‘œ ν•¨κ»˜ 무λ ₯ν™”). 3. `.mam/shadow/`λŠ” λ ˆμ§€μŠ€νŠΈλ¦¬μ™€ λΆ„λ¦¬λ˜μ–΄ μžˆμ–΄ μ‚­μ œν•΄λ„ job μƒνƒœμ— 영ν–₯이 μ—†λ‹€. ## 9. κ³„νš λŒ€λΉ„ μ΄νƒˆ (λ ˆμ½”λ“œ μŠ€ν‚€λ§ˆ) β€” **Β§8-1μ—μ„œ λΆ€λΆ„ 철회됨** > ⚠️ μ•„λž˜ νŒλ‹¨μ€ Round 2 ꡐ차 리뷰(`a45e5b7f` R2)둜 **λΆ€λΆ„μ μœΌλ‘œ λ°˜μ¦λλ‹€.** 증거 κ³„μΈ΅μ˜ λŒ€μ‘°λ§ŒμœΌλ‘œλŠ” **μ»€λ°‹κ³Όμ˜ μ›μžμ„±**을 얻을 수 μ—†μ–΄, `dispatch_token`을 λ ˆμ½”λ“œμ— μΆ”κ°€ν–ˆλ‹€(Β§8-1). μ•„λž˜ μ„œμˆ μ€ "μ™œ `attempt_id`λ₯Ό `expected_attempt`둜 μ“°μ§€ μ•ŠλŠ”κ°€"에 ν•œν•΄ μ—¬μ „νžˆ μœ νš¨ν•˜λ‹€. κ³„νšμ„œ Β§D2λŠ” `attempt_id`λ₯Ό job λ ˆμ½”λ“œμ˜ 1κΈ‰ ν•„λ“œλ‘œ μŠΉκ²©ν•  것을 κΆŒκ³ ν•˜κ³ , Phase 1이 λ™κ²°ν•œ "λ ˆμ½”λ“œ ν•„λ“œ λΆˆλ³€" κ³„μ•½μ˜ λ³€κ²½μ΄λ―€λ‘œ **리뷰어 μŠΉμΈμ„ μ„ ν–‰ 쑰건**으둜 κ±Έμ—ˆλ‹€. κ΅¬ν˜„ 쀑 μ‹€μΈ‘ν•œ κ²°κ³Ό **κ·Έ 변경이 ν•„μš”ν•˜μ§€ μ•Šμ•˜λ‹€**: - μ—”μ§„μ˜ `expected_attempt`λŠ” λ ˆμ½”λ“œμ˜ `attempt_id`(μ—†μŒ)λ₯Ό `iteration`(루프 회차)으둜 λŒ€μ²΄ λΉ„κ΅ν•œλ‹€ β€” 두 κ°œλ…μ΄ 달라 μ˜λ―Έκ°€ μ„±λ¦½ν•˜μ§€ μ•ŠλŠ”λ‹€. - 반면 **μ‹œλ„ 식별은 이미 증거 κ³„μΈ΅μ—μ„œ κ²€μ¦λœλ‹€**: `policy`κ°€ κ΄€μΈ‘ μ‹λ³„μžμ™€ shadow μ €μž₯μ†Œμ˜ dispatch λ ˆμ½”λ“œλ₯Ό λŒ€μ‘°ν•˜λ©°, μ‹œλ„κ°€ μ–΄κΈ‹λ‚˜λ©΄ `hold`ν•œλ‹€(μ‹€μΈ‘ 확인). λ”°λΌμ„œ μžλ™μ™„λ£ŒλŠ” 엔진에 `expected_attempt`λ₯Ό λ„˜κΈ°μ§€ μ•Šκ³  `expected_status="running"`(μ—”μ§„μ˜ 고유 μ˜μ—­μΈ μƒνƒœ)만 μ „μ œμ‘°κ±΄μœΌλ‘œ μ€€λ‹€. **μ‹œλ„ 보증은 μ‹œλ„ 정체성이 μ‹€μ œλ‘œ μ‚¬λŠ” 곳에 λ‘”λ‹€.** λ ˆμ½”λ“œ μŠ€ν‚€λ§ˆλŠ” λ°”λ€Œμ§€ μ•Šμ•˜κ³ , Phase 1 계약도 μœ μ§€λœλ‹€. `attempt_id` μŠΉκ²©μ€ μ—΄λ¦° 질문으둜 남긴닀. μŠΉκ²©ν•˜λ©΄ 엔진에 2μ°¨ 방어선이 μƒκΈ°μ§€λ§Œ 동결 계약을 λ°”κΏ”μ•Ό ν•˜λ©°, ν˜„μž¬λŠ” ν•„μš”ν•˜μ§€ μ•Šλ‹€. `test_x03_the_record_carries_iteration_not_an_attempt_id`κ°€ 이 μ „μ œλ₯Ό κ°μ‹œν•œλ‹€ β€” λ ˆμ½”λ“œκ°€ `attempt_id`λ₯Ό κ°–κ²Œ λ˜λŠ” μˆœκ°„ μ‹€νŒ¨ν•˜λ©°, κ·Έλ•Œκ°€ μž¬κ²€ν†  μ‹œμ μ΄λ‹€. ## 8-1. μ›μžμ  귀속 β€” dispatch token (ꡐ차 리뷰 Round 2 R2) **문제**: 귀속을 컀밋 **전에** ν™•μΈν•˜κ³  μ»€λ°‹μ—λŠ” `expected_status="running"`만 κ±Έλ©΄, κ·Έ 사이에 job이 `completed β†’ redispatch β†’ claim`으둜 μƒˆ μ‹œλ„λ₯Ό μ‹œμž‘ν•  수 있고 **μ˜› 증거가 μƒˆ μ‹œλ„λ₯Ό μ™„λ£Œμ‹œν‚¨λ‹€.** μƒˆ μ‹œλ„λ„ `running`μ΄λ―€λ‘œ μƒνƒœ κ²€μ‚¬λ§ŒμœΌλ‘œλŠ” κ΅¬λ³„λ˜μ§€ μ•ŠλŠ”λ‹€. μ‹€μΈ‘μœΌλ‘œ μž¬ν˜„λλ‹€(λ ˆμ§€μŠ€νŠΈλ¦¬κ°€ 이미 iteration 2인 μƒνƒœμ—μ„œ 컀밋됨). **ν•΄κ²°**: μ‹œλ„ 정체성을 **λ ˆμ½”λ“œ μ•ˆμ—** λ‘”λ‹€. μ „μ œμ‘°κ±΄μ΄ 컀밋과 μ›μžμ μ΄λ €λ©΄ νŠΈλžœμž­μ…˜μ΄ **자기 락 μ•ˆμ—μ„œ 읽을 수 μžˆμ–΄μ•Ό** ν•˜κΈ° λ•Œλ¬Έμ΄λ‹€. | ν•­λͺ© | κ°’ | |---|---| | ν•„λ“œ | `dispatch_token` (뢈투λͺ… λ¬Έμžμ—΄) | | λ°œκΈ‰ μ‹œμ  | μ‹œλ„κ°€ μ‹œμž‘λ˜λŠ” μš”μ²­ β€” `claim`, `redispatch` | | μ‚¬μš© | κ²Œμ΄νŠΈκ°€ νŒλ‹¨μ— μ‚¬μš©ν•œ 토큰을 `expected_dispatch_token`으둜 λ„˜κΈ°κ³ , 엔진이 **락 μ•ˆμ—μ„œ** λŒ€μ‘° | | 증거 결속 | shadow dispatch λ ˆμ½”λ“œλ„ 같은 토큰을 보관 β†’ 증거가 μ–΄λŠ μ‹œλ„μ˜ 것인지 증λͺ…λœλ‹€ | **μ™œ `iteration`이 μ•„λ‹ˆλΌ 토큰인가**: `iteration`은 이미 **루프 회차**λ₯Ό λœ»ν•œλ‹€. dispatch μ‹œλ„ 번호λ₯Ό 그것과 λΉ„κ΅ν•˜λ©΄ 값이 μš°μ—°νžˆ 같을 λ•ŒλŠ” κ³΅ν—ˆν•˜κ³ , κ°ˆλΌμ§€λ©΄ **정상 μ™„λ£Œλ₯Ό κ±°λΆ€**ν•œλ‹€(3회차 loop jobμ—μ„œ μ‹€μΈ‘). 뢈투λͺ… 토큰은 κ²½μŸν•˜λŠ” μ˜λ―Έκ°€ μ—†λ‹€. **이전 νŒλ‹¨μ˜ μ •μ •**: μ•„λž˜ Β§9λŠ” "μ‹œλ„ 보증이 증거 계측에 μžˆμœΌλ―€λ‘œ λ ˆμ½”λ“œ μŠ€ν‚€λ§ˆ 변경이 λΆˆν•„μš”ν•˜λ‹€"κ³  μ μ—ˆλ‹€. 증거와 dispatchλ₯Ό **λŒ€μ‘°**ν•˜λŠ” λ°λŠ” λ§žμ§€λ§Œ, **μ»€λ°‹κ³Όμ˜ μ›μžμ„±**μ—λŠ” ν‹€λ Έλ‹€. μ›μžμ„±μ€ νŠΈλžœμž­μ…˜μ΄ 읽을 수 μžˆλŠ” 곳에 값이 μžˆμ–΄μ•Όλ§Œ μ–»μ–΄μ§€λ©°, 그것이 λ ˆμ½”λ“œλ‹€. `dispatch_token`은 μΆ”κ°€ ν•„λ“œμ΄λ―€λ‘œ `SCHEMA_VERSION`은 1을 μœ μ§€ν•œλ‹€. ## 9-1. κ΅¬ν˜„ 쀑 μ •μ • 1건 β€” `finalize`의 νŒ¨ν‚€μ§€ μœ„μΉ˜ μ²˜μŒμ—λŠ” `finalize.py`λ₯Ό `lib_py/loop/`에 λ‘μ—ˆλŠ”λ°, 그러면 `publish_event`(=`lib_py.delegation`)κ°€ **ν˜•μ œ νŒ¨ν‚€μ§€λ₯Ό μž„ν¬νŠΈ**ν•˜κ²Œ λ˜μ–΄ freeze ν•˜μ—μ„œ νŠΈλ¦¬κ°€ μ„žμΈλ‹€. Phase 1이 λͺ…λ¬Έν™”ν•˜κ³  Phase 2aμ—μ„œ μ—”μ§„ 배치λ₯Ό μ •μ •ν•˜κ²Œ λ§Œλ“€μ—ˆλ˜ λ°”λ‘œ κ·Έ κ·œμΉ™μ΄λ©°, κΈ°μ‘΄ κ°€λ“œ ν…ŒμŠ€νŠΈ(`test_delegation_package_imports_no_sibling_lib_py_modules`)κ°€ 전체 μŠ€μœ„νŠΈμ—μ„œ 이λ₯Ό κ²€μΆœν–ˆλ‹€. **λ§€λ‹ˆνŽ˜μŠ€νŠΈλŠ” job의 리포트 디렉터리에 쓰이고 μ—μ΄μ „νŠΈκ°€ ν˜ΈμΆœν•˜λŠ” CLIλŠ” delegation μ§„μž…μ μ΄λ―€λ‘œ, `finalize`λŠ” `lib_py/delegation/`에 μ†ν•œλ‹€.** `lib_py.loop`κ°€ `lib_py.delegation`을 μž„ν¬νŠΈν•˜λŠ” λ°©ν–₯은 ν—ˆμš©λœλ‹€. 같은 κ·œμΉ™μ— 두 번 κ±Έλ¦° μ…ˆμ΄λ©°, κ°€λ“œκ°€ 두 번 λ‹€ μž‘μ•˜λ‹€. ## 10. Phase 3 인계 1. `preexec_fn`: 2b도 데λͺ¬μ„ μŠ€ν°ν•˜μ§€ μ•Šμ•„ λ―Έλ…ΈμΆœ μœ μ§€. μ•Œλ¦Ό flushλŠ” κΈ°μ‘΄ κ΅¬λ…μž ν”„λ‘œμ„ΈμŠ€ μ•ˆμ—μ„œ μˆ˜ν–‰ν•œλ‹€. 2. λΆ€μˆ˜νš¨κ³Όμ˜ **원격** 확인(μ‹€μ œ push 도달 μ—¬λΆ€ λ“±)은 λΉ„λ²”μœ„ β€” 증거의 μ‘΄μž¬Β·λŒ€μ‘κΉŒμ§€λ§Œ κ²€μ¦ν•œλ‹€. 3. `agy`/`hermes`/`opencode` μžλ™μ™„λ£ŒλŠ” μ •μ§€ μƒνƒœ μ‹€μΈ‘ 증거 확보 ν›„ 별도 νŒλ‹¨.