MotirBuilding in public
MOTIR · moooon
onMotir
You’re viewing a public project. Anyone can view it — no account needed. Sign in to submit, upvote, or comment on requests.View-only — you can’t edit work items
MOTIR-3472

(motir-core) Story gate — two workers do not double-fire a tick, the coverage floor, and the totality guards a percentage cannot see

Done
Description

The story's motir-core vitest gate: a coverage floor, the seams between the three code subtasks, and the guarantees a coverage percentage cannot see. Real Postgres, not mocks.

It runs AFTER the story's code subtasks merge, because it measures their real, merged surface. It is a gate resolved at run time, not a list of cases enumerated now — "already covered by the per-subtask floor" is the expected normal for much of it, not a redundancy to pre-subtract.

(1) Coverage floor

Run coverage over the story's changed surface — the scheduler, the repository method, the defineJob / EngineJobDefinition option, the 14 declarations — and wherever a file is below the project's per-file floor (≥90% branch/fn/line, CLAUDE.md § coverage), write the missing unit and branch tests to reach it.

(2) Integration seams

The joins the units mock:

  • Scheduler → repository → claim → ledger. Drive a real tick against a real Postgres, then a real worker claim, and assert the job_run row that comes out — including event_name = 'scheduled.<jobId>', which is the field three separate consumers read and no unit test of the scheduler alone can prove.
  • A scheduled run that THROWS reaches the DLQ. Exhaust the attempt budget on a scheduled row and assert the job_run_dlq row and the failed ledger row, via the worker's terminal-failure hook. lib/jobs/engine/ledger.ts explains at length why this write is easy to appear to test and not have — an in-process harness ran the catch synchronously and made the original Inngest bug look fixed when it was not (PRODECT_FINDINGS #39). Drive it through the worker's settle path, not around it.
  • The declared catchUp reaches the tick. Assert the disposition each of the 14 declares produces the row set the scheduler writes — the declaration and the reader are two cards, and this is the seam between them.

(3) Architecture and totality guards

The things a percentage cannot see:

  • TWO WORKERS DO NOT DOUBLE-FIRE A TICK. The story's headline criterion. Two JobWorkers, or two concurrent ticks, against one warm real-Postgres pool, both scheduling the same fire — exactly one job_queue row and exactly one job_run. Sequential calls do not test this, for the reason claimDueRuns' own header gives: the race needs genuine concurrency, and a serial test passes against a broken implementation.
  • A routed cron job does not also run on Inngest. defineJob's guard returns { skipped: 'routed-to-postgres-engine' }; assert it fires for a CRON-triggered invocation specifically. The switch's existing tests cover the event path; a cron job reaches the handler by a different trigger and the negative direction deserves its own assertion.
  • Registry totality. Every id in engineScheduledJobs() carries a catchUp, and the id set is READ from the registry rather than transcribed — so a fifteenth cron job added later fails this suite instead of shipping with no policy.
  • Schedule constants unchanged. Assert the 14 cron expressions against their exported constants, so a cutover cannot quietly re-time a sweep.
  • jobScheduleHealthService still judges a migrated job correctly. Seed a scheduled ledger row via the ENGINE path and assert check(now) reads it as healthy — the probe is unchanged and this proves it did not need to change.

Scope boundary

One repo, one suite, one PR. This gate is motir-core's; the story has no second repo.

Does NOT re-derive what the per-subtask unit tests already cover, and does NOT assert anything only a deployment can show — no production ledger, no live cadence. Those belong to the production cutover task under the epic.

Acceptance criteria

  • Every file this story changed meets the ≥90% per-file floor, or the gap is named with the reason the line is unreachable.
  • The double-fire assertion runs concurrently against a real Postgres and fails against a deliberately-broken check-then-insert — verify by breaking it locally once; a concurrency test that passes both ways is not a test.
  • A scheduled run's DLQ path is asserted through the worker's settle path, with the ledger row and the dead-letter row both present.
  • The catchUp seam is asserted for at least one job of each declared disposition.
  • The registry-totality and schedule-constant guards read the registry, never a hard-coded list of 14.
  • The suite runs in CI's existing vitest lane with no new service — real Postgres is already how tests/jobs/engine-*.test.ts runs.

Context refs

  • tests/jobs/engine-worker.test.ts · tests/jobs/engine-ledger.test.ts · tests/jobs/engine-schema.test.ts · tests/jobs/engine-story-gate.test.ts — the shape MOTIR-3414's own gate took, and the suites to extend
  • tests/jobs/schedule-health.test.ts — the registry-import precedent and the probe's own tests
  • lib/jobs/engine/ledger.ts — the PRODECT_FINDINGS #39 warning about a test harness that lies
  • lib/repositories/jobQueueRepository.tsclaimDueRuns' note that a serial test cannot see the defect
  • CLAUDE.md § coverage — the per-file floor