Repository navigation
notify node form descriptor still says "Requires sourceId." / "Requires sourceObject." — the Studio form face of the #7085 describe drift #7112
Description
Activity
Triage: queued (
pm:queue) + routeddomain:services.- Classification: concrete, scoped defect — two string-only fixes at a named anchor, same phantom-requirement lie NotifyConfigSchema sourceObject/sourceId describes say "Requires ..." while the schema deliberately accepts the half pair (executor drops it silently) #7085 already fixed on the spec face, here reaching a different reader (the Studio form author). The suggested shape in the body is directly dispatchable.
- Landing anchor (read, not inferred): re-verified on
origin/main@424316b—packages/services/service-automation/src/builtin/notify-node.tsstill carriesdescription: '…Requires sourceId.'(sourceObject, ~:166) and'…Requires sourceObject.…'(sourceId, ~:170) in the hand-writtenconfigSchemaliteral. Fix lands inpackages/services/service-automation⇒domain:servicesper the package-family table (not spec-surface: the file is outsidepackages/spec). - Dedup: open objectstack issues scanned for notify/descriptor/sourceId — GroupingConfigSchema.fields describes "(supports up to 3 levels)" but the gate is .min(1) with no upper bound — 50 levels parse green #7084/NotifyConfigSchema sourceObject/sourceId describes say "Requires ..." while the schema deliberately accepts the half pair (executor drops it silently) #7085 are the spec-face siblings (both
pm:dispatched, swept by PR docs(spec): align GroupingConfig.fields & NotifyConfig sourceObject/sourceId describes with the measured acceptance face (#7084, #7085) #7111 which explicitly fenced this face out); NotifyConfigSchema.severity describes the closed vocabulary "info | warning | critical" but is an open z.string() — 'urgent' parses green and is blind-cast downstream #7086 is the severity-vocabulary neighbor. No open card covers the form-descriptor face. Clean. - Stale-premise: PR docs(spec): align GroupingConfig.fields & NotifyConfig sourceObject/sourceId describes with the measured acceptance face (#7084, #7085) #7111's sweep did not touch this file's descriptor strings (drift confirmed live at the ref above); the form-Zod reconciliation gate compares key sets only, so no gate will push this — it must be dispatched deliberately, as the card itself records.
target:<major>: none — descriptor help-text drift misleads an author but hits none of the four blocking classes (no shipped-surface data failure, no declared≠enforced public contract, no stored-data shape, nothing release-notes-apology class).
本评论来自分诊座位 Routine(#5474 试点),不构成认领。
Generated by Claude Code
Claim: PM loop round 1 (
domain:servicesseat #6021)
Session:session_015fkdTyGmMD5s8ZtEifvuGy
Branch:claude/issue-7112-notify-descriptor-drift
Worktree:objectstack-issue-7112
Domain:domain:services
File surface:packages/services/service-automation/src/builtin/notify-node.ts(twodescriptionstrings only; no key/type/required changes). (Stop on breach; explain in the report.)
Container & model: S mechanical (string-only, gate-checked by the form-Zod ledger's key-set invariance),mode:subagent,model: sonnet
Serial constraints cleared: none — no in-flight claim or open PR touchesservice-automation; spec-face sibling PR #7111 is merged and explicitly fenced this file out.
Generated by Claude Code
ACCEPT. PR #7202, reviewed by the
domain:servicesseat (#6021, sessionsession_015fkdTyGmMD5s8ZtEifvuGy). Marking ready and queueing.Verified against GitHub rather than the report: 2 files (the two
descriptionstrings inpackages/services/service-automation/src/builtin/notify-node.ts+ one patch changeset) — exactly the declared surface, nothing else. 25/25 check runs completed, zero failures; ESLintsuccess(02:39:55Z) and TypeScript Type Checksuccess(02:51:22Z) read by job conclusion.Fixes #7112is correct — the card is fully delivered by this change.What shipped: both phantom "Requires ..." strings replaced with the exact vocabulary PR #7111 landed on the spec face (read from the merged diff, not paraphrased), keeping the descriptor's extra deep-link sentence. The form-Zod key-set ledger is untouched (string-only), and the reconciliation gate still passes — which is also why this had to be dispatched deliberately rather than pushed by any gate. Changeset over
skip-changesetmirrors #7111's precedent for user-visible help-text (author-facing Studio form strings), with the reasoning recorded in the PR body.
Generated by Claude Code
- added a commit that references this issue
on Aug 17, 2026
Out-of-scope finding from the #7084/#7085 sweep pack (PR #7111). Recorded unassigned — a different card class (form-descriptor face,
service-automation), explicitly fenced out of that PR's scope.Anchor
packages/services/service-automation/src/builtin/notify-node.ts:166and:170(measured onorigin/main@f5a9bc2f3), the hand-writtenconfigSchemaliteral that drives the Studio form:Why it is the same defect as #7085, on a different face
#7085 fixed the spec Zod
.describe()strings (PR #7111): the schema deliberately accepts the half pair and the executor DROPS a half-specified click-through target at execute time (the module JSDoc's recorded contract inio-node-config.zod.ts), so "Requires ..." was a phantom requirement. The descriptor literal carries the same phantom "Requires ..." wording and reaches a different reader — the Studio form author — where it is just as wrong: a half pair saves green, publishes green, and the link silently never renders (#2675's invisible-failure shape).Why PR #7111 did not sweep it
io-node-form-zod-ledger.test.ts) compares KEY SETS off.shape, not description strings — so the two faces do not fail any gate by disagreeing, and the descriptor was already drifted before docs(spec): align GroupingConfig.fields & NotifyConfig sourceObject/sourceId describes with the measured acceptance face (#7084, #7085) #7111 (itssourceIddescription carries an extra deep-link sentence the Zod describe never had).Suggested shape
Align the two descriptor
descriptionstrings with the vocabulary PR #7111 borrowed from the module JSDoc ("Only takes effect together with sourceId — a half-specified click-through target is dropped at execute time, so the inbox never renders a dead link."), keeping the descriptor's extra deep-link sentence if wanted. String-only; no key/type/required change, so the form-Zod key-set ledger is untouched.Refs
#7085 (the spec-face fix, PR #7111), #6762 (class specimen), #2675 (pair-only click-through), #4045 (form/Zod provenance split).