# Gate-D 운영 하드닝 최종 Critic 검토

검토 입력: immutable `/home/cube/projects/richard/traning coach/.gjc/_session-019f8455-334a-7000-99ca-318dfd0e06b1/plans/ralplan/019f8455-334a-7000-99ca-318dfd0e06b1/stage-22-revision.md`; assignment pin `83e8864e33e25d33cddb955351ffd02d248cced88c9d017cca36d28ba1daffe4`. 해당 RALPLAN `index.jsonl`의 stage 22 revision receipt가 같은 절대경로와 SHA를 기록함을 확인했다. 제품 파일은 변경하지 않았고, 두 저장소의 현재 구현·테스트·문서를 읽어 대표 실행 경로를 시뮬레이션했다.

## Verdict
**OKAY**

## Claim Checks

- **Artifact pin verified.** Parent RALPLAN index는 stage 22 revision의 path와 SHA `83e8864e...daffe4`를 assignment와 동일하게 기록한다.
- **Prior Required Change 1 — 모든 Topic-59 ingress 선점: closed.** Revision 22는 text, known/unknown command, location, photo/video/document/audio/voice/sticker/contact, edited/channel post, unrelated callback을 모두 generic routing 전에 예약하고, review-space update가 generic `handle_message`, model/provider, vision/media cache, customer/trainer wizard, raw append에 도달하지 못하게 고정했다. Wrong triple은 review space에서는 거부되고 별도 등록 route가 있는 다른 공간에서만 자기 route를 따른다는 경계도 뒤의 “No review-space update” 절로 결정된다. `test_telegram_group_gating.py`와 adaptive tests의 downstream counter 0 acceptance가 명시됐다. 현재 `telegram.py`는 text handler에만 operator-space 선점이 있고 command/location/media/callback registration이 분리돼 있으므로 이 변경은 실제 결함 지점과 정확히 대응한다.
- **Prior Required Change 2 — exact opener/action/session/edit/publish recovery: closed.** Canonical opener는 `적응형 영양 검토`와 동일 함수의 `/adaptive_review` alias 하나이고, action enum은 `select/create/view/edit_note/hold/release/approve/activate/delivery_enable/delivery_revoke/send/reconcile/back`으로 고정됐다. Pre-proposal에서 null digest/revision을 허용하는 action은 `select/create`뿐이다. `edit_note`는 originating message/current digest에 묶인 10분 `awaiting_input`, exact reply actor/message, UTF-16 ≤4000, canonical `revise_note`만 허용한다. Card mutation은 session/card를 먼저 영속화하고 실패 시 `publish_pending`을 남겨 restart에서 동일 card만 publish하며 lifecycle mutation은 재실행하지 않는 것으로 결정됐다. `publish`를 별도 callback으로 두지 않는 선택도 명시돼 executor가 UX contract를 발명할 필요가 없다.
- **Prior Required Change 3 — complete action TOCTOU matrix: closed.** Revision 22는 전체 action enum을 named test 대상으로 만들고 모든 mutation에 review config/actor, canonical owner/version, enabled customer, consent/activation, registration/source/policy/catalog/constraints, proposal/revision, epoch, originating message/session pins를 요구한다. Before mint, after mint/before append, immediately before append, after reservation/before provider injection points와 exact zero-mutation/provider outcome이 정해졌다. Create/edit/hold/release와 transactional card publish가 이전 matrix 누락 없이 포함된다.
- **Prior Required Change 4 — old-binary-safe schedule cutover and final APIs: closed.** Chosen barrier는 모든 new reservation에 old-format immutable `.claim` tombstone을 dual-write하는 방식이다. Reader guard → scheduler-disabled schema marker/legacy migration under exclusive lock → prepared ledger+tombstone durable pair → writer enable 순서, partial-pair recovery/abort, downgrade prohibition, recovery-only rollback과 crash/mixed/old-reader tests가 정해졌다. Final APIs 여섯 개가 열거되고 `release_customer_task_claim` 및 mutating `retry`의 production export/command 제거가 명시됐다. 현재 `customer_schedule.py`의 literal claim, `__init__.py` export, `customer_admin.py retry` unlink, `telegram.py::_send_nutrition_coaching_tick` claim-before-send 경로를 모두 교체할 수 있는 충분한 cutover contract다.
- **Prior Required Change 5 — P2–P6 exact outcome/UI/cleanup and verification: closed.** P2–P6는 각각 새 latest child revision/approval/activation을 사용하며 exact Korean UI, ordered delivery rows, provider counts, P5/P6 linked terminal `delivery_unknown` reason을 가진다. P6의 이전 `rejected/aborted or unknown` 선택지는 제거됐고 transition-only owner rotation은 P6 send outcome이 아님을 분리했다. 각 row 뒤 reconcile/count assertion, delivery revoke, terminal receipt와 최종 overlay rollback/customer disable/scheduler+gateway stop/evidence retention까지 cleanup이 결정됐다. P2–P6 사이 필요한 enabled reservation state는 common fixture와 per-row revoke/reset 계약, action matrix의 persisted enable transition으로 결정 가능하다.
- **Prior Required Change 6 — canonical runbook and exact release gates: closed.** Canonical executable runbook은 profile `workspace/checkin_cli/PILOT_RUNBOOK.md`; root `PILOT_RUNBOOK.md`는 digest-pinned non-executable pointer로 고정됐다. Korean guide, HANDOFF, HTML은 commands를 복제하지 않고 canonical version/digest를 링크한다. Profile full pytest+compileall, gateway full `tests/gateway`, four-file focused suite, three explicit gateway modules의 `py_compile`, offline docs/preflight assertions가 실행 가능한 release gates로 명시됐다.
- **Shared authority/session contracts remain coherent.** Revision 21의 single full `review_operator`, typed `AdaptiveOperatorCapability`, authority→lifecycle→store lock order, persisted token-to-customer session resolution, pre-provider revalidation은 Revision 22의 ingress/action matrix와 충돌하지 않는다. 현재 callback은 canonical owner triple을 ingress actor와 직접 비교하고 all-customer scan을 수행하므로, gateway-owned `AdaptiveOperatorService`와 exact persisted session lookup은 대표 구현 경로에 맞다.
- **Referenced file verification.** Existing targets were verified: gateway `gateway/platforms/telegram.py`, `nutrition_coaching.py`, `nutrition_coaching_config.py`; gateway tests `test_adaptive_nutrition.py`, `test_nutrition_coaching.py`, `test_telegram_physique_checkin.py`, `test_telegram_group_gating.py`; profile `checkin_cli/customer_schedule.py`, `customer_admin.py`, `__init__.py`, schedule/adaptive tests and canonical profile runbook; root runbook, Korean guide, HANDOFF and HTML. New capability/service/session/scheduled-ledger schemas are planned additions and have their behavioral contracts in revisions 21–22.

### Representative implementation simulation

1. **Ingress/menu callback:** add the canonical full review config resolver, reserve configured Topic-59 chat/topic at the top of every registered update-kind path, and dispatch exact triple only to `AdaptiveOperatorService`. A service-minted `an1:<24hex>:<action>` token resolves one persisted customer/action/session rather than scanning `_by_key`; wrong/stale/forwarded/message-mismatched inputs terminate before generic or lifecycle paths. The plan supplies the opener, action enum, nullable pre-proposal rule, edit state and replay behavior.
2. **Authority-sensitive mutation/send:** ingress mints `AdaptiveOperatorCapability`; shared authority lock then lifecycle/store lock validates all pins immediately before append/reservation. Locks release, final same-order validation gates provider. A post-reservation revoke or owner rotation appends exactly one reasoned `delivery_unknown`, with no consumed/delivered/audit/provider. This maps directly over current raw-triple `set_persisted_delivery`, `activate_latest`, `rollback_latest`, and send paths without an unresolved API choice.
3. **Scheduled tick migration/restart:** replace claim/unlink with the six typed ledger APIs, create legacy tombstone before exposing each reserved task, record sending before the single provider call, persist receipt before canonical audit, and reconcile receipt-backed audit without resend. Legacy claims become terminal unknown, partial pairs block/recover, corrupt/mixed versions fail closed, and old binaries see tombstones. Current tick/CLI/export callsites are explicitly accounted for.

## Missing Evidence
None.

## Approval Boundary
Execution may proceed on the two codebases and the listed tests/docs using revisions 21–22 as the binding contract. Executors may choose ordinary internal class/file decomposition, but may not weaken exact ingress reservation, capability pins/lock order, session/message binding, terminal unknown/no-retry, dual-write tombstones, P2–P6 outcomes, or release gates. Real credentials/accounts, live Telegram Gate-D, real-customer activation/delivery, and owner rollout approval remain outside this approval and human-only.

## Summary
- **Clarity:** exact opener, action/session state, mutation matrix, ledger APIs, UI and ownership are specified.
- **Verifiability:** observable row sequences, provider counts, zero-downstream counters, crash points and exact commands are present.
- **Completeness:** all six prior Required Changes are concretely closed across code, migration, tests, docs and cleanup.
- **Big Picture:** production-path Gate-D remains isolated; automated work and human/live approval stay separated.
- **Principle/Option Consistency:** review-vs-owner identity, at-most-once/no-retry, append-only evidence and chosen option B remain aligned.
- **Alternatives Depth:** rejected minimal patch/owner-topic/REPL options and chosen persisted control-plane/dual-write mechanisms are explicit.
- **Risk/Verification Rigor:** generic ingress, stale authority, provider ambiguity, restart/downgrade, scenario contamination and rollback are each covered by named evidence.

## Required Changes
None.
