Dual-Coach / Gate-D hardening
최코치 시스템 운영 보고서
운영자가 현재 경계와 승인 상태를 읽는 비실행 보고서입니다. 명령·REPL·직접 파일 편집 절차는 포함하지 않습니다.
sha256:fc1fdfa0e228ad15458037b246245b540d5c5c27a67cd29ab0d1c834e7e2e952운영 모델
고객은 등록된 공간에서 체크인을 제출하고, 트레이너는 별도 공간에서 세션을 기록합니다. 시스템은 canonical 이벤트와 승인된 artifact를 근거로 운영자 검토용 초안을 만듭니다. 운영자가 최신 revision을 확인·수정·승인하고 별도로 전송해야 고객에게 전달됩니다.
Host-owned Topic 59 운영자 경계
설정된 review 공간은 모든 Telegram update 종류보다 먼저 예약됩니다. 텍스트·명령(알 수 없는 명령 포함)·미디어·위치·연락처·edited/channel post·무관 callback도 동일합니다. 정확한 configured review full triple만 AdaptiveOperatorService로 들어가며, 같은 chat/topic의 다른 사용자는 거절되고 customer/trainer/generic/model/media/provider 경로로 흘러가지 않습니다.
유일한 시작 버튼은 적응형 영양 검토입니다. 동일 handler의 정해진 alias가 있으며, host가 live registry에서 적격 고객을 선택하고 KST evaluation day를 결정합니다. 선택이 없거나 모호하면 중지합니다.
- 허용 action: select, create, view, edit_note, hold, release, approve, activate, delivery_enable, delivery_revoke, send, reconcile, back.
- 각 카드에는 테스트 전용 표지, customer label, KST day, 최신 revision/digest/state와 opaque ID만 표시합니다.
- raw destination/text/digest/calories/macros, generic append, REPL, direct registry/file edit, process-memory enable은 허용하지 않습니다.
Review identity와 canonical owner
Topic 59 review triple은 ingress 인증 표면이고, canonical owner full triple은 lifecycle actor·audit identity입니다. 두 주소가 다른 것이 정상일 수 있습니다. 변경 직전과 reservation 뒤에 owner/config/registry/consent/activation/source/artifact/epoch를 새로 비교합니다. mismatch는 append/provider 전에 0건으로 거절하거나, reservation 뒤에는 provider 0의 terminal unknown으로 남깁니다.
전송 결과와 안전한 한국어 UX
성공은 delivered와 sent_audited가 모두 있을 때만 표시합니다. evidence는 opaque ID와 상태만 노출합니다.
Adaptive canonical durable states are reservation-started (the receipt-free reservation row), consumed, receipt-started (the immutable provider receipt row), delivered, audit_pending, and sent_audited. The receipt-started row preserves the result of the single provider call; it is not a second provider call or resend.
| 상태 | 표시 문구 | 다음 원칙 |
|---|---|---|
| 성공 | 고객 전송과 감사 기록이 완료되었습니다. | provider 1회와 audit 완료가 확인된 경우만 성공. |
| 중복 조작 | 이미 처리된 전송입니다. | 추가 provider call 없음. |
| 결과 불명 | 전송 결과를 확인할 수 없습니다. 다시 보내지 마세요. 조정이 필요합니다. | terminal unknown; blind retry 금지. |
| 영수증·감사 대기 | 고객 전송 영수증은 확인됐습니다. 재전송하지 말고 감사 기록을 복구해 주세요. | 기존 receipt를 조정하며 provider call 0. |
예약 일정·tombstone·startup fence
예약 전송은 immutable destination/body/day와 reservation을 먼저 보존하고 provider를 최대 한 번만 호출합니다. 구형 reader가 새 intent를 재발송하지 못하도록 old-format .claim tombstone을 먼저 durable하게 만들고, 그 다음 새 scheduled ledger의 prepared row를 기록합니다.
- tombstone 없는 ledger row, ledger 없는 tombstone, corrupt/mixed-version pair는 scheduler를 막습니다.
- cutover fence가
preparing또는recovery_required이면 전송하지 않습니다. 모든 migration/reconciliation 뒤에만ready가 됩니다. - legacy claim은 receipt 부재만으로 unsent라고 추정하지 않고 보수적인 terminal
unknown과 claim digest로 보존합니다. - timeout·예외·malformed receipt·authority mismatch는 terminal unknown입니다. receipt가 확인된 경우에만 provider call 0으로 reconcile합니다.
- downgrade/rollback도 tombstone을 삭제하지 않으며, scheduler를 멈춘 recovery-only 상태로 유지합니다.
읽기 전용 Gate-D preflight
정본의 typed preflight는 config와 full review triple, Topic-59 충돌, private mode/symlink, isolated test profile·bot, 서로 다른 operator/customer/trainer identity, current KST window, 승인 artifact, canonical reconciliation, schedule/transition journal, feature flags를 읽기만 검사합니다.
결과는 boolean·bounded count·digest·epoch뿐입니다. 계정·secret·customer·artifact·consent·activation·delivery flag·ledger row·provider message를 만들지 않습니다. 하나라도 누락·stale·corrupt이면 테스트를 진행하지 않습니다.
Fresh independent P2–P6 revisions
공통 fixture는 disposable isolated customer, separate bot, 서로 다른 세 identity, current KST window, approved artifacts, canonical reconciliation, epoch active/delivery false, prior reservation 0입니다. 모든 행은 새 latest child revision으로 별도 승인·활성화하며 revision을 재사용하지 않습니다.
| Revision | 정확한 UI | 정확한 ledger rows | provider calls |
|---|---|---|---|
| P2 success | 완료 문구. 중복 탭은 이미 처리됨. | reservation-started → consumed → receipt-started → delivered → sent_audited 정확히 5개. receipt-started는 두 번째 호출이 아닌 불변 영수증 row. | 1 총합; duplicate 추가 0. |
| P3 timeout/unknown | 결과 불명·재전송 금지. | reservation-started → consumed → delivery_unknown 정확히 3개; receipt/delivered/audit 없음. | 1 총합; retry 추가 0. |
| P4 provider success/audit failure | 영수증 확인·감사 복구 필요, reconcile 후 완료. | 조정 전 5개(reservation-started → consumed → receipt-started → delivered → audit_pending), reconcile이 sent_audited 1개 추가. receipt-started는 두 번째 호출이 아닌 불변 영수증 row. | 1 총합; reconcile 추가 0. |
| P5 revoke after reservation | 결과 불명·재전송 금지. | reservation-started → delivery_unknown 2개, reason delivery_revoked_after_reservation; consumed/receipt/delivered/audit 없음. | 0. |
| P6 owner rotation | 결과 불명·재전송 금지. | reservation-started → delivery_unknown 2개, reason owner_changed_after_reservation; consumed/receipt/delivered/audit 없음. reservation 전 변경은 transition_aborted. | 0. |
P5/P6 timing barrier는 자동 transport 시험용이며 production 메뉴나 human Telegram session에서 재현한다고 주장하지 않습니다.
최종 cleanup와 출시 경계
- 각 P 행 뒤 ledger/provider counts와 receipt를 대조하고 terminal scenario evidence를 보존합니다.
- 모든 revision의 persisted delivery를 끄고 feature epoch/네 flag를 확인합니다.
- 활성 overlay를 rollback하고 disposable customer를 비활성화합니다.
- scheduler와 Gateway를 멈추고 immutable evidence만 private bundle에 남깁니다.
- 실제 고객 activation/delivery나 manual Gate-D 완료로 상태를 바꾸지 않습니다.
비공개 증거에는 runbook version/digest, booleans/counts/digests/epoch, opaque proposal/revision/session/transition/delivery IDs, 상태, provider call count, KST 시각만 기록합니다. secret, Telegram ID, 고객명, 원문 check-in, 고객 메시지, 의료 문장은 기록하지 않습니다.