# NL intake spec refresh (Track C · spec-only · 코드 구현 0) — 260523

회장 결정(2026-05-23 batch 병렬): `system_nl_intake_spec_260522.md` 를 현재 stack(origin/main `88a1f2b0` CALLBACK_GOVERNANCE_STACK_PRODUCTION_VERIFIED + task-2637 real_merge wiring OFF-mode in-flight) 기준으로 최신화. **본 spec = 설계 갱신만**. 코드 구현 회장 별도 승인까지 금지.

기반: `system_nl_intake_spec_260522.md`(v1 · Track C 최초) + `system_merge_ready_executor_spec_260522.md` + `system_merge_ready_executor_dryrun_spec_260522.md` + `system_dryrun_executor_shadow_validation_spec_260523.md` + `system_normal_callback_registration_implementation_spec_260523.md` + `system_callback_collector_canonical_root_spec_260523.md` + `system_real_merge_executor_wiring_spec_260523.md`.

---

## 1. 갱신 동기

원본 spec(`system_nl_intake_spec_260522.md`)은 callback runtime enforcement 단계 기준. 이후 4 PR 머지(c80e875d/b2932ce0/5ffa87ae/1e24d79e/88a1f2b0) + task-2637 wiring 코드화로 stack 확장. NL intake task_contract 가 새 stack 의 8개 필드(5축 status + canonical_root + activation_flag + chair_authorization) 와 연결되어야 함.

---

## 2. NL intake → task_contract 흐름 (갱신)

```
자연어 요청 (회장 / 다른 채널)
    ↓
[INTAKE PARSER] 키워드 / 의도 / 위험도 분류
    ↓
task_contract.json 생성:
    {
      "task_id": "task-NNNN(+N|.phase|.lane)",
      "level": "Lv.0|1|2|3|4",
      "expected_files": [...],                     # 명시 (없으면 INSUFFICIENT_EVIDENCE)
      "forbidden_paths": [11+ 정적 가드 from spec §14],
      "risk_class": "low|medium|critical7",
      "callback_envelope_template": {              # ← NEW (task-2635+1)
         registration_intent, registration_attempted,
         registration_result_status, callback_delivery_status,
         collector_receipt_status, canonical_root, ...
      },
      "merge_policy": {                            # ← NEW (task-2637)
         activation_flag_required: <bool>,
         chair_authorization_required: <bool>,
         dryrun_only: <bool>,
         pilot_scope: "per_pr|batch|disabled"
      },
      "merge_ready_evidence": {                    # ← NEW (task-2632 classifier 입력)
         ci_checks_required: 11,
         gemini_review_gate_required: true,
         phase3_merge_gate_required: true,
         unresolved_threshold: 0,
         expected_files_exact: true,
         critical7_required: 0,
         blocking_secret_required: 0,
         admin_override_required: false,
         callback_lifecycle_artifact_required: true
      }
    }
    ↓
[ROUTER] Work / Core 분기
    ↓
[ANU SUPERVISOR] dispatch (회장 승인 후)
```

---

## 3. risk_class 정본 (4단계)

| class | 정의 | 자동 dispatch 가능 | 회장 사전 승인 |
|---|---|---|---|
| `low` | doc/fixture only · 변경 ≤ 10 · expected_files exact · Critical7 0 | YES (자동수렴 doctrine 적용) | NO (read-only 또는 사후 ACCEPT) |
| `medium` | 로컬 helper 추가 / 신규 모듈 · 프로덕션 영향 ≤ 1줄 (import 등) | YES | NO (코드 변경 시 사전 보고) |
| `high` | 프로덕션 본체 변경 / forbidden 인접 영역 / regression 신설 | NO | **YES** (사전 승인 필수) |
| `critical7` | Critical7 7종 트리거 가능 영역 / credential expansion / admin override 필요 | NO | **YES** + 직접 회장 결정 |

---

## 4. callback_envelope_template (task-2635+1 5축 + task-2636 6축 통합)

```json
{
  "schema": "utils.callback_envelope_schema.v2",
  "anu_key": "c119085addb0f8b7",
  "collector_role": "ANU",
  "task_id": "<from contract>",
  "registration_intent": true,
  "registration_attempted": false,
  "registration_result_status": "NOT_REGISTERED",
  "callback_delivery_status": "PENDING",
  "collector_receipt_status": "UNCONFIRMED",
  "canonical_root": "/home/jay/workspace",
  "delivery_method": "anu_cron_callback",
  "attempted_callback_registration": false,
  "cron_schedule_id": null,
  "registered_at_ts": null,
  "envelope_built_at": "<ts>",
  "result_path": "<canonical_root relative>",
  "report_path": "<canonical_root relative>"
}
```

intake 단계 = seed (registration_attempted=false / status=NOT_REGISTERED). 실 registrar 호출 후 build-then-register-then-update 패턴 (task-2635+1) 으로 최종값 정확 반영.

---

## 5. merge_policy enum

```
activation_flag_required:
  true  → real_merge_execute 진입 가능 (task-2637 wiring 머지 후만)
  false → dryrun_only 모드 (현재 stack 의 모든 task 가 기본값)

chair_authorization_required:
  true  → low-risk pilot 또는 real merge 진입 시
  false → dryrun + auto-converge 자동 진행

dryrun_only:
  true  → utils/merge_ready_dryrun_executor.dryrun_route 까지만 (artifact = auto_merge_candidate.v1 / remediation_required.v1 / hold_for_chair.v1)
  false → real_merge_hooks 결선 진입

pilot_scope:
  per_pr  → 1 PR 명시 승인 (chair_authorization.pr_numbers 1건)
  batch   → 다수 PR (별도 회장 결정 후 batch scope)
  disabled→ pilot 미참여 (기본)
```

---

## 6. merge_ready_evidence 9 필드 (task-2632 classifier 입력 정합)

| field | 값 | 기반 |
|---|---|---|
| ci_checks_required | 11 | task-2632 §4 / task-2637 §4 |
| gemini_review_gate_required | true | task-2632 / fresh head evidence |
| phase3_merge_gate_required | true | 별도 PASS 필수 |
| unresolved_threshold | 0 | reviewThreads totalCount = isResolved count |
| expected_files_exact | true | classifier scope guard |
| critical7_required | 0 | 7 카테고리 hits = 0 |
| blocking_secret_required | 0 | credential 3-tier `feedback_credential_scan_3tier_doctrine_260522` |
| admin_override_required | false | non-admin merge only |
| callback_lifecycle_artifact_required | true | `callback_lifecycle.json` + 5축 정합 |

intake 단계에서 위 9 필드 default 명시 → task md 에 반영 → classifier 가 evaluate.

---

## 7. forbidden_paths 11+종 (intake 강제 주입)

NL intake → task_contract 생성 시 forbidden_paths 자동 포함:
- `utils/replacement_pr_runner.py`
- `scripts/finish-task.sh`
- `utils/merge_ready_classifier.py`
- `utils/merge_ready_dryrun_executor.py`
- `utils/callback_envelope_schema.py`
- `utils/anu_callback_registrar.py`
- `utils/canonical_root_resolver.py`
- `utils/anu_collector_action_trigger.py`
- `dispatch/finalize_hooks.py`
- `.tasks/`
- `tests/fixtures/`
- `tests/regression/`

stack 추가 시 명시 갱신 정책 (자동 갱신 후속).

---

## 8. Work / Core 라우팅 정본

| intake 키워드 | 분기 | base |
|---|---|---|
| "정리 / 백로그 / triage / cleanup" | Core triage (read-only) | 회장 결정 task |
| "코드 / 구현 / dispatch / fixture / regression" | Core code (dev6 페룬 또는 적합 봇) | 회장 승인 후 |
| "spec / 설계 / 정책 / 문서" | Core spec (ANU 직접) | 회장 review 후 |
| "PR / merge / push / Gemini" | Core merge governance (ANU OWNER 권한) | 회장 승인 후 |
| "대시보드 / 회의 / 보고" | Work (anu-direct) | 즉시 |

---

## 9. acceptance criteria (owner-provided)

회장 verbatim 결정 = 유일 acceptance source. intake 가 추정 0:
- 회장 명시 활성화 승인이 없으면 NL intake 가 dispatch 진행 금지
- 회장 7대 트리거 (Critical7 / credential expansion / expected_files 밖 / admin override / replacement_pr fail / smoke fail / scope expansion) 시 회장 보고 강제
- expected_files 내부 medium/style → 자동수렴 (sub-criteria 회장 사전 doctrine 적용)

---

## 10. 본 spec 갱신 범위 (실 코드 구현 금지)

- 본 spec = **NL intake 흐름 설계 갱신** 까지만
- 실 parser/router/contract writer 코드 구현 = 회장 별도 승인 (다른 Track / 후속 task)
- Track A/B/D 와 expected_files overlap 0
- 회장 결정 대기:
  1. NL intake parser 구현 시점 (Track A 머지 후 vs 별도 회장 결정)
  2. risk_class enum 4단계 final
  3. task_contract.json schema final (위 §2~§7 통합)
  4. Work/Core 라우터 helper 위치 (dispatch/ 또는 utils/)
  5. acceptance criteria source-of-truth 단일 채널 (회장 텔레그램 verbatim)

---

## 11. frozen anchor

- ANCHOR-1: "본 spec = NL intake 흐름 설계 갱신만 · 코드 구현 회장 별도 승인 (Track A/B/D 와 분리)"
- ANCHOR-2: "task_contract.json 에 callback_envelope_template(5축+canonical_root) + merge_policy(activation_flag/chair_authorization/dryrun_only) + merge_ready_evidence(9 필드) 통합 반영"
- ANCHOR-3: "forbidden_paths 11+종 정적 자동 주입 (intake → contract)"
- ANCHOR-4: "risk_class 4단계 · acceptance criteria 회장 verbatim 단일 source"
- ANCHOR-5: "stack 추가 시 본 spec 갱신 명시 정책 (CALLBACK_GOVERNANCE_STACK_PRODUCTION_VERIFIED 88a1f2b0 + task-2637 in-flight 반영)"
