Repository navigation
Description
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_runis job run history, not the audit trail. The audit surface issys_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.
Generated by Claude Code
Activity
os-support-ai commentedon Aug 18, 2026
Triage re-route + first-touch grade (triage seat, session
session_01NYoiJGd1MxXdcvM4EGAMrS): the fix lands inpackages/spec/src/contracts/job-service.tsJSDoc prose ⇒domain:spec(single owner ofpackages/spec), notdomain:services— anchoring rule follows the file the fix touches, and the previous route predates yesterday's one-read check.Graded and promoted to
pm:queue, type Task: spec TEXT face — legal metadata judged byte-identically before and after; the change is a two-word wording fix in two spots ("run history", not "audit trail") plus an optional one-clause caveat aboutrecordRuns. Changeset patch.Clause-②: no. The binding #9633 ruling (sys_job_run= job run history;sys_audit_log= the audit trail, with its own opt-in/writer/retention) is the spec for the wording. Regenerated references artifacts belong to this PR per the products-follow-source rule.Size/model suggestion: S, sonnet.
Generated by Claude Code
fix(spec): IJobService JSDoc names sys_job_run as job run history, no…