Supersedes #144868 by @Alix-007. Issue #144851 was also reported by @Alix-007; the original commit and authorship are preserved.
## What Problem This Solves
QA final replies can be overwritten by late drafts or deleted during cleanup. A silent or empty completion can leave an unfinished preview visible.
## Why This Change Was Made
The existing preview owner decides which message is still an unfinished draft. Successful final promotion releases that draft handle and records durable delivery. Error, terminal-skip, and turn-settlement callbacks all call the same cleanup operation. The existing queue orders draft writes, promotion, and deletion.
## User Impact
Completed QA answers survive. Unfinished previews disappear before the turn is acknowledged. Distinct final chunks and attachments still arrive. This affects the repository-only QA transport.
## Evidence
- Real Gateway evidence uses identical deterministic fixtures on main `9d5fc2e49c` and candidate `72f2656c0e0b3d2381d5cb0900d4a256526fec7e`. HTTP readback after acknowledgement shows the silent draft retained on main and deleted on the candidate; the ordinary final survives on both.
- Late-partial, error-cleanup, failed-promotion, and distinct-delivery controls drive registered inbound callbacks with real HTTP bus operations. They complement the full Gateway reproduction; they do not claim every callback ordering occurred naturally in that run.
- The 55 selected tests passed on merge `5574f4821e476287b3c771b8b0b0b7c9eedb75f8`, with main parent `678f66a0b4` and candidate parent `72f2656c0e0b3d2381d5cb0900d4a256526fec7e`.
- The final correction preserves cleanup behavior with explicit awaited `try/finally`. The retained-final scenario still rejects missing answers and now verifies that the unfinished preview is deleted after acknowledgment. Its YAML success conditions are unchanged.
- All 66 owner/sibling tests passed on merge `3af49e8455a0860d99930363b2ce9f235364206b`, with main parent `e4ebb37723` and final candidate parent `597f869f9976d2707f7b0167f50f425c267372b3`.
- [CI run 34790888746](https://github.com/openclaw/openclaw/actions/runs/34790888746) is green at `597f869f9976d2707f7b0167f50f425c267372b3`, including lint and typechecks.
```sh
node scripts/run-vitest.mjs \
extensions/qa-channel/src/inbound.test.ts \
extensions/qa-channel/src/inbound-preview-lifecycle.test.ts \
extensions/qa-channel/src/inbound.preview-terminal.test.ts \
extensions/qa-channel/src/inbound.dispatch-lifecycle.test.ts \
extensions/qa-channel/src/gateway.test.ts \
extensions/qa-lab/src/scenario-retained-final.test.ts
```
## Consumers
QA Gateway polling waits for cleanup before acknowledging input. QA transcript and scenario readers retain completed answers and exclude deleted drafts. External production transports are unchanged.
## Invalidation
Preview handles and durable-delivery facts belong to one turn. Successful promotion releases the preview handle; terminal cleanup closes further preview updates.
## Compatibility
No config, schema, protocol, dependency, or public API changes.
Co-authored-by: Alix-007 <li.long15@xydigit.com>
Co-authored-by: Ayaan Zaidi <hi@obviy.us>