I read this as a read-only architecture decision for strict rerun delivery - I’ll trace the current approval, authorization, persistence, transport, operator, migration, and test paths, compare two minimal durable-capability designs, and recommend one with exact source evidence and invariants.


I read this as a read-only production design request - I’m closing the remaining evidence gaps around the atomic boundary, deployment receipts, capability precedent, and operator entrypoint before giving the recommendation.


I read this as a read-only production design request - I’ll recommend the smallest capability-based change and map it to exact code, schemas, operations, migration, tests, and invariants.

## Recommendation

Use a **dedicated strict-draft delivery capability embedded in the existing draft-delivery ledger**.

Do not reuse `AdaptiveOperatorCapability`, do not introduce a general token service, and do not create another transport path. Add one typed operation that:

1. Issues a short-lived grant for one already-approved, currently rendered review card.
2. On the exact owner callback, durably changes:
   - capability `issued -> consumed`; and
   - delivery `authorized -> unknown_provider_outcome`
   in the **same locked JSON replacement**.
3. Returns an opaque dispatch claim only after all generation, route, card, deployment, consent, safety, and expiry checks pass.
4. Allows exactly one provider invocation from that returned claim.
5. Uses the existing receipt, delivered, sent-audit, and reconciliation machinery afterward.

Keep `adaptive_nutrition.delivery_enabled: false`. A true global flag must no longer authorize this Telegram send path.

Strictly speaking, a remote provider cannot offer provable exactly-once delivery across unknown outcomes. The enforceable production guarantee is:

> one durable capability consumption, at most one provider invocation, and no automatic retry after an unknown outcome.

That is the fail-closed behavior the existing outbox already implements.

---

## Why this is the smallest safe design

### Design A — capability inside `draft-deliveries.json` — recommended

Add an `authorized` delivery state and a nested capability grant to the existing row.

Advantages:

- Capability consumption and dispatch claim are one atomic `os.replace` under the existing cross-process `flock`.
- Reuses current idempotency key, payload digest, provider route, receipt, audit, and reconciliation code.
- No cross-ledger transaction protocol.
- Legacy rows can remain readable without receiving authority.
- A torn generation-ledger write can lose availability but cannot cause a send: no provider call occurs unless the whole claim method returns successfully.

Cost:

- The delivery row schema grows.
- Existing tests that treat `delivery_enabled=True` as authorization must be rewritten.

### Design B — separate append-only capability journal

For example, `strict-draft-delivery-capabilities.jsonl`, linked to the delivery row by capability ID.

Advantages:

- Cleaner audit history.
- Capability events remain append-only.

Disadvantages:

- Consuming the capability and reserving dispatch requires writes to two files.
- Consume-first can strand an unused capability; reserve-first creates an ambiguous pending reservation.
- Crash-safe atomicity would require a two-phase recovery protocol or SQLite transaction.
- Substantially more schema, recovery, and migration code for no delivery benefit.

This is not the smallest production-safe choice.

### Design C — reuse `AdaptiveOperatorCapability` — reject

The existing type already has expiry, owner, review route, message provenance, and durable sessions at `gateway/platforms/nutrition_coaching.py:8920-9004` and validation at `13244-13384`.

It is nevertheless the wrong authority:

- It is scoped to adaptive proposal actions, not approved draft generations.
- It binds proposal digest/revision rather than draft/check-in/generation records.
- It couples this exception to adaptive delivery enablement.
- It does not bind the conventional delivery ledger identity.
- Reusing it would make it easier, not harder, for the capability to leak into adaptive sends.

---

## Proposed durable model

### Deployment authorization receipt

Add `dualcoach-strict-rerun-launch-authorization-v1`, written only by an explicit successful human `launch --start-service`.

Required immutable fields:

```text
schema
purpose = "strict_rerun_one_approved_draft"
authorization_id
issued_at_utc
arm_receipt_sha256
candidate_digest
candidate_manifest_sha256
wheel_sha256
provider_receipt_sha256
provider_config_sha256
profile_config_sha256
profile_authorization_digest
repository_status_sha256
controller_module_sha256
authorization_digest
```

The digest covers every preceding field in canonical JSON.

This is needed because the current launch returns an in-memory status but does not create durable proof that the human-authorized candidate was launched. Current launch validation is at `dualcoach_tasks21_25_controller.py:586-646`.

### Delivery capability grant

Nested in the delivery row:

```json
{
  "schema": "strict-draft-delivery-capability-v1",
  "purpose": "strict_rerun_one_approved_draft",
  "capability_id": "<256-bit random identifier>",
  "state": "issued",
  "issued_at_utc": "...",
  "expires_at_utc": "...",
  "consumed_at_utc": null,

  "deployment_authorization_digest": "...",
  "candidate_digest": "...",
  "candidate_manifest_sha256": "...",
  "wheel_sha256": "...",
  "provider_config_sha256": "...",
  "profile_authorization_digest": "...",

  "customer_key": "...",
  "customer_route": {
    "user_id": "...",
    "chat_id": "...",
    "topic_id": "..."
  },

  "draft_id": "...",
  "approved_generation": 4,
  "approved_generation_record_digest": "...",
  "checkin_event_id": "...",
  "checkin_revision": "...",
  "session_id": "...",
  "approved_draft_revision": "...",
  "approved_event_id": "...",
  "canonical_payload_digest": "...",

  "canonical_owner_route": {
    "user_id": "...",
    "chat_id": "...",
    "topic_id": "..."
  },
  "owner_authority_digest": "...",

  "review_card_route": {
    "user_id": "...",
    "chat_id": "...",
    "topic_id": "..."
  },
  "review_card_message_id": "...",
  "review_card_nonce": "...",
  "review_card_payload_digest": "...",

  "grant_digest": "..."
}
```

Use a fixed short TTL, preferably ten minutes. Do not accept an arbitrary CLI TTL in the first version.

### State transitions

```text
No row
  -> authorized + capability issued        CLI issuance; no provider effect

authorized/issued
  -> unknown_provider_outcome/consumed     exact callback dispatch claim

unknown_provider_outcome/consumed
  -> sent/consumed                          durable provider receipt

sent/consumed
  -> delivered/consumed
  -> sent_audited/consumed
```

Expiry and revocation are terminal authorization states. A negative provider reconciliation must not revive a consumed capability. Another attempt requires a new approved child revision and a new capability.

---

## Exact source changes

### 1. `gateway/platforms/nutrition_coaching.py`

Relevant existing boundaries:

- Coordinator and delivery paths: `2126-2174`
- Existing atomic pre-transport consume: `2587-2692`
- Durable card publication: `3846-4145`
- Generation/card-pinned delivery reservation: `6331-6643`
- Receipt and audit lifecycle: `6645-7056`
- Bounded reconciliation: `7058-7186`
- Strict delivery-row parser: `7547-7629`

Add:

- `StrictDraftDeliveryCapability`
- `StrictDeliveryCardContext`
- `StrictDeliveryDispatchClaim`
- Capability parser/digest validation.
- Injectable UTC clock for deterministic expiry tests.
- `issue_strict_delivery_capability(...)`
- `claim_strict_delivery_dispatch(...)`

`claim_strict_delivery_dispatch` must:

1. Acquire `_delivery_lock`.
2. Reload registry, draft, generation, card, delivery, and launch authority.
3. Require global adaptive delivery to still be false.
4. Verify all capability fields against live canonical values.
5. Require current generation to be the exact approved generation named by the grant.
6. Require the actual callback route, message ID, and nonce.
7. Persist capability consumption and `unknown_provider_outcome` together.
8. Persist the generation transition.
9. Return a dispatch claim only if all writes completed.

Change public `prepare_delivery` and `validate_delivery_transport` so neither can create a new transport-eligible reservation without this capability. They may still support post-transport receipt/audit reconciliation.

Add a hard adaptive master check: production `set_persisted_delivery(True)` and `deliver_latest_once()` must reject while the configured global gate is false. The current adaptive composite flow can otherwise enable persisted delivery at `nutrition_coaching.py:11926-11935`, despite starting with the global value false.

### 2. `gateway/platforms/telegram.py`

Current evidence:

- Render identity is the Telegram message ID: `6505-6516`
- Nonce binds draft and generation CAS values: `6518-6559`
- Callback data includes nonce and message identity: `6797-6838`
- Callback verifies both before mutation: `6870-6913`
- Current global authorization check: `7110-7116`
- Existing dispatch calls reservation, validation, then provider: `7117-7208`

Change the send branch to:

```text
parse and authenticate exact card
-> claim_strict_delivery_dispatch(...)
-> if and only if an opaque claim is returned, call Telegram once
-> existing receipt/delivered/audit sequence
```

Delete the meaning of:

```python
delivery_enabled is True -> send permitted
```

Instead:

- `delivery_enabled=True` without a capability must still fail.
- `delivery_enabled=False` with the exact valid capability may perform this one manual send.

Also persist the newly approved rendering after `query.edit_message_text` succeeds. The current card ledger records publication message IDs, but approval edits the same Telegram message without updating that ledger to the approved generation. Capability issuance must require a card row containing the current approved generation, current rendered payload digest, route, and message ID.

If that projection cannot be recorded, approval remains valid but capability issuance fails closed.

### 3. `gateway/platforms/dualcoach_tasks21_25_controller.py`

Current evidence:

- Candidate and arm schemas: `27-28`
- Global false and initial profile snapshot validation: `227-274`
- Candidate/source binding: `357-384`
- Arm receipt creation: `417-482`
- Installed wheel validation: `508-581`
- Human launch: `586-646`
- CLI parser: `654-674`

Add:

- Durable launch-authorization schema and receipt.
- Validation of the provider receipt's existing `config_sha256`.
- Required `wheel.sha256` extraction from the candidate manifest.
- Self-digest validation for launch authorization.
- `issue-delivery-capability` subcommand.

Proposed operator command:

```text
dualcoach_tasks21_25_controller issue-delivery-capability
  --launch-authorization <private receipt>
  --draft-id <draft id>
  --review-message-id <Telegram message id>
  --json
```

Do not accept customer route, owner route, text, revision, digest, or destination from the command line. Derive all of them from the launch receipt, committed registry, generation ledger, approval event, delivery/card ledgers, and current config.

The command must not call Telegram or the provider. JSON output should contain only:

```text
status
capability_id
expires_at_utc
draft binding digest
review-card message id
```

Do not print customer text or raw routes.

### 4. `gateway/platforms/dualcoach_admin.py`

No new provider operation is needed.

It already emits:

- Candidate digest: `274-286`
- Redacted config digest: `303-313`
- Receipt candidate/config fields: `669-715`
- Unchanged-profile evidence: `715-719`

The controller must begin validating and carrying these existing values into launch authorization.

### 5. `gateway/platforms/nutrition_coaching_config.py`

No new delivery boolean.

Keep:

- `AdaptiveNutritionConfig.delivery_enabled`: `124`
- Default false parsing: `169`

The strict capability is an exception for one manual approved-draft dispatch, not a second global enable switch.

### 6. Profile operator console

Current production console can reach the same transport lifecycle through:

- `CoordinatorLifecycleAdapter.send`: `operator_console.py:118-181`
- Production factory wiring `send_draft=adapter.send`: `795-838`

That is a bypass unless it can supply the exact Telegram review-card context.

Smallest change: production console remains available for evidence/edit/approve, but configure `send_draft=None`. A production `/send` then returns operation unavailable and cannot claim a capability. The exact Telegram card becomes the sole strict-rerun consumer.

Do not add a text box for capability IDs or raw destinations.

### 7. `scripts/reproducible-wheel-build`

No source change required. It already fixes ZIP time and offline build inputs.

Use the wheel digest from its sealed output as a launch/capability binding. Existing reproducibility coverage is at `tests/test_reproducible_wheel_build.py:17`.

---

## Operator procedure

1. Build and seal the candidate wheel.
2. Arm and explicitly launch the candidate.
3. Preserve the generated private launch-authorization receipt.
4. Generate and approve the draft in Telegram.
5. Confirm the approved card is durably bound to its exact message ID.
6. Run `issue-delivery-capability` for that draft/message.
7. Press **Send** on that same card before expiry.
8. Never retry after an unknown outcome.
9. Reconcile only from exact provider evidence.

No CLI command itself sends a message.

---

## Failure behavior

| Boundary | Durable state | Provider calls | Retry |
|---|---|---:|---|
| Issuance validation fails | no capability | 0 | correct inputs may be retried |
| Capability expired/tampered | issued but unusable, or terminal expired | 0 | requires new approved revision |
| Claim persistence fails before consumption | issued/authorized | 0 | safe before expiry |
| Consumption persists, then crash | consumed/unknown | 0 | no resend |
| Provider rejects or times out | consumed/unknown | at most 1 | no resend |
| Provider succeeds, receipt write fails | consumed/unknown | 1 | evidence-only reconciliation |
| Receipt persists, audit fails | sent/delivered | 1 | audit-only retry |
| Success | sent_audited | 1 | duplicate is idempotent |
| Concurrent callbacks | one consumed winner | at most 1 | losers rejected |

---

## Migration

Use an additive, fail-closed migration:

- Existing delivery rows without a capability remain readable for receipt/audit reconciliation.
- A legacy `pending` row is never transport-authorized.
- Do not auto-mint capabilities for existing drafts or rows.
- Existing approved cards whose current approved rendering was not recorded must be re-rendered through the typed card recovery path.
- Existing arm receipts remain historical evidence but cannot issue a capability without a new launch-authorization receipt.
- No startup rewrite of delivery/card ledgers.
- No legacy global `delivery_enabled=True` grant survives.

If an existing delivery row already exists for the same draft/revision, capability issuance should reject rather than guess whether a prior provider attempt occurred.

---

## Required tests

### `tests/gateway/test_nutrition_coaching.py`

Add coverage for:

- Exact issuance bindings.
- Tampering with every deployment, route, owner, draft, check-in, card, and expiry field.
- Expiry immediately before and at the boundary.
- Legacy rows confer no authority.
- Concurrent claim has exactly one winner.
- Capability consumption and unknown state appear in one persisted document.
- Crash before and after consumption.
- Negative reconciliation cannot reopen a consumed capability.
- Corrupt capability fails the whole delivery read closed.
- Global true without capability cannot send.
- Global false with capability can claim once.
- Adaptive `delivery_enable` and `deliver_latest_once` remain blocked.

Existing crash-matrix tests are at `6174`, `6231`, `6263`, `6332`, and `6402`.

### `tests/gateway/test_task7_generation_hardening.py`

Convert the real callback tests to global false plus an issued capability:

- Receipt projection restart: `720`
- Crash after provider before receipt: `967`

Add crash after durable capability consumption but before provider invocation: zero calls before restart and zero after restart.

### `tests/gateway/test_telegram_physique_checkin.py`

Extend:

- Approval-only/no-delivery test: `1886`
- Exact destination/text revalidation: `1943`

Add:

- Wrong message ID.
- Wrong nonce.
- Wrong review route.
- Stale approved generation.
- Card projection write failure.
- Capability expiry.
- Duplicate tap.
- `delivery_enabled=True` cannot replace a capability.

### `tests/gateway/test_dualcoach_tasks21_25_controller.py`

Extend current arm/launch tests at `208` and `333`:

- Private launch receipt permissions.
- Candidate, manifest, wheel, provider config, and profile authorization bindings.
- Receipt self-digest tampering.
- Installed wheel drift.
- Wrong profile.
- Issuance emits no Telegram/provider action.
- CLI rejects raw or mismatched card identity.

### Profile `tests/test_operator_console.py`

Assert production `/send` is unavailable and customer transport remains uncalled, while evidence/edit/approve continue to work.

---

## Security invariants

1. **No ambient authority:** neither `delivery_enabled=True` nor an approved draft alone authorizes transport.
2. **Global remains false:** strict dispatch is valid only while the global adaptive gate is false.
3. **One purpose:** the capability can invoke only the strict approved-draft dispatch method.
4. **Exact deployment:** candidate, manifest, wheel, provider config, profile authorization, and human launch receipt are immutable bindings.
5. **Exact customer:** customer key and full user/chat/topic route must match the live committed registry.
6. **Exact draft:** draft ID, approved generation, generation-record digest, check-in event/revision, approval event, and payload revision must all match.
7. **Exact operator:** actual review ingress and canonical owner are separately authenticated and bound.
8. **Exact card:** nonce, Telegram message ID, rendered payload digest, and review route must match the durable current approved card.
9. **Short lifetime:** claim is rejected before issuance time and at or after expiry.
10. **Consume before effect:** the capability is durably consumed before the provider call.
11. **One winner:** capability consumption and dispatch unknown-state reservation are one locked atomic replacement.
12. **Unknown is terminal:** timeout, missing receipt, exception, or crash after consumption never causes automatic resend.
13. **Receipt repair is not delivery:** reconciliation with a receipt performs zero provider calls.
14. **No legacy grant:** missing capability data means no transport authority.
15. **No adaptive leakage:** the strict type is not accepted as an `AdaptiveOperatorCapability`.
16. **No automatic consumer:** scheduler, startup recovery, operator console, and adaptive flows cannot consume the capability.
17. **Corruption fails closed:** malformed launch, capability, delivery, card, generation, or registry state prevents transport.

No files were edited, no tests were run, and no service, Telegram, provider, or migration action was performed.