fix(spec)!: ImportRequest.runAutomations declares the default the import route actually applies (#6704) - #7015
Merged
Conversation
…mport route actually applies (#6704) `POST /api/v1/data/:object/import` and its async twin have fired triggers for an omitted `runAutomations` since #2922 — the server decides with `body?.runAutomations !== false`. The schema declared the opposite twice: `.default(false)` in the published JSON Schema, and "off by default for bulk" in the describe prose that renders into the reference tables for BOTH defs. Maintainer ruling 2026-08-09 (#6704), disposition A — the spec follows the runtime. `packages/rest/src/import-prepare.ts` is untouched; runtime behaviour is unchanged. - `.default(true)` with prose stating opt-out must be explicit. - Both reference tables regenerated (ImportRequest + CreateImportJobRequest). - Declared per key in DEFAULT_CHANGES_BY_MAJOR[17]. - ADR-0087 D3 entry `import-run-automations-declared-default-corrected`; no D2 conversion and no tombstone — no key is removed, and an HTTP request body is neither authored nor persisted. - New agreement pin asserts the materialised value EQUALS the server decision; neither half alone is the fact this card is about. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PiRUoQkTSBBmpyXBY3cVn2
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
Contributor
📓 Docs Drift CheckThis PR changes 1 package(s): 113 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:
|
This was referenced Aug 9, 2026
os-zhuang
marked this pull request as ready for review
August 9, 2026 09:35
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #6704
POST /api/v1/data/:object/import— and its async twinPOST /api/v1/data/:object/import/jobs— has fired triggers and hooks for an omittedrunAutomationssince #2922. The schema declared the opposite, and said so twice. This PR moves the declaration to the runtime, per the maintainer ruling.⛔
packages/rest/src/import-prepare.tsis untouched. Runtime behaviour is unchanged in every direction; the decision line was verified read-only and is now pinned.Premise re-verified on
origin/mainbefore implementingBoth halves of the issue's claim hold at
97b0798(mainat dispatch):packages/spec/src/api/export.zod.ts:343runAutomations: z.boolean().default(false)+ prose "off by default for bulk"packages/rest/src/import-prepare.ts:262const runAutomations = body?.runAutomations !== false;premise_still_valid: true.Consumption-radius sweep — direction stated
Swept in the prefix direction (who consumes the schema), i.e.
'...@objectstack/spec', per #6218. Result confirms the issue's central claim and is why no gate could ever see the divergence:CreateImportJobRequestSchemaanywhere in the tree is the declarativeImportJobApiContractscatalog entry — a declaration, not a parse.Each half was internally consistent; only their disagreement was wrong. That also means no in-tree consumer changes behaviour, and the affected consumer class lives outside this repo (a client that validates its request and sends the parsed object).
What changed
.default(false)becomes.default(true), with prose stating automations run by default and that opt-out must be explicit, per the 数据导入:批量 insert 给 Hook 的输入形状与单条不一致(installFlatInput 失效);「运行自动化与触发器」开关是摆设且默认值应为选中 #2922 rationale.ImportRequestandCreateImportJobRequestincontent/docs/references/api/export.mdx(lines 82 and 371).DEFAULT_CHANGES_BY_MAJOR[17]— two rows, becauseCreateImportJobRequestSchemaisImportRequestSchema(one object, two separately published defs) and the ratchet names keys, not schemas.import-run-automations-declared-default-corrected. No D2 conversion and no tombstone: no key is removed, and an HTTP request body is neither authored nor persisted — the dispositionnotification-list-cursor-retired(GET /api/v1/notifications 从不解析它声明的请求 schema ——cursor被静默丢弃(SDK 分页永远第一页),limit默认 20 声明 vs 50 实现 #6361) already takes for the sibling default on this major.The dispatch located
DEFAULT_CHANGES_BY_MAJOR[17]inpackages/spec/src/migrations/registry.ts. It is not there — the gate's own copy-pasteable prescription namespackages/spec/scripts/lib/default-changes.ts, andregistry.tsonly mentions the table in prose. Followed the gate. (registry.tsis still edited here, for the separate ADR-0087 semantic entry.)Tests — the agreement, not either half
New
packages/rest/src/import-run-automations-agreement.test.ts. This is the only place in the repo that can assert the fact the card is about:@objectstack/restdepends on@objectstack/spec, so both the schema andprepareImportRequestare reachable from it and from nowhere upstream.Asserting
parse({}).runAutomations === truepins the schema; assertingprepare({}).runAutomations === truepins the server. Only asserting they are equal, over an input set including the omitted key, pins that the divergence is closed. Plus a spec-local declaration pin inexport.test.ts, and the pre-existing#2922server block inimport-prepare.test.tsis left as-is and stays green.Reverse verification — direction predicted first
Predicted before running: restoring
.default(false)turns RED exactly the three cases involving an omitted key, leaves the three explicit-spelling cases GREEN (they never disagreed), and additionally turns the ratchet RED as stale. Measured, both confirmed:That assertion message is the defect verbatim.
import-prepare.test.tsstayed fully green throughout the reverse run — which is the evidence that the red is purely the declaration half and the runtime never moved.The ratchet's independent direction:
A declaration that cannot outlive the fact it describes.
Verification
@objectstack/spec— 349 files / 9094 tests passed@objectstack/rest— 74 files / 1148 tests passedpnpm lintexit 0;turbo run typecheck121/121;turbo run build70/70; examples + downstream-contract typecheck exit 0.github/workflows/lint.yml, run one by one — all pass. (check:i18n/check:i18n-coverage/check:app-nav-i18nfailed first on an unbuilt@objectstack/cliin the fresh worktree, saying so themselves — "Nothing was checked" — and pass after the build.)node scripts/check-adr-0087-registration.mjs --base origin/main:pnpm --filter @objectstack/spec check:authorable-surfacegreen;check:generated --reconcile-only,check:spec-changes,check:upgrade-guide,check:docsgreen.authorable-surface.base.jsonwas not rewritten (keys did not drift, only defaults) — no re-anchoring performed.Maintainer ruling (2026-08-09), quoted verbatim
裁决(不可重裁):
Generated by Claude Code