From 9c15064b628ecffeeda52e33eace0bedefbcb413 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 6 Sep 2026 20:51:09 +0000 Subject: [PATCH 1/2] fix(spec): replace the croner-refused cron example in the DisasterRecoveryPlan docblock MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The `DisasterRecoveryPlanSchema` `@example` spelled its six-hourly backup schedule `'0 0/6 * * *'`. `0/6` is Quartz-style stepping, and `croner` — the only cron parser the platform runs, reached via `CronJobAdapter` -> `new Cron()` — refuses it: TypeError: CronPattern: Syntax error, stepping with numeric prefix ('0/6') is not allowed. Use wildcard (*/step) or range (min-max/step) instead. Measured against the croner 10.0.1 copy installed for `@objectstack/service-job`, with the sibling example `'0 2 * * *'` as the positive control (accepted). The replacement `'0 */6 * * *'` is accepted and fires at the same instants; it is the spelling this schema's own tests already use. Comment-only: no schema, no export, no accept-set movement. The docblock does publish into the shipped `dist/system/index.d.ts`, so the change is user-visible and carries a changeset. Claude-Session: https://claude.ai/code/session_01T6HeZvT9wdSJD1ZxJb5Eno Co-authored-by: Claude --- ...r-backup-schedule-croner-accepted-example.md | 17 +++++++++++++++++ .../spec/src/system/disaster-recovery.zod.ts | 2 +- 2 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 .changeset/dr-backup-schedule-croner-accepted-example.md diff --git a/.changeset/dr-backup-schedule-croner-accepted-example.md b/.changeset/dr-backup-schedule-croner-accepted-example.md new file mode 100644 index 0000000000..1d4dc11e59 --- /dev/null +++ b/.changeset/dr-backup-schedule-croner-accepted-example.md @@ -0,0 +1,17 @@ +--- +"@objectstack/spec": patch +--- + +The `DisasterRecoveryPlan` docblock example no longer teaches a cron dialect the platform's scheduler refuses. + +`DisasterRecoveryPlanSchema`'s `@example` block spelled its six-hourly backup schedule `'0 0/6 * * *'`. `0/6` is Quartz-style stepping. The only cron parser this platform runs is `croner` — reached through `CronJobAdapter`, which hands every scheduled expression to `new Cron(...)` — and it refuses that spelling. Measured against the `croner` 10.0.1 copy installed for `@objectstack/service-job`: + +``` +new Cron('0 0/6 * * *') + -> TypeError: CronPattern: Syntax error, stepping with numeric prefix ('0/6') + is not allowed. Use wildcard (*/step) or range (min-max/step) instead. +``` + +The example now reads `'0 */6 * * *'`, which the same parser accepts and which fires at 00:00, 06:00, 12:00 and 18:00 — the instants the old spelling was written to mean, and the spelling this schema's own tests and `integration/connector.test.ts` already use. The sibling example `'0 2 * * *'` on the same schema is accepted unchanged; it was the positive control for the measurement, so the refusal above is a reading rather than a broken probe. + +Nothing fires differently, because nothing fires at all: `BackupConfig.schedule` is declared-but-unwired and reaches no scheduler, and `CronExpressionInputSchema` judges no cron syntax at parse time by design (`shared/expression.zod.ts`) — so the bad example sat in a position that is deliberately undefended. The accept set of every schema is unchanged by this edit, and no export moves. What changes is what an author copying the example gets: the docblock publishes verbatim into the shipped `dist/system/index.d.ts`, so it is the text an editor shows on hover. diff --git a/packages/spec/src/system/disaster-recovery.zod.ts b/packages/spec/src/system/disaster-recovery.zod.ts index fef0d0530b..1a0d7c6d30 100644 --- a/packages/spec/src/system/disaster-recovery.zod.ts +++ b/packages/spec/src/system/disaster-recovery.zod.ts @@ -201,7 +201,7 @@ export type RTOParsed = z.infer; * rto: { value: 1, unit: 'hours' }, * backup: { * strategy: 'incremental', - * schedule: '0 0/6 * * *', + * schedule: '0 */6 * * *', * retention: { days: 90, minCopies: 5 }, * destination: { type: 's3', bucket: 'backup-bucket', region: 'us-east-1' }, * }, From 0e1867d18a5b37e1be6b135a6c746c9add3fa092 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 6 Sep 2026 20:54:41 +0000 Subject: [PATCH 2/2] =?UTF-8?q?fix(spec):=20use=20the=20enumerated=20six-h?= =?UTF-8?q?ourly=20spelling=20=E2=80=94=20the=20wildcard=20step=20closes?= =?UTF-8?q?=20the=20docblock?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The wildcard-step form croner's own error message suggests cannot be written inside a `/** ... */` block comment: the step separator is the comment terminator, so the file stops parsing. Measured — esbuild refused disaster-recovery.zod.ts at the example's own line, column 26, during `pnpm --filter @objectstack/spec build`. The enumerated equivalent carries no such sequence, is accepted by the same croner 10.0.1 copy, and was measured to fire at the identical instants (00:00, 06:00, 12:00, 18:00). Claude-Session: https://claude.ai/code/session_01T6HeZvT9wdSJD1ZxJb5Eno Co-authored-by: Claude --- .changeset/dr-backup-schedule-croner-accepted-example.md | 8 +++++--- packages/spec/src/system/disaster-recovery.zod.ts | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/.changeset/dr-backup-schedule-croner-accepted-example.md b/.changeset/dr-backup-schedule-croner-accepted-example.md index 1d4dc11e59..d7e0daa62e 100644 --- a/.changeset/dr-backup-schedule-croner-accepted-example.md +++ b/.changeset/dr-backup-schedule-croner-accepted-example.md @@ -4,14 +4,16 @@ The `DisasterRecoveryPlan` docblock example no longer teaches a cron dialect the platform's scheduler refuses. -`DisasterRecoveryPlanSchema`'s `@example` block spelled its six-hourly backup schedule `'0 0/6 * * *'`. `0/6` is Quartz-style stepping. The only cron parser this platform runs is `croner` — reached through `CronJobAdapter`, which hands every scheduled expression to `new Cron(...)` — and it refuses that spelling. Measured against the `croner` 10.0.1 copy installed for `@objectstack/service-job`: +`DisasterRecoveryPlanSchema`'s `@example` block spelled its six-hourly backup schedule `'0 0/6 * * *'`. A numeric prefix before the step (`0/6`) is Quartz-style stepping. The only cron parser this platform runs is `croner` — reached through `CronJobAdapter`, which hands every scheduled expression to `new Cron(...)` — and it refuses that spelling. Measured against the `croner` 10.0.1 copy installed for `@objectstack/service-job`: ``` new Cron('0 0/6 * * *') -> TypeError: CronPattern: Syntax error, stepping with numeric prefix ('0/6') - is not allowed. Use wildcard (*/step) or range (min-max/step) instead. + is not allowed. Use wildcard (asterisk-slash-step) or range (min-max/step) instead. ``` -The example now reads `'0 */6 * * *'`, which the same parser accepts and which fires at 00:00, 06:00, 12:00 and 18:00 — the instants the old spelling was written to mean, and the spelling this schema's own tests and `integration/connector.test.ts` already use. The sibling example `'0 2 * * *'` on the same schema is accepted unchanged; it was the positive control for the measurement, so the refusal above is a reading rather than a broken probe. +The example now reads `'0 0,6,12,18 * * *'`, which the same parser accepts and which fires at 00:00, 06:00, 12:00 and 18:00 — the instants the old spelling was written to mean. The sibling example `'0 2 * * *'` on the same schema is accepted unchanged; it was the positive control for the measurement, so the refusal above is a reading rather than a broken probe. + +The wildcard-step spelling croner's own error message suggests, and which this schema's tests use, is **not writable in this position**: inside a `/** … */` block comment the step separator closes the comment, and the file stops parsing (measured — esbuild refuses it at the example's own line). The enumerated form is the equivalent that survives a docblock, and both forms were measured to produce identical firing instants. Nothing fires differently, because nothing fires at all: `BackupConfig.schedule` is declared-but-unwired and reaches no scheduler, and `CronExpressionInputSchema` judges no cron syntax at parse time by design (`shared/expression.zod.ts`) — so the bad example sat in a position that is deliberately undefended. The accept set of every schema is unchanged by this edit, and no export moves. What changes is what an author copying the example gets: the docblock publishes verbatim into the shipped `dist/system/index.d.ts`, so it is the text an editor shows on hover. diff --git a/packages/spec/src/system/disaster-recovery.zod.ts b/packages/spec/src/system/disaster-recovery.zod.ts index 1a0d7c6d30..a30f4a5867 100644 --- a/packages/spec/src/system/disaster-recovery.zod.ts +++ b/packages/spec/src/system/disaster-recovery.zod.ts @@ -201,7 +201,7 @@ export type RTOParsed = z.infer; * rto: { value: 1, unit: 'hours' }, * backup: { * strategy: 'incremental', - * schedule: '0 */6 * * *', + * schedule: '0 0,6,12,18 * * *', * retention: { days: 90, minCopies: 5 }, * destination: { type: 's3', bucket: 'backup-bucket', region: 'us-east-1' }, * },