Repository navigation
docs(automation): the notify click-through default says a before-create run links to its record only when the caller wrote the id - #30926
Conversation
…reate run that has no record id yet Four texts said a run started by a record change other than a delete links its notification to that record. A before-create run is such a change and has no record id until the driver issues one at the write, after the hook, so the notification links nowhere unless the caller wrote the id. The spec describes and docblock, the notify node's docblock, descriptions and null failure text, the Flows guide and the automation skill's example now say so, and two pins hold the before-create cases. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01L9qibwUogojquWFFVyz422
…ick-through wording Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01L9qibwUogojquWFFVyz422
📓 Docs Drift Check3 anchor(s) derived from 2 changed package(s); no hand-written page names any of them, so this run has nothing to list — not a clean bill of health. This check sees only pages that NAME a derived anchor: one that documents this change in prose, or enumerates it in an authoring dialect, names none and stays invisible to it on every run. What this run could not see
Coarse fallback — 170 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): Which tree this was computed onThis run read A worktree cut from an older # while this PR is open — GitHub drops the merge commit once it closes
git fetch origin 6337c092fbfff6e1f12d1da144adb1ac43b05c7a && git checkout 6337c092fbfff6e1f12d1da144adb1ac43b05c7a
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 26c965cb8f61ca59804d55e27e737bf7ff91b383 7cf467745e681280fc3a6a7130f10ec308c61c8c && git checkout -B drift-repro 26c965cb8f61ca59804d55e27e737bf7ff91b383 && git merge --no-ff 7cf467745e681280fc3a6a7130f10ec308c61c8c
node scripts/docs-audit/affected-docs.mjs --json 26c965cb8f61ca59804d55e27e737bf7ff91b383 |
|
domain:spec#1 · os-tesla · session_01L9qibzzqHZdAVqgBAvxXKB Contract reviewServed-tier: Inputs: card #30759 (body + 4 comments: the sequencing note 6674423070, triage 6674582930, the claim 6683585123, the os-dev-report 6684368393), PR #30926 (body, 7-file list, net diff ① Derived judgments
② Semver level
③ Boundary flags
Tier H ( ④ Design judgment
No must-fix. Check-runs on Implemented-by: VERDICT: PASS |
…ps the pair rather than defaulting it The notifyStringSlotSchema and resolveStringSlot docblocks still carried the retired 'leaves the key unset' sentence; both now match the describes and the failure text. The click-through bullet is re-wrapped. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01L9qibwUogojquWFFVyz422
|
domain:spec#1 · os-tesla · session_01L9qibzzqHZdAVqgBAvxXKB Contract reviewServed-tier: Delta review of head ① Derived judgments
② Semver level
③ Boundary flags
④ Design judgment
No must-fix. No should-fix outstanding. Check-runs on Implemented-by: VERDICT: PASS |
|
domain:spec#1 · os-tesla · session_01L9qibzzqHZdAVqgBAvxXKB 维护者速读
席位意见:可以落地,待授权批准。 席位核对ACCEPT · seat
|
Requested by Tesla · project thread
Fixes #30759
Clause-②: no
Metadata-protocol: none
Text only; the runtime is unchanged. Triage 6674582930 routed the card to
domain:specas one PR over every surface that carries the wording, so no second dialect opens. Thenotify-node.tshunks aredomain:servercode carried by the spec lane per that triage.维护者速读
sourceId求值为null是"写了键但为空",半对被丢弃、不回退到默认。参考页io-node-config.mdx随之再生成。packages/spec/src/automation/io-node-config.zod.ts(docblock + 两条 describe)、packages/services/service-automation/src/builtin/notify-node.ts(docblock、null失败文案、两条 description)、skills/objectstack-automation/SKILL.md:125。pnpm --filter @objectstack/service-automation exec vitest run src/builtin/notify-node.test.ts,预期 25/25 通过,其中两条新 pin:无 id 的 beforeInsert 运行不写 source,调用方写了 id 的则链接。skills/**)——席位复审后交 os-zhuang 批准。What changes
idonly when the caller wrote one).packages/spec/src/automation/io-node-config.zod.ts: theNotifyConfigSchemadocblock bullet and thesourceObject/sourceIddescribes.packages/services/service-automation/src/builtin/notify-node.ts: thedefaultClickThroughOfdocblock and thesourceObject/sourceIdconfig descriptions (the wording source).content/docs/automation/flows.mdx: the click-through paragraph.skills/objectstack-automation/SKILL.md:125:// trigger record (not on delete/before-create), if any— the comment edited in place, net +0 lines, no re-wrap.content/docs/references/automation/io-node-config.mdx: regenerated from the describes bycheck:generated --fix, not hand-edited.nullclause.notify-node.ts'ssourceIdfailure text andflows.mdxsaid anull"leaves the key unset". Both now say it is a writtensourceIdthat resolves to nothing, so the pair is dropped rather than defaulted — whatdefaultClickThroughOfdoes, since it reads the written config, not the evaluated value.notify click-through defaults to the trigger recorddescribe ofnotify-node.test.ts: a notify on abeforeInsertrun whose record carries no id writes nosource(so nosource_object/source_id) and no URL; one whose caller wrote the id links to it..changeset/30759-notify-click-through-before-create.md:@objectstack/specpatch,@objectstack/service-automationpatch,@objectstack/skillspatch.Measured on
origin/main6ff27b3 before editing:record-before-create→beforeInsertandrecord-before-write→beforeInsert+beforeUpdate(packages/triggers/trigger-record-change/README.mdmapping table;record-change-trigger.ts:520 treatsbeforeInsertas the insert event), so the insert leg ofrecord-before-writeandrecord-before-createare the only before-create shapes. On that legbuildContexthas noctx.resultand noctx.previous, sorecordisctx.input.data(:477-485);driver-memorycreateissuesid: data.id || this.generateId(object)at the write (:845);triggerRecordOfneeds bothcontext.objectandcontext.record.id(:155-159).Why
A before-create run is "a record change other than a delete", so the shipped text promised a link the runtime cannot make: the notification links nowhere, not to a dead link. An author or an AI leaving the pair out on a before-create notify expected a link that never comes.
Tests
pnpm --filter @objectstack/service-automation exec vitest run --maxWorkers=2 src/builtin/notify-node.test.tsunder the verify lock:Test Files 1 passed (1),Tests 25 passed (25)(VERDICT command-exit 0).triggerRecordOfmutated on disk toreturn object ? { object, id: id ?? 'PIN_ABLATION_ID' } : undefined(1 hit of the marker, 0 of the original line), same run →Tests 2 failed | 23 passed (25):writes no source on a before-create run whose record has no id yetandlinks nowhere on a run with no trigger recordboth red (VERDICT command-exit 1). Restored withgit checkout HEAD -- <path>:git hash-objectequals the HEAD blob,git diff HEADempty; rerun 25/25.pnpm --filter @objectstack/service-automation typecheck: VERDICT command-exit 0.pnpm --filter @objectstack/spec typecheckVERDICT command-exit 0;pnpm --filter @objectstack/spec testVERDICT command-exit 0,Tests 25838 passed | 1 todo (25839);pnpm --filter @objectstack/service-automation testVERDICT command-exit 0,Tests 3431 passed (3431).test:repo(the vitestrepoproject) is CI's run (Test Core), not run here.Verification
pnpm --filter @objectstack/spec build(dts emitted 38/38), thencheck:generated --fix: 1 of 14 artifacts stale (check:docs), regeneratedcontent/docs/references/automation/io-node-config.mdx(2 lines), nothing else moved.node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstackat 87404ae (the final commit): 114 lines, every one run with</dev/null, exit codes landed on disk before any pipe, reconciled with--ran:114 derived, 114 run, 0 NOT-MEASURED, 0 UNRUN, every line exit 0 on the final tree. Three lines first exited 3 (PREREQUISITE NOT MET, nothing measured):check-plugin-teardown-shape.mjs --self-test(its positive control is a commit the shallow clone could not reach; fetched that sha, rerun → exit 0, 48 cases),check:skill-examplesandcheck:dual-build-cjs-loads(nodist/for the unbuilt packages;pnpm buildunder the lock, VERDICT command-exit 0, rerun → exit 0: 283 prose examples type-check; 116 entries / 71 packages / 2456 cjs files load). The ran list is/mnt/project-files/spec-seat-1/out/30759-gates-ran-87404ae2.list.pnpm check:skill-frame-freshnessexit 0;pnpm check:dev-prereqsexit 1 — "the workspace is not built" (71 of 106 packages have no dist in this worktree, which built only@objectstack/specand theservice-automationclosure); a precondition of this box, not a finding about the diff.node scripts/check-skills-token-ratchet.mjs:skills/objectstack-automation/SKILL.md6446 tokens (ceiling 6449; headroom 3), from 6443 on main.node scripts/pm/check-governed-merges.mjs --test skills/objectstack-automation/SKILL.md …→ Tier H (skills/**). Changed lines: 76 additions + 22 deletions, generated file included.skills/**readings, lines:skills/objectstack-automation/SKILL.md452 before / 452 after; the whole published catalog (11SKILL.mdfiles) 4525 before / 4525 after. Tokens (check-skills-token-ratchet): 6443 before / 6446 after.gh api search/issues): docs(skills): the automation skill teaches the mail option formatter for a notice's select label and the active-member rule for a user target; the docs page gains organization-authored assignment rules #30866 (skills/objectstack-automation/SKILL.md, a different hunk at :127 and later; no overlap with :125) and docs(skills): the platform skill's operations reference says the official image refuses to start without its database and secrets #30875 (skills/objectstack-platform/**, no overlap). None touchesnotify-node.tsorio-node-config.zod.ts. The later lander mergesmain.Acceptance notes
.changeset/30254-notify-default-link-skill.mdand.changeset/30689-notify-click-through-default-describe.md, repeat the old enumeration in their prose. Not edited here (another PR's release input); this PR's changeset states the corrected enumeration, and the release compiles both. Noted for the release-notes compiler, not filed.packages/triggers/trigger-record-change/README.md's mapping table is the only in-repo text that statesrecord-before-writefires onbeforeInsert+beforeUpdate; the code spells the union through its hook registration, not a literal table. Read-only observation, not a defect.notify-node.tsdescriptions were not byte-identical before this PR (the spec adds "a literal," and "not defaulted"); this PR keeps each text's own frame and changes the shared enumeration and the before-create clause in all of them.Human Minimum
packages/specholds no runtime logic.pnpm lintis CI's run.main, one pull request.packages/spectouched: its generated artifacts are regenerated and committed.content/docs/references/,packages/*/CHANGELOG.mdorcontent/docs/releases/.🤖 Generated with Claude Code
https://claude.ai/code/session_01L9qibwUogojquWFFVyz422