# task-2707 — dispatch_marker_writer.py FORMALIZATION_COMMIT_ONLY (task-2705+1 lineage formalize)

★ DRAFT — 회장 발사 인가 대기. 본 task md = 초안 보고용. ANU 자체 dispatch 0.

---

## 0. Header / Authorization Anchor

- **task_id**: `task-2707`
- **task_type**: `FORMALIZATION_COMMIT_ONLY` (★ 회장 verbatim)
- **chair_authorization_id**: `CHAIR-AUTH-TASK-2707-DISPATCH-MARKER-WRITER-FORMALIZATION-260529` (★ 회장 verbatim 후보)
- **executor_team**: `dev1-team` (헤르메스 · Hermes)
- **verifier_team**: `dev2-team` (오딘 · Odin) — ★ 본 task-2707 종료 후 task-2707+1 read-only 별도 dispatch
- **parent_chain**: task-2705+1 (signature bootstrap) → task-2705+3 (caller wiring commit f0bfcda1) → **task-2707 (callee formalize commit)**
- **lineage_category**: ACCEPTED_RUNTIME_DIRTY_TO_FORMALIZE (★ 회장 verbatim classification)
- **merge_policy**: `manual`
- **ttl_hours**: 6
- **anu_collector_key**: `c119085addb0f8b7` (★ ANU normal callback collector_role=ANU)
- **callback_envelope_prompt_byte_limit**: UTF-8 ≤ 3900 bytes hard (★ wc -c · NOT wc -m)

---

## 1. Problem Statement

`scripts/harness/v36/dispatch_marker_writer.py` 가 working tree dirty 상태로 잔존.

- **HEAD blob**: `a3e6805f` (task-2704 d96ab6f2 originated)
- **working blob**: `51b4124f` (task-2705+1 signature bootstrap 산물)
- **working sha256**: `63a3360513a96a22202c85143f652f44998979652e0887a02654adc714437bf3`
- **size**: 6716 bytes
- **mtime**: `2026-05-29 02:18:00.862795321 +0900`
- **git status**: ` M scripts/harness/v36/dispatch_marker_writer.py`

dirty 내용 3건 (★ 회장 STEP 1 confirmed_fact verbatim):
1. 모듈상수 `CHAIR_AUTHORIZATION_ID = "CHAIR-AUTH-TASK-2704-V36-CONTROL-PLANE-P0-MVP-260528"` 제거
2. `chair_authorization_id: Optional[str] = None` 파라미터 추가 (`write_dispatch_marker()` + `_write_dispatch_marker_impl()`)
3. marker 출력 `"chair_authorization_id"` 흐름: 모듈상수 → caller 전달 파라미터 (flow direction 역전)

문제 본질: **caller (commit f0bfcda1 task-2705+3)** 은 머지 완료 · **callee (dispatch_marker_writer.py signature)** 은 영구 dirty → caller-callee asymmetric commit.

---

## 2. Root Cause

- **task-2705+1 의 callee signature 변경 = 의도된 design (★ task-2705+3 caller 결선 의존)**
- **finish-task scope-guard cascade**: task-2705+1 finish-task 실행 시 prior dirty replay 로 commit 단계 차단 → callee signature 영구 dirty
- **task-2705+3 (commit f0bfcda1)**: caller (`dispatch/__init__.py` L3033-3047 / L4074-4088 / L265 helper) 결선 commit. callee 본체 책임 옮기지 않음
- **결과**: HEAD callee = old signature / HEAD caller = new kwarg `chair_authorization_id=` → 정합 fail 직전. working tree dirty 가 production runtime 을 막고 있는 유일 layer

---

## 3. Production Runtime Evidence (★ 회장 STEP 1 5 dispatch marker 박제 verbatim)

| dispatch marker | fire_time (KST) | chair_authorization_id | 의미 |
|---|---|---|---|
| `task-2705+1.dispatched-20260528.json` | 2026-05-29 01:51:06 | `CHAIR-AUTH-TASK-2704-...` | dirty 적용 이전 fallback |
| `task-2705+2.dispatched-20260528.json` | 2026-05-29 05:43:23 | `null` | dirty 적용 후 + caller helper 미결선 transitional |
| `task-2705+3.dispatched-20260528.json` | 2026-05-29 06:09:48 | `null` | f0bfcda1 직전 spawn |
| `task-2705+4.dispatched-20260528.json` | 2026-05-29 08:52:49 | `CHAIR-AUTH-TASK-2705PLUS3-INDEPENDENT-VERIFICATION-READONLY-260529` | ★ task-specific 정상 populate 시작 |
| `task-2706.dispatched-20260529.json` | 2026-05-29 10:36:34 | `CHAIR-AUTH-TASK-2706-V36-FINISH-TASK-PROFILE-LAYER-P1B-260529` | ★ P1-B 구현 L4 evidence |
| `task-2706+1.dispatched-20260529.json` | 2026-05-29 12:02:47 | `CHAIR-AUTH-TASK-2706PLUS1-MAAT-VERIFICATION-READONLY-260529` | ★ P1-B Maat L4 evidence |

→ **3회 연속 정상 populate = production runtime baseline lock** (task-2705+4 / task-2706 / task-2706+1)
→ Maat task-2706+1 보고서 #8 (chair_authorization_id propagation) PASS evidence 와 verbatim 일치

---

## 4. Goal

dispatch_marker_writer.py 의 accepted runtime dirty 를 정식 lineage 로 반영 (★ 회장 verbatim).

**구체화**: working tree blob `51b4124f` 를 그대로 commit. body byte 변화 = 0. header docstring 의 `chair_authorization_id=` attribution comment 1줄만 minor 갱신 허용 (task-2704 → task-2705+1 logical authorship 정정).

---

## 5. Allowed / Forbidden Files

### 5.1 expected_files (★ commit / 작성 허용)

1. `scripts/harness/v36/dispatch_marker_writer.py` (★ formalize commit 1건 — working tree blob 그대로)
2. `memory/reports/task-2707.md` (★ formalization 보고서)
3. `memory/events/task-2707.formalization-commit-260529.json` (★ formalization marker)
4. `memory/events/task-2707.dispatched-20260529.json` (★ dispatch.py 자동 생성 marker · executor 작성 0)
5. `memory/events/task-2707.callback-envelope.json` (★ ANU normal callback envelope)

### 5.2 allowed_existing_file_edits

- `scripts/harness/v36/dispatch_marker_writer.py` (★ body byte 0 변경 · header docstring 1줄 attribution comment 갱신만 허용)
- 그 외 기존 파일 edit 허용 0

### 5.3 forbidden_files (★ 회장 verbatim 강제)

- `scripts/finish-task.sh` (★ no-touch 증명 필수)
- `dispatch/__init__.py` (★ no-touch 증명 필수)
- `scripts/session-watchdog.sh` (★ no-touch 증명 필수)
- `.claude/settings.json` (★ no-touch 증명 필수)
- `dispatch_marker_writer.py 의 함수 body byte` (★ signature attribution comment 외 본문 변경 0)
- 그 외 P1-C 영역 / P2 finish-task routing / actor attribution / Goal-to-Done / PHASE_AUTO / Core-Work 이원화 파일 일체

### 5.4 forbidden_actions (★ 회장 verbatim 11 금지)

1. 기능 추가 금지
2. dispatch.py 수정 금지
3. finish-task.sh 수정 금지
4. session-watchdog.sh 수정 금지
5. settings.json 수정 금지
6. P1-C 구현 금지
7. P2 finish-task routing 구현 금지
8. GitHub write 금지
9. PR 생성 금지
10. branch push 금지
11. merge 금지

### 5.5 추가 ANU doctrine 정합 금지 (★ task-2706 lineage 정합)

- 코드 의미 변경 금지 (★ working tree blob byte-equal 강제)
- lineage rewrite 금지 (★ task-2705+1 → task-2707 attribution 단방향만)
- 자동 +N task 발의 금지
- self-collector callback 금지 (★ ANU key `c119085addb0f8b7` 강제)
- `.done` 수동 생성 금지

### 5.6 Capability Scope YAML (★ dispatch.py L4769 capability_scope parser 강제 대상 · 회장 OPTION B verbatim draft 정합)

```yaml
allowed_resources:
  expected_files:
    - scripts/harness/v36/dispatch_marker_writer.py
    - memory/reports/task-2707.md
    - memory/events/task-2707.formalization-commit-260529.json
    - memory/events/task-2707.callback-envelope.json
  allowed_existing_file_edits:
    - scripts/harness/v36/dispatch_marker_writer.py
  forbidden_paths:
    - scripts/finish-task.sh
    - dispatch.py
    - dispatch/init.py
    - scripts/session-watchdog.sh
    - .claude/settings.json
    - /home/jay/.claude/settings.json
    - utils/merge_queue_executor.py
    - utils/real_merge_hooks.py
    - anu_v3/
```

★ expected_files 와 allowed_existing_file_edits 에 동일 파일 (`dispatch_marker_writer.py`) 포함 = 회장 verbatim "의도된 기존 파일 최소수정 대상" 정합
★ dispatch_marker_writer.py 외 기존 파일 수정 금지 (★ 회장 verbatim)
★ 본 YAML 블록 = 회장 OPTION B draft verbatim 채택 (★ ANU 자체 정정 0 · 회장 verbatim 우선)

---

## 6. Step-by-Step Implementation Plan (★ 회장 5단계 verbatim 정합)

### Step 1 — pre-state 박제 (read-only)

- `git status --porcelain scripts/harness/v36/dispatch_marker_writer.py` → ` M scripts/harness/v36/dispatch_marker_writer.py` 박제
- `sha256sum scripts/harness/v36/dispatch_marker_writer.py` → `63a3360513a96a22...` 박제 (working tree)
- `git show HEAD:scripts/harness/v36/dispatch_marker_writer.py | sha256sum` → HEAD blob sha256 박제
- `git diff HEAD -- scripts/harness/v36/dispatch_marker_writer.py | sha256sum` → diff sha256 박제

### Step 2 — header attribution comment 갱신 (minor · body byte 0 변경)

- 파일 헤더 (L1~L22 영역의 module docstring 또는 주석) 에 1줄 추가:
  ```
  # chair_authorization_id propagation signature formalized in task-2707 (task-2705+1 lineage)
  ```
- ★ 함수 signature / body / 파라미터 default / marker output dict 전부 byte-equal 강제
- 갱신 후 sha256 박제

### Step 3 — formalization commit (★ 1건 only)

- `git add scripts/harness/v36/dispatch_marker_writer.py`
- commit message:
  ```
  [task-2707] dispatch_marker_writer.py signature formalize (task-2705+1 lineage)

  body byte 0 변경 · header attribution comment 1줄 minor 갱신
  task-2705+3 (commit f0bfcda1) caller 결선과 짝을 이루는 callee signature formalize
  chair_authorization_id: CHAIR-AUTH-TASK-2707-DISPATCH-MARKER-WRITER-FORMALIZATION-260529
  ```
- ★ `git push` 금지 · ★ PR 생성 금지 · ★ merge 금지

### Step 4 — post-state 검증 (read-only)

- `git status --porcelain scripts/harness/v36/dispatch_marker_writer.py` → 빈 출력 (clean) 박제
- `git log -1 --pretty=format:"%H %s" -- scripts/harness/v36/dispatch_marker_writer.py` 박제 (★ 신규 commit hash 박제)
- `git diff HEAD~1 HEAD -- scripts/harness/v36/dispatch_marker_writer.py` 박제 (★ 1줄 header comment 만 diff)
- forbidden_files 4 (finish-task.sh / dispatch.py / session-watchdog.sh / settings.json) sha256 동일 박제 (no-touch proof)

### Step 5 — formalization marker / report / callback envelope 작성

- `memory/events/task-2707.formalization-commit-260529.json` 작성 (★ 본 task md acceptance criteria 7 verbatim 인용)
- `memory/reports/task-2707.md` 작성 (★ 5 형식: confirmed_fact / caveat / blocker / verdict / recommendation)
- `memory/events/task-2707.callback-envelope.json` 작성 (★ envelope only · UTF-8 ≤3900 bytes hard · 상세는 report.md/marker.json 위임)
- ANU normal callback cron 발사 (★ ANU key `c119085addb0f8b7` · collector_role=ANU 강제)

---

## 7. Acceptance Criteria (★ 회장 STEP 1 5 baseline 정합)

1. ★ commit 1건만 (`scripts/harness/v36/dispatch_marker_writer.py` 단일 파일)
2. ★ dispatch_marker_writer.py 함수 body / signature / 파라미터 default / marker output dict **byte-equal** (★ 본문 변경 0 · header 1줄 minor comment 만)
3. ★ commit 후 git status clean (`scripts/harness/v36/dispatch_marker_writer.py` 항목 사라짐)
4. ★ 5 dispatch marker baseline 회귀 0 (★ task-2705+4 / task-2706 / task-2706+1 chair_authorization_id 정상 populate 패턴 유지 확인)
5. ★ 246/246 또는 408 PASS 회귀 0 (`pytest tests/harness/test_v36_dispatch_marker_contract.py` import / caller 호환성 smoke)
6. ★ forbidden_files 4 sha256 동일 (`scripts/finish-task.sh` / `dispatch/__init__.py` / `scripts/session-watchdog.sh` / `.claude/settings.json`)
7. ★ GitHub write 0 / PR 0 / branch push 0 / merge 0

---

## 8. Regression Smoke (★ no-op compatibility 한정)

### 8.1 import smoke

```bash
python3 -c "from scripts.harness.v36.dispatch_marker_writer import write_dispatch_marker; print('import_ok')"
```

기대: `import_ok`

### 8.2 caller compatibility smoke (★ dispatch/__init__.py kwarg 호환)

```bash
python3 -c "
from scripts.harness.v36.dispatch_marker_writer import write_dispatch_marker
import inspect
sig = inspect.signature(write_dispatch_marker)
assert 'chair_authorization_id' in sig.parameters, 'kwarg missing'
print('caller_kwarg_compat_ok')
"
```

기대: `caller_kwarg_compat_ok`

### 8.3 contract test smoke (★ 기존 test suite)

```bash
pytest tests/harness/test_v36_dispatch_marker_contract.py -v
```

기대: 전체 PASS (★ 회귀 0 강제)

### 8.4 forbidden_files no-touch proof

```bash
for f in scripts/finish-task.sh dispatch/__init__.py scripts/session-watchdog.sh .claude/settings.json; do
    pre=$(git show HEAD~1:"$f" 2>/dev/null | sha256sum | awk '{print $1}')
    post=$(git show HEAD:"$f" 2>/dev/null | sha256sum | awk '{print $1}')
    echo "$f pre=$pre post=$post match=$([ "$pre" = "$post" ] && echo YES || echo NO)"
done
```

기대: 4건 모두 `match=YES`

---

## 9. Safe-Fail Strategy

- 모든 step 에서 unexpected error 발생 시 **즉시 멈춤** · `.escalate` marker 작성 (★ `memory/events/task-2707.escalate`) · 회장 보고 대기
- `git commit` 실패 시: working tree 상태 박제 후 멈춤 · `git reset` / `git checkout` / `git stash` **금지**
- forbidden_files 의도치 않은 stat change 감지 시: 즉시 멈춤 · `.escalate` 작성
- finish-task.sh 실행 금지 (★ task-2706 Maat verifier 동일 강제) · `.done` 수동 생성 금지

---

## 10. Callback Envelope Schema (★ 회장 ANU collector contract 정합)

```json
{
  "task_id": "task-2707",
  "chair_authorization_id": "CHAIR-AUTH-TASK-2707-DISPATCH-MARKER-WRITER-FORMALIZATION-260529",
  "executor": "dev1-team / 헤르메스",
  "collector_role": "ANU",
  "collector_key": "c119085addb0f8b7",
  "result_path": "memory/events/task-2707.formalization-commit-260529.json",
  "report_path": "memory/reports/task-2707.md",
  "commit_sha": "<new commit hash>",
  "dispatch_marker_writer_post_sha256": "<post-commit sha256>",
  "forbidden_files_no_touch_4": "MATCH_ALL_YES",
  "regression_smoke_pass": "import_ok + caller_kwarg_compat_ok + contract_test_pass",
  "summary_one_line": "task-2705+1 lineage callee signature formalize commit 1건 · body byte 0 변경 · 5 baseline regression 0"
}
```

★ envelope UTF-8 byte 수: `printf '%s' "$P" | wc -c` 측정 · ≤3900 bytes 강제 (★ 회장 verbatim hard limit · paraphrase 금지)
★ envelope 에 긴 보고 금지 · 상세는 `result_path` / `report_path` 에 위임

---

## 11. Verifier Task (task-2707+1) — 별도 dispatch (★ 본 task 종료 후)

- **verifier**: dev2-team (오딘 · Odin)
- **scope**: read-only only (★ no commit / no file write 외 verification artifacts)
- **verification_items** (회장 verbatim "signature/caller compatibility + production marker continuity"):
  1. dispatch_marker_writer.py post-commit sha256 = pre-commit working tree sha256 (★ byte-equal proof except header 1줄)
  2. import smoke PASS
  3. caller_kwarg_compat smoke PASS
  4. contract test (`pytest tests/harness/test_v36_dispatch_marker_contract.py`) PASS
  5. forbidden_files 4 no-touch proof
  6. production dispatch marker 5건 chair_authorization_id 박힘 패턴 유지 (★ task-2705+4 / task-2706 / task-2706+1 baseline)
  7. lineage chain 정합 (★ task-2704 → task-2705+1 → task-2705+3 → task-2707 attribution)
  8. forbidden_actions 11 위반 0
- **5 enum classification**: FULL_ACCEPT / ACCEPT_WITH_KNOWN_CAVEATS / PARTIAL_ACCEPT_NEEDS_FOLLOWUP / HOLD_FOR_CHAIR / REJECT
- ★ task-2707+1 task md 는 본 task 종료 후 별도 작성 (★ 회장 발사 인가 별도 대기)

---

## 12. ANU Doctrine Compliance

- ★ "evidence 만 따른다" doctrine 정합 (★ STEP 1 confirmed_fact 인용만)
- ★ ANU 자체 분류 결정 0 (★ classification A 는 회장 verbatim 4 enum 중 선택 · 신규 분류 신설 0)
- ★ ANU 자체 FULL_ACCEPT 판정 0 (★ verifier 결과 이후에만 판단)
- ★ ANU 자체 P1-A/P1-B accepted 마커 추가 작성 0 (★ 기존 P1-A / P1-B accepted 마커 보존만)
- ★ ANU 자체 dispatch 0 (★ 본 task md 초안 작성만 · 발사 인가 회장 대기)
- ★ ANU 자체 코딩 0 (★ executor dev1 헤르메스 위임 강제)
- ★ self-collector callback 금지 (★ ANU key `c119085addb0f8b7` 강제 · executor self-key 발사 금지)

---

## 13. Lineage Preservation (★ 회장 verbatim)

- task-2704 (d96ab6f2) — original CHAIR_AUTHORIZATION_ID 모듈상수 작성자 (★ 보존)
- task-2705+1 — signature bootstrap (★ logical authorship 정정 attribution)
- task-2705+3 (f0bfcda1) — caller 결선 (★ 보존)
- task-2706 — P1-B external layer 구현 (★ 보존)
- task-2706+1 — P1-B Maat 독립 검증 (★ 보존)
- **task-2707 — callee signature formalize commit (★ 본 task)**
- lineage_rewrite_count: 0

---

## 14. Linked Markers (★ 회장 발사 인가 후 callback envelope 에 인용)

- `memory/events/anu_c1_step_1_dispatch_marker_writer_root_cause_260529.json` (★ STEP 1 root cause 박제)
- `memory/events/p1b_finish_task_profile_contract_accepted_with_known_caveats_260529.json` (★ C1 caveat 출처)
- `memory/events/p1a_task_md_sha_contract_accepted_with_known_caveats_260529.json` (★ P1-A 정합)
- `memory/events/task-2706+1.decision.json` (★ Maat #8 chair_authorization_id propagation PASS evidence)
- `memory/events/task-2705+1.dispatched-20260528.json` (★ fallback baseline 마지막 marker)
- `memory/events/task-2705+4.dispatched-20260528.json` (★ task-specific populate 시작 첫 marker)
- `memory/events/task-2706.dispatched-20260529.json` (★ P1-B 구현 dispatch marker)
- `memory/events/task-2706+1.dispatched-20260529.json` (★ P1-B Maat dispatch marker)
- `dispatch/__init__.py` L3033-3047 / L4074-4088 / L265 (★ caller 결선 — task-2705+3 f0bfcda1)

---

## 15. Out-of-Scope (★ 명시 강제)

- ★ P1-C (actor attribution contract) 구현 — task-2708 후보 / 회장 별도 인가 대기
- ★ P2 finish-task routing (실행 계층 정상화) — 별도 task 후보
- ★ session-watchdog L451 minimal patch — 회장 별도 인가 대기
- ★ reports/task-2705.md sha drift filesystem audit — 회장 별도 인가 대기
- ★ scope-guard `main..HEAD` → `lock_sha..HEAD` 패치 — 회장 별도 인가 대기
- ★ Goal-to-Done / PHASE_AUTO / Core-Work 이원화 — 절대 금지 (회장 verbatim 정합)

---

## 16. Chair Decision Pending (★ 회장 발사 인가 대기 영역)

1. ★ 본 task md 초안 승인 여부 (★ FORMALIZATION_COMMIT_ONLY 범위 정합 확인)
2. ★ chair_authorization_id 최종 확정 (`CHAIR-AUTH-TASK-2707-DISPATCH-MARKER-WRITER-FORMALIZATION-260529` 후보)
3. ★ dev1-team (executor 헤르메스) 단일 dispatch 인가 (★ ANU 자체 dispatch 금지)
4. ★ task-2707+1 (verifier dev2 오딘) 발사 인가 — 본 task 종료 후 별도

---

## 17. Sentinel

★ 본 task md = task-2707 초안. 회장 발사 인가 전 dispatch 0. body byte 0 변경 강제. 끝

## goal_assertions (auto-generated)
- `pytest tests/harness/test_v36_dispatch_marker_contract.py`
- `pytest tests/harness/test_v36_dispatch_marker_contract.py`
