# TASK2752 — Trust Boundary Clarification (read-only 분석)

상태: `P0B_REAL_DEV_RESULT_TRUST_BOUNDARY_AMBIGUITY_IDENTIFIED_ACTIVE_FALSE`
작성: 2026-06-15 KST / ANU / **read-only 분석(코드 수정 0·위임 0·구현 0)** / 회장 지시 TASK2752_..._DESIGN_CLARIFICATION

---

## 결론 (먼저)
**회장님 가설이 코드로 확정됩니다. re-signing(adoption)은 필요하지 않습니다.**
문제는 driver `process_one`이 **executor_result(A)에 `collector_envelope`(ANU-owned artifact, B/C 성격)를 필수로 요구**하는 단 한 곳(`anu_pickup_driver.py` line ~870)입니다. dev는 envelope를 만들면 안 되므로(ANU artifact·callback schedule 금지), **real dev result는 구조적으로 통과 불가**입니다. fixture는 envelope를 self-author해서 통과했을 뿐, real executor 흐름이 아닙니다.

---

## 핵심 질문 답: gate가 검증하는 대상은?
**세 대상이 한 경로에 섞여 있습니다 = 설계 혼선 확정.**
- `owner_proof_pickup_gate`(`anu_result_pickup_runner.py:1170`)는 사실 **dev result에 ANU proof를 요구하지 않습니다.** ② eligibility에서 오히려 **`owner_key_proof_present=false`를 요구**(dev result는 proof 없어야 정상), ③은 **runtime sealed ANU key**(="ANU runner가 실행 중인가" = C/callback fire 보호)를 검증. → 이 gate는 **객체 C(callback fire) 보호용**으로 올바르게 설계됨.
- 그러나 그 **앞 단계** `process_one`(`anu_pickup_driver.py:~870`)이 **executor_result(A)에 `collector_envelope` 필수**를 걸어 `owner_unprovable`/FOREIGN quarantine. → **여기가 A에 B/C 기준을 적용한 혼선 지점.**

답: **A. dev/executor result 자체**에 (B/C용) envelope 검증이 적용되고 있음.

---

## 분석 항목 (회장 지시 10)
1. **gate 적용 파일/함수**: `dispatch/anu_result_pickup_runner.py::owner_proof_pickup_gate`(1170) + `dispatch/anu_pickup_driver.py::process_one`(674, 특히 line ~870 envelope 검사).
2. **gate 대상**: owner_proof_pickup_gate = runtime ANU key(C) + result eligibility(proof 없음 정상). process_one = **executor_result(A)에 collector_envelope(B/C) 요구** ← 혼선.
3. **real dev result quarantine 정확 조건**: `process_one` line ~870 `envelope = result.get("collector_envelope"); if not isinstance(envelope, dict): return _quarantine("owner_unprovable", owner_class=OKC_FOREIGN)`. **task-2751 result에 `collector_envelope` 필드 부재**(실측 keys 확인) → 즉시 quarantine. (head_sha도 부재 — owner_proof_pickup_gate ④ freshness에도 걸렸을 것.)
4. **fixture 통과 vs real 차단 이유**: fixture builder(`legacy_skip_fixture_builder_2744.py`)는 `REQUIRED_SCHEMA_KEYS=("task_id","completion_signal","collector_envelope")` — **collector_envelope(dict)를 필수로 주입**. → A-path(owner_pickup_required·authoritative≠true·fired=false·schedule claim 없음) 진입 → owner_class=ANU. **real dev result는 envelope 없어 line ~870에서 차단.** 즉 fixture는 "ANU가 envelope를 미리 넣은 self-authored", real executor 흐름이 아님.
5. **"dev result는 ANU proof 없음 정상" 원칙과 충돌?**: owner_proof_pickup_gate는 충돌 안 함(proof 요구 0). **process_one은 충돌함** — dev에게 `collector_envelope`(ANU artifact)를 사실상 요구.
6. **adoption/re-signing 정말 필요?**: **불필요.** envelope 필수 가정만 분리하면 됨.
7. **필요한 것 = re-signing? 단계 분리? gate 위치 조정?**: **gate 적용 위치/대상 조정 + collector_result 생성 단계 분리**. re-signing 아님.
8. **callback envelope owner-proof와 executor result provenance 분리 가능?**: **가능.** owner_proof_pickup_gate(sealed ANU·C)는 callback fire 단계 전용으로 유지, executor result 수거는 provenance(dispatch record/task_id/capsule_sha/source/schema/terminal/sha256/epoch)로 분리.
9. **dev에 ANU token 없이 안전 수거 최소 설계**: process_one line ~870의 "envelope 부재 → quarantine"을 "envelope 부재 + provenance hard-fail 통과 → ANU가 collector_result 생성(envelope/owner_proof는 **ANU가** 채움)"으로. dev token 0.
10. **contract_split A/B 충돌?**: 충돌 없음. A-path는 "envelope 있는 owner_pickup_required"만 처리. envelope 없는 executor result용 분기를 A-path **진입 전**에 추가(provenance-path)하면 됨. B-path(claim)와 무관.

---

## 3객체 분리 (현재 → 올바른)
| 객체 | 정의 | owner-proof | 현재 코드 | 올바른 위치 |
|---|---|---|---|---|
| executor_result (A) | dev 작성·untrusted | 없음 정상 | ★process_one이 collector_envelope 요구(혼선) | provenance 검증만 |
| collector_result (B) | ANU 생성·수거 증명 | ANU-owned | 기존 writer 존재(source_result_sha256·owner_proof) | ANU가 envelope/proof 채움 |
| callback_envelope (C) | ANU의 callback/wake 실행 proof | 필수 | owner_proof_pickup_gate(sealed ANU) | 유지(callback fire 전용) |

---

## 설계 후보 (2개+)
### ★ Option B (권장) — provenance-based executor result 수거
- process_one의 "collector_envelope 부재 → quarantine"을 분리: **envelope 부재 dev result는 provenance 검증**(dispatch record·task_id·capsule_sha·source path·schema·terminal_status·result sha256·epoch) **hard-fail 통과 시 A-path 진입** → ANU가 collector_result(envelope·owner_proof는 ANU가 채움) 생성.
- owner_proof_pickup_gate(sealed ANU)는 그대로 = callback fire(C) 보호.
- dev token 0·re-signing 0·source 불변(sha256 연결). **변경 최소**(line ~870 분기 1곳 + provenance validator helper). 기존 collector_result 인프라·owner_proof_pickup_gate 재사용.
- 장점: trust boundary 정확 분리, surgical. 단점: provenance 검증을 hard-fail로 엄격히 짜야(세탁 통로 방지).

### Option A — explicit adoption receipt
- 동일 메커니즘이되 "adoption"을 1급 개념화: envelope 부재 dev result → ANU가 명시적 `adoption_receipt` 생성. Option B의 명시 버전(개념 가시성↑, 코드량 약간↑). 직전 packet이 이쪽.

### Option C — shared owner token (기각)
- dev가 ANU token 포함. self-collector 경계 흐림 → **기각**(회장 지시 일치).

**권고: Option B.** 가장 단순·정확하며 "executor result는 untrusted, owner-proof는 ANU artifact/callback에만"이라는 trust boundary를 코드에 그대로 새깁니다. Option A는 동일 효과의 명시 버전이라 보조 후보.

---

## 금지 설계 준수 (전부 회피)
dev에 ANU key/token 0 · dev가 owner-proof 포함 0 · dev callback schedule 허용 0 · self-collector 허용 0 · gate 완화로 아무 result 통과 0(provenance hard-fail) · source 변조 0.

## 완료 보고 (회장 형식 13항목)
1. **현재 gate 적용 위치**: `anu_result_pickup_runner.py::owner_proof_pickup_gate`(1170) + `anu_pickup_driver.py::process_one`(674, line ~870 envelope 검사).
2. **현재 gate 대상**: owner_proof_pickup_gate=runtime ANU key(C/callback fire)+eligibility(proof 없음 정상). process_one=executor_result(A)에 collector_envelope(B/C) 요구 ← 혼선.
3. **real dev result quarantine 원인**: process_one line ~870 — `collector_envelope` 필드 부재 → `owner_unprovable`/FOREIGN. (task-2751 실측: envelope·head_sha 부재.)
4. **fixture 통과 이유**: fixture builder가 collector_envelope를 필수 self-author → A-path 진입. = ANU 자작 envelope, real executor 흐름 아님.
5. **신뢰 경계 혼선 여부**: **혼선 확정** — A(executor result)에 B/C(envelope) 검증 적용.
6. **권장 설계**: Option B(provenance-based 수거, owner-proof gate를 callback 단계 전용으로 유지).
7. **권장하지 않는 설계**: Option C(dev에 ANU token — self-collector 경계 흐림) 기각. gate 완화로 무조건 통과 금지.
8. **필요한 코드 변경 후보** (Option B, surgical):
   - `anu_pickup_driver.py::process_one`: line ~870 "envelope 부재→quarantine"을 분기 — envelope 없으면 **provenance validator 호출** → 통과 시 수거 경로 진입(provenance-adopted 라벨), 실패 시 quarantine. envelope 있는 기존 경로 무손상.
   - 신규 순수함수 `validate_executor_provenance(result, dispatch_record_reader)`: dispatch record·task_id·capsule_sha·source path·schema·terminal_status·result sha256·epoch **hard-fail** 검증.
   - `anu_collector_result.py`: collector_result에 `adopted_via="provenance"` 라벨(source_result_sha256는 이미 존재). owner_proof/envelope는 **ANU가** 채움.
   - **opt-in flag(default OFF)** — 기존 self-authored 경로·ACTIVE=false 무손상.
9. **필요한 테스트 후보**: envelope 없는 dev result+provenance 통과→수거 / provenance 실패 8분기(dispatch record 없음·task_id·capsule_sha·source path·schema·terminal·sha256·stale epoch)→quarantine / fixture(envelope) 경로 회귀 무손상 / callback fire 시 owner_proof_pickup_gate 여전히 강제 / duplicate idempotent / raw key 0.
10. **기존 PR/기능 충돌 가능성**: 낮음. contract_split A/B(task-2746)=A-path 진입 **전** 신규 provenance 분기라 무충돌. owner_proof_pickup_gate 변경 0(C 보호 유지). legacy_skip/epoch cutoff(task-2744) 재사용. **단 process_one 핵심 분기 수정이라 회귀 범위 주의**.
11. **Critical risk**: ★ provenance 검증 부실 시 "untrusted→trusted 세탁" 통로 → **hard-fail + dispatch record 교차검증(capsule_sha·source path·sha256 다중)** 필수. dispatch record 위조 가능성 대비 다중 앵커. opt-in OFF 기본이라 활성화 전 영향 0. ACTIVE=true 아님.
12. **ACTIVE=false proof**: gate(driver/real_wake/callback_launch) absent·anu-pickup.path inactive·ANU cron 0·canonical==CODE_ROOT·read-only 분석(코드/cron/flag 무변경).
13. **다음 회장 결정 후보**: (A) Option B 채택→design packet 갱신→dev2 위임(merge 회장 승인) / (B) Option A(adoption receipt 명시 버전) 채택 / (C) 추가 분석/보류.

## 안전
read-only 분석. 코드 수정 0·위임 0·구현 0·cron 0·gate OFF·canonical==CODE_ROOT·ACTIVE=false. **분석 후 즉시 구현 안 함(회장 지시 준수) — 설계 판단만 보고.**

---
**최종**: `P0B_REAL_DEV_RESULT_TRUST_BOUNDARY_AMBIGUITY_IDENTIFIED_ACTIVE_FALSE`
**다음 회장 결정**: Option B/A 중 택1(또는 보류) → 선택 시 design packet 갱신 → dev2 위임. **re-signing 불필요 확정. ACTIVE=false 유지.**
