Collapse system.ci-runner-boot's stepped supervision the same way the index collapse collapses the fleet's — but in the CI runner's own files, which it shares with nothing.
lib/jobs/definitions/ciRunnerFleet.ts's ciRunnerBoot handler drives ciRunnerBootService as durable steps: boot-runner → supervise-wait:<n> / supervise-poll:<n> up to FLEET_TIME_BUDGETS.maxPollIterations (2_000) → settle-runner. Its header explains the shape from maxDuration = 300 and MOTIR-2007, the incident where an hour-long supervision inside one invocation meant every CI job over ~5 minutes had its supervisor killed with no teardown.
And ciRunnerBootService.runIntent is the same loop without the step ids — boot → poll-loop → settle, with a plain sleep. bootIntent / pollOnce / settleSupervision were carved out of it by MOTIR-2007, and the file still says so at each one ("This is the old runIntent up to and including recordBoot", "what used to be runIntent's finally, as an ordinary step"). The service therefore already carries the collapsed composition; only the reason to prefer the stepped one has gone.
Mirror the index card's move in these files: give runIntent the same optional step seam, have the job pass ctx.step into it, and delete the handler's own loop. Keep memoized exactly what the restart decision says to keep — the boot and the teardown are the operations with external effects; the interval and the poll are not.
CORRECT the comments, do not delete them. Four blocks in the handler reason from the invocation ceiling: "⚠️ THE DURABLE POLL LOOP (MOTIR-2007)", "Free waiting: Inngest schedules the resume", "⚠️ AND IT RETIRES MOTIR-2002's MEMO", and "⚠️ TEARDOWN IS REACHED ON EVERY PATH OUT OF THE LOOP". Two of them state properties that must SURVIVE the collapse and now hold for a different reason — the boot executing once per run (memoization, unchanged) and teardown being reached on every exit path (an ordinary finally, which is what a long-lived process makes trustworthy again). Say that. A reader must be able to see that the guarantee stayed and its mechanism changed.
retryPolicy: 'none' — ONE attempt, and it is a correctness decision. The handler's own comment says a retry would re-enter from the top and that the failures worth retrying come back through the next sweep instead. On the engine a LEASE RECLAIM refunds the attempt (lib/jobs/engine/worker.ts: "a reclaim and a drain both refund the attempt"), so a worker restart does not consume this job's single attempt — verify that against the worker rather than assuming it, because if it did, a deploy mid-CI-job would dead-letter a run that was fine, and this is the one job in the fleet where that budget is exactly one.admit's atomic pending → provisioning claim is what stops a second container, NOT the retry policy — the handler says so. The collapse must not move or weaken that claim; it lives in the service, inside bootIntent.ENDS at: one composition in ciRunnerBootService, driven by the job through the step seam, with pnpm test green.
Does NOT change any observable behaviour — pollWaitMs, every value in FLEET_TIME_BUDGETS, the typed bootIntent outcomes, the reap-after window and the failure details are unchanged.
Does NOT touch the two CRON jobs in the same file. system.ci-runner-provision-sweep and system.ci-runner-reap belong to MOTIR-3416, which counts them among its fourteen. This card edits ciRunnerBoot and nothing else in that file — with ONE exception it does not own either: the sweep's inngest.send(ciRunnerBootEvent(intentId)) at line 152 is MOTIR-3456's single line, already claimed there. Leave it alone.
Does NOT touch lib/ciFleet/limits.ts or the admission gate — MOTIR-3417 forbids it.
Does NOT touch the index fleet — lib/jobs/indexFleetSteps.ts and lib/services/codeGraphIndexDispatchService.ts are the sibling card's, and the two share no file, which is why neither blocks the other.
HANDS OFF the DOCUMENTS to the docs card, exactly as the index card does.
ciRunnerBoot's handler contains no poll loop; git grep -n "for (let iteration" lib/jobs/definitions/ciRunnerFleet.ts lib/services/ciRunnerBootService.ts finds it in exactly one place.job_step rows a completed CI supervision writes is a small CONSTANT, independent of how many times it polled — asserted by a test driving a supervised run at millisecond budgets.done verdict, the iteration ceiling, and a throw from inside the loop — asserted by a test per path, since the mechanism changes from a step reachable on both exits to an ordinary finally and the guarantee must be re-proven, not inherited.admit's pending → provisioning claim is unchanged, and a second boot for one intent still loses that claim.FLEET_TIME_BUDGETS is byte-identical, asserted against the shipped values.git diff shows no change to system.ci-runner-provision-sweep, system.ci-runner-reap, CI_RUNNER_PROVISION_SWEEP_CRON, CI_RUNNER_REAP_CRON, or the inngest.send at ciRunnerFleet.ts:152.git diff --stat shows no change under lib/ciFleet/limits.ts.lib/jobs/definitions/ciRunnerFleet.ts — ciRunnerBoot, its four maxDuration comment blocks, and the two cron jobs it must not touchlib/services/ciRunnerBootService.ts — runIntent, bootIntent, pollOnce, settleSupervision, FLEET_TIME_BUDGETS, pollWaitMs, and the "this is the old runIntent" markerslib/ciFleet/bootDispatch.ts — the three senders of the boot event, unchanged herelib/jobs/engine/worker.ts — the lease reclaim, and the attempt refund this card depends ontests/ciFleet/ciRunnerAdmissionWake.test.ts — the existing caller of runIntent, which must keep working through the new seam with no argumentdocs/decisions/ci-runner-fleet.md — the fleet's own record