---
status: ready
intent: clear
review_required: false
approved: true
slug: dualcoach-production-readiness
execution_repository: /home/cube/projects/richard/hermes-agent
evidence_repository: /home/cube/projects/richard/traning coach
---

# DualCoach Production Readiness Plan

## Status

- Planning date: 2026-08-06
- Execution repository: `/home/cube/projects/richard/hermes-agent`
- Evidence repository: `/home/cube/projects/richard/traning coach`
- Source retrospective: `.omo/retrospectives/dualcoach-live-qa-2026-08-06.md`
- Planning notepad: `/tmp/ulw-20260806-dualcoach-production-plan.md`
- Active execution handoff: `.omo/start-work/dualcoach-production-readiness-handoff.md`
- Current release verdict: **GO for one explicitly consenting bounded pilot only**
- This artifact is a work plan only. It does not authorize a release, commit, push,
  reset, stash, clean, customer activation, or customer delivery.

## Objective

Produce one reproducible DualCoach release candidate whose complete customer lifecycle
works through the real Telegram surfaces without raw listeners, direct JSON mutation,
manual ledger deletion, direct service replay, or forced card republication:

```text
readiness/auth preflight
  -> customer onboarding and attestation
  -> owner/operator review
  -> readiness
  -> activation
  -> customer check-in
  -> automatic draft generation
  -> operator review and approval
  -> explicit customer send
  -> exactly-once receipt
  -> safe disable and cleanup
```

## Strict rerun amendment — 2026-08-17

The owner selected strict remediation after the Task26 release review rejected the
cross-candidate incident lineage. This amendment governs the replacement rehearsal and
supersedes conflicting candidate, migration, recovery, and evidence clauses below:

- Reuse Telegram actor `8527916639` only as a **new logical customer lifecycle** after
  an authenticated archive-first reset to an empty baseline. This is not a new Telegram
  identity and must never be described as one.
- The replacement lifecycle uses one final candidate and wheel from preflight through
  onboarding, activation, check-in, generation, review, explicit send, receipt,
  disable, and cleanup. No candidate replacement, polling recovery, direct replay, or
  post-start product/config repair is allowed. Any such need aborts and archives the
  attempt before another fresh run.
- Specification 22 and F5 references to a `migrated-session receipt` are superseded for
  this replacement rehearsal by candidate-bound **fresh-lineage provenance** proving
  empty baseline, new customer/session identifiers, no restored historical session
  bytes, canonical activation, and archive-first cleanup.
- Activation requires fresh start-of-lifecycle membership receipts for the customer
  against the complete configured staff-chat inventory. Every receipt must report
  `left` or `kicked` and bind candidate, wheel, customer, route inventory, observation
  time, and activation journal. Equivalent end-of-lifecycle receipts plus bounded
  membership-change evidence are required before cleanup PASS.
- Customer delivery uses a durable one-use capability bound to the final candidate,
  customer route, approved draft/revision, owner route, callback nonce, and rendered
  card. The global adaptive/automatic delivery flags remain false. The capability is
  consumed fail-closed for success, failure, timeout, and unknown-provider outcomes.
- The archive-first controller must use complete-write atomic persistence, detect
  session-owned monitors/log followers, and publish the preserved lifecycle to a
  verifier-enforced immutable retention target before the first cleanup mutation.
- Intended-surface evidence includes a hash-bound customer-DM artifact showing the
  single delivered message and correlating its chat, message ID, and timestamp to the
  durable exactly-once receipt.
- No human Telegram action begins until all fixes are sealed into the final candidate,
  Gate18–20 pass, the strict observer/controller dry-runs pass, and pre-lifecycle
  objective, security, trainer-free, quality, QA, and provenance reviews report
  `READY_STRICT_REHEARSAL`.

## Approved product decisions

### Privacy boundary

Use **customer Bot DM plus a customer-free staff review group**.

- Customer DM contains onboarding, activation notices, check-ins, and approved coaching.
- Staff-only Telegram surfaces contain owner/operator review artifacts only. Trainer collaboration is not a v1 capability.
- A Telegram forum topic is an organizational aid, not an authorization or privacy
  boundary.
- No customer joins the staff review group.
- Staff messages contain the minimum required customer data and refer to a canonical
  customer identity.
- Existing shared customer topics are migration sources only; they are not a supported
  production route.

Rejected:

- Multiple customers separated only by topics in one shared group.
- A customer-visible group containing owner/operator review material.
- Continuing the current shared-topic topology with documentation alone.

### Draft generation, approval, and delivery

Use **automatic durable draft generation after check-in**, with approval and send as
separate transitions:

```text
checkin_completed
  -> generation_pending
  -> generating
  -> draft_created
  -> approved
  -> delivery_pending
  -> sent_audited
```

- Telegram callbacks acknowledge immediately; they never wait for model generation or
  delivery.
- A durable worker owns generation and can resume after restart.
- `approved` never sends to the customer.
- Only the explicit `send_to_customer` action may create a delivery outbox entry.
- The delivery idempotency key is derived from customer, check-in revision, and approved
  draft revision.
- A repeated send returns the existing pending or sent result; it never creates a second
  customer message.

Rejected:

- A button-gated long-running model call inside the callback handler.
- Approval and customer delivery in one transition.
- Manual canonical service calls as a normal operator workflow.

## Non-negotiable invariants

1. Before activation, the customer is disabled and receives no coaching delivery.
2. Before operator approval, customer delivery count is zero.
3. After approval but before explicit send, customer delivery count is zero.
4. A successful explicit send creates exactly one provider message and one durable
   `sent_audited` receipt.
5. Wrong-role, wrong-chat, wrong-topic, stale-generation, and duplicate callbacks cause
   no state mutation.
6. Telegram callback acknowledgement failure cannot roll back an already committed
   transition or prevent the next card from being published.
7. Provider authentication failure is detected before customer work begins when
   possible, and leaves a retryable durable state when it occurs later.
8. Restart at every waiting boundary preserves progress and does not duplicate delivery.
9. User-visible completion is not inferred from a provider `200 OK`; it requires a
   durable receipt and observation on the intended customer surface.
10. Production release evidence must come from the exact immutable candidate being
    reviewed.
11. The owner/operator is the sole nutrition review authority in v1. No trainer marker,
    claim, invite, card, UI, route, data access, review, readiness, activation requirement,
    or safety-hold path exists or is required.

## Known evidence and blockers

The 2026-08-06 live QA proved substantial behavior but is not release evidence:

- The customer completed 22 onboarding fields and a 12-step check-in.
- The historical run used a trainer review workflow and is not v1 evidence.
- Its trainer-specific approval and wrong-role results are retained only as superseded
  historical context, not as release proof.
- One customer coaching message was eventually observed on the customer handset.
- The operator Telegram button path did not complete end-to-end.
- Owner readiness, activation, generation, and delivery required manual canonical
  recovery at multiple points.
- Shared topics exposed customer content to every group member with access.
- Startup polling, ForceReply anchoring, callback acknowledgement, DM topic
  normalization, Q7 navigation, provider credentials, generation claims, and delivery
  draining all failed during the run.
- Current execution worktree is dirty: 27 tracked files changed with 12,596 additions and
  742 deletions, plus 73 untracked files at planning time.

No evidence from that run may be promoted to a production PASS unless the same behavior
is reproduced from the immutable candidate through the normal surface.

### Historical evidence labels

The following prior artifacts contain trainer setup, routes, claims, cards, or review
branches. They remain append-only historical records, but are superseded and must not be
used as v1 release proof: Task 4 and Task 5 evidence, Task 15 and Task 16 receipts,
Task 18 Golden Path evidence, Task 21 topology evidence, and the existing Task22 receipt
and focused JUnit. The artifacts are not deleted or rewritten in this scope. Any later
release evidence must use the owner/operator-only authority, the frozen-session journaled
reconciliation, and the amended automation matrix.

## Retrospective blocker traceability

| 2026-08-06 blocker | Preventive implementation | Proof gate |
| --- | --- | --- |
| Polling startup discarded pending updates | Specifications 15 and 19 | PTB startup contract and restart matrix |
| Q1 ForceReply lacked the proven user anchor | Specifications 5 and 16 | Full DM onboarding and all-question render walkthrough |
| Shared customer topic exposed content to all group members | Specifications 4 through 6 | Privacy readiness matrix and isolated DM rehearsal |
| Hermes auxiliary OAuth expired during reconciliation/generation | Specifications 9 and 10 | Startup/activation/worker preflight and reauthentication-resume tests |
| Callback acknowledgement expired after a committed transition | Specifications 11 and 14 | Immediate-ACK and expired-query transition tests |
| OWNER DM supplied `message_thread_id=None` | Specifications 4, 5, and 19 | Canonical DM topic-0 and callback context matrix |
| Q7 navigation displaced choices `1` through `5` | Specifications 16, 18, and 23 | Full-question automated walkthrough and handset capture |
| Feature epoch and activation notice drain were hidden manual prerequisites | Specifications 6, 21, and 23 | Readiness preflight and intervention-free activation rehearsal |
| Operator button route did not finish end-to-end | Specifications 11, 12, 14, and 24 | Real staff-card generation, approval, and send |
| Generation claim required manual deletion after provider failure | Specifications 9, 10, and 19 | Lease expiry, auth failure, and restart recovery tests |
| Canonical service replay and forced card publication substituted for UI success | Specifications 2, 3, 18, 22, and 24 | Golden Path shortcut prohibition and fresh no-intervention rehearsal |
| Delivery completion was reported before a durable receipt existed | Specifications 13, 24, 26, and 27 | One provider message, one `sent_audited` receipt, and customer observation |
| Gateway metadata reported `running` for an absent PID and orphan followers remained | Specifications 17 and 25 | Process-state QA and post-disable cleanup audit |

## Execution constraints

- Work only in `/home/cube/projects/richard/hermes-agent`.
- Preserve unrelated user and agent changes.
- Do not run `git commit`, `git push`, `git reset`, `git stash`, or `git clean`.
- Use a dedicated test profile and synthetic customer identities.
- Keep all real customers disabled throughout implementation and QA.
- External authentication and Telegram actions require the normal approval and
  device-code procedures.
- Every behavior change is test-first.
- Tests must use events and bounded timeouts; fixed sleeps and timing-luck polling are
  forbidden.
- Each phase must finish with its listed evidence before the next phase begins.

### Minimum-operation v1 scope directive

The remaining work freezes the existing DualCoach lifecycle as a minimum operational
v1 baseline. It is production hardening, not a mandate to add customer-facing features.

- Implement only the smallest change required by the existing acceptance criteria and
  non-negotiable invariants.
- Do not add speculative abstractions, convenience features, future-feature scaffolding,
  or unrelated UX expansion.
- Do not skip or weaken a top-level checkbox; narrow its implementation to the
  operational behavior needed for privacy, durable state, restart recovery, explicit
  approval, exactly-once delivery, observability, and truthful cleanup.
- The immutable candidate manifest, Golden Path, Recovery Runbook, automated gates, and
  rehearsal evidence together define the v1 operating contract.
- After v1, every new feature must update the affected state transitions, runbooks,
  focused tests, candidate manifest, and release evidence instead of weakening this
  baseline.
- When scope is ambiguous, preserving the v1 invariants outranks adding capability.

#### Per-checkbox execution rule

Before editing for each remaining specification, the executor must record:

1. the existing implementation and evidence that can be reused;
2. the exact unsatisfied v1 acceptance condition;
3. the smallest product or test delta needed to close that condition;
4. optional capability, refactoring, and future work explicitly rejected from scope.

Apply these decisions as follows:

- If the live candidate already satisfies an acceptance condition, make no product edit;
  verify it through the required automated, manual, adversarial, and cleanup gates.
- If a condition has a confirmed gap, change only the owning seam and its focused tests.
- Do not rewrite stable behavior, create parallel infrastructure, or add a feature merely
  to make verification easier.
- Every DoneClaim and ledger receipt must distinguish reused behavior from new changes
  and list the rejected out-of-scope work.
- Candidate identity changes only when candidate bytes change. Reuse valid evidence when
  its exact candidate and covered behavior remain unchanged; rerun gates affected by a
  changed digest.
- Workers receive one bounded goal and one deliverable. Once the owning seam is known,
  repeated broad reconnaissance is not completion progress.

#### v1 completion and pilot handoff

- Completing this plan means **ready for a bounded real-customer pilot**, not automatic
  customer activation or delivery.
- Final evidence must leave rehearsal customers disabled, runtime state truthful, and
  the release candidate reproducible.
- The final verdict must include a short normal-surface launch sequence: production
  preflight, explicit go/no-go approval, one selected pilot customer, onboarding link,
  customer check-in, operator approval, explicit send, receipt observation, monitoring,
  and rollback/disable ownership.
- Real-customer activation remains a separate explicit post-plan operation.
- Optional trainer collaboration is deferred to a later version and is not represented by
  v1 scaffolding, configuration, UI, data access, or acceptance criteria.

---

## Foundation

### Specification 1 — Build the immutable-candidate manifest

Inventory every tracked and untracked DualCoach file in the current worktree and classify
it as:

- product implementation;
- automated test;
- migration/configuration;
- diagnostic-only instrumentation;
- temporary recovery code;
- unrelated change.

Primary inputs:

- `gateway/platforms/telegram.py`
- `gateway/platforms/telegram_nutrition_onboarding_*.py`
- `gateway/platforms/telegram_room_bootstrap*.py`
- `gateway/platforms/telegram_activation_notice.py`
- `gateway/platforms/physique_checkin.py`
- `checkin_cli/customer_admin.py`
- `checkin_cli/nutrition_onboarding*.py`
- `tests/gateway/test_telegram_nutrition_*.py`
- `tests/gateway/test_telegram_*checkin*.py`
- `tests/gateway/test_telegram_*callback*.py`
- `tests/checkin_cli/test_*nutrition*.py`

Deliverables:

- `.omo/evidence/dualcoach-candidate-manifest.md`
- Machine-readable file list with path, Git status, classification, owner, and reason.
- Explicit list of diagnostic/recovery files to remove before release review.

Acceptance:

- Manifest counts reconcile with `git status --porcelain --untracked-files=all`.
- Every untracked DualCoach implementation and test file is represented.
- Unrelated files are identified but not modified.
- Candidate identity is a content digest over the manifest and listed file bytes, not an
  unrequested Git commit.

### Specification 2 — Write the Golden Path contract

Create `docs/runbooks/dualcoach-golden-path.md`.

For every lifecycle step record:

- actor and canonical role;
- customer DM or staff-only surface;
- exact user action;
- expected durable state and receipts;
- expected Telegram artifact;
- evidence required to advance;
- failure condition;
- permitted retry behavior.

The Golden Path must not contain:

- raw `getUpdates` listeners;
- direct JSON edits;
- manual claim deletion;
- direct service replay;
- forced card publication;
- manual delivery drains.

Acceptance:

- The runbook covers every state from readiness preflight to cleanup.
- Every transition names one authoritative state store and one user-visible artifact.
- Approval and send are distinct entries.

### Specification 3 — Write the Recovery Runbook

Create `docs/runbooks/dualcoach-recovery.md`.

Define supported recovery for:

- expired Hermes OAuth;
- pending update at gateway startup;
- stale or expired callback;
- committed transition with failed callback acknowledgement;
- orphan generation claim;
- provider success before receipt persistence;
- gateway restart during onboarding, review, generation, or delivery;
- activation notice reservation without dispatch;
- stale gateway-state metadata.

Each recovery procedure must state:

- detection evidence;
- safe automated recovery;
- operator action, if unavoidable;
- idempotency boundary;
- prohibited direct mutation;
- success and rollback evidence.

Acceptance:

- No procedure depends on editing durable JSON by hand.
- Every automated recovery has a regression test assigned in a later phase.
- Recovery cannot create customer delivery before explicit approved send.

---

## Privacy and Routing

### Specification 4 — Introduce explicit customer and staff addresses

Replace overloaded group-topic addressing with distinct typed concepts:

- customer private-delivery address;
- owner/operator review address.

Parse and validate these at configuration boundaries. A customer address must be a
private chat. A staff address must reject customer membership as a readiness failure.

Likely touchpoints:

- `gateway/platforms/telegram.py`
- Telegram nutrition onboarding authority/address modules
- room bootstrap configuration and ledger projection
- customer registry and activation readiness validation

Acceptance:

- A group/topic cannot be configured as a production customer-delivery address.
- A customer cannot be activated while present in the configured staff group.
- Existing shared-topic test data is recognized as legacy and fails production readiness
  with an actionable migration message.
- Tests cover DM topic normalization to canonical `0`.

### Specification 5 — Migrate bootstrap and onboarding to customer DM

Preserve canonical identity and consent while moving customer-facing publication,
ForceReply, activation notice, check-in, and coaching delivery to the customer DM.

Keep owner/operator artifacts in the staff-only route. Store no customer phone-specific
state; use Telegram user/chat identity and canonical customer key. Trainer setup, UI, and
data access are prohibited in v1.

Acceptance:

- Onboarding Q1 through Q22 works in DM without forum thread IDs.
- ForceReply is anchored to a customer-authored message when available.
- Direct typed answers remain supported and safe.
- Only the owner/operator can answer or review nutrition onboarding from the staff surface.
- Staff cards never appear in the customer DM.
- No trainer marker, claim, invite, card, UI, route, or data-access path is configured.

### Specification 6 — Add privacy readiness and migration gates

Extend readiness/activation checks so activation is rejected when:

- the customer DM binding is absent or mismatched;
- the customer is a member of the staff-only group;
- staff review routing is absent;
- a legacy shared-topic route remains active;
- privacy consent or identity authority is stale.

Acceptance:

- Gate failures leave the customer disabled.
- Error output names the exact corrective action without exposing sensitive customer
  content.
- A migration test proves legacy shared-topic records cannot silently activate.

---

## Durable Generation and Review

### Specification 7 — Define the generation state machine and schemas

Create typed durable records for:

- `generation_pending`;
- `generating`;
- `draft_created`;
- `generation_failed`;
- `approved`;
- `delivery_pending`;
- `sent_audited`.

Each record must bind:

- customer key;
- check-in event/revision;
- draft revision;
- model/provider contract version;
- current owner/operator review actor and authority digest when the record is a review
  transition; worker identity remains separate for generation;
- predecessor digest;
- timestamps and bounded error metadata;
- idempotency key.

Acceptance:

- Invalid or skipped transitions are rejected.
- A new check-in cannot reuse an older approved draft.
- A stale operator card cannot approve or send a newer draft.
- State projection is deterministic from the event/receipt history.

### Specification 8 — Enqueue generation atomically with check-in completion

When a check-in becomes final, persist the finalized check-in and one generation job in
the same durable transaction or recoverable journal boundary.

Acceptance:

- Crash before commit leaves neither finalized check-in nor job.
- Crash after commit leaves one recoverable job.
- Duplicate finalization creates no second job.
- Customer delivery remains zero.

### Specification 9 — Implement the resumable generation worker

Move model calls out of Telegram callbacks. The worker must:

1. claim one pending job with a lease;
2. verify provider readiness and current revision;
3. build grounded model input;
4. validate schema and semantic grounding;
5. permit at most one bounded correction attempt;
6. persist a new draft revision;
7. update the staff operator card;
8. release or expire the claim safely on failure.

Acceptance:

- Restart resumes an expired claim.
- Invalid model output creates no draft.
- Authentication failure becomes `generation_failed` with a retry action.
- No manual receipt deletion is required.
- Logs contain IDs and gate names, not raw customer answers.

### Specification 10 — Implement provider authentication preflight

Run preflight:

- at gateway startup;
- before customer activation;
- before claiming a generation job.

Check the credential store actually used by the Hermes auxiliary provider, not only the
Codex CLI credential.

Acceptance:

- An invalidated credential is detected before activation.
- The operator receives an actionable reauthentication status.
- Reauthentication resumes the existing job rather than creating a new request.
- No secrets or OAuth tokens enter logs, cards, or evidence artifacts.

### Specification 11 — Build asynchronous operator cards

On check-in completion publish an operator card immediately:

```text
Check-in saved
Draft generation pending
```

Update or replace it as the durable state changes. Buttons by state:

- `generation_failed`: retry;
- `draft_created`: edit, regenerate, approve, approval_hold;
- `approved`: send to customer, revoke approval;
- `sent_audited`: no active buttons.

Callback data must bind action, request/draft revision, card generation, and a unique
render identity while remaining within Telegram's byte limit.

Acceptance:

- Every callback is acknowledged before long-running work begins.
- A stale card produces a clear refresh message and no mutation.
- Card recreation after restart retains the same durable revision semantics.
- No content-derived cache workaround substitutes for server-side revision validation.

### Specification 12 — Separate approval from delivery

`approve` persists an immutable operator approval receipt and transitions only to
`approved`.

`send_to_customer` revalidates:

- operator authority;
- customer active state;
- latest approved draft revision;
- current delivery route;
- absence or status of the idempotent outbox entry.

Acceptance:

- Approval produces zero customer messages and zero provider delivery attempts.
- Send cannot use a draft that changed after approval.
- Revoking approval before send prevents delivery.
- Wrong-role and wrong-route actions fail closed.

### Specification 13 — Add the exactly-once delivery outbox

Use an idempotency key derived from:

```text
customer_key + checkin_revision + approved_draft_revision
```

Represent pending, unknown-provider-outcome, and sent states explicitly. Do not retry an
unknown provider outcome until receipt reconciliation determines whether Telegram
accepted it.

Acceptance:

- Duplicate button presses create one outbox entry.
- Restart before send resumes one entry.
- Restart after provider success but before local receipt performs reconciliation and
  never blindly sends again.
- `sent_audited` includes provider chat/topic-or-DM, message ID, approved revision, and
  canonical payload digest.

---

## Telegram Reliability

### Specification 14 — Make callback acknowledgement best-effort and bounded

Commit state transitions independently from `query.answer()`. Acknowledgement occurs
immediately where possible; an expired query is logged as an acknowledgement failure,
not a workflow failure.

Acceptance:

- `BadRequest: Query is too old` cannot undo a committed transition.
- The next card is published from durable state even if acknowledgement fails.
- Tests use events rather than sleeps.

### Specification 15 — Preserve pending updates and make ingress observable

Keep polling startup non-destructive and add structured, privacy-safe stage logging:

```text
ingress -> authority -> route -> validation -> persistence -> publication -> receipt
```

Acceptance:

- Startup never uses `drop_pending_updates=True` for production polling.
- A captured-but-unacknowledged update survives restart.
- Every silent rejection has a reason code keyed by update ID.
- Logs do not contain customer answer text.

### Specification 16 — Make cards and navigation restart-safe

Unify card generation rules for onboarding, check-in, owner/operator review, and
operator delivery surfaces. Trainer cards and routes do not exist in v1.

Acceptance:

- Choice buttons and navigation buttons coexist.
- Q7 and every other choice question retain all choices.
- Old cards are rejected by durable generation, not by client-cache assumptions.
- A restart at each waiting state republishes or resumes exactly one current card.

### Specification 17 — Reconcile gateway process state truthfully

Make gateway state metadata reflect the actual process and connection:

- absent PID cannot remain `running`;
- shutdown markers are authoritative;
- no orphan log followers or session-owned monitors remain;
- other profiles remain untouched.

Acceptance:

- Start, graceful stop, signal stop, and stale-PID startup tests pass.
- Manual QA confirms CLI status matches actual PID and Telegram connection.

---

## Automated Verification

### Specification 18 — Build one executable Golden Path scenario

Create a deterministic integration scenario that drives the real application handlers
and durable stores:

```text
preflight -> onboarding and attestation -> owner/operator review -> readiness
-> activation -> check-in -> automatic draft -> approve -> explicit send -> receipt -> disable
```

Use a fake Telegram provider only at the HTTP boundary and a contract-preserving model
provider. Do not mock the state machine or route/authority logic being asserted.

Acceptance:

- State and visible card assertions exist at every boundary.
- Delivery is zero until explicit send and one afterward.
- The test fails if any manual recovery hook is invoked.

### Specification 19 — Add negative and restart matrices

Cover:

- wrong actor;
- wrong chat;
- wrong topic;
- stale revision;
- duplicate callback;
- callback expiry;
- provider auth failure;
- invalid model output;
- generation-worker crash;
- gateway restart in every waiting state;
- owner/operator review restart and card recovery;
- provider success before receipt persistence;
- duplicate explicit send.

Acceptance:

- The exact matrix includes owner/operator Revise, Reject, wrong-actor, stale-card, and
  duplicate-callback review branches, and each case names the invariant it protects.
- Existing reliability, restart, unknown-outcome, and exactly-once cases remain covered;
  removing trainer branches must not reduce matrix coverage.
- Every async test subscribes before triggering and uses a bounded timeout.
- No fixed sleeps or polling delays.

### Specification 20 — Run candidate-level quality gates

Run from the immutable candidate:

- LSP diagnostics on every changed Python module;
- Ruff for changed Python code;
- compileall for changed Python modules;
- focused onboarding/check-in/operator/delivery tests;
- full `tests/gateway`;
- project-wide build/type checks that cover touched packages;
- JUnit output retained under `.omo/evidence/`.

Acceptance:

- Commands exit zero.
- Failures caused by the candidate are fixed.
- Pre-existing unrelated failures are recorded, not suppressed.
- Evidence records candidate digest, command, exit code, counts, and timestamp.

---

## Real-Surface QA

### Task26 exact-candidate rehearsal amendment — reused Telegram actor

The user approved one additional exact-candidate rehearsal on 2026-08-15 because a new
disposable Telegram account is not currently available. For this rehearsal only,
**fresh customer lifecycle** means a new canonical customer and session lineage created
from an empty live runtime baseline. The synthetic Telegram actor `8527916639` and its
existing private DM are intentionally reused and must not be described as a fresh
Telegram identity, account, chat, or surface.

This narrow amendment requires:

- one authenticated archive-first profile-wide reset before registration;
- no restoration, lookup, prepopulation, or retargeting from the Task21-25 or Task26
  historical archives;
- a new customer key, bootstrap session, invite token/SID hash, onboarding and check-in
  revisions, generation job, draft, card binding, delivery idempotency key, and delivery
  receipt;
- exactly one new canonical bootstrap invite and one accepted private-DM Start from
  actor `8527916639`;
- the immutable candidate `2e0894eac92bc396cc4723bf1f18ebc653b95018dd41574df435941c235da925`
  and wheel `af4a9d0a1ffffb6eb7551c1d6dc2b32853ca6d024332a4f8f5702bbf992f141b`
  to be the deployed runtime bytes;
- one uninterrupted normal path through onboarding, owner/operator readiness,
  activation, check-in, generation, owner/operator review, explicit send, exactly-once
  customer-DM observation, disable, and cleanup, with no recovery shortcut;
- one authenticated archive-first cleanup reset after final disable, leaving an empty
  live baseline and truthful stopped runtime.

The approval authorizes only the controlled reset, candidate deployment/service rebind,
one invite, the synthetic Telegram/provider/owner actions needed for this rehearsal,
exactly one synthetic customer delivery, final disable, and cleanup. Historical
evidence remains quarantined under least privilege for audit provenance and is not
deleted or made reachable by the runtime. This amendment does not authorize a real
customer, pilot activation, release, commit, push, or unrelated profile changes.

On 2026-08-15 the user authorized exactly one replacement canonical invite after the
first authorized invite expired without its handoff being disclosed, without a claim,
and without any Telegram Start or customer row. The replacement must use a new customer
key, bootstrap session, invite token, and SID hash. The expired session remains
append-only evidence and may not be restored, reused, or retargeted. This is a one-for-one
replacement only; it does not authorize a third invite or relax any other limit above.

### Specification 21 — Prepare an isolated live rehearsal

Create fresh synthetic identities and routes:

- one customer DM;
- one owner/operator;
- one customer-free staff review group with no trainer membership or route;
- one dedicated test profile and bot.

Before starting:

- provider auth preflight passes;
- candidate digest matches automated-test evidence;
- all other profiles are recorded and left untouched;
- customer is disabled;
- delivery outbox is empty.

### Specification 22 — Run onboarding and owner/operator review without intervention

Reuse the current synthetic session's committed Q1 through Q22 answers and attestation.
A supported journaled reconciliation must move its frozen `trainer_review` projection to
`owner_review` without re-answering, while preserving the answers, attestation, consent,
and zero downstream state.

Drive through real Telegram:

- the existing customer attestation and finalized questionnaire record;
- one owner/operator review card and Approve happy path;
- restart while awaiting the owner/operator action;
- owner Revise and Reject behavior through the exact automated matrix, not live clicks;
- wrong-actor, stale-card, and duplicate-callback behavior through the exact automated
  matrix.

Capture:

- customer DM and owner/operator handset screenshots;
- owner/operator callback update IDs;
- journaled reconciliation, restart, and owner/operator decision receipts;
- zero activation, generation, and coaching delivery.

No trainer marker, claim, invite, card, UI, route, data access, review, readiness,
activation requirement, or safety-hold path may be configured or exercised in v1. Any raw
listener, service replay, direct mutation, or forced republication fails the rehearsal.

### Specification 23 — Run activation and customer check-in

Activate the synthetic rehearsal customer only after owner/operator readiness passes.
No real customer is activated. Verify:

- activation notice reaches the customer DM;
- all 12 check-in questions render correctly;
- Q7 has choices `1` through `5` plus navigation;
- final save creates one check-in event and one generation job;
- restart during the check-in preserves answers;
- no coaching delivery occurs.

### Specification 24 — Run operator review and exactly-once delivery

Through the real staff Telegram card:

1. observe automatic generation pending;
2. observe draft created;
3. regenerate and edit;
4. approve;
5. prove customer delivery remains zero;
6. explicitly send;
7. observe the customer DM message;
8. prove one provider message and one `sent_audited` receipt;
9. repeat send, stale card, and wrong-role actions;
10. restart before and after the send boundary.

Acceptance:

- Every action uses Telegram, not direct service calls.
- Operator route uses the configured effective user/chat/message context.
- Owner/operator is the sole nutrition approval authority for the generated draft.
- Customer observes exactly one message.
- Negative actions create no second receipt or provider message.

### Specification 25 — Disable and clean the rehearsal

Use the canonical disable transaction. Verify:

- customer registry is disabled;
- scheduled jobs cannot deliver;
- bootstrap/activation projection is coherent;
- test gateway is stopped;
- gateway state reports stopped;
- no orphan monitors/processes remain;
- temporary credentials and evidence containing customer data are removed;
- other profiles retain their original PIDs and state;
- no trainer marker, claim, invite, card, route, observer, or temporary trainer artifact
  remains.

---

## Release Review

### Specification 26 — Run the multi-lane release review

Run independent reviewers for:

- objective and constraint coverage;
- code quality and maintainability;
- security, privacy, and authority;
- hands-on real-surface QA;
- context and evidence provenance;
- owner/operator-only authority and trainer-free v1 scope.

Every reviewer must receive:

- candidate manifest and digest;
- Golden Path and Recovery Runbook;
- automated evidence;
- live rehearsal evidence;
- durable receipts and cleanup evidence.

Acceptance:

- All reviewers return PASS.
- Missing, inconclusive, timed-out, or unverified lanes count as failure.
- Findings are fixed and the affected gates rerun against a new candidate digest.

### Specification 27 — Issue the release verdict

Release is permitted only when all previous tasks pass.

The release report must state:

- exact candidate digest;
- privacy architecture;
- all automated commands and results;
- real-surface evidence for the customer and owner/operator only;
- exactly-once delivery proof;
- recovery scenarios exercised;
- cleanup state;
- reviewer verdicts;
- residual risks;
- pilot scope and rollback criteria.

Initial rollout:

- one explicitly consenting pilot customer;
- no shared customer group;
- daily operator review;
- immediate disable on authorization, duplication, or delivery anomaly;
- expansion only after the defined observation window is clean.

## Todos

Every task below inherits **Execution constraints**, **Minimum-operation v1 scope
directive**, and **Per-checkbox execution rule**. A task's specification defines the
required operating behavior; it does not authorize customer-facing feature expansion,
speculative architecture, convenience work, or future scaffolding. The executor must
reuse already-correct live behavior, identify only the unsatisfied v1 gap, and record
the minimal delta plus rejected extras in its DoneClaim and ledger receipt.

- [x] 1. Build the immutable-candidate manifest
  - Recommended task executor category: `unspecified-high`
  - Dependencies: none.
  - References: Foundation, Specification 1.
  - Acceptance: reconcile every tracked/untracked file and produce the candidate digest.
  - Agent-executed QA: compare manifest counts and digests with Git and filesystem output.
  - Commit: none; the user prohibited commits in this workflow.

- [x] 2. Write the Golden Path contract
  - Recommended task executor category: `writing`
  - Dependencies: 1.
  - References: Foundation, Specification 2.
  - Acceptance: cover every actor, surface, state, visible artifact, and evidence gate.
  - Agent-executed QA: lint the runbook for missing lifecycle states and prohibited shortcuts.
  - Commit: none; the user prohibited commits in this workflow.

- [x] 3. Write the Recovery Runbook
  - Recommended task executor category: `writing`
  - Dependencies: 1-2.
  - References: Foundation, Specification 3.
  - Acceptance: cover every known 2026-08-06 failure without direct durable-state edits.
  - Agent-executed QA: map each retrospective blocker to one recovery procedure and test.
  - Commit: none; the user prohibited commits in this workflow.

- [x] 4. Introduce explicit customer and staff addresses
  - Recommended task executor category: `deep`
  - Dependencies: 1-3.
  - References: Privacy and Routing, Specification 4.
  - Acceptance: typed customer DM and owner/operator staff addresses reject shared-topic production routing and expose no trainer address.
  - Agent-executed QA: failing-first parser, migration, authority, and no-trainer-surface tests plus LSP diagnostics.
  - Commit: none; the user prohibited commits in this workflow.

- [x] 5. Migrate bootstrap and onboarding to customer DM
  - Recommended task executor category: `deep`
  - Dependencies: 4.
  - References: Privacy and Routing, Specification 5.
  - Acceptance: all customer-facing onboarding surfaces use DM, owner/operator cards stay staff-only, and no trainer setup, UI, route, or data access exists.
  - Agent-executed QA: real-handler onboarding scenario, wrong-surface negatives, owner/operator authority, and DM topic-0 tests.
  - Commit: none; the user prohibited commits in this workflow.

- [x] 6. Add privacy readiness and migration gates
  - Recommended task executor category: `unspecified-high`
  - Dependencies: 4-5.
  - References: Privacy and Routing, Specification 6.
  - Acceptance: unsafe topology or trainer authority setup fails activation and leaves the customer disabled.
  - Agent-executed QA: privacy gate matrix covering legacy, mismatched, customer-in-staff, and no-trainer cases.
  - Commit: none; the user prohibited commits in this workflow.

- [x] 7. Define the generation state machine and schemas
  - Recommended task executor category: `ultrabrain`
  - Dependencies: 1-3.
  - References: Durable Generation and Review, Specification 7.
  - Acceptance: typed records reject invalid, skipped, stale, and cross-revision transitions.
  - Agent-executed QA: exhaustive state-transition tests and schema round trips.
  - Commit: none; the user prohibited commits in this workflow.

- [x] 8. Enqueue generation atomically with check-in completion
  - Recommended task executor category: `deep`
  - Dependencies: 7.
  - References: Durable Generation and Review, Specification 8.
  - Acceptance: one final check-in creates one recoverable generation job.
  - Agent-executed QA: crash-boundary and duplicate-finalization tests without sleeps.
  - Commit: none; the user prohibited commits in this workflow.

- [x] 9. Implement the resumable generation worker
  - Recommended task executor category: `deep`
  - Dependencies: 7-8.
  - References: Durable Generation and Review, Specification 9.
  - Acceptance: generation resumes safely and invalid/auth-failed output creates no draft.
  - Agent-executed QA: event-driven worker success, correction, crash, expiry, and retry tests.
  - Commit: none; the user prohibited commits in this workflow.

- [x] 10. Implement provider authentication preflight
  - Recommended task executor category: `unspecified-high`
  - Dependencies: 7,9.
  - References: Durable Generation and Review, Specification 10.
  - Acceptance: the actual Hermes auxiliary credential is checked before activation and generation.
  - Agent-executed QA: valid, expired, reauthenticated, and secret-redaction tests.
  - Commit: none; the user prohibited commits in this workflow.

- [x] 11. Build asynchronous operator cards
  - Recommended task executor category: `unspecified-high`
  - Dependencies: 7-10.
  - References: Durable Generation and Review, Specification 11.
  - Acceptance: cards mirror durable state and callbacks ACK before background work.
  - Agent-executed QA: callback-byte, stale-card, recreation, and immediate-ACK tests.
  - Commit: none; the user prohibited commits in this workflow.

- [x] 12. Separate approval from delivery
  - Recommended task executor category: `deep`
  - Dependencies: 7,11.
  - References: Durable Generation and Review, Specification 12.
  - Acceptance: approval alone creates no customer delivery and send revalidates the approved revision.
  - Agent-executed QA: approval-zero-delivery, revoke, stale revision, and wrong-role tests.
  - Commit: none; the user prohibited commits in this workflow.

- [x] 13. Add the exactly-once delivery outbox
  - Recommended task executor category: `ultrabrain`
  - Dependencies: 7,12.
  - References: Durable Generation and Review, Specification 13.
  - Acceptance: duplicate/restart/unknown-outcome paths produce at most one provider message.
  - Agent-executed QA: deterministic outbox crash matrix and receipt reconciliation tests.
  - Commit: none; the user prohibited commits in this workflow.

- [x] 14. Make callback acknowledgement best-effort and bounded
  - Recommended task executor category: `unspecified-high`
  - Dependencies: 11-13.
  - References: Telegram Reliability, Specification 14.
  - Acceptance: expired callback ACK cannot undo or hide committed work.
  - Agent-executed QA: immediate and expired ACK tests using events and bounded timeouts.
  - Commit: none; the user prohibited commits in this workflow.

- [x] 15. Preserve pending updates and make ingress observable
  - Recommended task executor category: `unspecified-high`
  - Dependencies: 4,14.
  - References: Telegram Reliability, Specification 15.
  - Acceptance: pending updates survive startup and every rejection has a privacy-safe reason code.
  - Agent-executed QA: real PTB startup contract plus structured-log redaction tests.
  - Commit: none; the user prohibited commits in this workflow.

- [x] 16. Make cards and navigation restart-safe
  - Evidence: `.omo/evidence/dualcoach-task-16.md`; candidate rebaseline approval remains required.
  - Recommended task executor category: `unspecified-high`
  - Dependencies: 5,11,14-15.
  - References: Telegram Reliability, Specification 16.
  - Acceptance: all choices/navigation survive render, one current owner/operator card resumes after restart, and no trainer card or route is required.
  - Agent-executed QA: all-question render walkthrough, owner/operator restart-state card tests, and no-trainer-surface checks.
  - Commit: none; the user prohibited commits in this workflow.

- [x] 17. Reconcile gateway process state truthfully
  - Recommended task executor category: `unspecified-high`
  - Dependencies: 15.
  - References: Telegram Reliability, Specification 17.
  - Acceptance: state metadata, process existence, and Telegram connection agree.
  - Agent-executed QA: start/stop/signal/stale-PID tests and CLI manual QA.
  - Commit: none; the user prohibited commits in this workflow.

- [x] 18. Build one executable Golden Path scenario
  - Recommended task executor category: `deep`
  - Dependencies: 4-17.
  - References: Automated Verification, Specification 18.
  - Acceptance: one owner/operator-only scenario covers every lifecycle state with delivery 0 before send and 1 after.
  - Agent-executed QA: run the scenario once and retain JUnit evidence labeled as owner/operator-only.
  - Commit: none; the user prohibited commits in this workflow.

- [x] 19. Add negative and restart matrices
  - Recommended task executor category: `deep`
  - Dependencies: 4-18.
  - References: Automated Verification, Specification 19.
  - Acceptance: every named invariant, including owner Revise, Reject, wrong-actor, stale, and duplicate review branches, has deterministic negative and restart coverage.
  - Agent-executed QA: execute the complete amended matrix once without fixed sleeps and retain the trainer-free scope label.
  - Commit: none; the user prohibited commits in this workflow.

- [x] 20. Run candidate-level quality gates
  - Recommended task executor category: `unspecified-high`
  - Dependencies: 1,18-19.
  - References: Automated Verification, Specification 20.
  - Acceptance: diagnostics, lint, compile, focused tests, full Gateway, and build/type gates pass.
  - Agent-executed QA: retain command, exit code, counts, timestamp, JUnit, and candidate digest.
  - Commit: none; the user prohibited commits in this workflow.

- [x] 21. Prepare an isolated live rehearsal
  - Recommended task executor category: `unspecified-high`
  - Dependencies: 2-3,6,10,20.
  - References: Real-Surface QA, Specification 21.
  - Acceptance: fresh customer DM and owner/operator staff topology pass preflight with delivery empty and no trainer setup or authority artifact.
  - Agent-executed QA: verify identities, memberships, routes, digest, frozen gateway state, and baseline runtime state.
  - Commit: none; the user prohibited commits in this workflow.

- [x] 22. Run onboarding and owner/operator review without intervention
  - Recommended task executor category: `unspecified-high`
  - Dependencies: 21.
  - References: Real-Surface QA, Specification 22.
  - Acceptance: the existing synthetic session is reconciled from frozen `trainer_review` to `owner_review` without re-answering; one real owner/operator Approve path and restart pass without recovery shortcuts.
  - Agent-executed QA: retain customer and owner/operator screenshots and receipts; verify owner Revise, Reject, wrong-actor, stale, and duplicate branches in the exact automated matrix.
  - Commit: none; the user prohibited commits in this workflow.

- [x] 23. Run activation and customer check-in
  - Recommended task executor category: `unspecified-high`
  - Dependencies: 22.
  - References: Real-Surface QA, Specification 23.
  - Acceptance: synthetic activation and the 12-question check-in complete in DM with one generation job after owner/operator readiness; no real customer activation.
  - Agent-executed QA: capture customer screen, durable event, Q7 controls, restart recovery, and delivery 0 before Task24.
  - Commit: none; the user prohibited commits in this workflow.

- [x] 24. Run operator review and exactly-once delivery
  - Recommended task executor category: `unspecified-high`
  - Dependencies: 23.
  - References: Real-Surface QA, Specification 24.
  - Acceptance: actual owner/operator staff buttons create, approve, and send one synthetic customer message and one receipt.
  - Agent-executed QA: capture the live owner/operator button path and synthetic customer DM receipt; verify regenerate, edit, approve, explicit send, wrong-role, stale, duplicate, and restart behavior against the sealed disposable-profile matrix in `.omo/evidence/dualcoach-task-24-evidence.json`.
  - Commit: none; the user prohibited commits in this workflow.

- [x] 25. Disable and clean the rehearsal
  - Recommended task executor category: `unspecified-high`
  - Dependencies: 24.
  - References: Real-Surface QA, Specification 25.
  - Acceptance: customer disabled, no future jobs, truthful stopped runtime, no orphan artifacts, and no trainer setup or authority artifacts.
  - Agent-executed QA: restart after disable and prove no delivery while other profiles remain unchanged.
  - Commit: none; the user prohibited commits in this workflow.

### Clarification root-fix and one-pass Golden Path amendment — 2026-08-18

Task 26 remains blocked until one replacement exact candidate proves the following
without a live customer rehearsal:

- A deterministic compiler owns clarification eligibility for all 22 onboarding
  fields. Provider output is advisory only and cannot create, select, order, persist,
  or publish a customer question.
- Production and preview use the same compiler result. Publications reload the
  committed reconciliation record rather than rendering a transient provider object.
- Every visible issue has a stable issue ID, canonical field, machine reason code,
  fixed copy, answer-digest binding, deterministic ordering, and exact revision
  binding. A valid canonical answer can never be asked again.
- Sensitive disclosures become deterministic safety holds where required; they are
  never converted into provider-authored clarification copy.
- Existing domain authorities remain authoritative. A new runtime-wide aggregate is
  rejected because replacing every proven persistence seam would materially expand
  scope and introduce a second migration risk. The Golden Path instead creates a
  hash-linked evidence graph over the existing committed receipts and independently
  verifies every edge.
- The installed-candidate Golden Path must exercise production ingress through all
  22 natural-language answers, zero-issue reconciliation, customer attestation,
  owner review, activation, one complete nutrition check-in, draft generation,
  approval, one-use capability, exactly one customer delivery, duplicate-send
  rejection, archive, disablement, quiescence, and truthful cleanup.
- The same invocation must prove provider-invented questions are invisible, genuine
  parse ambiguity is deterministic, later-field revision cannot target field zero,
  preview cannot satisfy production acceptance, approved-card projection failure
  blocks capability issuance, unknown delivery is never retried, and cleanup resumes
  forward with one terminal receipt.
- No further live invite may be issued until the exact installed candidate, complete
  Golden Path bundle, related/full suites, independent verifier, and cleanup seal all
  pass.

- [x] 26. Run the multi-lane release review
  - Recommended task executor category: `unspecified-high`
  - Dependencies: 1-25.
  - References: Release Review, Specification 26.
  - Acceptance: objective, quality, security, owner/operator hands-on QA, and provenance lanes all return PASS.
  - Agent-executed QA: reconcile every finding to a fixed candidate, revalidate trainer-free scope, and rerun affected gates.
  - Commit: none; the user prohibited commits in this workflow.

- [x] 27. Issue the release verdict
  - Recommended task executor category: `unspecified-high`
  - Dependencies: 26.
  - References: Release Review, Specification 27.
  - Acceptance: release report contains every named evidence item and authorizes only the limited pilot.
  - Agent-executed QA: run the completion audit and reject release on any missing or inconclusive evidence.
  - Final status: the historical initial verdict remains suspended in
    `.omo/evidence/task27/task27-v38-verdict-suspension.json`; canonical and supplemental
    cleanup completed, fresh F1-F5 all passed, and the bounded-pilot verdict was reissued in
    `.omo/evidence/task27/task27-v38-bounded-pilot-release-verdict-final.md`.
  - Commit: none; the user prohibited commits in this workflow.

## Final verification wave

Every final verifier inherits the same minimum-operation v1 directive and must judge the
exact fixed candidate. PASS means the existing lifecycle is ready for the bounded pilot
handoff defined above; it never authorizes automatic customer activation, delivery, or
new feature scope.

- [x] F1. Verify objective and invariant coverage
  - Check every revised objective clause and invariant, including owner/operator sole authority and trainer-free v1, against a task, acceptance criterion, and evidence path.

- [x] F2. Verify privacy and authority architecture
  - Confirm customer DM isolation, customer-free owner/operator staff membership, wrong-role fail-closed evidence, and no trainer marker, claim, invite, card, route, or data access.

- [x] F3. Verify reliability and exactly-once behavior
  - Confirm owner/operator review restart, stale, duplicate, wrong-actor, unknown-outcome, and one-receipt evidence from the candidate.

- [x] F4. Verify real-surface evidence
  - Confirm the customer and owner/operator used the intended Telegram surfaces for one real happy path and the customer observed exactly one synthetic delivery only after explicit send.

- [x] F5. Verify cleanup and release provenance
  - Confirm disabled customer, truthful runtime state, no orphan or trainer artifacts, exact candidate digest, migrated-session receipt, and all reviewer PASS receipts.

## Completion audit

The worker may mark this plan complete only when:

- Tasks 1 through 27 are complete;
- all listed acceptance criteria have evidence;
- no normal-path step used a recovery shortcut;
- all todo items are completed or explicitly dropped with reasons;
- customer delivery was observed on the intended DM;
- exactly-once evidence is retained;
- the rehearsal customer is disabled and runtime cleanup is truthful;
- no trainer setup or authority artifact remains in the v1 rehearsal;
- every release reviewer passed.

Anything less remains **NO-GO**.
