# Dual-coach connection flow — brownfield implementation plan

## Summary
Implement the minimum typed handoff from a trainer's first agreed session record to customer-scoped nutrition strategy and operator review: accept an initial date/time plus both confirmations; start a safe schedule-unconfirmed baseline and morning check-ins immediately; replace that baseline with a schedule-confirmed weekly strategy after operator confirmation; and surface high-risk, safety, and one-reminder non-response cases for operator review. The design remains customer-isolated, append-only, and approval-gated; no AI/customer auto-send and no trainer calendar management.

Repository evidence: `checkin_cli.models.Event` is the append-only typed event discriminator; `WizardService.start_trainer_session()` and `build_trainer_session_event()` already provide a customer-scoped trainer-session path; `propose()`/`compile_weekly_carb_cycle()` already compile deterministic weekly targets from schedule inputs; `customer_schedule.py` has delivery reservations/fences; the local console only exposes explicit draft edit/approve/send operations. `history_imports._baseline_event()` emits archived `history_imported` events without an `import_manifest`, while `adaptive_nutrition.canonical_snapshot()` skips history rows without `import_manifest.observation_kst_day`; compatibility must be resolved before any synthetic history.

## Intent Diff
- **Add:** minimal first-session reference (`date`, start time, customer confirmation, trainer confirmation, last change note) and its state transitions.
- **Add:** immutable baseline/confirmed nutrition-strategy revisions and operator-review items tied to canonical event IDs, policy versions, and customer scope.
- **Extend:** trainer-session wizard, morning check-in capture, canonical projection, and operator review evidence to consume those records.
- **Preserve:** exact identity boundaries, registered `CanonicalEventTransaction`, append-only corrections via `supersedes`, explicit latest-revision approval, and at-most-once delivery protections.
- **Do not add:** trainer availability/calendar features, detailed schedule-change audit trails/conversation retention, direct storage edits, synthetic baseline history before schema compatibility, or automatic customer messages.

## RALPLAN-DR
### Principles
1. Treat each customer’s registered canonical EventStore and nutrition-plan journals as the sole writable truth; all new facts are typed, customer-scoped, append-only events/projections.
2. Model only the coaching-relevant current schedule reference and one last-change note; do not turn the handoff into calendar or trainer-workflow software.
3. A safe schedule-unconfirmed baseline is useful, but it must never claim workout-day targeting or replace an operator-approved confirmed strategy silently.
4. Safety signals and delivery uncertainty fail closed: pain or inability to train creates review independent of a numeric risk score; AI output cannot reach a customer without the existing explicit approval/send lifecycle.
5. Reconciliation and historical data are evidence-driven: fix the importer/projection contract before creating fixtures, synthetic history, or derived strategy evidence.

### Decision Drivers
1. Reuse the existing exact-triple/customer-runtime/canonical-transaction boundaries rather than create a parallel customer ledger.
2. Allow coaching to start before a trainer records the first schedule without producing ungrounded workout-day nutrition advice.
3. Make every review reason deterministic, idempotent, and inspectable while preserving the operator’s final approval and send authority.

### Options
- **A — Add typed dual-coach events and a customer-local projection on the existing canonical EventStore; feed confirmed schedule data into the existing adaptive proposal/cycle APIs.** Pros: preserves isolation, append-only correction semantics, existing safety and approval paths, and one source of truth; supports an explicit unconfirmed baseline. Cons: requires extending the event schema/projection and coordinated gateway wiring. **Chosen.**
- **B — Reuse `AdaptiveRegistrationInputs.training_schedule` as the only schedule record and require it before any strategy.** Pros: smaller surface and existing `CustomerTrainingScheduleEntry` validation. Cons: it is registration input, requires at least one dated entry, cannot represent customer/trainer confirmation or a last-change note, and blocks the required unconfirmed baseline.
- **C — Build a separate dual-coach schedule/review store or trainer calendar service.** Pros: isolated implementation surface. Cons: duplicates identity/approval/audit boundaries, risks cross-customer joins and double truth, and violates the no-calendar non-goal.

## In scope / out of scope
**In scope:** first agreed-session capture; baseline versus confirmed strategy state; the specified six morning fields; deterministic risk/review routing; one reminder then non-response review; last schedule-change note displayed as strategy/review context; adapter/host wiring that preserves current approval/send gates.

**Out of scope:** trainer availability, recurring calendars, booking, calendar sync, detailed change audit/history, raw conversation capture, autonomous medical/nutrition advice, automatic customer delivery, production activation, and synthetic historical data until the importer/projection gate passes.

## File-level changes
### Canonical domain and persistence
- `checkin_cli/models.py` — extend `EventType`, `Event` discriminator/payload validation, dedupe-key builders, and typed payload models/builders for: first schedule reference; baseline/confirmed/superseded nutrition strategy; and operator review item. Define bounded fields and explicit status/reason/policy-version identities. Reuse `Safety`/`SafetyReason`; do not store raw chats. Preserve `Event` immutability and correction rules.
- `/home/cube/.hermes/profiles/physique-coach/contracts/checkin-event.schema.json` — update the external schema in lockstep with `Event` if the canonical contract governs new payloads. `tests/test_event_contract.py` currently validates this exact file.
- `checkin_cli/store.py` — extend canonical append/rebuild/projection plumbing only through `CanonicalEventTransaction`/registered `EventStore`; add idempotent typed entry points rather than raw JSON writes.
- `checkin_cli/history_imports.py` and `checkin_cli/adaptive_nutrition.py` — first reconcile `HISTORY_IMPORTED` event shape with `canonical_snapshot()`’s `import_manifest.observation_kst_day` requirement. Select one canonical representation, validate it at the model boundary, preserve existing archived events/revisions, and make historical projection deterministic; do not fabricate history.
- `checkin_cli/customer_admin.py` — align `_reconciliation_event_plan()` and source-day mappings with the resolved history contract so the new/legacy projections retain epoch, root-event, and source-day idempotency.

### Dual-coach capture and strategy projection
- `checkin_cli/wizard_models.py` — add only the flow/session state needed for initial schedule entry or extend `WizardFlow.TRAINER_SESSION` without weakening exact owner/topic/customer context.
- `checkin_cli/wizard.py` — extend `TRAINER_STEPS`, parsing, `_trainer_payload()`, `_save()`, and correction behavior to capture the required date/time/dual confirmation/current-note fields. Extend `MORNING_STEPS`, `_parse_field()`, and `_checkin()` for explicit fatigue, pain, exercise-possible, and meal-plan-deviation capture; keep existing safety classification before save and save only canonical events.
- `checkin_cli/customer_coaching.py` — retain `CustomerTrainingScheduleEntry` as confirmed strategy input; add a bounded typed bridge only where the confirmed first-session reference must become planned-session input. Do not change `CustomerSpec.schedule`, which is the reminder cadence, into a trainer calendar.
- `checkin_cli/adaptive_nutrition.py` — add a strategy-state projection/factory around `propose()` and `compile_weekly_carb_cycle()`: unconfirmed baseline contains only meal principles, hydration, protein, and regularity; confirmed strategy includes seven-day training/rest categories, exception behavior, last change note, and review-required state. Version strategy/risk policy inputs and use canonical IDs/digests for idempotency.

### Review, reminders, and adapter integration
- `checkin_cli/customer_schedule.py` — add a customer-scoped one-reminder/non-response evaluator only if it can use the existing KST fence/reservation ledger without sending. It must record/return a review candidate after exactly one durable reminder fact and never infer successful delivery from an unknown receipt.
- `checkin_cli/operator_console.py` — extend evidence/rendering with schedule status, last change note, strategy revision, and review reasons; keep edit/approve/send separate and preserve loopback token/customer-key validation.
- Gateway/host integration is outside the inspected `checkin_cli` tree but required for release: wire registered trainer exact-triple input to the new wizard action and route review cards through the host-owned Topic-59 `AdaptiveOperatorService` described by `PILOT_RUNBOOK.md`. The implementation owner must locate its concrete gateway symbols before editing; it must not add a generic route or a new send path.

### Tests
- `tests/test_event_contract.py` — schema/discriminator, immutable typed payload, dedupe, and supersession cases.
- `tests/test_wizard_domain.py` — trainer first-session entry/correction and morning six-field validation, including unauthorized/stale contexts.
- `tests/test_adaptive_nutrition.py` — unconfirmed baseline restrictions; confirmed seven-day cycle, rest/training categories, note propagation, and policy/risk version behavior.
- `tests/test_history_imports.py` — importer/projection compatibility and concurrent idempotency before any fixture generation.
- `tests/test_customer_admin.py` — reconciliation/source-day epoch preservation and cross-customer failure behavior.
- Add focused tests adjacent to `tests/test_customer_schedule.py` and `tests/test_operator_console.py` for one-reminder non-response review, unknown-delivery no-retry, operator evidence, and no direct send.

## Sequencing and dependencies
1. **Schema gate first.** Trace `history_imported` from `history_imports._baseline_event()` through `models.Event`, `adaptive_nutrition.canonical_snapshot()`, `customer_admin._reconciliation_event_plan()`, source-day mappings, and existing migration tests. Choose and document the single compatible historical observation-day representation. Implement/verify this compatibility before adding fixtures, generated history, or strategy projections.
2. **Define additive canonical contract.** Add typed schedule-reference, strategy, and review payloads/events, their validation, event-schema update, deterministic keys, and supersession model. Decide which state transitions require a new child revision versus a correction before wiring surfaces.
3. **Implement trainer and morning capture.** Add minimal wizard prompts/parsers/typed builders; require trainer and customer confirmations before schedule state becomes confirmed; preserve the last valid reference on incomplete/corrected attempts. Validate the six required check-in fields and classify safety prior to normal scoring.
4. **Build strategy and review projection.** Emit an unconfirmed baseline immediately after customer readiness; only an operator-confirmed schedule may create the confirmed strategy. Feed confirmed schedule data into the existing weekly-cycle API, persist the prior baseline as immutable history, and calculate versioned risk/review candidates with pain or training-impossible overriding score thresholds.
5. **Integrate reminder/review and operator surfaces.** Use a durable one-reminder fact plus the existing KST scheduling/reconciliation boundary to create a non-response review exactly once. Add schedule/reference/reason evidence to Topic-59/operator views while retaining explicit draft lifecycle and no-send defaults.
6. **Wire host routing and regression-test end to end.** Locate the gateway’s registered trainer/review symbols, add exact-triple actions, verify rejection/no-fallthrough behavior, and run the focused suite plus migration/recovery regressions. Keep real customers disabled and do not treat automated output as Gate-D completion.

Dependencies: (1) blocks all fixture/synthetic-history work and downstream projection proof; (2) blocks (3–5); (3) and confirmed registration artifacts feed (4); (4) feeds (5); only then may host wiring/release verification proceed.

## Acceptance criteria
1. A trainer’s initial record cannot become a confirmed schedule without a date, KST start time, customer confirmation, and trainer confirmation; malformed, unauthorized, stale, or duplicate input produces no new canonical state.
2. Before confirmation, a customer can submit the morning check-in and receive only a persisted baseline containing meal principles, hydration, protein, and regularity—never training/rest-day or session-timed prescriptions.
3. After an explicit operator confirmation, the confirmed strategy is a new immutable revision linked to the schedule reference; the baseline remains recoverable history; the confirmed revision includes seven daily training/rest categories, meal principles, exception behavior, operator-review status, and last change note.
4. Morning check-in requires body weight, sleep, fatigue, pain, exercise feasibility, and meal-plan deviation; range/enum failures do not persist. Existing typed safety reasons remain mandatory for held/unsafe events.
5. Score at/above the documented common threshold, any pain signal, exercise-impossible answer, and a missing response after one durable reminder each create one idempotent customer-scoped review item with a versioned reason. Safety override is independent of score.
6. A schedule correction creates a superseding record and updates only the current reference/last note; it does not create calendar availability, a recurring schedule, detailed change audit, or raw dialogue retention.
7. Customer A cannot read, derive, approve, or send customer B’s schedule, strategy, check-in, or review; trainer/customer/owner/review triples remain disjoint and invalid routing fails closed.
8. No baseline, confirmed strategy, risk score, review item, AI draft, scheduler, or console path sends a customer message automatically. Sending remains the existing latest-revision operator approval plus receipt/audit path.
9. Existing append-only history, source-day mappings, feature epochs, revisions, and delivery-fence/reconciliation semantics survive restart and schema migration; no synthetic history is added before the schema gate passes.

## Verification
No commands are run in this planning pass, per assignment. The implementation owner should execute these focused checks from `/home/cube/.hermes/profiles/physique-coach/workspace/checkin_cli` after the corresponding changes:
- `pytest tests/test_history_imports.py tests/test_adaptive_nutrition.py -q` — history/projection compatibility, cycle/baseline behavior, and no invented data.
- `pytest tests/test_event_contract.py tests/test_wizard_domain.py -q` — contract/schema, trainer/morning validation, safety, dedupe, and correction paths.
- `pytest tests/test_customer_schedule.py tests/test_operator_console.py tests/test_customer_admin.py -q` — reminder/reconciliation, explicit send boundary, customer isolation, and epoch/source-day recovery.
- `pytest -q` — full package regression only after focused suites pass.
- Add an adapter-level isolated test with distinct owner/customer/trainer/review triples proving trainer input reaches only its customer record, Topic-59 review displays the candidate, and provider call count stays zero until explicit operator send.

## Escalation/Risk Gate
**Stop implementation before fixture generation, migration, or rollout** when any of the following is true:
- `history_imported` still lacks a schema/projection-compatible observation-day contract, source-day mappings disagree, or archived history would be rewritten.
- New event payloads cannot be represented in both `models.Event` and the external JSON schema without an unambiguous discriminator/version migration.
- Gateway routing cannot prove exact trainer/review triple authorization and no-fallthrough before generic/model/media paths.
- Any proposed reminder/review implementation needs a provider call, raw registry/JSONL mutation, inferred receipt, or retry after unknown delivery.
- Operator evidence lacks a current revision/authority/epoch pin, customer consent/activation is invalid, or a path could auto-send customer content.

Escalate to an **architect** for the historical schema migration and gateway-owned Topic-59 contract, to an **executor** for the bounded library/test slices after those decisions, and to a **critic** before enabling any adapter path that touches delivery or cross-boundary review. A team/ultragoal is warranted only if gateway, profile schema, and checkin CLI must land as independently owned changes.

## Verification Plan
| Layer | Scenario | Expected proof |
|---|---|---|
| Contract | Build each new event, duplicate it, and correct it | Valid schema; one logical fact per deterministic key; correction uses `supersedes`; prior event remains |
| Import/projection | Reconcile existing archived history concurrently, then build a snapshot | Observation days map once; no row is silently skipped; no history is invented or mutated; epoch/source-day receipts match |
| Trainer handoff | Valid and invalid initial-session entries across exact triples | Only the registered trainer/customer scope can create it; four required fields gate confirmation; no calendar fields appear |
| Strategy | Start unconfirmed then operator-confirm schedule/correct note | Baseline is restrictive; confirmed child has exactly seven categories; baseline remains; latest note is visible |
| Check-in/review | Threshold boundary, pain, exercise-impossible, meal deviation, and one reminder/no response | Boundary score policy is stable/versioned; safety overrides score; each reason creates one review candidate |
| Isolation/delivery | Customer A/B and owner/trainer/review route permutations; unknown receipt restart | Unauthorized access fails closed; provider calls are zero before approval/send; unknown delivery is terminal/no retry |
| Regression | Full suite and existing Gate-D preflight read-only checks | Existing append-only, approval, fence, reconciliation, and disabled-live-delivery guarantees remain intact |

## Risks and mitigations
- **Importer/projection mismatch can discard historical observations.** Mitigation: make it the blocking first step; add concurrent regression tests and preserve old rows/epochs instead of rewriting them.
- **Schedule scope can grow into a calendar.** Mitigation: seal the payload to date, time, dual confirmation, current state, and one last-change note; reject recurrence, availability, booking, and detailed audit fields.
- **Risk scoring can under-triage safety.** Mitigation: version the score policy and hard-override review creation for pain and exercise-impossible; retain typed safety reasons.
- **Reminder handling can accidentally send or duplicate.** Mitigation: separate candidate creation from delivery; use the existing reservation/receipt/fence state and treat unknown outcome as terminal.
- **Parallel truth between registry training schedules and schedule-reference events can drift.** Mitigation: define one projection authority and an explicit, one-way confirmed-strategy bridge; reconciliation fails closed on disagreement.
- **Gateway integration can bypass isolation.** Mitigation: require exact triple tests and Topic-59 first-match verification before release; never introduce a generic action or raw destination parameter.
- **Operational approval can be mistaken for delivery.** Mitigation: keep strategy/review creation, draft approval, activation, delivery enable, provider receipt, and audited send as distinct states.
