Skip to content

Commit 419facd

Browse files
claude[bot]claude
andauthored
docs(qa): checklist refs name the live duration keys, not the #14478 tombstones (#16997)
The hook and job liveness ledgers split their `timeout` row in two when `#14478` ruling B renamed the key to `timeoutMs`: a `live` row for the new spelling and a `dead` tombstone row for the old one. Five checklist rows were not moved with the rename, so each cited a key its own referent records as retired. `records-forms.object-hook-lifecycle` (rev 1 -> 2), source citation only: packages/spec/liveness/hook.json#retryPolicy asserted `timeout` among the props that are 'live'. Measured on the ledger it names, `timeout` is `dead` and `timeoutMs` is `live`. Because the row is a REF -- the coordinate a runner opens to learn what the item must prove -- following it landed the reader on a tombstone row with the replacement key unmentioned, leaving them to reconstruct which of the two spellings was meant. The citation now names `timeoutMs` as live and anchors the `timeout` tombstone explicitly. `integration-system.job-scheduled-run` (rev 2 -> 3), key spelling only, found by the bounded sweep for residue of the same rename: - the fixture citation said `timeout 300000`; the file it names, examples/app-showcase/src/automation/jobs/index.ts, authors `timeoutMs: 300000`; - the timing step and the over-limit acceptance clause instructed a runner to author `timeout`, which the schema now refuses at parse and at tsc; - the job.zod.ts citation named the `timeout` docs, which are the tombstone's. No clause moved in either item and no oracle changed; the job execution STATUS is still spelled 'timeout' and is left alone, as are the ladder-step name in hook-wrappers.ts, the ApprovalEscalationSchema `timeoutHours` rows and their `timeout`/`sla` alias, and the webhook and CLI prose uses. Verified: pnpm check:platform-checklist OK (631/631 symbol anchors resolved, 17 file floors held; areas/records-forms.json 78 -> 79 anchors, well over its floor). No changeset: docs/qa/** is in no package's files[], and an npm pack of @objectstack/spec -- the only publishable package whose files[] reaches past dist/README/CHANGELOG, and the one that publishes the referent liveness/ tree -- carries none of the changed text, with positive controls firing in the same sweep. Claude-Session: https://claude.ai/code/session_016N6xmWt5hYm94ffVEwGH8x Co-authored-by: Claude <noreply@anthropic.com>
1 parent db76982 commit 419facd

2 files changed

Lines changed: 19 additions & 7 deletions

File tree

docs/qa/platform-checklist/areas/integration-system.json

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -652,13 +652,13 @@
652652
"title": "Job metadata schedules through every ScheduleSchema variant, executes with retry/timeout enforced, records sys_job/sys_job_run truth, and refuses the closed doors (id key, runtime create, missing handler)",
653653
"since": "v15",
654654
"status": "active",
655-
"revision": 2,
655+
"revision": 3,
656656
"priority": "P1",
657657
"surface": "mixed",
658658
"fixtures": {
659659
"app": "showcase",
660660
"requires": [
661-
"the shipped cron fixture: showcase_health_sweep (schedule cron '0 1 * * *' UTC, handler 'sweepProjectHealth' registered in defineStack({ functions }), retryPolicy { maxRetries: 2, backoffMs: 5000, backoffMultiplier: 2 }, timeout 300000 — examples/app-showcase/src/automation/jobs/index.ts; the handler-missing regression here was #4774/#4888)",
661+
"the shipped cron fixture: showcase_health_sweep (schedule cron '0 1 * * *' UTC, handler 'sweepProjectHealth' registered in defineStack({ functions }), retryPolicy { maxRetries: 2, backoffMs: 5000, backoffMultiplier: 2 }, timeoutMs 300000 — examples/app-showcase/src/automation/jobs/index.ts; the handler-missing regression here was #4774/#4888)",
662662
"scratch jobs in a writable package for the interval / once / failing / timing-out probes (near-term schedules so the run observes real executions)"
663663
]
664664
},
@@ -675,7 +675,7 @@
675675
"read sys_job over /api/v1/data: the row is keyed by NAME (the adapter mints its own row id) with the schedule persisted",
676676
"author three scratch jobs (interval ~5s, once at now+1min, and a cron) with observable side effects; boot; let each fire; read sys_job_run rows and sys_job.last_run_at/last_status/run_count",
677677
"author a deliberately-throwing job with retryPolicy { maxRetries: 2, backoffMs: 1000, backoffMultiplier: 2 }; let it exhaust; capture run rows + failure_count",
678-
"author a job whose handler sleeps past a small `timeout`; capture the run's status",
678+
"author a job whose handler sleeps past a small `timeoutMs`; capture the run's status",
679679
"author a job with enabled:false and one whose handler string names NO registered function; boot; capture how each is skipped",
680680
"author a job carrying `id: 'x'` and one with a stray key; build both; capture the errors",
681681
"attempt to create a job at runtime through the meta door and capture the refusal (allowRuntimeCreate:false, #4509)"
@@ -700,7 +700,7 @@
700700
"evidence": "run rows + timestamped log"
701701
},
702702
{
703-
"clause": "an over-`timeout` run is recorded with execution status 'timeout' (the in-flight handler is abandoned, not force-cancelled — as documented), and timeouts COUNT as failures for the retry loop (#3494)",
703+
"clause": "an over-`timeoutMs` run is recorded with execution status 'timeout' (the in-flight handler is abandoned, not force-cancelled — as documented), and timeouts COUNT as failures for the retry loop (#3494)",
704704
"oracle": "api",
705705
"verify": "the timeout probe's run row status",
706706
"evidence": "the run row"
@@ -727,7 +727,7 @@
727727
"seed-data-thin"
728728
],
729729
"source": [
730-
"packages/spec/src/system/job.zod.ts#ScheduleSchema (ScheduleSchema discriminated union; JOB_ID_RETIRED; retryPolicy/timeout docs incl. the 17.0.0 maxRetries default flip #4661; JobExecutionStatus)",
730+
"packages/spec/src/system/job.zod.ts#ScheduleSchema (ScheduleSchema discriminated union; JOB_ID_RETIRED; retryPolicy/timeoutMs docs incl. the 17.0.0 maxRetries default flip #4661; JobExecutionStatus)",
731731
"packages/spec/liveness/job.json (per-prop verdicts + the #4509 closed-door rationale)",
732732
"packages/runtime/src/app-plugin.ts#handler (registration, enabled/handler skip lines)",
733733
"packages/services/service-job/src/cron-job-adapter.ts + db-job-adapter.ts (all three schedule shapes; sys_job/sys_job_run persistence) + run-with-policy.ts (retry/timeout enforcement, #3494)",
@@ -745,6 +745,12 @@
745745
"date": "2026-08-07",
746746
"change": "expanded to deep-test contract: concrete steps, multi-clause acceptance, negatives, variants",
747747
"ref": "claude/platform-test-checklist-ocwugl"
748+
},
749+
{
750+
"revision": 3,
751+
"date": "2026-09-09",
752+
"change": "key spelling only, no clause moved — the same #14478 rename residue as records-forms.object-hook-lifecycle: `job.timeout` became `timeoutMs` (old spelling kept as a retiredKey tombstone), so the fixture citation, the timing step, the over-limit clause and the job.zod.ts citation all named a key the schema now refuses. What is exercised is unchanged; the execution STATUS is still 'timeout'.",
753+
"ref": "#15839"
748754
}
749755
]
750756
},

docs/qa/platform-checklist/areas/records-forms.json

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3030,7 +3030,7 @@
30303030
"title": "Object lifecycle hooks fire on the write path with the right timing, gate, async and error semantics — driven over /api/v1/data/*, oracled by the record effect and the log line",
30313031
"since": "v15",
30323032
"status": "active",
3033-
"revision": 1,
3033+
"revision": 2,
30343034
"priority": "P1",
30353035
"surface": "mixed",
30363036
"personas": [
@@ -3168,7 +3168,7 @@
31683168
"packages/objectql/src/hook-wrappers.ts#wrapDeclarativeHook (wrapDeclarativeHook wrapping order condition→async→retry→timeout→onError; pickRecordPayload #4770 record = stored ⊕ payload total over declared fields; pickPreviousPayload #4784 previous binding; HookConditionError #4775 fail-closed, raised OUTSIDE onError; fireAndForget = async && isAfterEvent)",
31693169
"packages/objectql/src/hook-binder.ts#bindHooksToEngine (bindHooksToEngine: per-event × per-object engine.registerHook with priority; unresolved-body / empty-target skips)",
31703170
"packages/runtime/src/sandbox/body-runner.ts#engineCtx (log: engineCtx.logger — the ['log'] capability routing that makes the audit/warn lines an observable log oracle)",
3171-
"packages/spec/liveness/hook.json#retryPolicy (object/events/body/priority/async/condition/retryPolicy/timeout/onError all 'live'; label/description 'dead' but kept as docs)",
3171+
"packages/spec/liveness/hook.json#retryPolicy (object/events/body/priority/async/condition/retryPolicy/timeoutMs/onError all 'live'; packages/spec/liveness/hook.json#timeout is 'dead' — the #14478 tombstone left when the key was renamed to timeoutMs, so a runner reads the wall-clock abort off the timeoutMs row; label/description 'dead' but kept as docs)",
31723172
"examples/app-showcase/src/data/objects/{task,inquiry,project}.object.ts (task.done boolean + task.title required; inquiry.status select['new' default:true]/source text no-default; project.budget/spent currency + spent_within_budget rule rejecting spent > budget*1.2)",
31733173
"examples/app-showcase/src/data/seed/index.ts#tasks (done tasks 'Audit current IA'/'App wireframes'; not-done 'Build homepage'; projects 'Data Platform' 600000/420000 and 'Website Relaunch' 150000/60000)",
31743174
"packages/qa/dogfood/test/showcase-public-form.dogfood.test.ts + hook-error-format.dogfood.test.ts (the two existing dogfood pins this item cites)"
@@ -3179,6 +3179,12 @@
31793179
"date": "2026-08-08",
31803180
"change": "initial — the hook coverage.json waiver was STALE (showcase ships 4 observable hooks); authored a lifecycle+condition+async+onError+priority item",
31813181
"ref": "claude/platform-test-checklist-ocwugl"
3182+
},
3183+
{
3184+
"revision": 2,
3185+
"date": "2026-09-09",
3186+
"change": "citation only, no clause moved — the hook liveness citation asserted `timeout` 'live'; #14478 renamed it to `timeoutMs` and left `timeout` as a 'dead' tombstone row, so the ref sent a runner to a contradiction. Now names the live key and the tombstone.",
3187+
"ref": "#15839"
31823188
}
31833189
]
31843190
},

0 commit comments

Comments
 (0)