Skip to content

fix(objectql): exempt curated seed writes from state_machine validation (#3433)#3454

Merged
os-zhuang merged 2 commits into
mainfrom
claude/ecstatic-blackburn-5c9467
Jul 24, 2026
Merged

fix(objectql): exempt curated seed writes from state_machine validation (#3433)#3454
os-zhuang merged 2 commits into
mainfrom
claude/ecstatic-blackburn-5c9467

Conversation

@os-zhuang

Copy link
Copy Markdown
Contributor

Fixes #3433.

问题

state_machine.initialStates(#3165)在每次 insert 都强制 FSM 入口态,导致种子重放静默拒绝一切 mid-lifecycle 行,并级联丢掉其 master-detail 子记录 —— 空库启动 showcase 只入 1/5 项目、1/10 任务。所有带 closed_won/closed 种子行的 marketplace 模板,以及 rehydrate-heal、per-org replay 路径,都会撞上同样的"装了却没数据"。

方案(平台级 / issue 方案 A)

种子是策展的既成事实,不是走生命周期的记录,因此豁免 state_machine 规则:

  • spec — 新增服务端设置的 ExecutionContext.seedReplay 意图旗标(isSystem 的姊妹,客户端注入不了)。
  • objectql — 4 个 evaluateValidationRules 调用点(insert + 3 个 update)在上下文带 seedReplay 时传 skipStateMachine;规则求值器跳过 state_machine(insert 的 initialStates + update 的 transitions)。只跳这一种 —— format/cross_field/script/json_schema/conditional 照常运行。
  • metadata-protocolSeedLoaderService.SEED_OPTIONSseedReplay: true,一处武装所有种子路径(boot inline、marketplace runInlineSeed、per-org replay、http-dispatcher、protocol),无需改任何 call site。

同时回退 #3435 的三段式 FSM-walk 变通,showcase 项目种子恢复为单个 upsert 直写终态。

验证

  • pnpm --filter @objectstack/objectql --filter @objectstack/metadata-protocol test → objectql 1056 绿、metadata-protocol 54 绿。
  • 三层回归:rule-validator(跳规则限定 FSM)、真引擎(seedReplay 上下文豁免)、seed loader(穿旗标 + 全量入库);均已验红(临时抽掉旗标即失败)。
  • 真实空库启动:showcase_project=5showcase_task=10,看板 active=2/completed=1/on_hold=1/planned=1,banner Seeds: 130 insertedREJECTED

changeset:spec/objectql/metadata-protocol 三包 patch。

🤖 Generated with Claude Code

…on (#3433)

`state_machine.initialStates` (#3165) enforced the FSM entry point on every
insert, so seed replay silently rejected every mid-lifecycle row and cascaded
its master-detail children — an empty-DB showcase boot loaded 1/5 projects and
1/10 tasks, and every marketplace template with a `closed_won`/`closed` seed row
plus the rehydrate-heal and per-org replay paths hit the same "installed but no
data" trap.

A seed is a curated snapshot of established facts, not a record walking its
lifecycle, so it is now exempt from the state_machine rule:

- spec: new server-set `ExecutionContext.seedReplay` intent flag (sibling of
  `isSystem`; clients cannot inject it).
- objectql: the four `evaluateValidationRules` call sites pass
  `skipStateMachine` when the context carries `seedReplay`; the rule evaluator
  skips `state_machine` on both insert (initialStates) and update (transitions).
  Scoped to state_machine only — format/cross_field/script/json_schema/
  conditional still run.
- metadata-protocol: `SeedLoaderService.SEED_OPTIONS` sets `seedReplay: true`, so
  all seed paths (boot inline, marketplace runInlineSeed, per-org replay,
  http-dispatcher, protocol) are covered with no call-site changes.

The showcase project seed drops its three-phase FSM-walk workaround (#3415) and
seeds each project directly at its real status again.

Regression tests span rule-validator (skip is FSM-scoped), the real engine
(seedReplay context bypasses enforcement), and the seed loader (threads the flag,
loads all mid-lifecycle rows). Verified on a real empty-DB boot:
showcase_project=5, showcase_task=10, no rejected seed rows.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@vercel

vercel Bot commented Jul 24, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
spec Ready Ready Preview, Comment Jul 24, 2026 4:16pm

Request Review

@github-actions github-actions Bot added documentation Improvements or additions to documentation size/m tests tooling labels Jul 24, 2026
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 3 package(s): @objectstack/metadata-protocol, @objectstack/objectql, @objectstack/spec.

108 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 packages/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 @objectstack/metadata-protocol, @objectstack/objectql, packages/spec)
  • content/docs/concepts/north-star.mdx (via packages/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 packages/objectql, @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/migration-from-objectql.mdx (via @objectstack/objectql)
  • content/docs/deployment/troubleshooting.mdx (via @objectstack/spec)
  • content/docs/deployment/validating-metadata.mdx (via @objectstack/spec)
  • content/docs/deployment/vercel.mdx (via @objectstack/objectql)
  • 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 packages/spec)
  • content/docs/kernel/index.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/email-service.mdx (via packages/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 packages/spec)
  • content/docs/kernel/runtime-services/sms-service.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/storage-service.mdx (via packages/spec)
  • content/docs/kernel/services-checklist.mdx (via @objectstack/objectql, @objectstack/spec)
  • content/docs/kernel/services.mdx (via @objectstack/objectql)
  • content/docs/permissions/authentication.mdx (via @objectstack/objectql)
  • 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/plugins/adding-a-metadata-type.mdx (via @objectstack/spec)
  • content/docs/plugins/development.mdx (via @objectstack/spec)
  • content/docs/plugins/index.mdx (via @objectstack/objectql, @objectstack/spec)
  • content/docs/plugins/packages.mdx (via @objectstack/objectql, @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/i18n-standard.mdx (via @objectstack/spec)
  • content/docs/protocol/kernel/index.mdx (via @objectstack/objectql, @objectstack/spec)
  • content/docs/protocol/kernel/lifecycle.mdx (via @objectstack/spec)
  • content/docs/protocol/kernel/plugin-spec.mdx (via @objectstack/spec)
  • content/docs/protocol/kernel/runtime-capabilities.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/objectql, @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/objectql, @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/v9.mdx (via @objectstack/objectql, @objectstack/spec)
  • content/docs/ui/actions.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/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.

…gen exec-context ref doc

Two CI follow-ups to the #3433 seed exemption:

- examples/app-showcase/test/seed.test.ts — the #3415 guard asserted every
  seeded status enters through `initialStates`, the exact constraint #3433
  removes. Retargeted to the new contract: a seeded value must be a state the
  FSM declares (not a typo), and the fixture must seed ≥1 non-initial state so
  a regression back to a planned-only walk fails here.
- content/docs/references/kernel/execution-context.mdx — regenerated so the
  spec reference doc reflects the new `seedReplay` field (generated-artifact
  drift gate).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@github-actions github-actions Bot added size/l and removed size/m labels Jul 24, 2026
@os-zhuang
os-zhuang merged commit 0c302a7 into main Jul 24, 2026
16 of 17 checks passed
@os-zhuang
os-zhuang deleted the claude/ecstatic-blackburn-5c9467 branch July 24, 2026 15:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation size/l tests tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

seed replay vs state_machine initialStates: mid-lifecycle fixture rows are silently rejected on INSERT (showcase kanban can never repopulate)

1 participant