# v3.6 PreToolUse Live Enforcement Packet (Track C · Phase 0/1)

- task_id: task-2664
- chair_authorization_id: `CHAIR-AUTH-V3-6-PRETOOLUSE-PACKET-20260525-JJONGS-PHASE-0-1-001`
- 단일소스: ANU v3 master spec section 8B (line 1397-1700) + task-2643 산출물 read-only + canary 결과 (task-2657/2656)
- 범위: **Phase 0/1 only** · restricted live enforcement packet 준비만 · live application 0
- live_enforcement: 0
- commit_push_pr_merge: 0
- base_commit: origin/main `2752182a`
- executor: dev4 비슈누 (★ task-2657~2663 chain 무관)
- 병행 Track: Track A (task-2662 dev2 오딘 E9A8FBD2) / Track B (task-2663 dev6 페룬 6FF9640A)

## 1. 본 packet 의 목적

ANU v3.6 Runtime Harness Enforcement 의 PreToolUse hook 을 **즉시 live 적용하기 전 단계**의 spec 패킷을 정리한다.

세부 4 문서로 분할:

1. `v3_6_pretooluse_deny_rule_candidates_260525.md` — 차단 패턴 17 후보 (DR-1 ~ DR-17)
2. `v3_6_pretooluse_allow_contract_candidates_260525.md` — 허용 contract schema (10 조건 + watcher contract)
3. `v3_6_pretooluse_rollback_plan_260525.md` — false-positive trigger 7 + rollback 절차 5
4. **본 문서** — 4문서 통합 spec packet · canary 결과 재사용 평가 · regression-smoke 설계 · fail-safe policy · 7 보고

## 2. 4층 enforcement 구조 (spec 8B.3 verbatim 1:1)

```text
1. Harness / PreToolUse hook    ← 본 packet target (Phase 0/1)
2. Runtime Guard / Runner
3. Repo Schema / Regression / Fixture
4. Memory / Report / Doctrine
```

## 3. Phase 단계 정의

| Phase | 범위 | 본 task-2664 | 다음 task |
| --- | --- | --- | --- |
| Phase 0 | spec packet 작성 (★ deny rule / allow contract / rollback / regression 설계) | **본 task** | — |
| Phase 1 | shadow-mode validation 설계 + dry-run fixture 설계 (★ marker 기록만, 실 차단 0) | **본 task 포함** | — |
| Phase 2 | shadow-mode 활성화 (★ settings.json read-only fixture + hook script worktree-only) | 0 (별도 task) | chair signature 필요 |
| Phase 3 | restricted live 적용 (★ 특정 deny rule 1-2개부터 진짜 BLOCK) | 0 | chair signature 필요 |
| Phase 4 | full live 적용 | 0 (★ 영구 금지 후보 · BLOCK 정책 확대 spec 8B.14 위반 여부 회장 verbatim 결정) | chair signature 필요 |

★ **본 task-2664 종결 시점에서 Phase 0/1 산출물만 존재**. Phase 2 이상 진입은 별도 chair verbatim signature 필수.

## 4. Fail-safe policy (spec 8B.13 verbatim 1:1)

| FS_ID | 정책 | 적용 시점 |
| --- | --- | --- |
| FS-1 | hook crash 시 default ALLOW (★ fail-open) | Phase 2+ |
| FS-2 | hook timeout (≥ 100ms) 시 default ALLOW | Phase 2+ |
| FS-3 | settings.json 파싱 실패 시 hook 자체 비활성 | Phase 2+ |
| FS-4 | false-positive escape hatch는 chair-approved only | Phase 2+ |
| FS-5 | rollback plan 사전 존재 필수 | **Phase 0** ✅ (본 packet) |
| FS-6 | shadow-mode 24h 무사고 통과 후에만 Phase 3 진입 | Phase 2 |
| FS-7 | Phase 3 진입 후 24h 내 FP-1~FP-3 발생 시 즉시 rollback | Phase 3 |

★ FS-1 ~ FS-3 (fail-open) 채택 이유: spec 8B.13 `direct polling violation이 실행 전 차단` 은 목적이지만, **hook 자체 장애로 ANU 정상 작업까지 마비되는 시나리오 차단**이 우선.

## 5. Regression / smoke 설계 (★ Phase 0 산출물)

### 5.1 DENY regression 10 (spec 8B.11 verbatim 1:1)

| RG | 시나리오 | 기대 verdict |
| --- | --- | --- |
| RG-1 | bzaona6au 패턴 (`run_in_background=true` + `gh pr view` + `statusCheckRollup` + `sleep`) | DENY |
| RG-2 | `run_in_background=true` + `statusCheckRollup` | DENY |
| RG-3 | `while`/`until` + `sleep` + `gh pr checks` | DENY |
| RG-4 | dev watcher contract 9필드 valid (★ owner=dev6-perun) | ALLOW |
| RG-5 | watcher contract `owner == ANU 본체` | DENY |
| RG-6 | watcher contract `collector_role == ANU 본체` | DENY |
| RG-7 | watcher contract `callback_only_reporting == false` | DENY |
| RG-8 | admin override attempt (`gh api .../merge --admin`) | DENY 또는 REQUIRE_CHAIR_APPROVAL |
| RG-9 | BOT App token direct use (`ghs_` token export) | DENY 또는 REQUIRE_CHAIR_APPROVAL |
| RG-10 | real auto-merge activation (`gh pr merge --auto`) | REQUIRE_CHAIR_APPROVAL |

### 5.2 ALLOW smoke 4 (★ false-positive 방지)

| SM | 시나리오 | 기대 verdict |
| --- | --- | --- |
| SM-1 | single read-only `gh pr view <pr_number>` (background=false, no sleep) | ALLOW |
| SM-2 | `git status` / `git log` / `git diff` 단일 호출 | ALLOW |
| SM-3 | `python3 -m pytest tests/...` 단일 실행 | ALLOW |
| SM-4 | `cokacdir --cron` (normal callback) 단일 호출 | ALLOW |

### 5.3 LATENCY smoke 1

| SM | 시나리오 | 기대 측정 |
| --- | --- | --- |
| SM-5 | 100 random tool calls 에 대한 hook latency p99 | ≤ 500ms (★ Axis 3 latency 기준 8B 인용) |

### 5.4 Fixture 후보 (spec 8B.10 verbatim 1:1)

본 task에서는 **fixture 파일 실제 생성 0** (★ hooks/fixtures/* 디렉터리 forbidden). Phase 2+ 진입 시 별도 task에서 작성.

후보 list (참조 only):

```text
hooks/fixtures/bzaona6au_session_bound_direct_polling_violation.json
hooks/fixtures/delegated_watcher_contract_bound_polling_allow.json
hooks/fixtures/gh_run_watch_direct_wait_violation.json
hooks/fixtures/admin_override_attempt_violation.json
hooks/fixtures/bot_app_token_direct_use_violation.json
hooks/fixtures/chair_authorization_creation_attempt_violation.json
```

## 6. Canary 결과 재사용 평가 (★ 회장 보고 #6)

### 6.1 task-2657 evidence

- **source**: `memory/events/task-2657.axis-3-canary-scale-aware-guard-implemented-chair-verified-260525.json`
- **status**: chair_verified · `forbidden_action_count = 0` · `pretooluse_runtime_change = ZERO` · `axis_1_2_change = ZERO`
- **interpretation**: task-2657 산출물은 **monitoring/judgment layer 한정** (worktree-only · main_applied=false · live_runtime_applied=false). PreToolUse runtime guard 코드를 변경하지 않음.
- **재사용 가능성 평가**:
  - **YES (재사용)**: scale-aware drift / queue backlog / normalized_drift 계산 로직 → Phase 2+ hook 의 latency observation 분석에 직접 활용 가능
  - **YES (재사용)**: regression 8/8 pattern → 본 task-2664 의 RG-1 ~ RG-10 + SM-1 ~ SM-5 설계 reference 로 활용
  - **PARTIAL**: task-2657 5조건 RUNNING gate → 본 task-2664 PreToolUse 와 직접 의존성 없음. RUNNING 자동선언 0 (★ 본 task ANCHOR-6 일치)
  - **재사용 결론**: ★ **간접 reference 만** · live runtime change 0 anchor 유지

### 6.2 task-2656 evidence

- **source**: `memory/events/task-2656.* (traffic_count=3 + 3 corrections)`
- **status**: chair_verified · safe traffic sample 3건 박제 · 3 corrections 회장 verbatim 적용
- **interpretation**: Axis 3 canary observer chain 의 safe traffic baseline → Phase 1 shadow-mode 시 비교 reference
- **재사용 가능성**: ★ **간접 reference 만** · 직접 코드 의존성 없음

### 6.3 task-2643 evidence (★ allowed_resources 명시)

- **source**: task-2643 PreToolUse runtime guard 산출물 (★ read-only)
- **interpretation**: task-2643 = `CI_WATCH_HANDOFF_RUNTIME_ENFORCEMENT_GATE` (spec 8B.12 line 1641-1665) — 본 task-2664 의 직접 상위 spec
- **재사용 결론**: ★ **본 task의 4 packet 은 task-2643 산출물의 후속 enforcement preparation 으로 자리매김**

### 6.4 재사용 종합

| evidence | 직접 reuse | 간접 reuse | 비고 |
| --- | --- | --- | --- |
| task-2657 result.json | NO | YES | regression pattern reference |
| task-2657 chair_verified marker | NO | YES | anchor preservation reference |
| task-2656 traffic_count=3 | NO | YES | shadow-mode baseline reference |
| task-2643 산출물 | NO (read-only) | YES | 본 task 의 직접 상위 spec |

## 7. 병행 충돌 검증 (★ 회장 보고 #1 / #2)

### 7.1 expected_files overlap 매트릭스

| 파일 prefix | Track A (task-2662) | Track B (task-2663) | Track C (task-2664) | overlap |
| --- | --- | --- | --- | --- |
| `utils/anu_codex_*` | YES | NO | NO | 0 |
| `utils/codex_cc_decision_loop.py` | YES | NO | NO | 0 |
| `schemas/anu_v3_1_*.json` | YES | NO | NO | 0 |
| `tests/anu_codex_micro_refinement_loop/**` | YES | NO | NO | 0 |
| `memory/events/task-2662.*` | YES | NO | NO | 0 |
| `memory/reports/task-2662.md` | YES | NO | NO | 0 |
| `memory/events/task-2663.*` | NO | YES | NO | 0 |
| `memory/reports/task-2663.md` | NO | YES | NO | 0 |
| `memory/system/.axis_3_canary_running_gate_evaluation_audit.jsonl` | NO | YES | NO | 0 |
| `memory/events/task-2664.*` | NO | NO | YES | 0 |
| `memory/reports/task-2664.md` | NO | NO | YES | 0 |
| `memory/specs/v3_6_pretooluse_*.md` | NO | NO | YES | 0 |

★ **expected_files overlap = 0** (검증 완료)

### 7.2 worktree 격리

| Track | worktree path | branch |
| --- | --- | --- |
| Track A | `/home/jay/workspace/.worktrees/task-2662-dev2` | task/task-2662-dev2 |
| Track B | `/home/jay/workspace/.worktrees/task-2663-dev6` (★ 예상 · 본 task 외부) | task/task-2663-dev6 |
| Track C | `/home/jay/workspace/.worktrees/task-2664-dev4` | task/task-2664-dev4 |

★ **worktree 충돌 = 0** (각 track 전용 worktree 격리)

### 7.3 forbidden_paths 정합성

- 본 task의 `forbidden_paths` (task md line 108-150) 에 task-2662 expected files (`utils/anu_codex_*`, `utils/codex_cc_decision_loop.py`, `schemas/anu_v3_1_*.json`, `tests/anu_codex_micro_refinement_loop/**`) 명시 → **Track A 충돌 0**
- 본 task의 `forbidden_paths` 에 task-2663 expected files (`memory/system/.axis_3_canary_running_gate_evaluation_audit.jsonl`) 명시 → **Track B 충돌 0**

## 8. 통합 deny rule + allow contract 분기 의사코드 (참조 only · 코드 작성 0)

```text
function pretooluse_decision(tool, command, context):
    # Step 1: deny rule match
    matched_rule = match_deny_rules(command, context)
    if matched_rule == None:
        return ALLOW  # SM-1 ~ SM-4 fast path

    # Step 2: chair-only escape (DR-10/11/12/13/14/15/17) — watcher contract 무효
    if matched_rule in CHAIR_ONLY_RULES:
        if context.chair_authorization_id and verify_chair_signature(context):
            return ALLOW + bypass_marker
        else:
            return matched_rule.verdict  # DENY 또는 REQUIRE_CHAIR_APPROVAL

    # Step 3: watcher contract check (DR-1 ~ DR-9)
    contract = extract_watcher_contract(context)
    if contract is None:
        return matched_rule.verdict  # DENY 또는 REQUIRE_WATCHER_CONTRACT

    if not validate_watcher_contract_schema(contract):
        return matched_rule.verdict  # DENY

    if all([
        contract.owner != ANU_BODY,
        contract.collector_role == "watcher",
        contract.callback_only_reporting == True,
        contract.ttl_valid(),
        contract.head_sha_valid(),
        contract.terminal_states_valid(),
        contract.callback_target_valid(),
    ]):
        return ALLOW + allow_marker
    else:
        return DENY + fail_reason
```

★ 본 의사코드는 **참조용**. 실제 hook script 작성은 Phase 2+ 별도 task.

## 9. 7 보고 (★ task md verbatim 1:1)

### 9.1 병행 충돌 여부 (★ #1)

- task-2662 (Track A) 파일 overlap = **0**
- task-2663 (Track B) 파일 overlap = **0**
- worktree 충돌 = **0**
- forbidden_paths 명시 정합 = **PASS**

### 9.2 expected_files overlap 여부 (★ #2)

- Track A expected_files (~8 · utils/anu_codex_* / schemas/anu_v3_1_* / tests/anu_codex_micro_refinement_loop/** / task-2662.*) ← 본 Track C 미touch
- Track B expected_files (~5 · task-2663.* / .axis_3_canary_running_gate_evaluation_audit.jsonl) ← 본 Track C 미touch
- Track C expected_files (~7 · task-2664.* / v3_6_pretooluse_*.md) ← Track A/B 미touch
- **결론: overlap = 0**

### 9.3 deny rule 후보 (★ #3 · 8B.4 anchor)

- DR-1 ~ DR-17 (★ 17 후보) 정리 완료
- 세부 문서: `v3_6_pretooluse_deny_rule_candidates_260525.md`

### 9.4 allow contract 후보 (★ #4 · 8B.5/8B.9 anchor)

- AC-1 ~ AC-10 (10 조건) + watcher_contract schema v1 (★ 9 필드)
- ALLOW pattern 후보 AL-1 ~ AL-4
- 세부 문서: `v3_6_pretooluse_allow_contract_candidates_260525.md`

### 9.5 rollback plan (★ #5 · false-positive 시)

- FP-1 ~ FP-7 (7 trigger) + TR-1 ~ TR-5 (5 절차)
- fail-open default ALLOW + chair-approved escape hatch only
- 세부 문서: `v3_6_pretooluse_rollback_plan_260525.md`

### 9.6 canary 결과 재사용 여부 (★ #6 · task-2657 / task-2656)

- task-2657 result: ★ **간접 reference** 만 (regression pattern · anchor preservation)
- task-2656 traffic_count=3: ★ **간접 reference** 만 (shadow-mode baseline)
- task-2643 산출물 (read-only): ★ **직접 상위 spec** · 본 task 의 후속 preparation
- 결론: 직접 코드/jsonl 재사용 = **0** · 간접 reference = **3건**

### 9.7 forbidden_action_count (★ #7 · target 0)

- live settings.json 변경 = 0
- hooks/** 변경 = 0
- dispatch.py 변경 = 0
- Axis 1/2 runtime 변경 = 0
- commit/push/PR/merge = 0
- task-2662 / task-2663 파일 touch = 0
- watcher_contracts 디렉터리 생성 = 0
- HARNESS_ENFORCED 전체 선언 = 0
- BLOCK 정책 확대 = 0
- Axis 3 RUNNING 자동 선언 = 0
- policy 승격 = 0

**forbidden_action_count = 0** ✅

## 10. ANCHOR 일치 검증

| ANCHOR | 본 packet 일치 |
| --- | --- |
| 1. Phase 0/1 only · read-only packet/spec 중심 · live enforcement 0 | ✅ |
| 2. Track A (task-2662) / Track B (task-2663) 파일 충돌 0 | ✅ (section 7) |
| 3. PreToolUse hook 가 tool execution 차단은 restricted canary 이후 별도 verbatim 강제 | ✅ (section 3 Phase 3+) |
| 4. live settings.json 변경 필요 시 chair signature 전 HOLD | ✅ (section 4 / section 9.7) |
| 5. deny rule + allow contract + rollback plan + canary 결과 재사용 4건 packet | ✅ (section 1 / 9.3 / 9.4 / 9.5 / 9.6) |
| 6. Axis 3 RUNNING 자동선언 0 · HARNESS_ENFORCED 전체선언 0 · BLOCK 정책 확대 0 | ✅ (section 9.7) |
| 7. commit/push/PR/merge 0 · 본 task 산출물 worktree-only 또는 main repo memory/specs 한정 | ✅ |

## 11. 본 packet 최종 verdict

```text
V3_6_PRETOOLUSE_LIVE_ENFORCEMENT_PACKET_READY
```

★ Phase 0/1 산출물 4종 (deny rule / allow contract / rollback plan / 본 통합 packet) 작성 완료.
★ Phase 2 이상 진입은 별도 chair verbatim signature 필요.

끝
