# Gate-D 운영 하드닝 실행 계획

## Status
Planning only. Pending consensus review and execution handoff.

## Goal
실제 Telegram Gate-D 수동 리허설 전에 자동으로 해결 가능한 운영 차단 문제를 모두 제거하고, 인간만 수행할 수 있는 계정·토큰·수동 리허설·실고객 활성화만 명시적으로 남긴다.

## Principles
1. Canonical owner는 감사·승인 신원이고 Topic 59 review address는 ingress 인증 표면이다. 둘을 혼용하지 않는다.
2. 전송은 reservation-first, provider-at-most-once, unknown은 terminal이며 재전송하지 않는다.
3. 모든 변경 권한은 transition 직전 refreshed full triple과 current digest로 재검증한다.
4. 운영 진입점은 host-owned typed API/Telegram menu뿐이며 REPL·JSON 직접 편집은 증거로 인정하지 않는다.
5. 자동 검증과 수동 Gate-D/실고객 rollout 승인을 분리한다.

## Decision Drivers
1. 오발송·중복발송·stale authority를 provider 호출 전에 차단할 것.
2. 실제 운영자가 Topic 59에서 재현 가능하고 한국어 상태 문구만 보고도 안전한 결정을 할 수 있을 것.
3. 장애·재시작·provider 불확실성 뒤에도 append-only 증거로 조정 가능할 것.

## Options
### A. Existing callbacks에 최소 패치
- 장점: 변경량이 작다.
- 단점: lifecycle 시작 진입점, 권한 역할 분리, schedule receipt 복구가 계속 흩어진다.
- 판정: 일부 단기 수정에만 사용하고 전체안으로는 기각.

### B. Host-owned adaptive operator control plane + shared transition/reconciliation contracts (Chosen)
- 장점: Topic 59 인증, canonical owner audit, proposal/card lifecycle, delivery/recovery를 한 경계에서 검증한다.
- 단점: gateway/profile/docs/tests 여러 표면을 함께 수정해야 한다.
- 선택 이유: 실제 Gate-D가 production path를 그대로 검증하며 REPL 우회를 제거한다.

### C. Canonical owner topic을 Topic 59로 변경
- 장점: 현재 callback equality를 단순히 만족한다.
- 단점: canonical audit identity를 UI 위치에 종속시키고 normal flow와 충돌한다.
- 판정: 보안·모델 경계 훼손으로 기각.

## Scope and Workstreams

### WS1 — Review identity and callback authorization
Targets: `gateway/platforms/telegram.py`, `nutrition_coaching.py`, config model/tests.
- configured Topic 59 review triple을 ingress 인증에 사용한다.
- refreshed canonical owner full triple은 lifecycle actor/audit identity로 전달한다.
- wrong user/chat/topic, owner rotation, canonical owner topic != review topic positive path를 검증한다.
- callback token은 opaque/bounded/current revision만 허용한다.

### WS2 — Host-owned operator entrypoint/menu
Targets: Telegram adaptive handlers/menu, coordinator, gateway tests.
- Topic 59 전용 typed actions: create/publish/view/edit/hold/release/approve/activate/delivery-enable/delivery-revoke/send/reconcile.
- customer key는 live enabled registry에서 고르고 KST evaluation day는 host가 결정한다.
- raw destination/text/digest 입력, REPL, generic append를 금지한다.
- 각 카드에 current revision/digest/state를 표시하고 stale callback을 명시적으로 거부한다.

### WS3 — Safe delivery UX and reconciliation
Targets: Telegram callback result mapping, adaptive workflow, tests.
- `delivery_unknown`: “전송 결과를 확인할 수 없습니다. 다시 보내지 마세요. 조정이 필요합니다.”
- provider receipt persisted but audit pending: “고객 전송 영수증 확인. 재전송 금지. 감사 기록 복구 필요.”
- delivered/sent_audited만 성공 문구 사용.
- opaque delivery ID만 operator evidence에 노출한다.
- double tap/restart/reconcile은 provider 0 또는 총 1회를 증명한다.

### WS4 — Authority TOCTOU hardening
Targets: `set_persisted_delivery`, `activate_latest`, `rollback_latest`, focused tests.
- lifecycle/store lock 안에서 live registry refresh → supplied full actor triple 비교 → source/registration/consent/activation/config pins 재검증 → append.
- owner가 검증 직후 바뀌면 feature epoch/overlay/prepared/committed/provider 모두 0.
- profile admin authority TOCTOU는 current live loader가 downstream을 fail-safe 차단하도록 유지하되, Gate-D 전 preflight에서 stale approval을 거부하고 후속 강화 항목을 문서화한다.

### WS5 — Scheduled prompt durable intent/receipt
Targets: `customer_schedule.py`, Telegram scheduled tick, tests/runbook.
- claim-only 구조를 prepared/sending/delivered/unknown/audited intent ledger로 확장한다.
- provider 호출 전에 immutable destination/body/day를 예약한다.
- receipt 저장 후 audit; timeout/unknown은 terminal no-retry.
- provider receipt가 있으면 resend 없이 reconcile한다.
- 기존 claim migration은 additive/read-compatible, corrupt ledger fail-closed.

### WS6 — Isolated test-profile preflight
Targets: supported setup/preflight code, test fixture/config template, runbook/tests. Never manipulate real credentials/accounts.
- adaptive config required fields, delivery=false, private modes/no symlink.
- fresh disposable customer with current KST plan window.
- operator/customer/trainer distinct identity requirement and separate bot documented/validated.
- approved policy/food-catalog/derived constraints/registration/activation receipts and canonical reconciliation required.
- bounded receipt returns only counts/digests/epoch; no Telegram IDs/raw data.

### WS7 — Gate-D and operator docs
Targets: profile `PILOT_RUNBOOK.md`, Korean guide, `HANDOFF.md`, `choi_coach_system_report.html`.
- obsolete direct `enable` and direct registry edits removed; guarded activate only.
- stale counts replaced or explicitly historical.
- separate fresh revisions: P2 success, P3 timeout/unknown, P4 provider-success/audit-failure, P5 revoke-after-reservation, P6 owner-change.
- actual KST rollover, stale click, duplicate tap, incomplete check-in, low adherence, safety, disable/restart mandatory rows.

## Execution Order
1. Freeze snapshot and map existing public contracts/tests.
2. WS1 identity split and WS4 authority TOCTOU first; they gate all later actions.
3. WS2 host entrypoint/menu on the hardened authority boundary.
4. WS3 delivery UX/result typing.
5. WS5 scheduled prompt receipt ledger/recovery.
6. WS6 preflight and WS7 documentation/migration.
7. Focused tests per workstream, then full profile/gateway regression.
8. Cleaner → frozen Architect + executor QA/red-team → terminal Critic.
9. Leave manual Gate-D checklist pending; do not touch real accounts or activate customers.

## Compatibility and Migration
- Existing canonical EventStore, draft outbox, adaptive ledgers, callbacks, and normal customer/trainer routes remain authoritative.
- New schedule delivery ledger is additive; old claims are imported as conservative unknown/claimed state and never blindly resent.
- Existing callback tokens remain bounded but stale/unknown tokens reject; no dead aliases.
- `food-catalog.json` remains canonical; `catalog.json` validated migration-read fallback only.

## Acceptance Criteria
1. Topic 59 configured review actor can operate when canonical owner topic differs; all wrong triples reject with zero lifecycle/provider rows.
2. Supported live menu can create and publish a production proposal without REPL/direct file edits.
3. Every operator action delegates to canonical lifecycle and exact latest revision/digest.
4. Unknown and audit-pending Telegram messages are unambiguously no-retry/reconcile; success only for delivered/audited.
5. Owner change injected after first auth in enable/activate/rollback leaves feature/overlay/transition/provider unchanged.
6. Scheduled prompt timeout/restart never duplicates; receipt reconciliation sends zero times; corrupt ledger blocks.
7. Preflight rejects missing config/artifacts, stale window, same-role identities, unsafe modes/symlinks, and delivery=true.
8. P2–P6 Gate-D script has separate immutable revisions and exact expected Telegram/ledger/provider outcomes.
9. Automated red-team covers wrong routing, stale/double clicks, KST rollover, incomplete, low-adherence, safety, disabled/restart.
10. Full profile and gateway suites/compile gates pass; Architect CLEAR/APPROVE, QA/e2e/red-team pass, terminal Critic OKAY.
11. Real-customer activation/delivery remains disabled and manual Gate-D remains pending.

## Verification Plan
### Unit
- address-role resolver, result-to-Korean-message mapping, owner refresh comparison, schedule ledger schema/digest/state transitions, KST day/window, preflight validators.

### Integration
- Topic 59 != owner topic positive route; wrong triple negatives; menu create→edit→approve→activate; persisted enable/revoke; unknown/audit reconcile; schedule provider receipt/no-resend; corrupt journal.

### E2E/Red-team
- disposable fixture with three identities and separate bot stubs.
- P2 success exactly once; P3 timeout terminal; P4 receipt/audit recovery no resend; P5 revoke barrier provider0; P6 owner rotation provider0.
- stale callback, duplicate send, 23:59→00:01, incomplete draft, low adherence operator-only, safety zero-send, disable/restart.
- actual Telegram/manual proof remains human-only and is not fabricated.

### Observability
- opaque event/transition/delivery IDs, state, epoch/digests, provider call count; never token, raw check-in, Telegram triple, or customer text.

## Pre-mortem
1. **Role conflation returns:** normal tests pass but Topic 59 real operator rejects. Mitigation: owner-topic-different positive integration is mandatory.
2. **Provider sent, UI says retry:** duplicate customer message. Mitigation: typed delivery outcome mapping; unknown/audit-pending no-retry wording and receipt reconciliation tests.
3. **Schedule timeout loses or duplicates prompt:** claim lacks receipt truth. Mitigation: reservation/receipt journal and restart failure injection.
4. **Stale owner transition commits:** old operator changes delivery/overlay. Mitigation: append-adjacent refreshed full-triple equality under lock.
5. **Gate-D contaminates real routes:** test config points to production. Mitigation: preflight proves isolated registry/bot/distinct identities, main customers empty/delivery false, and refuses real destinations.

## Human-only Remaining Work
- Create/manage Telegram test accounts, bot token, groups/topics, and distinct identities.
- Enter secrets through approved secret storage.
- Execute the live Gate-D Telegram rehearsal and capture private opaque evidence.
- Explicitly approve real-customer rollout after all rows pass.

## ADR
### Decision
Adopt a host-owned adaptive operator control plane that separates review-surface authentication from canonical owner audit identity, uses durable exactly-once outcome ledgers, and leaves live Gate-D to the human owner.
### Drivers
Mis-send prevention, reproducible production-path rehearsal, crash/restart reconciliation.
### Alternatives considered
Minimal callback patch; canonical owner moved to Topic 59; ad-hoc REPL. Rejected for incomplete boundary coverage or authority corruption.
### Consequences
More explicit lifecycle and ledger code, but fewer hidden fallbacks and a reproducible one-session Gate-D.
### Follow-ups
Profile-admin approval authority transaction may be further unified after Gate-D; no such residual may bypass gateway revalidation.

## Intent Reconciliation
- User wants all automatable work completed autonomously, then one more workflow/red-team pass and fixes.
- Manual account/token/Telegram actions and actual Gate-D remain for the user.
- No real-customer activation or delivery is authorized by this plan.

## RALPLAN-DR
- Mode: deliberate.
- Chosen option: B, host-owned control plane plus durable reconciliation.
- Main tension: narrow patch speed versus coherent operational authority; coherence wins because Gate-D must exercise production paths.
- Completion boundary: code/tests/docs/reviews complete, manual Gate-D pending.
