# ANU Operational Wiring Matrix — Activation Decision Packet

상태명: `ANU_OPERATIONAL_WIRING_MATRIX_PREPARE_APPROVED_ACTIVE_FALSE` → (완료 시) `ANU_OPERATIONAL_WIRING_MATRIX_READY_FOR_ACTIVATION_DECISION_ACTIVE_FALSE`
작성: ANU 직접 (2026-06-29 KST, 코드 0 · 결정 문서). 회장 C안 승인.
근거 실측: main HEAD `b12a4226`, `scripts/anu_control_status.py` smoke(ACTIVE=false·전 flags OFF·systemd inactive·disabled·cron 0), 파일 존재 grep, `memory/state/automation_capability_matrix.json`(19 capabilities), 메모리 박제.

## 0. 이 문서의 목적과 한계
- **목적**: 지금까지 만든 자동화 구성요소가 실제 운영 흐름에서 **어디까지 꽂혀 있는지** 한 장으로 판정하는 decision packet. 새 구현 정당화 문서 **아님**.
- **상태 7단계 (엄격 구분, "파일 존재 = WIRED 금지")**:
  - `IMPLEMENTED` 코드 존재 / `VERIFIED` 테스트·검증 통과 / `MERGED` main 반영 / `CALLABLE` 수동 호출 가능 / `WIRED_RUNTIME` 운영 흐름이 실제로 호출 / `ENFORCED` 차단/강제력 발휘 / `ACTIVE` production 상시 가동
  - ★ `CALLABLE`(부르면 됨) ≠ `WIRED_RUNTIME`(실제로 불림) ≠ `ACTIVE`(상시 가동). 셋을 절대 섞지 않음.
- **전역 사실**: `ACTIVE=false` (전 컴포넌트) · 전 flags OFF · systemd anu-pickup.path inactive·disabled · real fire 0 · 신규 cron 0. 즉 **현재 자동화는 켜져 있지 않다.**

---

## 1. owner pickup chain
- 구현 파일: `dispatch/anu_result_pickup_runner.py` · `dispatch/anu_pickup_driver.py` · `dispatch/anu_pickup_wake_launcher.py` · owner-proof gate(PR#245) · callback launch(PR#246, squash 38ee0555) · spawn safety governor(PR#250, feea9dce)
- 목적: dev 결과 result.json을 owner-proof 후 ANU-key로 수거→ANU 세션 wake→terminal closeout
- 호출 주체: (설계) systemd anu-pickup.path / ANU-owned cron. (현재) ANU 수동 1-shot
- 호출 시점: dev 완료 result.json 도착 시
- 입력: result.json(p0b_inbox) · owner-proof(local canonical HEAD freshness)
- 출력 artifact: ledger append · spawn decision · terminal callback
- 출력 소비자: ANU collector
- 현재 상태: IMPL ✓ / VERIF ✓(1-shot canary 5축 end-to-end) / MERGED ✓ / CALLABLE ✓ / **WIRED_RUNTIME = 1-shot only(상시 아님)** / ENFORCED = governor candidate(observed-bounded) / **ACTIVE false**
- 지금 실제 호출자: 없음(systemd disabled). 1-shot 수동 실증만
- 아직 안 꽂힌 이유: 회장 동결(FROZEN). always-on runner 미가동(폭주 리스크 PR#143/144 박제)
- WIRE 조건: systemd anu-pickup.path enable + driver loop 가동
- ACTIVE 조건: 위 + flag ON + owner-proof freshness 운영 sync
- activation trigger: 회장 별도 승인(`P0B_..._FROZEN` 해제)
- rollback/kill: flag OFF · systemd disable · p0b_kill
- 금지선: self-key fire · raw key · 무한 spawn(governor 6게이트)
- 다음 결정 필요: A안 핵심 의존축

## 2. live inbox evidence wiring
- 구현 파일: `dispatch/anu_pickup_driver.py`(scan_live_inbox, write_evidence) — PR#256 `1ee4204f`
- 목적: live inbox 스캔 결과(LIVE_* verdict)를 main runtime evidence(driver_runs.jsonl)로 영속
- 호출 주체: driver(event_strategy ON 시)
- 호출 시점: driver 1회 실행 시 inbox 스캔
- 입력: live_inbox 항목 · event_strategy flag
- 출력 artifact: `driver_runs.jsonl` 의 LIVE_PENDING_OWNER_PROOF 등 verdict
- 출력 소비자: control status command · owner-proof gate
- 현재 상태: IMPL ✓ / VERIF ✓ / MERGED ✓ / CALLABLE ✓ / **WIRED_RUNTIME = OBSERVED(Phase1 retry 1회, flag ON+driver 1회 수동)** / ENFORCED n/a / **ACTIVE false**
- 지금 실제 호출자: 없음(flags OFF). Phase1 retry 수동 1회만
- 아직 안 꽂힌 이유: owner-proof gate freshness FAIL(head_sha 000≠canonical)에서 차단층 도달, 통과 아님. always-on 아님
- WIRE 조건: event_strategy ON + driver 상시
- ACTIVE 조건: 위 + owner-proof 통과(LIVE_PROCESSED) — 미검증
- activation trigger: 회장 승인(LIVE_PROCESSED 통과 실증 별도 안건)
- rollback/kill: flags OFF
- 금지선: real fire 0 유지
- 다음 결정 필요: A안 의존축(LIVE_PROCESSED 미검증이 선행 리스크)

## 3. limited runtime guard
- 구현 파일: limited activation bound gate(driver+test) — PR#255 `189f1f0d`
- 목적: activation 시 3경계(kill switch / N회 / T시간)로 폭주 제한 + fire-capable epoch fail-closed
- 호출 주체: driver(activation 경로)
- 호출 시점: fire 시도 직전 bound 체크
- 입력: limited_runtime 신호 · epoch · counters
- 출력 artifact: bound 판정(allow/block)
- 출력 소비자: fire 경로
- 현재 상태: IMPL ✓ / VERIF ✓(133 passed) / MERGED ✓ / CALLABLE ✓ / **WIRED_RUNTIME no(fire 경로 미가동)** / ENFORCED = candidate / **ACTIVE false**
- 지금 실제 호출자: 없음(activation 경로 OFF)
- 아직 안 꽂힌 이유: activation 자체가 OFF라 bound 체크 도달 안 함
- WIRE 조건: activation 경로 ON
- ACTIVE 조건: limited pilot 승인
- activation trigger: 회장 승인(limited pilot 별도 안건)
- rollback/kill: kill switch · flag OFF
- 금지선: canary 0 유지
- 다음 결정 필요: A안의 **안전판** — A 선택 시 먼저 켜야 할 가드

## 4. control status command (조종석)
- 구현 파일: `scripts/anu_control_status.py` — PR#257 `5a281ef9`
- 목적: 자동화 상태(ACTIVE/flags/verdict/counts/systemd/cron) read-only 관측 조종석
- 호출 주체: ANU(회장 보고용)
- 호출 시점: 상태 확인 필요 시 수동
- 입력: driver_runs.jsonl · flags · systemd 상태 · inbox/archive 카운트
- 출력 artifact: human/JSON 상태 리포트(파일 미기록, stdout)
- 출력 소비자: ANU·회장
- 현재 상태: IMPL ✓ / VERIF ✓(30 tests) / MERGED ✓ / CALLABLE ✓ / **WIRED_RUNTIME = manual/read-only(ANU가 실제로 호출 중)** / ENFORCED no(관측 전용) / **ACTIVE false(production activation 아님)**
- 지금 실제 호출자: ANU(이번 세션 post-merge smoke 등 실호출)
- 아직 안 꽂힌 이유: 자동 호출(예: 보고 자동화) 미배선 — 의도적 read-only
- WIRE 조건: (선택) 정기 보고 cron에 연결
- ACTIVE 조건: n/a(관측 도구라 ACTIVE 개념 약함)
- activation trigger: 없음(이미 운영 사용 중인 유일 축, manual)
- rollback/kill: n/a(read-only, side-effect 0)
- 금지선: write 0 · subprocess read-only만
- 다음 결정 필요: 없음(이미 실사용). **현재 가장 "꽂힌" 컴포넌트**

## 5. terminal artifact surfacing
- 구현 파일: `dispatch/terminal_artifact_index.py` · `scripts/anu_terminal_artifact_surface.py` — PR#258 `b12a4226`
- 목적: worktree-local terminal artifact를 canonical manifest로 surface(visibility gap 해소)
- 호출 주체: (설계) ANU collector / pickup. (현재) 수동 CLI
- 호출 시점: dev 완료 후 closeout 검증 / envelope dangling 의심 시
- 입력: task_id · worktree_root · canonical_root
- 출력 artifact: `memory/events/terminal_artifact_index/<task_id>.json` manifest
- 출력 소비자: ANU closeout verifier(설계상)
- 현재 상태: IMPL ✓ / VERIF ✓(31 tests) / MERGED ✓ / CALLABLE ✓ / **WIRED_RUNTIME no** / ENFORCED no / **ACTIVE false**
- 지금 실제 호출자: 없음(수동 CLI만, 자동 호출 미배선)
- 아직 안 꽂힌 이유: collector/pickup/Stop hook에 연결 안 함(C안: WIRE는 activation 결정 후)
- WIRE 조건: ANU collector worktree-read 연결 또는 Stop hook/pickup 호출
- ACTIVE 조건: owner pickup chain ACTIVE와 연동
- activation trigger: 회장 승인(2778 후속 WIRE 안건)
- rollback/kill: 호출 제거(read/manifest only라 side-effect 경미)
- 금지선: callback fire 0 · path containment helper 유지(보안 HIGH 박제)
- 다음 결정 필요: A안 시 owner pickup chain과 함께 WIRE 대상

## 6. normal callback / result.json contract
- 구현 파일: `dispatch/executor_completion_contract.py` · `anu_owned_callback_enforcement.py` · `callback_owner_enforcer.py` · `spawn_callback_contract_validator.py` · `normal_fallback_callback_helper.py` · `anu_executor_provenance.py` — stack `88a1f2b0` 등
- 목적: dev 완료 시 ANU-owned callback envelope/result.json 강제(self-key 금지·SENDFILE_ONLY 차단)
- 호출 주체: dispatch(위임 시) + finish-task closeout
- 호출 시점: dispatch 진입 시 contract 검증 + 봇 종료 시 callback
- 입력: task result.json · owner_key_class
- 출력 artifact: result.json(p0b_inbox) · callback envelope
- 출력 소비자: owner pickup chain / ANU collector
- 현재 상태: IMPL ✓ / VERIF ✓ / MERGED ✓ / CALLABLE ✓ / **WIRED_RUNTIME = yes(dispatch 시 contract validator가 실제로 진입 차단 — 이번 세션 task-2778_a 위임들에서 작동)** / ENFORCED = partial(dispatch 차단 작동, OS-level forced 미완) / **ACTIVE false(real callback delivery 상시 아님)**
- 지금 실제 호출자: dispatch.py(매 위임) — **실제 WIRED**
- 아직 안 꽂힌 이유: callback **delivery**(cokacdir fire→spawn)는 owner pickup chain ACTIVE 의존. 현재 envelope/result.json 작성까지만 WIRED, delivery는 1-shot only
- WIRE 조건(delivery): owner pickup chain ACTIVE
- ACTIVE 조건: real callback delivery 상시
- activation trigger: 회장 승인(owner pickup과 연동)
- rollback/kill: contract flag
- 금지선: dev self-key fire · raw key
- 다음 결정 필요: contract 검증은 이미 WIRED, **delivery만 A안 의존**

## 7. Stop hook verifier / enforcer
- 구현 파일: (enforcer) **없음** — task-2778 설계 `terminal_callback_enforcement_design_260628.md` DESIGN_READY only. `.claude/settings.json` hooks = PostToolUse만(Stop hook 미등록)
- 목적: 봇 idle/종료 전 terminal signal 강제(없으면 생성 + canonical surface)
- 호출 주체: (설계) Claude Code Stop hook
- 현재 상태: **DESIGN_READY only** / IMPL no / VERIF no / MERGED no / CALLABLE no / WIRED_RUNTIME no / ENFORCED no / ACTIVE false
- 아직 안 꽂힌 이유: 미구현(task-2778C 후보, 동결)
- WIRE/ACTIVE 조건: 구현(2778C) → 회장 승인
- activation trigger: 회장 승인(2778C 별도 안건)
- 금지선: enforcer fail-open(종료 방해 금지)
- 다음 결정 필요: A안 시 구현 필요(현재 공백)

## 8. pre-push terminal guard
- 구현 파일: **없음** — `.git/hooks/pre-push` 미설치. task-2778 설계 DESIGN_READY only
- 목적: PR push 시점 terminal artifact 부재 감지 + canonical envelope 생성
- 현재 상태: **DESIGN_READY only** / IMPL no / 전 단계 no / ACTIVE false
- 아직 안 꽂힌 이유: 미구현(task-2778B 후보, 동결). strict가 push 차단 시 작업물 유실 리스크 → warn-mode 우선 설계
- WIRE/ACTIVE 조건: 구현(2778B warn→strict) → 회장 승인
- activation trigger: 회장 승인(2778B 별도 안건)
- 다음 결정 필요: A안 시 구현 필요(현재 공백)

## 9. CI / Gemini watch handoff
- 구현 파일: 코드 모듈 아님 — 운영 컨벤션 + record(`memory/events/ci_watch_handoff/*.json`) + ANU watcher cron(세션-bound 회피용 OS 스케줄)
- 목적: PR open 후 CI/Gemini 수렴을 ANU 세션-bound polling 없이 watcher에 위임
- 호출 주체: ANU(handoff record 작성) + watcher cron(재평가)
- 호출 시점: PR open / fresh Gemini 후
- 입력: pr_number · head_sha · 종료선 분기 규칙
- 출력 artifact: handoff json · watcher 판정 → ANU callback
- 출력 소비자: ANU
- 현재 상태: IMPL = convention/record ✓ / VERIF = 실운영(이번 세션 PR#257/#258 수렴에 반복 사용) / MERGED n/a(코드 아님) / CALLABLE ✓ / **WIRED_RUNTIME = manual(ANU가 매번 watcher cron 수동 등록)** / ENFORCED no / ACTIVE false
- 지금 실제 호출자: ANU(이번 세션 다수 watcher cron 실등록·실발사)
- 아직 안 꽂힌 이유: 자동 handoff 생성/watcher 자동화 미배선 — ANU 수동 운영
- WIRE 조건: dispatch/PR-open 훅에 handoff 자동 생성 연결
- ACTIVE 조건: watcher 자동 재무장 상시
- activation trigger: 선택(운영 편의), A/B와 독립
- rollback/kill: cron 제거
- 금지선: 세션-bound polling 금지(박제) · prompt ≤3900 bytes
- 다음 결정 필요: 낮음(현 수동 운영으로 충분히 작동 중)

## 10. Capability Matrix reporting
- 구현 파일: `memory/state/automation_capability_matrix.json`(19 capabilities) — 수동 갱신 산출물
- 목적: 각 capability의 IMPLEMENTED/VERIFIED/WIRED/ACTIVE 상태 기록(단일 진실원 시도)
- 호출 주체: ANU(수동 갱신) · control status command(일부 읽음)
- 현재 상태: IMPL = data file ✓ / VERIF n/a / MERGED ✓(state file) / CALLABLE ✓ / **WIRED_RUNTIME = manual(수동 갱신, 자동 sync 아님)** / ENFORCED no / ACTIVE n/a
- 지금 실제 호출자: ANU 수동 + status command 부분 참조
- 아직 안 꽂힌 이유: 자동 sync 미배선(updated_at 06-25, 본 결선표와 별개)
- WIRE 조건: 컴포넌트 상태 자동 수집 연결
- 금지선: gitignore(memory/state) 유지
- 다음 결정 필요: 본 결선표가 사실상 최신 스냅샷 — matrix json 자동 sync는 별도 hygiene

---

## 11. 종합 판정 (정직한 분류)
- **실제 WIRED_RUNTIME (지금 운영에서 불림)**: control status command(manual·read-only) · normal callback contract **검증부**(dispatch 차단) · CI watch handoff(ANU 수동 cron) · capability matrix(수동). → 전부 **manual 또는 검증/관측층**. **상시 자동(ACTIVE) 0건.**
- **MERGED·CALLABLE but NOT WIRED_RUNTIME**: terminal artifact surfacing · limited runtime guard · (owner pickup chain·live inbox·callback delivery = 1-shot/OBSERVED only, 상시 아님)
- **DESIGN_READY only (코드 공백)**: Stop hook enforcer(2778C) · pre-push terminal guard(2778B)
- **한 줄 요약**: 안전장치·관측층은 대부분 IMPLEMENTED/VERIFIED/MERGED. 그러나 **자동화 본체(owner pickup always-on + real callback delivery + activation)는 ACTIVE 0**. 즉 "에어백·ABS는 정교하게 달렸으나 시동은 안 건 상태."

## 12. 활성화 결정 — A안 / B안 (evidence 기준, 특정안 미추천)

### A안: `CONTROLLED_ACTIVATION_PILOT_PREPARE_ACTIVE_FALSE`
- 내용: owner pickup chain을 bounded pilot로 실제 ON(limited runtime guard 안전판 하에)
- **선행조건(공백)**: ① live inbox LIVE_PROCESSED 통과 실증(현재 owner-proof 차단층까지만) ② owner-proof freshness 운영 sync(local canonical↔origin) ③ real callback delivery 검증(현재 1-shot only) ④ Stop hook enforcer(2778C)·pre-push guard(2778B) 구현(현재 DESIGN_READY) ⑤ terminal surfacing WIRE
- **리스크**: 무한 spawn 폭주(PR#143/#144 박제) — governor 6게이트가 완화하나 always-on 미검증 / 미검증 경로의 production 노출 / 메타 인프라 추가 구현 부담(2778B/C)
- **안전판**: limited runtime guard(kill/N/T) · governor · flag/systemd 즉시 롤백

### B안: `META_INFRA_CLOSED_BUSINESS_WORK_RETURN_ACTIVE_FALSE`
- 내용: 현 상태(전 컴포넌트 MERGED·ACTIVE=false) 동결, InsuWiki/InsuRo/보험 사업 복귀
- **선행조건**: 없음(현 상태 유지)
- **리스크**: 만든 안전장치가 shelf-ware로 남음 / visibility gap류 운영 혼선이 잠재(단 ACTIVE=false라 실 production 피해 제한적, 이번 사이클처럼 검증 단계 시간비용 형태로만 발현) / 2778B/C 미구현 공백 잔존
- **부합**: `META_INFRA_PHASE1_CLOSED` 회장 결정 · "사업/ANU-Work 전환" 우선순위와 정합

### 결정 변수 (회장 판단)
자동화 always-on을 **가까운 시일에 켤 의지**가 있으면 A(선행조건 5개 충족 필요 = 추가 구현). 당분간 manual+안전장치로 충분하고 사업 우선이면 B(즉시, 추가 구현 0). doctrine 현 상태(META_INFRA_PHASE1_CLOSED)는 B 쪽이나, 결정은 회장 몫.

## 13. 범위 준수 확인
코드 0 · 새 PR 0 · hook 설치 0 · systemd 0 · cron 0(본 작성 중) · real fire 0 · ACTIVE=true 0 · 2778B/C 착수 0 · dev팀 위임 0. 본 문서는 정리·판정 only.
