Observation-class finding, recorded while implementing #9633 (disposition 1: replay() honours recordRuns). Filed rather than absorbed: the fix lands in packages/services/service-job, this sentence lives in packages/spec, and editing spec would widen that PR's gate surface for a wording question.
The sentence
packages/spec/src/contracts/job-service.ts:190-195 (generic spaced to survive the body sanitizer; the source has no spaces):
/** * Replay the most recent execution of a job — useful from admin UI. * Equivalent to `trigger(name)` but records that this run is a replay * in the execution audit trail. */replay?(name: string,data?: unknown): Promise<void>;
Two things about it, in ascending order of interest.
1. It is now conditional where it reads as unconditional. Before #9633, replay() recorded its synthetic row unconditionally, so "records that this run is a replay" held for every call. After it, an adapter constructed with recordRuns: false executes the handler and records nothing durable. The interface never mentioned the adapter-level flag — reasonably, since recordRuns is a DbJobAdapter option and replay is optional on the interface — so the sentence is loose rather than newly false. Worth a caveat, not an alarm.
2. The sharper half: it names the wrong subsystem. The PM ruling on #9633 turned on exactly this distinction, and stated it as binding:
sys_job_run is job run history, not the audit trail. The audit surface is sys_audit_log, and it has its own opt-in, its own writer and its own retention.
The published contract for replay calls the thing it writes to "the execution audit trail". That is the conflation the ruling refused, sitting in the spec package's own words — and it is the reading that makes disposition (2) sound principled to the next agent who arrives at this code. The JobRunOutcome.reason field twelve lines up (packages/spec/src/contracts/job-service.ts:70) carries the same phrase: "short, human-readable, for the audit trail."
Neither is a behavioural defect. Both are published .d.ts tooltip text that points a reader at the wrong subsystem, in the same channel #9611 and #9631 were about.
Why finding and not a queued defect
Nothing is broken; a reader is merely pointed at sys_audit_log when the writer is sys_job_run. The cheap fix is two words in each spot ("the run history"), plus optionally one clause noting that an adapter which persists run history at all is the precondition for replay recording anything. It wants a triage grade rather than a dispatch, hence no pm:queue.
Two implementers of replay exist today, both of which would inherit whatever the interface says: packages/services/service-job/src/db-job-adapter.ts and packages/services/service-queue/src/db-queue-adapter.ts.
Refs: #9633 · #9611 · #9631
Generated by Claude Code
Observation-class finding, recorded while implementing #9633 (disposition 1:
replay()honoursrecordRuns). Filed rather than absorbed: the fix lands inpackages/services/service-job, this sentence lives inpackages/spec, and editing spec would widen that PR's gate surface for a wording question.The sentence
packages/spec/src/contracts/job-service.ts:190-195(generic spaced to survive the body sanitizer; the source has no spaces):Two things about it, in ascending order of interest.
1. It is now conditional where it reads as unconditional. Before #9633,
replay()recorded its synthetic row unconditionally, so "records that this run is a replay" held for every call. After it, an adapter constructed withrecordRuns: falseexecutes the handler and records nothing durable. The interface never mentioned the adapter-level flag — reasonably, sincerecordRunsis aDbJobAdapteroption andreplayis optional on the interface — so the sentence is loose rather than newly false. Worth a caveat, not an alarm.2. The sharper half: it names the wrong subsystem. The PM ruling on #9633 turned on exactly this distinction, and stated it as binding:
The published contract for
replaycalls the thing it writes to "the execution audit trail". That is the conflation the ruling refused, sitting in the spec package's own words — and it is the reading that makes disposition (2) sound principled to the next agent who arrives at this code. TheJobRunOutcome.reasonfield twelve lines up (packages/spec/src/contracts/job-service.ts:70) carries the same phrase: "short, human-readable, for the audit trail."Neither is a behavioural defect. Both are published
.d.tstooltip text that points a reader at the wrong subsystem, in the same channel #9611 and #9631 were about.Why
findingand not a queued defectNothing is broken; a reader is merely pointed at
sys_audit_logwhen the writer issys_job_run. The cheap fix is two words in each spot ("the run history"), plus optionally one clause noting that an adapter which persists run history at all is the precondition forreplayrecording anything. It wants a triage grade rather than a dispatch, hence nopm:queue.Two implementers of
replayexist today, both of which would inherit whatever the interface says:packages/services/service-job/src/db-job-adapter.tsandpackages/services/service-queue/src/db-queue-adapter.ts.Refs: #9633 · #9611 · #9631
Generated by Claude Code