Turn the amendment's per-job table into a declaration a scheduled job cannot omit, and apply it to all 14.
catchUp field on DefineJobOptions in lib/jobs/defineJob.ts, typed so that a definition supplying cron must supply it too. The union is already discriminated in this file — JobIdAndTrigger<N> is a two-arm union distinguishing the 1:1-convention job from an additional consumer — so the pattern for making one option conditional on another is established here and does not need inventing.EngineJobDefinition in lib/jobs/engine/registry.ts and written by registerEngineJob, beside the cron it qualifies. defineJob is the single choke point every job passes through; registering here is what makes the table complete BY CONSTRUCTION, which is the argument that file and lib/jobs/schedules.ts both already record.defineJob's config object is what inngest.createFunction receives; catchUp is an engine-side fact and belongs only in registerEngineJob, exactly as the engine's maxAttempts translation already sits outside the Inngest config.It is purely additive and nothing reads it yet — the scheduler is its first consumer. That is the same shape registerEngineJob itself shipped in (MOTIR-3421's pass, "PURELY ADDITIVE … this table is written and never read"), and it keeps the scheduler's diff to a loop rather than a loop plus fourteen touched definition files.
cron job that omits catchUp does not type-check — asserted by a compile-level check (a @ts-expect-error fixture in the test suite), because a rule enforced only by review is not enforced.catchUp at all, or supplying it is a type error — the option is meaningless without a schedule and an accepted-but-ignored field is a lie.engineScheduledJobs() carries a non-null catchUp — asserted by walking the registry after importing lib/jobs/registry, never against a transcribed list of 14. The test imports the registry for its side effect and says why, as tests/jobs/schedule-health.test.ts already does.fn.opts for every job is unchanged — the Inngest config a job syncs with must not move because of this card. Assert the forwarded config, not just that the app builds.tests/jobs/engine-units.test.ts (which already walks engineScheduledJobs() at line 86) is extended rather than duplicated.lib/jobs/defineJob.ts — DefineJobOptions, JobIdAndTrigger's discriminated union, and the registerEngineJob call that carries engine-side factslib/jobs/engine/registry.ts — EngineJobDefinition, registerEngineJob, engineScheduledJobs()lib/jobs/schedules.ts — the completeness-by-construction argument in fulllib/jobs/definitions/ — the 14 files, each with its schedule constanttests/jobs/engine-units.test.ts · tests/jobs/schedule-health.test.ts — the registry-walking suites and the side-effect-import precedentdocs/decisions/job-queue-foundation.md — the amendment this card implements verbatim