# P0-B result.json Schema Contract

**날짜**: 2026-06-16
**출처**: task-2755 (P0-B scope-limited ACTIVE wiring, Wiring2)
**validator**: `dispatch/anu_executor_provenance.py::validate_executor_provenance` (14조건)

---

## result.json 필수 필드

| 필드 | 타입 | 설명 |
|------|------|------|
| `task_id` | str | 비어있지 않은 task ID (예: `task-2755`). path traversal 문자 금지. |
| `completion_signal` | str | 반드시 `"EXECUTOR_RESULT_WRITTEN"` |
| `terminal_status` | str | `PASS`, `PASS_WITH_WARNINGS`, `PARTIAL` 중 하나 |
| `capsule_sha256` | str | dispatch capability snapshot `source_sha256` 와 일치해야 함 |
| `report_path` | str | **비어있지 않은 str 필수** (아래 규칙 참조) |
| `collector_envelope` | (부재) | **부재** 여야 provenance-path 진입 조건 충족. 존재 시 envelope 경로 사용. |

---

## report_path 규칙

`report_path` 는 다음 세 형태를 **모두 허용**한다(비어있지 않은 str이면 schema 통과):

1. **(a) self-ref**: `report_path` 가 result.json 자기 자신의 경로를 가리킴.
   - result-only task(별도 report 파일 미생성)에서 허용.
   - `report_path_self_ref(report_path, result_path)` 로 판정 (`dispatch/anu_executor_provenance.py`).
2. **(b) 실제 존재 report 파일**: `os.path.exists(report_path)` 또는 `os.path.exists(root/report_path)` 가 True인 파일 경로.
3. **(c) 그 외 비어있지 않은 report 참조 문자열**: 위 두 조건 외의 비어있지 않은 str (예: 상대경로 `report.md`).

**금지**: `missing`(필드 부재) 또는 `빈 str`(`""`, 공백만) → `schema_fail`.

---

## 금지 필드 (조건11~14 hard-fail)

| 필드 | 이유 |
|------|------|
| `callback_schedule_created: true` | executor 직접 callback cron 등록 금지 (조건11) |
| `schedule_created_by_executor: true` | executor 직접 callback cron 등록 금지 (조건11) |
| `callback_fired_by_executor: true` | executor 직접 callback fire 금지 (조건11) |
| `self_collector: true` | self-collector 차단 (조건12) |
| `owner_key_proof_present: true` | dev self-key claim 차단 (조건13) |
| raw key literal (예: ANU/dev key 실제 값) | `forbidden_key_literals` 주입 시 hard-fail (조건14) |

---

## validator 14조건 요약

```
조건0  task_id path traversal 방지 (보안 whitelist)
조건1  dispatch record 존재 (memory/capabilities/<task_id>.json)
조건2  task_id 일치 (result ↔ capability snapshot)
조건3  capsule_sha256 일치 (result ↔ snapshot.source_sha256)
조건4  source path ∈ inbox (memory/events/p0b_inbox/<task_id>.result.json)
조건5  schema 유효 (report_path 비어있지 않은 str 필수, self-ref/존재파일/그 외 모두 허용)
조건6  terminal_status ∈ {PASS, PASS_WITH_WARNINGS, PARTIAL}
조건7  completion_signal == "EXECUTOR_RESULT_WRITTEN"
조건8  result sha256 계산 (source_result_sha256)
조건9  activation epoch 이후 result (mtime >= activation_epoch)
조건10 duplicate 없음 (ledger_reader 주입 시)
조건11 callback schedule claim 없음
조건12 self-collector claim 없음
조건13 dev self-key claim 없음
조건14 raw key literal 없음 (forbidden_key_literals 주입 시)
```

전부 통과 → `ProvenanceResult(ok=True)` → ANU `collector_result(adopted_via="provenance")` 생성.
