# DualCoach Task 14 Evidence

## Verdict

PASS — callback acknowledgement is immediate where possible, bounded to two seconds,
best-effort, privacy-safe, and independent from durable callback workflow progress.

## Reused behavior and exact gap

Reused:

- Task 11 durable card projection and stale-card CAS;
- Task 12 approval/delivery separation;
- Task 13 outbox, unknown outcome, and reconciliation;
- existing onboarding, adaptive, operator, `n3`, and `nc1` callback routing.

Confirmed gaps:

- expired/failed ACK could abort durable consent, pause, start, or callback work;
- some stateful callbacks still called `query.answer()` directly;
- a post-consent success-notice edit failure could block reconciliation and onboarding
  start;
- callback protocols and test doubles left Task 14-owned type diagnostics.

Rejected extras:

- Task 15 ingress/pending-update work;
- ACK retries;
- Telegram/provider/customer delivery changes;
- new UX/framework, broad callback rewrite, compatibility shim, speculative abstraction,
  future scaffolding, suppressions, fixed sleeps, polling, `Any`, and casts.

## Implementation

- Added a two-second best-effort ACK helper.
- ACK expiry, `BadRequest: Query is too old`, and timeout are logged as ACK failures and
  do not become workflow failures.
- The underlying ACK await is cancelled on timeout.
- Outer callback cancellation propagates.
- Converted stateful consent, pause, start, `n3`, `nc1`, adaptive, operator, and
  onboarding callback paths.
- Remaining direct `query.answer()` paths are response/error/stale-only early exits with
  no committed or scheduled continuation.
- Post-consent success-notice edit failure is logged independently and cannot block
  reconciliation or `start_after_consent`.
- Reconciliation/start exceptions are not swallowed by the narrow edit-failure handler.
- Callback IDs, gate names, and exception types are logged; customer notice or answer
  content is not.

## Failing-first and runtime receipts

Failing-first:

- five stateful consent/pause/start ACK tests failed before conversion;
- consent edit failure aborted before reconciliation/start;
- Task 14-owned type audit found 55 diagnostics and later two residual diagnostics.

After remediation:

- BadRequest/timeout consent:
  `ack -> consent -> start`, one answer, one edit, final `AWAITING_ACTIVATION`.
- Success-notice edit failure:
  `ack -> consent -> edit -> reconcile -> start`, one warning, one reconciliation, one
  start, final `AWAITING_ACTIVATION`.
- Pause:
  `ack -> pause -> card`, one mutation and one card.
- Start:
  `ack -> open -> bind -> transition -> card`, each exactly once.
- Pre-mutation cancellation:
  ACK only, `CancelledError` propagated, no state mutation.
- Post-commit edit cancellation:
  cancellation propagated; fresh replay reconciled durable consent and published the
  next card without a duplicate transition.
- Stale/duplicate callbacks remained mutation-free.
- `n3`/`nc1`/adaptive/operator behavior remained unchanged.

## Independent verification

Manual verifier `st_019fe391`: CONFIRMED.

- Event-controlled BadRequest, timeout, edit failure, and cancellation probes passed.
- Timeout ACK futures were cancelled.
- No double ACK, duplicate transition, or leaked temporary task.
- Structured logs contained no raw customer text, token, or secret.

Adversarial reviewer `st_019fe392`: CONFIRMED.

- Original consent ACK and card-publication findings are closed.
- Reconciliation/start errors remain observable.
- Post-commit cancellation is restart-reconcilable.
- No Task 15 spillover or type lie was found.

Automated verifier `st_019fe390`:

- candidate digest and manifests reproduced;
- all runtime/static gates passed;
- unrelated invite fixture debt was correctly classified outside Task 14;
- its last report reused two stale type locations.

Direct lead adjudication on the current candidate ran:

```text
uv --directory /home/cube/projects/richard/hermes-agent run ty check \
  --output-format concise --color never gateway/platforms/telegram.py
```

The file retains 218 whole-file diagnostics, but there are zero live diagnostics
mentioning `assign_role`, `_send_room_bootstrap_owner_review`, or the reported former
locations 11559/11608. This agrees with the executor's exact Task 14 symbol/test audit:
55 -> 0.

## Automated verification

- Room-bootstrap transport with warnings as errors: 41 passed.
- Onboarding plus callback observability: 49 passed.
- Telegram physique callbacks: 122 passed.
- Operator console: 13 passed.
- Focused adaptive/`n3`/`nc1` ACK matrix: 4 passed.
- Additional manual regression slice: 19 passed.
- Exact Task 14-owned symbol/test type diagnostics: zero.
- Ruff: PASS.
- Compileall: PASS.
- `git diff --check`: PASS.
- No Task 14-added `Any`, cast, suppression, ignore, fixed sleep, polling loop, or ACK
  retry.

Residual whole-file typing debt and the pre-existing private-role invite fixture
expectation are documented candidate debt, not Task 14 regressions.

## Candidate identity

- 67-path candidate digest:
  `15b26c8f06a39f046a8d270277520dd01972f4d15ff7d77fa902087aaf5ff69e`
- JSON manifest SHA-256:
  `2d4db230786b656702ae89f03e4e46bc07d0fa5d5b62be856727143b7f5e4373`
- Markdown manifest SHA-256:
  `43acef0423d7913bbdba0eb2b44a35a7a29a5c74a274312229db4722f1d5eabd`
- `gateway/platforms/telegram.py`:
  `3a89267f53e6c4b725aacf8bf180040d8b8b9a863dbd34cac3e1f285c4c12858`
- `gateway/platforms/telegram_nutrition_onboarding_runtime_callback.py`:
  `4bec1d1ac318fef678ad2a939e3827a5ab585deac7684fd6d362212cc5b71b2c`
- `tests/gateway/test_telegram_room_bootstrap_transport.py`:
  `68c05e320379368bf2a0fa6cf129f8167e861d9f4199ae93f6a17ade187c75c8`
- `tests/gateway/test_telegram_nutrition_onboarding.py`:
  `df4fb82e7f945c967e2c4fbfef721bf02a7f7b3d9897b7d082f95c2657345245`
- `tests/gateway/test_telegram_nutrition_onboarding_callback_observability.py`:
  `7753cc08b813fdbedb1bc3aaa112ea889ca13c2c01f2d5407305957a4872765c`

JSON, Markdown, and raw-byte recomputation agree.

## Cleanup and non-touch

- Fake Telegram/provider surfaces only.
- No real network, Telegram, provider, activation, customer action, or delivery.
- No commit, push, reset, stash, or clean.
- No retained temporary resources.
- Unrelated dirty-worktree files and invite fixture debt were not modified.

