Found while reading the ledger during MOTIR-3475. job_run is the surface every wave of this migration was verified against and the table /settings/workspace/jobs renders, so its integrity is load-bearing.
1. Runs enter running and never leave. Measured 2026-08-27, status='running' and older than one hour:
system.daily-health-check INNGEST n=24 2026-08-02 .. 2026-08-26
system.code-graph-refresh INNGEST n=3 2026-08-20 .. 2026-08-27
system.ci-runner-reap INNGEST n=1 2026-08-02
system.ci-runner-provision-sweep INNGEST n=1 2026-08-04
Twenty-nine rows. The oldest has been running for 25 days. A daily job has left one behind every single day for three weeks.
2. The failure that ends those runs is written as a SEPARATE row, with an event_id that belongs to no lane.
system.daily-health-check n=27 last 2026-08-26T09:01:52Z
system.ci-runner-provision-sweep n=2
system.ci-runner-reap n=1
These rows' event_id matches neither the engine's cuid (^c[a-z0-9]{24}$) nor Inngest's ULID (^[0-9A-HJKMNP-TV-Z]{26}$), so the lane discriminator that MOTIR-3467 established — and that every read-back in this epic depends on — cannot attribute them at all.
The pairing is exact and daily:
2026-08-26T09:01:16.943Z INNGEST system.daily-health-check running <- never resolves
2026-08-26T09:01:52.776Z ? system.daily-health-check failed <- 36s later, different event_id
One logical run; two rows; neither one tells the truth on its own.
/settings/workspace/jobs shows a job that failed 25 days ago as still running. "Running" reads as healthy-and-working, which is the worst available misreading of a dead job.job_run on the cuid/ULID lane discriminator. A row matching neither is invisible to that query. It happened not to matter here because the affected runs were pre-existing Inngest ones — but a ?-lane row is a run that no lane audit can see, and lane audits are how this whole epic is being verified.I did not establish WHY the second row is written or why the first is never closed. Both plausible stories (a step-level retry record vs. a start row whose completion write is lost on a particular failure path) predict this data, and guessing between them would put a theory on the card instead of evidence. jobRunsService.recordStart / its completion counterpart, and how ledgerIdentity() derives event_id on the failure path, are where to start.
Note the affected runs are all INNGEST/?, none ENGINE — so this may be specific to the Inngest wrapper and may retire itself with MOTIR-3418. Establish that before investing in a fix; if it is Inngest-only, the correct outcome may be to backfill the stale rows and let the retirement remove the cause.
running indefinitely: either a completion write that cannot be lost, or a reaper that marks an abandoned run terminal with a distinguishable status. A run stuck in running must not render as healthy.job_run row's event_id is attributable to a lane, or the ledger exposes the lane explicitly instead of leaving it to be inferred from the id format.lib/jobs/engine/ledger.ts — ledgerIdentity(), run.eventId ?? run.idlib/services/jobRunsService.ts — recordStart and the completion pathlib/jobs/defineJob.ts — the Inngest wrapper's job-run:start stepapp/(authed)/settings/workspace/jobs — the surface that renders these rows