# W46 — Request #64: the retro-apply window comes out with the floor raise

**One release, one commit.** `min_spt_core_version` rises to the spt-core that orders the
frames, and BOTH halves of the #52 mitigation are deleted in the same change. Not before (the
old ordering still needs them), not after (that gap is when the misfire is live).

## The version string — HANDED, not inferred

doyle handed it at publish, 2026-08-04: **spt-core `v0.54.0`**, published
`2026-08-04T23:13:44Z`, tag at sha `86f0d84`, update-set counter 89, channel stable, decoded
by deployah from the PUBLISHED artifact rather than from source or a success line. That is the
floor. Nothing in this wave re-derives it.

Two behavioral notes riding v0.54.0, recorded here so the wave knows them from the changelog
rather than discovering them: `spt endpoint run` is RETIRED with no alias (fresh bringup is
create then start/go, two commands), and resume-with-a-session-argument now REFUSES rather than
ignoring. Neither is on alchemy's surface — we spawn via the manifest's `[shell].spawn` and
never shell `endpoint run` — but the runbook's bringup prose is checked against them.

## Why deletion, not repair

The window is a 15-second per-requester timer with no invocation correlation. Under the OLD
order (text frame first) it converges a stranded file to its own create. Under the NEW order
(file frame first) the same code retro-applies the NEXT invocation's file to the PREVIOUS
create — wrong Request, and the intended one mints with nothing. It is correct under exactly
one ordering, and that ordering stops being deployed. An in-place repair needs the invocation
correlation key doyle considered and refused as heavier than the ordering fix, so there is no
safe version of the mitigation to keep.

## Scope

| Surface | Change |
|---|---|
| `manifest.toml:12` | `min_spt_core_version` `0.44.0` → `0.54.0`, reason line rewritten |
| `tests/manifest_contract.rs:244` | pin updated to `0.54.0`, assertion prose names frame ordering |
| `src/runtime.rs` | delete `RecentCreate`, `RecentComment`, `RETRO_APPLY_WINDOW`, the `recent_creates`/`recent_comments` fields and their `new()` init, both retro branches in `handle_file`, both window open/close blocks in `run_engine`, and `staged_was_empty` |
| `src/verbs.rs` | delete `retro_apply_file`, `retro_apply_comment_file`, `Outcome::minted`, `Outcome::commented` and their writers (`out.minted` in `create`, `out.commented` in `comment`) |
| `src/github.rs:410` | delete `get_comment` — added at W44 for the comment retro-apply only, no other caller |
| `traceable-reqs.toml` | retire `REQ-SEND-FILE-RETRO-APPLY` and `REQ-COMMENT-FILE-RETRO-APPLY` (W26 retirement pattern: delete the entry, leave a dated comment block saying why); drop both from their groups; amend `REQ-CREATE-BODY-LIMIT`'s title to lose its retro clause |
| `CONTEXT.md` | same two edits in prose |
| `docs/KNOWN-HAZARDS.md` | NEW `REQ-HAZARD-MITIGATION-RETIREMENT-COUPLING` |
| tests | three retro tests deleted, three new-order tests replace them |

## The hazard this wave is required to add

Ratified in #64's first comment, from doyle's framing: **a mitigation whose correctness depends
on the defect it mitigates is a coupling the fix must ship AGAINST, not alongside.** Registered
as `REQ-HAZARD-MITIGATION-RETIREMENT-COUPLING` so the next mitigation written against a known
upstream defect records its retirement coupling when it is INTRODUCED, not when it breaks.

Its evidence is the misfire test below — the one that proves the wrong-Request delivery cannot
happen any more. A hazard with only prose is not covered.

## Tests

1. **New-order regression** (`REQ-CREATE-FILE-BODY`): file frame FIRST, then the `create` text
   frame → the file's text fills the body. This is the behaviour
   `REQ-SEND-FILE-RETRO-APPLY` always really wanted, now reached by plain staging.
2. **New-order comment** (`REQ-VERB-COMMENT`): file frame first, then `comment #N` → the file
   attaches to that comment through the ordinary staged-attachment path.
3. **The misfire cannot fire** (`REQ-HAZARD-MITIGATION-RETIREMENT-COUPLING`): bare create A,
   then a file frame, then create B — the file lands on **B**, and A is never touched. Under
   the deleted mitigation with the new ordering this test fails by putting the file on A. No
   GET/PATCH of A is mocked, so a retro-apply would 404 rather than pass quietly.

## Gate

`cargo test` green, `traceable-reqs check` green, then the release per
`docs/RELEASE-RUNBOOK.md` (standing DRI authority, no Operator go-ahead needed). Version bump
and CHANGELOG ride the same commit; #64 closes on the release.
