fix(spec): send a top-level flow trigger to the START node config, not to a type rename - #14735
fix(spec): send a top-level flow trigger to the START node config, not to a type rename#14735os-sam wants to merge 3 commits into
trigger to the START node config, not to a type rename#14735Conversation
…t to a `type` rename
`FlowSchema` aliased `trigger` and `triggerType` to `type`, and `type` is the
flow KIND enum (`autolaunched` | `record_change` | `schedule` | `screen` |
`api`). An author who took that rename landed on `Invalid option: expected one
of "autolaunched"|…` one round later with the trigger binding still nowhere.
Both keys move to the `guidance` table beside `object` / `objectName` /
`schedule`, naming where the binding really lives: the START node's `config`
(`{ objectName, triggerType, condition }`, `triggerType` a `record-*` token).
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017RbbUMnxkUnWhE4j94v8FE
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017RbbUMnxkUnWhE4j94v8FE
…low.zod line shift `node scripts/check-system-context-census.mjs --fix` — pure line rot from the guidance entries added above the cited line. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017RbbUMnxkUnWhE4j94v8FE
📓 Docs Drift CheckThis PR changes 1 package(s): 10 hand-written doc(s) NAME something this change touched and may need an implementation-accuracy re-verification:
⛔ 2 release-owned page(s) also name something this change touched. These are read-only:
What this run could not see
Coarse fallback — 128 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 ac50f706795e1e5df86a9fd1cf7c70112826c33c && git checkout ac50f706795e1e5df86a9fd1cf7c70112826c33c
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin dbf115284295b1989d4648dbfbd7e5f3f96357dc efe488c42ce309a010a3e9d6a490c4e74db3a8ae && git checkout -B drift-repro dbf115284295b1989d4648dbfbd7e5f3f96357dc && git merge --no-ff efe488c42ce309a010a3e9d6a490c4e74db3a8ae
node scripts/docs-audit/affected-docs.mjs --json dbf115284295b1989d4648dbfbd7e5f3f96357dc
|
⛔ merge queue 构建失败 — 先分诊,再决定要不要重排队列构建 33695118192 红了。队列跑的是全量套件(PR 侧 CI 只跑 affected 子集), 失败的 job(日志抽取,best effort):
跨 PR 相同签名(24h,按失败测试文件聚合):
历史信号:
分诊清单:
Generated by Claude Code · merge-queue-triage workflow (#4859) |
⛔ merge queue 构建失败 — 先分诊,再决定要不要重排队列构建 33697809557 红了。队列跑的是全量套件(PR 侧 CI 只跑 affected 子集), 失败的 job(日志抽取,best effort):
跨 PR 相同签名(24h,按失败测试文件聚合):
历史信号:
分诊清单:
Generated by Claude Code · merge-queue-triage workflow (#4859) |
|
Re-enqueue receipt (
Generated by Claude Code |
⛔ merge queue 构建失败 — 先分诊,再决定要不要重排队列构建 33704757465 红了。队列跑的是全量套件(PR 侧 CI 只跑 affected 子集), 失败的 job(日志抽取,best effort):
跨 PR 相同签名(24h,按失败测试文件聚合):
历史信号:
分诊清单:
Generated by Claude Code · merge-queue-triage workflow (#4859) |
|
Second kick — re-queueing stops here (
Generated by Claude Code |
|
Unlock re-check (
Generated by Claude Code |
Fixes #14337
FlowSchema'saliasestable pointedtriggerattype, and the rename it prescribed cannot be taken.typeis the flow KIND, so an author who follows the advice lands onInvalid optionone round later with the trigger binding still nowhere. Both keys move to theguidancetable, beside theobject/objectName/scheduleprescriptions that already name the START node'sconfig.No accept/reject change. A top-level
trigger/triggerTypewas refused before and is refused now;FlowSchema's accepted keys and itstypeenum are untouched. Only the prescription the refusal carries changes.The sibling was unmeasured — it is measured now, and it reproduces
The card flagged
triggertype: 'type'as probably the same mistake without measuring it. Measured onorigin/main(itsflow.zod.tsrestored on disk, everything else at this branch), verbatim:That is the same dead end as
trigger: the enum the rename points at contains norecord-*token at all, so the second round cannot succeed either. The alias table is probed case- and separator-insensitively (aliases[aliasProbe(key)],packages/spec/src/shared/suggestions.zod.ts:463), which is why the source spellingtriggertypewas answering an authoredtriggerType. Fixed in this PR, as the card directed.After this change, the same two inputs:
Where the binding really lives (cited, not paraphrased)
config, as{ objectName, triggerType, condition }packages/spec/src/automation/flow-trigger-kind.ts:12record-*token is the lifecycle-event grammarpackages/spec/src/automation/flow-trigger-kind.ts:74(triggerType.startsWith('record-')resolvesrecord_change)typenames the KIND, and contains no event tokenpackages/spec/src/automation/flow.zod.ts:669guidanceis exact-key and suppresses the rename;aliasesrenders "Did you mean X -> Y?"packages/spec/src/shared/strict-object.ts:122,packages/spec/src/shared/suggestions.zod.ts:445and:463One measured consequence, stated rather than hidden
The alias row was probe-matched, so it also answered the folded spellings;
guidanceis exact-spelling by design (case folding is the rename channel's job). A non-canonicaltriggertypetherefore now gets the bare rejection instead of the rename it could not take. That is a deliberate trade - no advice beats confidently wrong advice - and it is pinned inflow.test.tsso it cannot drift back into a rename unnoticed.Verification (all on
efe488c42, the final commit; heavy runs underscripts/pm/os-verify-lock.sh)@objectstack/spec-flow.test.ts,flow-trigger-kind.test.ts,strict-object.test.ts,alias-integrity.test.ts,suggestions.test.ts,visible-when-alias-guidance.test.tsVERDICT command-exit 0)@objectstack/spec typecheck(tsc --noEmit+check:scripts-typecheck+check:test-typecheck)tsconfig.test.json, so the new pins are type-checkedcheck:generated(afterpnpm --filter @objectstack/spec build)check:authorable-surfaceandcheck:api-surfaceamong them - the guidance change projects into no generated pagecheck:system-context-censuscheck:doc-authoring@objectstack/lint(lint-flow-patterns,validate-flow-trigger-readiness,flow-variable-scope,authoring-rule-input-tier)@objectstack/service-automation(engine,canonicalize-stored-flow,flow-cold-boot-bind)node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstackcheck:nul-bytes,check:skill-examples256 blocks,check:doc-anchors,check:corpus-claim-drift,check:cross-package-test-inputs,check:test-source-alias,check:type-check-coverage,check:empty-changeset,check:changeset-no-major,check:adr-0087-registration, and the docs family)check:test-completeness,check:type-check-debtturbo run testlog, the other a fully built workspace) - left to CI, which has bothReverse verification
Removing the guidance entries on disk (
flow.zod.tsrestored toorigin/main, mutation confirmed by grep counts before the run) turns exactly the three new prescription pins red:The two positive controls stay green under the same ablation, correctly - they pin the claim, not the change. The file was restored with
git checkout HEAD -- FILE, spelled as an absolute pathand the restore proved by blob hash (abc5dc708...on disk equalsHEAD:packages/spec/src/automation/flow.zod.ts), withgit diff HEADempty afterwards.The third commit on this branch re-anchors a
file:linecitation oncontent/docs/permissions/system-context.mdxfromflow.zod.ts:685to:702, because this change inserts 17 lines above it. That commit is load-bearing, not cosmetic: reverting only that file makescheck:system-context-censusfail with[anchor-is-not-a-read-site]on:685plus[ledger-row-unused]on:702. The anchored line's content is byte-identical at both numbers.Notes
.not.toContainon thetrigger->typestring, in a dedicated test that also pins the prescription.@objectstack/spec: patch, customer-facing text, no issue ids.Generated by Claude Code
Generated by Claude Code