# Axis 1/2 Import Collision Analysis — Axis 3 Phase 0

- task_id: task-2652
- chair_authorization_id: `CHAIR-AUTH-AXIS-3-PHASE0-20260524-JJONGS-PRETOOLUSE-AUDIT-001`
- ts: 2026-05-24 KST
- finding: **COLLISION = ZERO**
- analysis_scope: import / settings.json slot / runtime ordering / shared state

## 1. import collision 분석 (코드 차원)

### task-2643 산출물 import 매트릭스 (PR #146 head 33c51992)

| 파일 | line | import (verbatim) | Axis 1/2 직접 의존 |
|---|---|---|---|
| `hooks/pre_tool_use_anu_guard.py` | 259 | `argparse`, `json`, `re`, `sys`, `pathlib.Path`, `typing.Any` | **NO** |
| `utils/pr_open_watcher_wrapper.py` | 261 | `dataclasses.dataclass/field`, `typing.Any/Callable/Optional` | **NO** |
| `utils/closeout_grade_auto_classifier.py` | 157 | `dataclasses.dataclass/field`, `enum.Enum`, `typing.Any/Iterable` | **NO** |

→ task-2643 코드 3 file 모두 **stdlib only**. Axis 1/2 utils 6종 import 0.

### Axis 1 helper 3종 (회장 verbatim 변경 0)

| 파일 | 현재 main branch 존재 | task-2643 가 import? |
|---|---|---|
| `utils/callback_registration.py` | task-2646/task-2648 staged (main 미머지) | NO |
| `utils/callback_authority_validator.py` | task-2646/task-2648 staged | NO |
| `utils/callback_source_cross_checker.py` | task-2646/task-2648 staged | NO |

### Axis 2 hooks 3 + utils 4 v2 canonical (회장 verbatim 변경 0)

| 파일 | 현재 main branch 존재 | task-2643 가 import? |
|---|---|---|
| `hooks/session_start_anu_callback_collector_v2.py` | staged 별도 | NO |
| `hooks/stop_anu_callback_collector_verifier_v2.py` | staged 별도 | NO |
| `hooks/user_prompt_submit_hook_callback_inbox_v2.py` | staged 별도 | NO |
| `utils/callback_collector_helper_integration.py` | ✓ (main · 18848 byte) | NO |
| `utils/callback_adjudicator_v2.py` | ✓ (Axis 2 canonical) | NO |
| `utils/callback_next_action_runner_v2.py` | ✓ (Axis 2 canonical) | NO |
| `utils/source_attribution_guard_v2.py` | ✓ (Axis 2 canonical) | NO |

### dispatch.py (회장 verbatim 변경 0)

- task-2643 산출물 어디서도 `dispatch.py` import / import from / subprocess 호출 0
- dispatch.py 안에서 task-2643 utils import 도 0 (task-2643 utils 가 main 미머지 상태)

→ **양방향 import 의존 0** 확정.

## 2. settings.json 슬롯 충돌 분석

### claude-code hooks slot

claude-code 의 `~/.claude/settings.json` `hooks.*` 슬롯:

| slot | Axis 1/2 점유 (recovery 가능 staged) | Axis 3 점유 (예정) |
|---|---|---|
| `PreToolUse` | (none) | ★ task-2643 `pre_tool_use_anu_guard.py` |
| `PostToolUse` | (none) | (none) |
| `SessionStart` | task-2648 staged `session_start_anu_callback_collector_v2.py` | (none) |
| `Stop` | task-2648 staged `stop_anu_callback_collector_verifier_v2.py` | (none) |
| `UserPromptSubmit` | task-2648 staged `user_prompt_submit_hook_callback_inbox_v2.py` | (none) |
| `PreCompact` | hooks/pre-compact-backup.sh / hooks/pre-compact-diary.sh (★ Axis 무관 · 기존 운영) | (none) |
| `SubagentStop` | (none) | (none) |
| `Notification` | (none) | (none) |

→ Axis 3 (`PreToolUse`) ↔ Axis 1/2 (`SessionStart`/`Stop`/`UserPromptSubmit`) **슬롯 분리 ✓**. claude-code 가 hook 을 호출하는 시점도 다름 (tool 호출 직전 vs 세션 시작/종료/유저 입력).

### staged settings template 검증

`memory/specs/staged_settings_template_pre_tool_use_anu_guard_260523.json`:

```json
"hooks": {
  "PreToolUse": [
    {
      "matcher": "Bash",
      "hooks": [
        {
          "type": "command",
          "command": "python3 <REPO_ROOT>/hooks/pre_tool_use_anu_guard.py --mode=stdin",
          "timeout_seconds": 5
        }
      ]
    }
  ]
}
```

→ **PreToolUse 만 추가**. SessionStart/Stop/UserPromptSubmit 미수정 ✓.

## 3. runtime ordering 분석

| 순서 | 행위자 | hook |
|---|---|---|
| 1 | claude-code 세션 시작 | Axis 2 `SessionStart` (collector 발사) |
| 2 | 유저 입력 | Axis 2 `UserPromptSubmit` (inbox 적재) |
| 3 | claude tool 호출 직전 | **Axis 3 `PreToolUse` (deny/allow 판정)** |
| 4 | claude tool 실행 | (Axis 무관) |
| 5 | claude tool 완료 후 | (현재 PostToolUse 등록 0) |
| 6 | claude 응답 출력 | (Axis 무관) |
| 7 | 세션 종료 | Axis 2 `Stop` (collector verifier) |

→ Axis 3 hook 은 step 3 위치. step 1/2/7 (Axis 2) 와 시간 겹침 0 ✓. Axis 1 helper 는 dispatch 호출 안에서 발화하므로 hook slot 자체에 등록 안 됨 ✓.

## 4. shared state 충돌 분석

| state | Axis 1/2 사용 | Axis 3 사용 | 충돌 |
|---|---|---|---|
| `memory/system/.callback_ledger.jsonl` | ✓ (write) | ✗ | NO |
| `memory/system/.callback_dedupe_table.jsonl` | ✓ (read/write) | ✗ | NO |
| `~/.claude/data/pre_tool_use_audit.jsonl` | ✗ | (★ live activation 시 신규) | NO |
| `memory/events/*.json` | ✓ (write) | (★ dry-run report · staged template) | NO (디렉토리 동일하나 file name prefix 분리) |
| ENV `CLAUDE_PRE_TOOL_USE_HOOK_ENABLED` | ✗ | ★ Axis 3 전용 | NO |
| ENV cokacdir ANU key `c119085addb0f8b7` | ✓ (callback registration) | ✓ (Axis 3 Phase 0 cron 등록) | 공유 사용 (read-only · 의미 동일) |

→ 충돌 0. ANU collector key 는 양 Axis 가 공유 사용하지만 read-only 사용 (write 권한 없음).

## 5. process / file descriptor 분석

- task-2643 hook spawn 방식: claude-code 가 `python3 <REPO_ROOT>/hooks/pre_tool_use_anu_guard.py --mode=stdin` subprocess 생성
- timeout: 5 sec (staged template)
- stdin: JSON payload (claude-code 가 작성)
- stdout: JSON decision (hook 이 작성)
- exit code 0: decision 적용

→ Axis 1/2 hook 도 동일 subprocess 모델. claude-code 가 직렬 호출하므로 동시 spawn 충돌 0.

## 6. PYTHONPATH 의존 분석 (Axis 2 hardening lesson_2 적용 검증)

- task-2643 hook 코드 안에서 `sys.path` 조작 0 ✓
- `importlib.util.spec_from_file_location` 사용 0 ✓
- `from utils import ...` 절대경로 import 0 ✓ (★ `from typing import Any` 와 같은 stdlib import 만 사용)
- canonical `/home/jay/workspace/hooks/pre_tool_use_anu_guard.py` 경로에서 직접 실행 가능 ✓

→ Axis 2 hardening 교훈 (canonical path first · no worktree hardcoded import) **완전 충족** ✓.

## 7. 결론

- **import collision = ZERO** (확정)
- settings.json slot collision = ZERO (★ PreToolUse vs SessionStart/Stop/UserPromptSubmit 분리)
- runtime ordering collision = ZERO (★ step 3 단독)
- shared state collision = ZERO (ledger / dedupe table 미접근)
- PYTHONPATH 의존 0 (Axis 2 hardening lesson 충족)

→ Axis 3 live activation 시 Axis 1/2 동작에 영향 0 (정적 분석 차원). 단 SP5 smoke test에서 동적 검증 필수.

## 8. 후속 검증 (★ live activation task 진입 시)

- [ ] SP5 smoke fixture 작성: sample dispatch cycle 1회 실행 → ledger row 신규 entry 정합
- [ ] Axis 2 regression suite (callback_collector_helper_integration / adjudicator_v2 / next_action_runner_v2 / source_attribution_guard_v2) baseline test count 유지 확인
- [ ] Axis 1 callback authority gate gate-fire 동작 확인 (PreToolUse 추가가 callback launch path 차단 0)
- [ ] PreToolUse hook timeout 5sec 안에 동작 완료 (Axis 1/2 dispatch cycle latency 영향 0)

## 9. forbidden_action_count = 0

본 분석 단계 코드 수정 / git action / settings.json 변경 0.

끝
