Skip to content

fix(spec)!: ImportRequest.runAutomations declares the default the import route actually applies (#6704) - #7015

Merged
os-zhuang merged 1 commit into
mainfrom
claude/issue-6704-import-runautomations-default
Aug 9, 2026
Merged

fix(spec)!: ImportRequest.runAutomations declares the default the import route actually applies (#6704)#7015
os-zhuang merged 1 commit into
mainfrom
claude/issue-6704-import-runautomations-default

Conversation

@os-zhuang

Copy link
Copy Markdown
Contributor

Fixes#6704

POST /api/v1/data/:object/import — and its async twin POST /api/v1/data/:object/import/jobs — has fired triggers and hooks for an omitted runAutomations since #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.ts is untouched. Runtime behaviour is unchanged in every direction; the decision line was verified read-only and is now pinned.

Premise re-verified on origin/main before implementing

Both halves of the issue's claim hold at 97b0798 (main at dispatch):

WhereWhat it says
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:

  • No request path parses an import body through this schema. The route reads the raw body.
  • The single reference to CreateImportJobRequestSchema anywhere in the tree is the declarative ImportJobApiContracts catalog 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

⚠️ Fork from the dispatch, recorded per instructions

The dispatch located DEFAULT_CHANGES_BY_MAJOR[17] in packages/spec/src/migrations/registry.ts. It is not there — the gate's own copy-pasteable prescription names packages/spec/scripts/lib/default-changes.ts, and registry.ts only mentions the table in prose. Followed the gate. (registry.ts is 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/rest depends on @objectstack/spec, so both the schema and prepareImportRequest are reachable from it and from nowhere upstream.

Asserting parse({}).runAutomations === true pins the schema; asserting prepare({}).runAutomations === true pins 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 in export.test.ts, and the pre-existing #2922 server block in import-prepare.test.ts is 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:

× omitted: the materialised value and the server decision are the same
✓ explicit true: the materialised value and the server decision are the same
✓ explicit false: the materialised value and the server decision are the same
× validating before sending cannot change the outcome
× the async job body agrees too
✓ an omitted flag is the only input whose declaration ever moved
Tests 3 failed | 11 passed (14)
AssertionError: expected { declared: false, server: true } to deeply equal { declared: true, server: true }

That assertion message is the defect verbatim. import-prepare.test.ts stayed 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:

❌ 2 DEFAULT_CHANGES_BY_MAJOR declaration(s) at major 17 no longer describe reality:
- api/ImportRequest:runAutomations: declared to end at true, but this build emits false
- api/CreateImportJobRequest:runAutomations: declared to end at true, but this build emits false

A declaration that cannot outlive the fact it describes.

Verification

  • @objectstack/spec349 files / 9094 tests passed
  • @objectstack/rest74 files / 1148 tests passed
  • pnpm lint exit 0; turbo run typecheck121/121; turbo run build70/70; examples + downstream-contract typecheck exit 0
  • Every gate enumerated from .github/workflows/lint.yml, run one by one — all pass. (check:i18n / check:i18n-coverage / check:app-nav-i18n failed first on an unbuilt @objectstack/cli in the fresh worktree, saying so themselves — "Nothing was checked" — and pass after the build.)
  • node scripts/check-adr-0087-registration.mjs --base origin/main:
    ✓ 1 declared-breaking changeset(s), each carrying an ADR-0087 disposition.
    [major+bang] registered import-run-automations-declared-default-corrected (new here)
    
  • pnpm --filter @objectstack/spec check:authorable-surface green; check:generated --reconcile-only, check:spec-changes, check:upgrade-guide, check:docs green. authorable-surface.base.json was not rewritten (keys did not drift, only defaults) — no re-anchoring performed.

Maintainer ruling (2026-08-09), quoted verbatim

裁决(不可重裁):

Maintainer ruling (2026-08-09): disposition A — the spec follows the runtime.ImportRequest.runAutomations becomes .default(true) with corrected describe prose (state that automations run by default and opt-out must be explicit, per the #2922 rationale); the generated reference tables follow. Runtime behaviour unchanged. [...] Changeset notes the declared-default flip of a published schema (a correction toward the actual shipped behaviour, not a behaviour change).


Generated by Claude Code

…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
@vercel

vercelBot commented Aug 9, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
ProjectDeploymentActionsUpdated (UTC)
objectstackIgnoredIgnoredAug 9, 2026 9:11am

Request Review

@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 1 package(s): @objectstack/spec.

113 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:

  • content/docs/ai/agents.mdx(via @objectstack/spec)
  • content/docs/ai/skills-reference.mdx(via @objectstack/spec)
  • content/docs/ai/skills.mdx(via @objectstack/spec)
  • content/docs/api/client-sdk.mdx(via @objectstack/spec)
  • content/docs/api/environment-routing.mdx(via @objectstack/spec)
  • content/docs/api/error-catalog.mdx(via @objectstack/spec)
  • content/docs/api/error-handling-client.mdx(via @objectstack/spec)
  • content/docs/api/error-handling-server.mdx(via @objectstack/spec)
  • content/docs/api/index.mdx(via @objectstack/spec)
  • content/docs/automation/approvals.mdx(via @objectstack/spec)
  • content/docs/automation/connectors.mdx(via @objectstack/spec)
  • content/docs/automation/flows.mdx(via @objectstack/spec)
  • content/docs/automation/hook-bodies.mdx(via packages/spec)
  • content/docs/automation/hooks.mdx(via @objectstack/spec)
  • content/docs/automation/index.mdx(via @objectstack/spec)
  • content/docs/automation/webhooks.mdx(via @objectstack/spec)
  • content/docs/automation/workflows.mdx(via @objectstack/spec)
  • content/docs/concepts/architecture.mdx(via @objectstack/spec)
  • content/docs/concepts/design-principles.mdx(via packages/spec)
  • content/docs/concepts/index.mdx(via @objectstack/spec)
  • content/docs/concepts/metadata-driven.mdx(via @objectstack/spec)
  • content/docs/concepts/metadata-lifecycle.mdx(via packages/spec)
  • content/docs/concepts/north-star.mdx(via @objectstack/spec)
  • content/docs/data-modeling/analytics.mdx(via @objectstack/spec)
  • content/docs/data-modeling/drivers.mdx(via @objectstack/spec)
  • content/docs/data-modeling/external-datasources.mdx(via @objectstack/spec)
  • content/docs/data-modeling/field-types.mdx(via @objectstack/spec)
  • content/docs/data-modeling/fields.mdx(via @objectstack/spec)
  • content/docs/data-modeling/formulas.mdx(via @objectstack/spec)
  • content/docs/data-modeling/index.mdx(via @objectstack/spec)
  • content/docs/data-modeling/objects.mdx(via @objectstack/spec)
  • content/docs/data-modeling/queries.mdx(via @objectstack/spec)
  • content/docs/data-modeling/schema-design.mdx(via @objectstack/spec)
  • content/docs/data-modeling/seed-data.mdx(via @objectstack/spec)
  • content/docs/data-modeling/validation-rules.mdx(via @objectstack/spec)
  • content/docs/data-modeling/validation.mdx(via @objectstack/spec)
  • content/docs/deployment/cli.mdx(via @objectstack/spec)
  • content/docs/deployment/tenancy-modes.mdx(via @objectstack/spec)
  • content/docs/deployment/troubleshooting.mdx(via @objectstack/spec)
  • content/docs/deployment/validating-metadata.mdx(via @objectstack/spec)
  • content/docs/getting-started/build-with-claude-code.mdx(via @objectstack/spec)
  • content/docs/getting-started/common-patterns.mdx(via @objectstack/spec)
  • content/docs/getting-started/examples.mdx(via @objectstack/spec)
  • content/docs/getting-started/quick-reference.mdx(via @objectstack/spec)
  • content/docs/getting-started/quick-start.mdx(via @objectstack/spec)
  • content/docs/getting-started/your-first-project.mdx(via @objectstack/spec)
  • content/docs/kernel/cluster.mdx(via @objectstack/spec)
  • content/docs/kernel/contracts/auth-service.mdx(via packages/spec)
  • content/docs/kernel/contracts/cache-service.mdx(via packages/spec)
  • content/docs/kernel/contracts/data-engine.mdx(via @objectstack/spec)
  • content/docs/kernel/contracts/index.mdx(via @objectstack/spec)
  • content/docs/kernel/contracts/metadata-service.mdx(via packages/spec)
  • content/docs/kernel/contracts/storage-service.mdx(via @objectstack/spec)
  • content/docs/kernel/index.mdx(via packages/spec)
  • content/docs/kernel/runtime-services/data-service.mdx(via @objectstack/spec)
  • content/docs/kernel/runtime-services/email-service.mdx(via packages/spec)
  • content/docs/kernel/runtime-services/examples.mdx(via @objectstack/spec)
  • content/docs/kernel/runtime-services/index.mdx(via packages/spec)
  • content/docs/kernel/runtime-services/queue-service.mdx(via packages/spec)
  • content/docs/kernel/runtime-services/sharing-service.mdx(via @objectstack/spec)
  • content/docs/kernel/runtime-services/sms-service.mdx(via packages/spec)
  • content/docs/kernel/runtime-services/storage-service.mdx(via @objectstack/spec)
  • content/docs/kernel/services-checklist.mdx(via @objectstack/spec)
  • content/docs/kernel/services.mdx(via @objectstack/spec)
  • content/docs/permissions/authorization.mdx(via @objectstack/spec)
  • content/docs/permissions/permission-sets.mdx(via @objectstack/spec)
  • content/docs/permissions/permissions-matrix.mdx(via @objectstack/spec)
  • content/docs/permissions/positions.mdx(via @objectstack/spec)
  • content/docs/permissions/rls.mdx(via @objectstack/spec)
  • content/docs/permissions/sharing-rules.mdx(via @objectstack/spec)
  • content/docs/permissions/system-context.mdx(via packages/spec)
  • content/docs/plugins/adding-a-metadata-type.mdx(via @objectstack/spec)
  • content/docs/plugins/development.mdx(via @objectstack/spec)
  • content/docs/plugins/index.mdx(via @objectstack/spec)
  • content/docs/plugins/packages.mdx(via @objectstack/spec)
  • content/docs/protocol/backward-compatibility.mdx(via @objectstack/spec)
  • content/docs/protocol/diagram.mdx(via packages/spec)
  • content/docs/protocol/kernel/config-resolution.mdx(via @objectstack/spec)
  • content/docs/protocol/kernel/http-protocol.mdx(via @objectstack/spec)
  • content/docs/protocol/kernel/i18n-standard.mdx(via @objectstack/spec)
  • content/docs/protocol/kernel/index.mdx(via @objectstack/spec)
  • content/docs/protocol/kernel/lifecycle.mdx(via @objectstack/spec)
  • content/docs/protocol/kernel/plugin-spec.mdx(via @objectstack/spec)
  • content/docs/protocol/knowledge.mdx(via @objectstack/spec)
  • content/docs/protocol/objectql/index.mdx(via @objectstack/spec)
  • content/docs/protocol/objectql/query-syntax.mdx(via @objectstack/spec)
  • content/docs/protocol/objectql/schema.mdx(via @objectstack/spec)
  • content/docs/protocol/objectql/security.mdx(via packages/spec)
  • content/docs/protocol/objectql/state-machine.mdx(via @objectstack/spec)
  • content/docs/protocol/objectui/actions.mdx(via @objectstack/spec)
  • content/docs/protocol/objectui/concept.mdx(via @objectstack/spec)
  • content/docs/protocol/objectui/index.mdx(via @objectstack/spec)
  • content/docs/protocol/objectui/layout-dsl.mdx(via @objectstack/spec)
  • content/docs/protocol/objectui/record-alert.mdx(via @objectstack/spec)
  • content/docs/protocol/objectui/widget-contract.mdx(via @objectstack/spec)
  • content/docs/releases/implementation-status.mdx(via @objectstack/spec)
  • content/docs/releases/index.mdx(via @objectstack/spec)
  • content/docs/releases/v12.mdx(via @objectstack/spec)
  • content/docs/releases/v13.mdx(via @objectstack/spec)
  • content/docs/releases/v16.mdx(via @objectstack/spec)
  • content/docs/releases/v17.mdx(via @objectstack/spec)
  • content/docs/releases/v9.mdx(via @objectstack/spec)
  • content/docs/ui/actions.mdx(via @objectstack/spec)
  • content/docs/ui/apps.mdx(via @objectstack/spec)
  • content/docs/ui/create-vs-edit-form.mdx(via @objectstack/spec)
  • content/docs/ui/dashboards.mdx(via @objectstack/spec)
  • content/docs/ui/field-grouping-and-order.mdx(via @objectstack/spec)
  • content/docs/ui/forms.mdx(via @objectstack/spec)
  • content/docs/ui/index.mdx(via @objectstack/spec)
  • content/docs/ui/public-data-collection.mdx(via @objectstack/spec)
  • content/docs/ui/setup-app.mdx(via @objectstack/spec)
  • content/docs/ui/translations.mdx(via @objectstack/spec)
  • content/docs/ui/views.mdx(via @objectstack/spec)

Advisory only. To re-verify, run the docs-accuracy-audit workflow scoped to these files:
node scripts/docs-audit/affected-docs.mjs origin/main → pass the list as args.docs.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentationImprovements or additions to documentationsize/mteststooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[finding] ImportRequest.runAutomations declares .default(false) and documents "off by default for bulk", but POST /data/:object/import defaults it ON

2 participants

@os-zhuang@claude