Uh oh!
There was an error while loading. Please reload this page.
docs(automation): add scheduled jobs and email templates guides - #10273
Conversation
Both kinds are first-class authorable metadata with a generated reference and no how-to page: `job` had one bullet in automation/index.mdx and no page, and `emailTemplates` returned zero hits across the hand-written docs. - `jobs.mdx` leads with the job vs `schedule`-type flow decision. The two share their timing: a schedule flow is registered against the same IJobService as `flow-schedule:<name>`, so cluster leader election and the schedule forms are identical for both. What differs is what runs, who may change it after deploy (`job` is allowRuntimeCreate:false / allowOrgOverride:false), the identity its writes carry, and where its run history lands. - `email-templates.mdx` documents authoring against the canonical EmailTemplateDefinitionSchema, the three-rung locale ladder (exact, en-US, then deterministic for no-locale calls only), the notify-node path, and the seed-not-clobber materialization into sys_email_template. Every TypeScript sample carries an `os:check` marker, so check:skill-examples type-checks all three against the built @objectstack/spec. `.claude/workflows/docs-accuracy-audit.js` is regenerated by `scripts/docs-audit/check-audit-scope.mjs --write` — mechanical, and required by check:docs-audit-scope for any new hand-written page. Part of #10206 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GawRwpD44VwBDVy3hs77AX
os-elon
commented
Aug 21, 2026
Landed by the PM under the maintainer's explicit instruction — audit record. This is a governed PR ( Provenance — who, what, where. The repository owner, in the PM session driving epic #10206, 2026-08-20. Authorization verbatim: 「你帮我处理合并吧」. Their per-PR verdict on this one, verbatim: 「可合」 — 「证据规格最高的一张:premise 三核 + 反向验证还自纠了一次 no-op 突变」. PM position, recorded rather than dropped. I stated before acting that an agent-executed governed merge removes the human click the fence treats as the review record, and that the audit would flag it. The maintainer instructed anyway. The decision is theirs; this is the record of it, not a silent reinterpretation of the rule. Landing route. A direct merge is refused by repository rules ( Generated by Claude Code |
Fixes#10211
Part of #10206
jobandemail_templateare both first-class authorable metadata with a generatedreference page and no how-to. This adds the two guides and puts them in the Automation
sidebar.
Premise check
All three of the PM's claims verified against
origin/mainbefore writing:references/system/job.mdx182 lines,references/system/email-template.mdx95 linesautomation/index.mdxmentions jobs in one bullet, no Card, no pageemailTemplatesreturns zero hits across the hand-written docscontent/docs/, generated pages includedEmailTemplateDefinitionSchema, not the removedEmailTemplateSchemaWhat the measurement changed
The card proposed leading
jobs.mdxwith "job versus aschedule-type flow". Thatframing is right, but the obvious axis for it is wrong, so the page says so explicitly.
A
schedule-type flow does not own a timer.ScheduleTriggerregisters eachschedule-triggered flow as a job named
flow-schedule:plus the flow name, and hands itto the same
IJobService(packages/triggers/trigger-schedule/src/schedule-trigger.ts).So the two share their schedule forms, their adapter, and their cluster leader election —
including the per-job
lock.acquire('job:' + name)inpackages/services/service-job/src/cron-job-adapter.ts. Cluster behaviour thereforecannot be the deciding axis, and
kernel/cluster.mdx§1's "aschedule-triggered Flowfires once on every node" is a motivating bug class the document exists to close, not a
current-state claim. §5.1 is the current one, it still holds, and it is what the page
cross-links.
What actually decides is what runs, who may change it after deploy (
jobisallowRuntimeCreate: false/allowOrgOverride: false— a code artifact byconstruction, since
handlernames a key in the compiled bundle's function table), theidentity the run's writes carry, and where run history lands.
Deliberately not documented
Per the card's "an undocumented gap is smaller than a documented fiction":
clusterScope/leaderStrategyauto-wiring — schema accepts the annotations, noruntime consumes them (cluster.mdx §5.1 marks it Phase 4). The page documents the lock
that does work and says nothing about declaring scope.
jobsroutes on the client are dataimport jobs, unrelated. Observability is documented as
sys_job/sys_job_runrecords plus
IJobService.getExecutions.variables[].typecoercion — declared, and the renderer does not coerce by it. Itis documented as an authoring hint; only
requiredis described as enforced, becauseonly
requiredis (MISSING_VARIABLES).Verification
Every TypeScript sample carries an
os:checkmarker, socheck:skill-examplestype-checks all three against the built
@objectstack/spec— this is the acceptancecriterion "every code sample validates against the real schema", made machine-checkable
rather than asserted. Confirmed the blocks are actually extracted, not skipped:
Reverse-verified that green is not vacuous. Replacing
schedule:with the legacycron:alias in thedefineJobsample turned it red in the predicted direction:then restored, byte-identical, back to green. Both legs proved on disk by anchor count
before reading any result — the first mutation attempt was a
perl -0pino-op (zeromatch, exit 0, file untouched) and would have read as a passing ablation had the count
not been checked.
Gate union re-derived against the actual diff with
node scripts/pm/dispatch-gates.mjsand re-run at
98b5b91f3— all green. Re-derivation added four families thedispatch list did not name (
check:doc-authoring,check:doc-formula-expressions,check:pm-governed-merges,check:skill-frame-sync), pulled in by the.claude/filebelow.
The one file outside
content/docs/automation/.claude/workflows/docs-accuracy-audit.js— two added lines, generated bynode scripts/docs-audit/check-audit-scope.mjs --write.check:docs-audit-scopeis onthis card's own gate list and fails for any new hand-written page until that
derived list is regenerated; the workflow runs in a
node:vmwith no filesystem, so itcannot enumerate
content/docs/**itself. Mechanical and required, but naming it heresince the card scoped the surface to
content/docs/automation/.No changeset: this PR publishes nothing (docs content plus one derived workflow list), so
it carries
skip-changeset.Out of scope, filed separately
degradedconsumption is "not yet wired" — all three adapters have mapped it since #7072 #10266:JobHandler's docblock still claimsdegradedconsumption is "not yet wired"; all three adapters have mapped it since Job status vocabulary has nodegradedvalue — #5548's services half cannot compile or persist without wideningJobExecutionStatus+ the twosys_job*selects #7072. Comment-only drift inpackages/spec/**, which this card may not touch.locale: 'en', which noen-USsend can resolve — and it bypassesdefineEmailTemplateDefinition#10267: app-showcase's email template declareslocale: 'en', which noen-USsend can resolve, and it bypassesdefineEmailTemplateDefinition.Generated by Claude Code