Bring docs/jobs.md up to what this story actually shipped. Audience: whoever adds a job, and whoever operates the cutover — the two readers who will otherwise learn these rules by breaking them.
Three sections are owed. Grep for each before writing it — this card asserts they are absent and that assertion is unverified at authoring time, so the criteria below are phrased as obligations that close as verified-no-change if the text is already there.
1. The emit seam. Every event goes through sendEvent / sendSystemEvent; nothing else calls inngest.send. Say WHY, in one line: the per-job cutover switch is read there, so an emitter that bypasses it is an emitter the switch cannot route. Name the ESLint rule and the guard test that now enforce it, so a reader who trips one knows what it is protecting rather than how to silence it.
2. Engine-side idempotency, and the ONE place it differs from Inngest. How defineJob's idempotency option behaves on the engine, which template forms the resolver accepts, and — stated plainly rather than buried — that engine dedup is unbounded where Inngest's is windowed. That divergence was argued and chosen on the idempotency card; this is where it becomes findable. MOTIR-3413's scope boundary says no job's observable behaviour changes, so a documented, argued exception is the difference between a decision and a discrepancy.
3. What "cut over" means to an operator. MOTIR_POSTGRES_JOB_IDS is a comma-separated set of defineJob ids; absent means Inngest; the switch is read live, so a change takes effect without a deploy; and rolling back is removing an id. Say where to look to confirm a job moved — a job_queue row and a job_run row for that id — and what the Inngest dashboard shows for a migrated job ({ skipped: 'routed-to-postgres-engine' }), because a run that did nothing is otherwise indistinguishable from a job that broke.
Does NOT rewrite the existing "Concurrency" or "Debounce" sections. They document measured Inngest behaviour, both lanes are live, and that measurement is still true of the lane it describes. Removing Inngest-specific claims is MOTIR-3418's, which owns the retirement and the epic criterion about it.
Does NOT document the scheduled jobs' cutover (MOTIR-3416) or the supervisors' (MOTIR-3417).
Prose only. No file outside docs/ is modified.
docs/jobs.md carries the three sections above — each added if absent, and left alone if a grep shows it already says the same thing. The PR body quotes the grep for each.docs/ is modified.docs/jobs.md — the file, and its existing Concurrency / Debounce sections which staylib/jobs/engine/cutover.ts — the env var, the live read, and the switch's own documented endlib/jobs/sendEvent.ts — the emit seam as mergedlib/jobs/defineJob.ts — the skipped: 'routed-to-postgres-engine' marker and why it is a marker rather than a silent returneslint.config.mjs — the widened import boundary to name