# V3.6 Runtime Harness Control Plane Spec (★ 회장 verbatim 2026-05-28 · 운영층 contract 설계 · 구현 dispatch 금지)

- 작성: 2026-05-28 14:30 KST · ANU chair-facing session
- 분류: **read-only design packet** (회장 verbatim 금지: 구현 dispatch · 코드 수정 · finish-task.sh 수정 · watchdog/dispatch.py 수정 · PR/branch push/merge · "사업 복귀라고 결론" · "추후 필요시" 같은 느슨한 표현)
- 상위 doctrine: task-2703 본 결과(`V36_HARNESS_MVP_RUNTIME_GATE_ACTIVE_AND_VERIFIED`) 인정 유지 + 운영층 결함 8건 인정 → ★ 운영층을 contract/evidence/guard 기반으로 재설계
- 사상 (회장 verbatim): "ANU 본체, dispatch, watchdog, callback, finish-task, closeout 이 감·grep·mtime·self-attestation 에 의존하지 않고 contract/evidence/guard 기반으로만 판단"

---

## 0. Control Plane 8 contract 위계

```
[layer 0] task md sha contract             — dispatch 직전 ~ 봇 수신 정합
[layer 1] dispatch marker contract         — dispatch 직후 자동 fact 박제
[layer 2] spawn detection contract         — 봇 spawn 진행 상태 9-enum
[layer 3] watchdog contract                — alive/stalled 판정 다신호 + alert/escalation 분리
[layer 4] callback/closeout collector contract  — closeout marker → ANU 능동 회수
[layer 5] finish-task profile contract     — task_mode 6 분기 PASS/WARN/FAIL
[layer 6] actor attribution contract       — Hermes/Vulcan/Maat evidence level
[layer 7] incident-to-fix routing          — 8 incident ↔ contract 매핑 + P0/P1/P2
```

상호 의존: layer 0 → 1 → 2 → 3 / 4 / 5 모두 layer 1·2 신호 소비 / 6 = 5의 evidence 보조 / 7 = 메타 매핑.

---

## 1. Spawn Detection Contract (layer 2 · 회장 verbatim 영역 #1)

### 1.1 금지

- process grep 단독 판정 금지
- `grep -v <broad-substring>` 으로 봇 세션 필터 금지 (예: `grep -v cokacdir` 가 봇 cmd args 의 system_prompt path 매칭)
- schedule_history 단독 부재로 "spawn 실패" 단정 금지

### 1.2 신호 (★ 8 source 교차)

1. `task_id` — task md / task-timers 키
2. `schedule_id` — dispatch.py 또는 직접 cron 의 cron id
3. `bot_key` — 봇 owner key (hash 만 저장 · raw 금지)
4. `session_id` — 봇 system_prompt 파일 path (`/home/jay/.cokacdir/system_prompt_<hex>_<n>` · ANU 세션과 별개 hex)
5. `timer` — `memory/task-timers.json::tasks[<task_id>].status`
6. `worktree_or_artifact_mtime` — `.worktrees/<task_id>-<team>/` 또는 `memory/events/<task_id>.*` mtime
7. `bot_output` — `/home/jay/.cokacdir/<schedule_id>.output` 또는 stream 신호
8. `schedule_history` — `/home/jay/.cokacdir/schedule_history/<schedule_id>.log`

### 1.3 상태 9-enum (회장 verbatim 박제)

```
NOT_REGISTERED       — schedule_id 미발급 또는 cron-list 부재 + history 부재 + timer 부재
REGISTERED           — schedule_id 등록 확인 + timer 등록 (★ DISPATCHED_SUBMITTED_UNVERIFIED 동의어)
FIRED                — schedule fire_time 도래 + cron-history 또는 schedule_history 진입
SESSION_SEEN         — 별도 system_prompt path 의 봇 claude 프로세스 관측 (★ ANU 세션 path 와 다른 hex)
WORK_STARTED         — 봇이 worktree 생성 또는 task-2703 패턴: events_dir 에 첫 봇 write 마커 생성
ARTIFACT_SEEN        — code/test/report 등 봇 산출물 mtime 신규 변동
CALLBACK_REGISTERED  — 봇이 ANU-key cron 등록 (collector_role=ANU verified)
DONE                 — finish-task `.done` 마커 생성 + task-timers status 종결
UNKNOWN              — 위 8 신호 어느 것도 명확히 진단 불가 (★ false-negative 발생 시 UNKNOWN 명시 · "spawn 0" 단정 금지)
```

### 1.4 판정 알고리즘 (★ 다신호 OR weighted · single source decisive 금지)

- `WORK_STARTED` 이상으로 판정하려면 **최소 2 신호 필수** (예: timer running + session_seen 또는 timer + artifact_mtime)
- `NOT_REGISTERED` 단정은 **4 신호 전부 부재** 시에만 (timer 부재 AND schedule_id 부재 AND session 부재 AND artifact 부재)
- 신호 부족 시 `UNKNOWN` → 다음 sample 까지 polling 또는 chair 보고
- ★ task-2703 #1·#2 incident: ANU 가 `grep -v cokacdir` 단일 신호로 SESSION_SEEN 신호를 잘못 부정 → `NOT_REGISTERED` 잘못 단정. 본 contract 적용 시 timer=running + artifact_mtime 13:22:33 fresh + closeout marker 13:52 = WORK_STARTED 또는 ARTIFACT_SEEN 정확 판정 가능

---

## 2. Watchdog Contract (layer 3 · 회장 verbatim 영역 #2)

### 2.1 금지

- `hb_age=-1` + `ev_age=-1` 단독으로 `stalled` 판정 금지
- alert-only (`escalate=no`) 가 회장 chat sendMessage 직접 호출 금지 ([[feedback_followup_cron_policy_260509]] 준수 강제)
- task-timers status `running` + closeout marker 존재 시 stalled 판정 금지

### 2.2 alive 다신호 판정

- alive 신호 OR 집합: (a) `PROGRESS_MARKERS` 확장 패턴(`<task_id>.dispatched-*` / `<task_id>.harness-mvp-active*` / `<task_id>.*active.json` / `<task_id>.done*` / `<task_id>.escalate*` / `<task_id>.completion.txt`) (b) spawn detection contract `WORK_STARTED` 이상 (c) bot session process active (d) worktree mtime < 900s (e) recent artifact mtime < 900s
- 위 OR 집합 중 1 이상 참 → `alive`
- alive 신호 전부 0 + ev_age > 900s + hb_age 측정 불가 → `silently_stalled` (★ stalled 의 단일 분류 아니라 sub-class)

### 2.3 alert/escalation 2축 분리

- `alert_class`: `INFO` (로그만) / `WARN` (로그 + 다음 cycle 재확인) / `ESCALATE` (chair chat 직접 sendMessage)
- escalate 진입 조건 (★ AND):
  - `silently_stalled` 상태 + 2 cycle 연속 + Critical 7 분류 OR 회장 명시 escalate
- alert-only 는 `INFO` 또는 `WARN` 만 → chair chat 0
- ★ task-2703 #3: alert-only 6회 chair chat 발사 = 본 contract 위반. 본 contract 적용 시 13:42~13:52 INFO 로그만, chair chat 0

### 2.4 false alert 억제 규칙

- 같은 task_id 같은 alert_class 가 N cycle 이내 K회 초과 시 자동 throttle
- `.escalate` 또는 `.escalate.acked` 마커 존재 시 즉시 skip (회장 task-2405 fix#A 메커니즘 보존)
- closeout marker `<task_id>.*active.json` mtime < 1800s 시 alive 자동 판정 (확장 PROGRESS_MARKERS)

---

## 3. Dispatch Marker Contract (layer 1 · 회장 verbatim 영역 #3)

### 3.1 강제

- dispatch.py 또는 직접 cron 발사 직후 자동으로 `memory/events/<task_id>.dispatched-<team>-<YYMMDD>.json` 생성
- 코드 강제 (ANU manual doctrine 의존 0)
- 본 marker 가 layer 2 (spawn detection) 의 신호 #6 (artifact_mtime) 및 layer 3 (watchdog) 의 alive 신호 초석

### 3.2 schema (필수 7 필드)

- `task_id` (string)
- `schedule_id` (string · 1차 dispatch.py cron id 또는 직접 cron id)
- `executor` (string · 팀명 + 봇 페르소나)
- `bot_key_hash` (string · sha256(bot_key)[:16] · ★ raw key 금지)
- `fire_time` (ISO 8601 KST)
- `prompt_sha` (string · sha256(cron prompt))
- `task_md_sha_before` (string · sha256(task md) at dispatch entry)
- `dispatch_method` (enum: `dispatch_py` / `direct_cron_bot_key` / `fallback_safety_net`)

### 3.3 라이프사이클

- 생성: dispatch fire 직후 ≤5s 내 atomic write
- 갱신: spawn detection 상태 변화 시 sidecar (`<task_id>.dispatched-<team>-<YYMMDD>.spawn-state.json`)
- 종료: task `DONE` 시 marker 보존 (★ 삭제 금지 · audit 용)

### 3.4 task-2703 #4 적용

- 본 contract 강제 시 dispatch.py가 BE5161A0 fire 직후 marker 자동 생성 → events_dir 첫 file 이 13:22:33 dispatch marker → watchdog ev_age=-1 이슈 즉시 해소

---

## 4. Task MD SHA Contract (layer 0 · 회장 verbatim 영역 #4)

### 4.1 금지

- "sha 다르지만 괜찮음" 같은 자연어 판단 금지
- 봇이 expected_sha mismatch 발견 후 verbatim 일치 검증 없이 진행 금지
- dispatch.py가 task md write 후 expected_sha 갱신 없이 봇에 전달 금지

### 4.2 4 marker 필드 (회장 verbatim 박제)

- `content_verbatim_match` (bool · 내용 verbatim 비교 결과)
- `metadata_patch_detected` (bool · dispatch.py 메타데이터 추가 인지)
- `continue_allowed` (bool · 본 결정에 따른 진행 허용)
- `reason` (string · 결정 사유 · 자연어 아닌 enum 권장: `verbatim_match_metadata_patch_ok` / `verbatim_mismatch_block` / `expected_sha_outdated_resync` 등)

### 4.3 강제 절차

- dispatch.py가 task md write 직후 sha 재계산 → 봇 prompt 에 `dispatch_final_sha` 전달 (★ dispatch_entry_sha 와 분리)
- 봇은 수신 sha vs 실제 read sha 비교:
  - 일치 → 정상 진행
  - 불일치 → diff 비교 (content_verbatim_match + metadata_patch_detected 자동 분류) → 4 marker 필드 기록 → `continue_allowed` 결정에 따라 진행/HOLD
- 결정은 marker 파일 `<task_id>.task-md-sha-decision.json` 으로 박제

### 4.4 task-2703 #5 적용

- 본 contract 강제 시 봇이 sha mismatch 발견 시 자연어 "내용은 verbatim 과 일치합니다" 아닌 4 marker 필드로 결정 박제 → audit 가능

---

## 5. Callback/Closeout Collector Contract (layer 4 · 회장 verbatim 영역 #5)

### 5.1 금지

- ANU 본체 progress polling 금지 유지 (spec §3.6 차단 대상 #2)
- closeout marker 생성 후 ANU 인지 지연 허용 금지
- normal callback 의존 단일화 금지 (회장 [[feedback_dispatch_must_register_fallback_safetynet_260520]] 준수)

### 5.2 회수 우선순위 (★ 3 경로 정의)

1. **normal callback** (★ 1순위 · 봇 finish-task 후 ANU-key cron 발사 · 이벤트 트리거)
2. **closeout marker watcher** (★ 2순위 · file event-driven 또는 inotify · `memory/events/<task_id>.*active.json` / `.done` / `.harness-mvp-active*` 패턴 감지 시 ANU 세션에 next_action signal)
3. **fallback safety-net** (★ 3순위 · cron-based · normal callback 미도착 + closeout marker watcher 미작동 시 N분 후 ANU read-only 회수)

### 5.3 closeout → finish-task 라이프사이클 상태 (★ 회장 verbatim 박제)

- `WORK_CLOSEOUT_STARTED` — 봇이 첫 closeout marker (`*.harness-mvp-active.json` 등) 생성
- `FINISH_IN_PROGRESS` — 봇이 finish-task.sh 호출 + G3/G4 게이트 진행 + `.callback-cause.json` / `.callback-launch.json` / `.completion.txt` 생성 중
- `DONE` — `.done` + `.done.notified` + `.anu-notified` 3 마커 모두 + task-timers status 종결

### 5.4 task-2703 적용 (실제 timeline)

- 13:52:19 — WORK_CLOSEOUT_STARTED (`task-2703.harness-mvp-active.json` 생성)
- 14:04~14:09 — FINISH_IN_PROGRESS (`.escalate` 14:04 / `.callback-cause` 14:06 / `.callback-launch` 14:09 / `.completion.txt` 14:09)
- 14:09:13 — DONE (`.done` + `.done.notified` + `.anu-notified` + task-timers `completed`)
- ★ ANU 인지: ~14:00 (회장 사진) → ~14:08 (incident report 작성) — 본 contract 적용 시 13:52 WORK_CLOSEOUT_STARTED 시점 closeout marker watcher 가 ANU 에 즉시 signal → 회장 사진 불필요

---

## 6. Finish-task Profile Contract (layer 5 · 회장 verbatim 영역 #6)

### 6.1 금지

- code task QC 를 system_hook / local_runtime / read_only task 에 그대로 적용 금지
- L1 smoke / git_evidence / scope guard 가 task_mode 무관 동일 기준 강제 금지

### 6.2 task_mode 6 enum (★ 회장 verbatim)

- `code` — 일반 코드 변경 (PR/branch/머지 path)
- `system_hook` — `.claude/hooks/` 또는 `settings.json` 등 runtime/harness 변경 (★ task-2703 본 분류)
- `local_runtime` — workspace local runtime infra (예: dispatch wrapper, watchdog config) 변경
- `read_only` — 진단/audit/report 만 (mutating 0)
- `callback_only` — ANU callback 발사 전용 (산출물 0 또는 envelope only)
- `closeout_marker_only` — 회장 결정 박제 / closeout 운영 마커 작성 (예: `.escalate.acked` · `decision-closeout-*`)

### 6.3 game/scope/L1 기준 (★ task_mode 별 PASS/WARN/FAIL)

- **git_evidence**
  - `code` PASS = working tree change + commit author audit
  - `system_hook` PASS = .claude/hooks/ + settings.json 결선 trace + DENY smoke evidence
  - `local_runtime` PASS = workspace local file change + 결선 evidence
  - `read_only` PASS = git diff 0 (mutating 0)
  - `callback_only` PASS = ANU-key cron registration evidence + envelope sha
  - `closeout_marker_only` PASS = marker JSON schema valid + chair authorization linkage
- **L1 smoke**
  - `code` PASS = 서버 재시작 + API/Playwright
  - `system_hook` PASS = hook 실제 trigger DENY/HOLD trace (★ task-2703 본 case)
  - `local_runtime` PASS = runtime restart + 기능 smoke
  - `read_only` = 해당없음 (WARN 0)
  - `callback_only` = 해당없음
  - `closeout_marker_only` = 해당없음
- **scope guard**
  - `code` PASS = main..HEAD diff 가 expected_files 범위 내
  - `system_hook` PASS = .claude/ + harness/ scope (★ allowed_resources 명시)
  - `read_only` PASS = diff 0
  - `closeout_marker_only` PASS = memory/events/ + memory/reports/ scope

### 6.4 task-2703 #6 적용

- task-2703 = `system_hook` task_mode → `code` 기준 적용 시 L1 smoke "API/Playwright" PASS 불가 (해당없음). 본 contract 적용 시 `system_hook` 기준 = "hook 실제 trigger DENY/HOLD trace" PASS · `.external-dirty-blocker.json` 은 EXTERNAL_DIRTY_BLOCKER 별도 classification 적용

---

## 7. Actor Attribution Contract (layer 6 · 회장 verbatim 영역 #7)

### 7.1 금지

- 봇 self-attestation 만으로 "직접 코딩 0" 단정 금지
- git author 단독으로 actor 구분 불가 시 verifiable 0 명시 (단정 금지)

### 7.2 actor evidence level 3 분류

- `L1 SELF_ATTESTATION` — 봇 보고서 본문 진술만 (★ 가장 약함 · 외부 검증 없음)
- `L2 AUDIT_LOG_OR_COMMIT_TRAILER` — git commit author + message prefix `[task-N] [vulcan] ...` 또는 Sub-Agent: vulcan trailer
- `L3 RUNTIME_HOOK_EVIDENCE` — PreToolUse hook 또는 Task tool subagent_type runtime evidence + JSONL audit (executor 식별 코드 강제)

### 7.3 evidence 수준별 단정 허용 범위

- L1 → "주장된 actor: vulcan (★ self-attestation only · verifiable 0)"
- L2 → "commit author trailer 기준: vulcan (★ pre-commit hook 강제)"
- L3 → "runtime hook 기록 기준: vulcan (★ tool-call gate 가 actor 자동 식별)"

### 7.4 강제 절차

- commit message 강제 prefix: `[task-N] [<actor>] ...` (★ pre-commit hook)
- Task tool subagent_type / 직접 Edit 시 actor 자동 분류 → JSONL audit
- 보고서 "직접 코딩 0" 표현 시 evidence level 명시 강제

### 7.5 task-2703 #8 적용

- 현 보고서 "Hermes 직접 코딩 0 / Vulcan 구현" = L1 SELF_ATTESTATION only
- L3 강제 시 PreToolUse hook + Task tool dispatch 가 actor 자동 식별 → verifiable evidence

---

## 8. Incident-to-Fix Routing Matrix (layer 7 · 회장 verbatim 영역 #8)

- 8 incident 의 contract 매핑 · Critical 7 / 사업 차단 / 명시적 병목 분류 · P0/P1/P2 우선순위는 별도 문서: `memory/reports/task-2703_operational_incidents_to_contract_map.md`
- 본 spec 의 layer 7 은 그 매핑 결과를 단일 routing matrix 로 통합 · contract 신규/확장 시 본 spec 갱신

---

## ★ Control Plane 의 단일 효력 (회장 verbatim 박제)

- 본 spec 은 **설계 패킷** — 구현 dispatch 0 · 코드 수정 0 · finish-task.sh 수정 0 · watchdog/dispatch.py 수정 0 · PR/branch push/merge 0
- 본 spec 자체는 ANU의 다음 메타 작업 발의 도구가 아니라 운영층 contract 단일 기준 파일
- 구현은 회장 결정 + chair_authorization_id verbatim + 우선순위 P0/P1/P2 별 별도 task 로만
- 본 spec 갱신은 회장 결정 후만

★ 회장 verbatim 2026-05-28 운영층 contract 설계 패킷. 8 layer · 9 spawn state · 3 callback 경로 · 6 task_mode · 3 actor evidence level · 8 incident routing. 구현 dispatch 0 · 사업 복귀 결론 0 · "추후 필요시" 0.

끝
