# 3축 Activation Readiness 분리 설계 문서 (켜기 전 회장 판단용 · 코드 0)

상태명: `THREE_AXIS_ACTIVATION_READINESS_DESIGN_DOC_REQUESTED_ACTIVE_FALSE`
작성: ANU 직접 (2026-07-04 KST). **설계 문서 only — 코드 수정 0 · PR 0 · merge 0 · activation 0 · runner/systemd/cron/daemon 설치 0 · real fire 0 · owner-pickup 실행 0 · Merge Queue/required check/ruleset 변경 0 · ACTIVE=false 유지.** 이 문서는 "켜기"가 아니라 "무엇을·어디까지·어떤 순서로 켤지" 정리하는 판단 재료다.

---

## 1. 현재 baseline
- current main sha: **5f707910** (local == origin/main).
- PR #263 `PR263_MERGED_WORKSPACE_FALLBACK_P1_SAFE_REPODIR_INVARIANT_ACTIVE_FALSE` — code-only merged (2c79ffc5).
- PR #264 `PR264_MERGED_TASK2782_TERMINAL_ARTIFACT_EMIT_CODE_ONLY_ACTIVE_FALSE` — code-only merged (45e8f19d).
- PR #265 `PR265_MERGED_TASK2781_MERGE_GROUP_EVIDENCE_AUDITOR_CODE_ONLY_ACTIVE_FALSE` — code-only merged (5f707910).
- 공통 불변식(현재): **모두 code-only merge · ACTIVE=false · production activation 없음 · owner-pickup 완료 아님 · callback delivery 완료 아님 · Merge Queue 활성화 아님 · required check 등록 아님 · ruleset 변경 아님.**

---

## 2. 축별 activation 정의 (무엇을 켠다는 뜻인가)

### 축 A — PR #263 (P1 safe repo_dir invariant / truncate 차단)
- 성격: **수동적(passive) 방어 가드**. `_resolve_safe_repo_dir`가 canonical WORKSPACE write를 fail-closed로 막는다. 이미 main 코드 실행 경로에 들어가 있어 **별도 flag/runner 없이 상시 동작**한다(가드는 함수 호출 시 즉시 raise).
- "activation" 정의: **별도 activation 개념이 사실상 없음.** 이미 코드상 passive guard로 발효 중. 남는 선택지는 (a)현 상태 유지 (b)추가 호출자에도 invariant 적용 확대(별개 코드 안건) 정도. → **activation 대상이 아니라 "발효 확인/회귀 유지" 대상**.

### 축 B — PR #264 (terminal artifact emit / owner-pickup-required result artifact)
- 성격: finish-task 4종 종단에 result.json + terminal_state_callback **emit**을 결선. 단 emit은 `TERMINAL_CALLBACK_ENABLED` flag(기본 OFF) gate라 **현재 실제 emit 스킵**(result.json/context만 박제).
- "activation" 스펙트럼(어디까지가 activation인지 분리):
  - B0: flag OFF (현재) — result.json/context만.
  - B1: `TERMINAL_CALLBACK_ENABLED=1` → terminal_state_callback **emit** 실행(단 executor self-key 발사 0·OS-level pickup contract 유지).
  - B2: owner-pickup **runner** 가동(OS crontab/systemd-path/inotify가 result.json 수거→owner-proof→closeout).
  - B3: schedule_history proof + ANU inbox 확인으로 **실제 callback delivery 검증**(DELIVERY_UNVERIFIED→DELIVERED 승격은 이 단계에서만).
- ★ 경계: B1(emit ON)만으로는 "callback delivery 완료"가 아님. **delivery는 B2+B3까지 가야 성립.** 지금까지 지켜온 "최대 표현 OWNER_PICKUP_REQUIRED/DELIVERY_UNVERIFIED"는 B0~B1 상태의 정확한 표현.

### 축 C — PR #265 (merge_group evidence auditor)
- 성격: merge_group head SHA 기반 evidence 직접판정(skipped=success 뒤집기) + PR 역추적 resolver. **현재는 main에 스크립트만 존재**, 어떤 workflow도 호출하지 않음(.github 무배선).
- "activation" 스펙트럼:
  - C0: 코드만 존재(현재). 호출자 0.
  - C1: **CLI 수동 실행**(사람이 `python3 scripts/merge_group_evidence_auditor.py --merge-group-sha ...`로 1회 판정).
  - C2: **shadow report**(merge_group workflow에서 실행하되 결과를 report-only로 기록, gate 판정에 미반영).
  - C3: **CI advisory**(비필수 check로 노출, 실패해도 merge 차단 안 함).
  - C4: **required check 등록**(merge_group에서 이 check가 필수 → 실패 시 merge 차단).
  - C5: **ruleset enforcement**(branch protection/merge queue ruleset에 결선, 강제).
- ★ C1~C2는 관찰/보고, C4~C5는 `.github`/ruleset/required 변경 = **고위험·되돌리기 어려움**.

---

## 3. 축별 위험도 / blast radius (위험도 순)

| 축 | canonical write 위험 | callback 중복/오발사 | self-key/ANU key 경계 | CI block 위험 | merge queue/branch protection 장애 | rollback 난이도 | 회장 개입 필요도 |
|---|---|---|---|---|---|---|---|
| A(263) | 없음(오히려 방어) | 무관 | 무관 | 없음 | 없음 | 매우 낮음 | 낮음 |
| C(265) C1~C2 | 없음(read-only 판정) | 무관 | 무관 | 없음(shadow) | 없음 | 낮음(호출 제거) | 중 |
| C(265) C4~C5 | 없음 | 무관 | 무관 | **높음**(오탐 시 merge 전면 차단) | **높음**(ruleset/queue 오설정 시 전 PR 장애) | **높음**(ruleset revert 필요) | **높음** |
| B(264) B1 | 낮음 | **중**(emit 경로 중복 방지 필요) | **높음**(self-key 0·ANU literal 0 유지 필수) | 낮음 | 없음 | 중(flag OFF) | 높음 |
| B(264) B2~B3 | 낮음 | **높음**(runner 무한 spawn/오발사 이력) | **매우 높음** | 낮음 | 없음 | **높음**(runner 중지+marker 정리) | **매우 높음** |

- 종합 위험 순위(낮→높): **A ≤ C1~C2 < C3 < B1 < C4~C5 ≈ B2~B3.**
- 핵심 리스크: (1) B2~B3 = spawn 무한/오발사 사고 이력([[project-spawn-safety-governor-merged-pr250-260624]] 등) — 가장 신중. (2) C4~C5 = ruleset/required 오설정 시 전 PR merge 장애 — 되돌리기 어려움.

---

## 4. 축별 단계 설계 (Stage 0~6 · 모든 축이 6까지 갈 필요 없음)

공통 단계 정의: **Stage0** code-only/inactive · **Stage1** manual dry-run · **Stage2** shadow mode · **Stage3** report-only · **Stage4** advisory gate · **Stage5** blocking/enforcing · **Stage6** production activation.

- **축 A (263)**: 현재 이미 코드상 발효(passive). → **Stage 0~1로 충분할 수 있음**(별도 activation 불필요, 회귀 유지·확대 적용만 별개 안건). Stage 2+ 불필요.
- **축 C (265)**: Stage0(현재) → Stage1(CLI 수동) → Stage2(shadow report) → Stage3(report-only) → Stage4(advisory) → Stage5(required/ruleset enforcing). **Stage4까지는 관찰/비차단, Stage5는 고위험.** 권고 검토 범위 = **Stage1~2 우선**, Stage5는 별도 대형 안건.
- **축 B (264)**: Stage0(현재·flag OFF) → Stage1(mock/dry-run emit) → Stage2(shadow: flag ON이되 owner-pickup 미가동, emit marker만) → Stage3(owner-pickup runner report-only) → ... → Stage6(실 delivery). **B2~B3부터 real fire 영역**이라 각 단계 회장 승인 필수.

---

## 5. 축별 선행조건 (켜기 전 필요조건)

- **축 A**: 테스트 통과(P1 회귀 36 유지) · 추가 호출자 확대 시 grep 전수. rollback script 불필요(코드 revert만). → 선행조건 사실상 충족.
- **축 C (Stage1~2)**: (a)회귀 13 통과 유지 (b)merge_group 이벤트 샘플 확보(실 merge_group SHA로 CLI 판정 재현) (c)shadow 결과 log/marker 경로 (d)오탐률 관측(skipped=success 뒤집기가 정상 merge를 잘못 차단 안 하는지) (e)capability matrix 갱신 (f)Stage3+는 회장 승인. Stage5(required/ruleset)는 (g)ruleset rollback script + (h)전 PR 영향 시뮬레이션 필수.
- **축 B (Stage1~2)**: (a)회귀 10 통과 유지 (b)`TERMINAL_CALLBACK_ENABLED` gate 동작 확인 (c)emit 중복방지(1회 보장 lock) 검증 (d)**self-key 0·ANU key literal 0 재확인** (e)**truncate watcher lifecycle 보강**(현 조기종료 hygiene backlog 해소 — B 검증엔 신뢰할 관찰기 필요) (f)Stage3+(owner-pickup)는 (g)owner proof 조건 (h)schedule_history proof (i)ANU inbox 확인 (j)spawn governor 발효 확인([[project-spawn-safety-governor-merged-pr250-260624]]) (k)rollback(runner 중지+marker 정리) (l)회장 승인 필수.

---

## 6. 축별 rollback 계획

- **축 A**: 즉시 OFF = 해당 없음(passive guard). 문제 시 = 코드 revert PR. marker 정리 불필요. STOP_REPORT 조건: 정상 tmp sandbox를 오탐 차단 시.
- **축 C**: 즉시 OFF = workflow에서 auditor 호출 제거(C2~C3) 또는 required check 해제(C4~C5). flag rollback = advisory↔required 토글. ruleset/required rollback = ruleset에서 check 제거(관리자 권한·회장 영역). PR revert = 최후. STOP_REPORT: 정상 merge를 auditor가 오탐 차단 / PR 역추적 실패 급증 / merge_group_sha freshness 오판.
- **축 B**: 즉시 OFF = `TERMINAL_CALLBACK_ENABLED` 해제(B1) · owner-pickup runner 중지(OS crontab/systemd disable)(B2). marker 정리 = terminal-callback/result.json 잔재 정리(canonical 무접촉). PR revert = 최후. STOP_REPORT: self-key 발사 관측 / callback 중복·오발사 / spawn 무한 / DELIVERED 오승격 / real fire loop.

---

## 7. Recommended activation 검토 순서 (실행 제안 아님 · 검토 순서만)

회장 가설 검토 결과 — **가설 대체로 타당, 일부 보정:**
1. **축 A (263)** — 가설 "이미 passive protection이므로 별도 activation 없음 또는 검증-only" → **타당**. activation 대상 아님. **검증-only(회귀 유지 확인)로 종결 권고**. 여기에 시간 쓸 필요 낮음.
2. **축 C (265) Stage1~2** — 가설 "shadow/report-only부터 검토 가능하나 required check/ruleset은 고위험" → **타당**. **가장 먼저 실질 검토할 축**: CLI 수동 실행(C1) + shadow report(C2)는 read-only·비차단·rollback 쉬움이라 안전하게 "관찰"을 시작할 수 있고, 원래 회장 문제의식(8팀 병렬 merge false-pass)에 직접 답한다. **단 C4~C5(required/ruleset)는 분리된 대형 안건으로 보류.**
3. **축 B (264)** — 가설 "owner-pickup/callback runner라 가장 신중, real fire 이력 때문에 마지막 검토 후보" → **타당**. **최후 검토**. B1(emit ON)조차 self-key/중복 경계가 걸리고, B2~B3은 spawn 사고 이력이 커서 governor 발효·watcher 보강 등 선행조건이 가장 많다.

→ **검토 순서 권고: A(검증-only 종결) → C Stage1~2(shadow 관찰) → B(최후·선행조건 충족 후).** 각 단계는 별도 회장 승인. 이 순서는 "위험 낮은 것부터 관찰을 켜고, real fire 축은 가장 마지막"이라는 원칙.

---

## 8. backlog와 activation의 분리

5 backlog는 **activation과 별개**이며, activation 결정을 막지 않는다. 단 일부는 특정 축의 **선행조건**으로 승격될 수 있다:
- `PR263_HELPER_RUNNER_ABSTRACTION_TESTABILITY_BACKLOG` — 축 A와 무관한 코드 품질(testability). activation 선행조건 아님.
- `PR264_TEST_HELPER_ROBUSTNESS_BACKLOG` / `PR264_FINISH_TASK_SHELL_ROBUSTNESS_BACKLOG` — 축 B 코드 품질. B activation 선행조건 아님(있으면 좋음).
- `PR265_AUDITOR_RESOLVER_ROBUSTNESS_BACKLOG` — 축 C 코드 품질(dead-code/observability). C Stage3+ 전 observability(stderr 노출)는 **shadow 관찰 품질을 위해 우선 처리 권고**(선행조건 후보).
- `TRUNCATE_WATCHER_LIFECYCLE_HYGIENE_BACKLOG` — ★ **축 B 검증의 선행조건으로 승격 권고**. B의 delivery 검증엔 신뢰할 관찰기가 필요한데 현 watcher가 조기종료(inconclusive)하므로, B 검토 전 이 hygiene를 닫아야 한다.
- 원칙: **backlog 정리 자체를 activation으로 오인 금지.** backlog는 옵션, activation은 별도 결정.

---

## 결론 (회장 결정 요청 사항)
1. 축 A = **검증-only로 종결**할지(권고) 확인.
2. 축 C = **Stage1~2(CLI 수동 + shadow report) 설계를 먼저 볼지** 확인(required/ruleset는 별도 대형 안건).
3. 축 B = **최후 검토**로 두고, 선행조건(watcher hygiene·self-key 경계·spawn governor)부터 정리할지 확인.
4. 각 축의 실제 Stage 전진은 **전부 개별 회장 승인**. 본 문서는 코드 0·activation 0.
