# system_callback_authority_4source_verify_doctrine_260526

- task: task-2680
- chair_authorization_id: `CHAIR-AUTH-CALLBACK-SELF-KEY-HARDENING-FIX-20260526-JJONGS-IMPLEMENT-001`
- mode: fix implementation doctrine 박제 · 코드 수정 ON (별도 PR · merge 금지 → 별도 chair signature)
- author: dev2 오딘
- date: 2026-05-26
- depends_on:
  - task-2677 RCA packet `callback_self_key_registration_hardening_*` (worktree-585CFEE9)
  - `memory/events/callback_self_key_root_cause_audit.json` (task-2625 audit 1차 사료)

## §0 단일소스

- 본 spec 은 task-2677 packet 의 4-source verify doctrine 을 **코드로 enforce** 한 결과의 1:1 박제.
- 본 packet 의 모든 코드 변경은 helper 5종 자체는 추가 hook 만, 신설 module 은 별도 파일.
- merge 는 별도 chair signature 강제 (task md `merge_policy = fix_implementation_separate_pr_no_merge_chair_signature_required`).

## §1 4-source 정의 (task-2677 doctrine §1.1 1:1)

| Source | 위치 | 코드 hook |
|--------|------|----------|
| S1 schedule_history | `/home/jay/.cokacdir/schedule_history/<schedule_id>.log` | `utils.callback_authority_4source_validator._read_schedule_history` |
| S2 cron-history     | `cokacdir --cron-history <schedule_id> --key <K>` | `utils.callback_authority_4source_validator._query_cron_history` (ANU + executor self-key 2회 query) |
| S3 envelope         | S1.prompt 본문 (envelope text) | `utils.callback_authority_4source_validator._parse_envelope_from_prompt` |
| S4 result artifact  | `memory/events/<task_id>.*-result-*.json` | `utils.callback_authority_4source_validator._read_result_artifact` |

## §2 분류 enum (task-2677 doctrine §2.1 1:1 · 코드 enforce)

`utils.callback_authority_4source_validator`:

```python
ANU_AUTHORITATIVE = "ANU_AUTHORITATIVE"
NON_AUTHORITATIVE_SELF_COLLECTOR = "NON_AUTHORITATIVE_SELF_COLLECTOR"
NON_AUTHORITATIVE_KEY_DRIFT = "NON_AUTHORITATIVE_KEY_DRIFT"
UNDETERMINED_HISTORY_GAP = "UNDETERMINED_HISTORY_GAP"
PROMPT_DRIFT = "PROMPT_DRIFT"

REVERIFY_TRIGGER_CLASSIFICATIONS = frozenset({
    NON_AUTHORITATIVE_SELF_COLLECTOR,
    NON_AUTHORITATIVE_KEY_DRIFT,
    UNDETERMINED_HISTORY_GAP,
    PROMPT_DRIFT,
})
```

`utils.callback_collector_helper_integration` 에 동일 enum 재노출 (single import 진입점).

## §3 transition table (코드 검증)

`classify_collector_authority(schedule_id, executor_key, task_id, ...)`:

| S2.anu_count | S2.self_count | S3.owner_key (text) | classification |
|--------------|---------------|---------------------|----------------|
| >=1          | 0             | == ANU              | `ANU_AUTHORITATIVE` |
| >=1          | 0             | != ANU (≠None)      | `PROMPT_DRIFT` |
| 0            | >=1           | *                   | `NON_AUTHORITATIVE_SELF_COLLECTOR` |
| >=1          | >=1           | *                   | `NON_AUTHORITATIVE_KEY_DRIFT` (collision) |
| 0            | 0             | *                   | `UNDETERMINED_HISTORY_GAP` |
| query error  | query error   | *                   | `UNDETERMINED_HISTORY_GAP` |

regression 테스트 (`tests/callback_authority_4source/test_4source_validator.py`):
- R1 (TRACK_A · TRACK_J self-key) — `test_r1_track_a_self_key_detected_classification_self_collector` / `test_r1_track_j_self_key_detected`
- R6 (history gap / dual-owner / prompt drift / subprocess error / evidence completeness / JSON roundtrip) — 6 케이스

## §4 6 수정 목표 ↔ 코드 hook 1:1 매핑

| 목표 | 코드 변경 위치 | regression 테스트 |
|------|---------------|------------------|
| 1. task md ANU 명시인데 실제 cron self-key 등록 방지 | `utils/anu_callback_registrar.py:_build_cokacdir_cron_argv` 내부 `_assert_independent_anu_key(anu_key)` 추가 + `utils/callback_authority_4source_validator.classify_collector_authority` | R1 3 케이스 |
| 2. helper --key 인자 cron layer 강제 | `utils/anu_callback_registrar.py:assert_cron_argv_uses_anu_key` 신설 + `dispatch/normal_fallback_callback_helper.py:assert_argv_uses_anu_key` 신설 + `build_anu_owned_callback_request` 의 argv post-build verifier 추가 | R2 6 케이스 |
| 3. actual owner key 검증 callback collector gate | `utils/callback_collector_helper_integration.py:classify_collector_authority_4source` wiring 신설 | R3 2 케이스 |
| 4. self-key callback NON_AUTHORITATIVE_SELF_COLLECTOR 자동 분류 | `utils/callback_authority_4source_validator.classify_from_observed` + `is_self_key_callback` 신설 | R4 6 케이스 |
| 5. ANU independent reverify flow 강제 | `utils/callback_authority_4source_validator.build_anu_independent_reverify_request` + `utils/callback_collector_helper_integration.py:emit_anu_independent_reverify_request` 신설 | R5 4 케이스 |
| 6. regression (self-key 재발 방지 + 4 source 교차 + collector gate) | `tests/callback_authority_4source/test_4source_validator.py` 29 케이스 + Track A/J 1:1 재현 anchor 2 케이스 | 29 PASS |

## §5 ANU independent reverify trigger (회장 검토영역 #5 박제)

`utils.callback_collector_helper_integration.emit_anu_independent_reverify_request` 가 `classify_collector_authority` 결과의 `requires_anu_reverify == True` 시 `ReverifyRequest` 객체를 build 한다. 이 객체는 caller (ANU dispatch layer 또는 chair escalation path) 가 받아 실 dispatch 또는 회장 보고 발송한다.

```python
@dataclass
class ReverifyRequest:
    schema: str
    task_id: str
    original_schedule_id: str
    classification: str
    chair_authorization_id: str
    artifact_path_hint: str
    reason: str
```

artifact_path_hint = `memory/events/<task_id>.independent_anu_reverify.result.json` (★ task-2625 anchor 1:1 박제).

## §6 본 packet 의 scope invariants

- `merge_policy = fix_implementation_separate_pr_no_merge_chair_signature_required` (회장 verbatim · task md L169)
- PR #149 코드 변경 0 (`utils/anu_codex_micro_refinement_loop.py` · `utils/codex_cc_decision_loop.py` · `tests/anu_codex_micro_refinement_loop/**` 미수정)
- PR #150 코드 변경 0 (`utils/pr_watcher_terminal_state_classifier.py` · `tests/pr_watcher_*` 미수정)
- task-2662 ~ 2679 event/file overlap 0
- Axis runtime 변경 0 · `dispatch.py` 변경 0 · `.github/**` 변경 0 · live `settings.json` 변경 0
- helper 5종 자체 read-only 분석 + 추가 hook 만 (기존 함수 signature 보존)

## §7 frozen anchors

- ANCHOR-4S-DOC-1: 4 source = schedule_history + cron-history + envelope + result artifact (task-2677 doctrine 1:1)
- ANCHOR-4S-DOC-2: classify_collector_authority 가 ANU/SELF 2회 cron-history query 를 강제 → actual owner 결착의 외부 사료
- ANCHOR-4S-DOC-3: NON_AUTHORITATIVE_SELF_COLLECTOR 분류 시 ReverifyRequest 자동 build (caller dispatch 책임)
- ANCHOR-4S-DOC-4: helper 5종 자체는 변경 없음 — wiring + verifier 신설로 결선 강제
- ANCHOR-4S-DOC-5: merge 별도 chair signature (`fix_implementation_separate_pr_no_merge_chair_signature_required`)

## §8 끝

성공: `CALLBACK_SELF_KEY_REGISTRATION_HARDENING_FIX_IMPLEMENTED`
