Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 11 additions & 5 deletions docs/qa/platform-checklist/areas/integration-system.json
Original file line number Diff line number Diff line change
Expand Up @@ -652,13 +652,13 @@
"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)",
"since": "v15",
"status": "active",
"revision": 2,
"revision": 3,
"priority": "P1",
"surface": "mixed",
"fixtures": {
"app": "showcase",
"requires": [
"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)",
"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)",
"scratch jobs in a writable package for the interval / once / failing / timing-out probes (near-term schedules so the run observes real executions)"
]
},
Expand All @@ -675,7 +675,7 @@
"read sys_job over /api/v1/data: the row is keyed by NAME (the adapter mints its own row id) with the schedule persisted",
"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",
"author a deliberately-throwing job with retryPolicy { maxRetries: 2, backoffMs: 1000, backoffMultiplier: 2 }; let it exhaust; capture run rows + failure_count",
"author a job whose handler sleeps past a small `timeout`; capture the run's status",
"author a job whose handler sleeps past a small `timeoutMs`; capture the run's status",
"author a job with enabled:false and one whose handler string names NO registered function; boot; capture how each is skipped",
"author a job carrying `id: 'x'` and one with a stray key; build both; capture the errors",
"attempt to create a job at runtime through the meta door and capture the refusal (allowRuntimeCreate:false, #4509)"
Expand All @@ -700,7 +700,7 @@
"evidence": "run rows + timestamped log"
},
{
"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)",
"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)",
"oracle": "api",
"verify": "the timeout probe's run row status",
"evidence": "the run row"
Expand All @@ -727,7 +727,7 @@
"seed-data-thin"
],
"source": [
"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)",
"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)",
"packages/spec/liveness/job.json (per-prop verdicts + the #4509 closed-door rationale)",
"packages/runtime/src/app-plugin.ts#handler (registration, enabled/handler skip lines)",
"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)",
Expand All @@ -745,6 +745,12 @@
"date": "2026-08-07",
"change": "expanded to deep-test contract: concrete steps, multi-clause acceptance, negatives, variants",
"ref": "claude/platform-test-checklist-ocwugl"
},
{
"revision": 3,
"date": "2026-09-09",
"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'.",
"ref": "#15839"
}
]
},
Expand Down
10 changes: 8 additions & 2 deletions docs/qa/platform-checklist/areas/records-forms.json
Original file line number Diff line number Diff line change
Expand Up @@ -3030,7 +3030,7 @@
"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",
"since": "v15",
"status": "active",
"revision": 1,
"revision": 2,
"priority": "P1",
"surface": "mixed",
"personas": [
Expand Down Expand Up @@ -3168,7 +3168,7 @@
"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)",
"packages/objectql/src/hook-binder.ts#bindHooksToEngine (bindHooksToEngine: per-event × per-object engine.registerHook with priority; unresolved-body / empty-target skips)",
"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)",
"packages/spec/liveness/hook.json#retryPolicy (object/events/body/priority/async/condition/retryPolicy/timeout/onError all 'live'; label/description 'dead' but kept as docs)",
"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)",
"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)",
"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)",
"packages/qa/dogfood/test/showcase-public-form.dogfood.test.ts + hook-error-format.dogfood.test.ts (the two existing dogfood pins this item cites)"
Expand All @@ -3179,6 +3179,12 @@
"date": "2026-08-08",
"change": "initial — the hook coverage.json waiver was STALE (showcase ships 4 observable hooks); authored a lifecycle+condition+async+onError+priority item",
"ref": "claude/platform-test-checklist-ocwugl"
},
{
"revision": 2,
"date": "2026-09-09",
"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.",
"ref": "#15839"
}
]
},
Expand Down
Loading