# [DRAFT · 미dispatch] B축 bounded task 지시문 초안 — 4종 종단 terminal callback 결선

상태명: `BSIDE_TERMINAL_CALLBACK_BOUNDED_TASK_DRAFT_ACTIVE_FALSE`
작성: ANU 직접 (2026-07-02 KST). **초안 — 아직 dispatch 안 함.** GPT 승인: 방향 수용·코드수정 착수 금지·"expected_files/실패 enum/result.json envelope/4종 종단 테스트를 task 문서 수준으로 고정." 실제 dispatch는 별도 승인 + **watcher(C안 inotify) arm 선행 필수**.

## 레벨
Lv3 (finalize/callback 경로 수정 + 회귀 테스트).

## 목표 (한 줄)
finish-task 4종 종단(SUCCESS/FAILED/BLOCKED/ESCALATED) **모두** ANU terminal status(terminal marker + 최소 result.json + terminal callback 등록 또는 fail-closed marker)가 남도록 결선. `.done.escalated`를 정상완료가 아니라 **terminal callback 대상**으로 편입. dispatched marker 부재 시 **silent exit 0 금지**.

## 배경 (근거)
task-2781에서 state_file_missing → `.done.escalated`만 남고 result.json/ANU 콜백 0 = CALLBACK_NOT_DELIVERED. escalation 종단이 ANU terminal callback 보장 결선 밖. dispatched marker 부재 시 terminal_state_callback이 fail-open 침묵 종료. 단일소스: [[infra_defect_two_axis_260702]] · [[infra_defect_remediation_design_260702]].

## expected_files (이 범위만)
- `scripts/finish-task.sh` — state_file_missing/ESCALATED/BLOCKED 분기(≈878~929)에 (a)최소 result.json write (b)terminal_state_callback emit 호출 추가.
- `scripts/harness/v36/terminal_state_callback.py` — dispatched marker 부재 시 fallback context 또는 fail-closed marker(침묵 exit 0 제거).
- `tests/regression/test_finish_task_terminal_termination_<id>.py` (신규).

## forbidden_paths (건드리면 STOP)
- `.github/**` · ruleset/branch protection · `utils/replacement_pr_runner.py` 및 merge-executor 체인(A축 조사 대상, 무접촉) · dispatch.py · expected_files 밖 전부.

## 종단 상태 enum (고정)
- `terminal_state`: **SUCCESS / FAILED / BLOCKED / ESCALATED** — 각각 **필수 3산출**: ① terminal marker(.done/.done.failed/.done.blocked/.done.escalated) ② 최소 result.json ③ terminal callback(등록 성공) **또는** fail-closed marker.
- callback 분류(검증용): `CALLBACK_DELIVERED / CALLBACK_NOT_DELIVERED / CALLBACK_REGISTERED_BUT_NOT_PICKED_UP / CALLBACK_FALSE_CLAIM`.
- context fallback: `DISPATCHED_MARKER_MISSING_FALLBACK_SCHEDULE_ID / CALLBACK_CONTEXT_UNRESOLVED_FAIL_CLOSED`.

## result.json 최소 envelope (고정 스키마)
```json
{
  "task_id": "<id>",
  "terminal_state": "SUCCESS|FAILED|BLOCKED|ESCALATED",
  "result_path": "<self-ref 허용>",
  "report_path": "<report 또는 self-ref>",
  "callback_schedule_created": true,
  "callback_context": "dispatched_marker|fallback_schedule_id|unresolved_fail_closed",
  "reason": "<종단 사유>",
  "ts": "<UTC ISO8601>"
}
```
- **보장**: 모든 종단 분기가 terminal marker 발행 **직후 result.json(최소본) 원자적 write**. write 실패 시 finalize를 fail-closed 처리(침묵 통과 금지).

## terminal callback 보장 방식
- escalation/BLOCKED/FAILED 분기에서도 `terminal_state_callback emit` **호출**(현재 SUCCESS .done 경로만 커버).
- terminal_state_callback: dispatched marker 있으면 그 schedule_id 사용; 없으면 **dispatch 시점 산출물(capabilities/task-<id>.json 또는 cron_response schedule_id)로 fallback**; 그래도 불가면 **fail-closed marker(.terminal-callback-failed.json)** 남기고 명시 신호(비차단이되 침묵 금지).
- ★ executor self-key 발사 0 유지(OS-level pickup contract 준수) — 본 task는 "종단마다 terminal status가 반드시 남는다"를 보장할 뿐, executor 자가 콜백 발사를 새로 만들지 않는다.

## 테스트 케이스 (신규 회귀, mock/tmp 격리)
1. state_file_missing escalation → result.json 생성 + terminal callback marker/registration 존재.
2. dispatched marker 부재 → fallback context 또는 fail-closed marker 기록(**silent exit 0 금지** assert).
3. BLOCKED 종단 → result.json + terminal callback 존재.
4. FAILED(QC FAIL) 종단 → result.json + terminal callback 존재.
5. SUCCESS(.done) → 기존 동작 회귀 0(마커·콜백·result.json 정상).
6. 4종 종단 각각 ANU terminal status 마커 존재 전수 assert.
7. terminal callback 등록 실패 주입 시 fail-closed marker 존재(침묵 금지) assert.
8. escalation result.json에 `callback_schedule_created`·`callback_context` 필드 존재.

## ACTIVE=false 불변식
- CI/ruleset/PR 변경 0. real fire 0. executor self-key 콜백 0. merge-executor 체인(A축 대상) 무접촉.
- 산출물 = 수정 2파일 + 신규 테스트 + 로컬 pytest 통과. 실제 활성화/결선 검증은 별도.

## 산출물 & 보고 (PR 생성 전 ANU 선보고)
- PR 전 ANU 선보고: 파일 범위 + pytest 결과 + forbidden 무접촉(.github/·merge-executor 체인 diff 0).
- 봇 종료 전 ANU callback(envelope만, UTF-8 ≤3900B).

## ★ dispatch 전제 (GPT verbatim)
- **이 task의 finish-task 자체가 truncate 재현 포착 기회**이므로, **C안 inotify watcher(/tmp/truncate_inotify_watch_260702.py)를 arm하지 않은 상태로 dispatch 금지.**
- 순서: watcher arm → dispatch → finish-task 재현 관측 → truncate 캡처(A축) + terminal callback 결선 검증(B축) 동시.

## 상태
초안 고정·**미dispatch**. 실제 dispatch = 회장 승인 + watcher arm 선행 시.
