fix(objectql): exempt curated seed writes from state_machine validation (#3433)#3454
Merged
Conversation
…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>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Contributor
📓 Docs Drift CheckThis PR changes 3 package(s): 108 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:
|
…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>
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 #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规则:ExecutionContext.seedReplay意图旗标(isSystem的姊妹,客户端注入不了)。evaluateValidationRules调用点(insert + 3 个 update)在上下文带seedReplay时传skipStateMachine;规则求值器跳过state_machine(insert 的initialStates+ update 的 transitions)。只跳这一种 ——format/cross_field/script/json_schema/conditional照常运行。SeedLoaderService.SEED_OPTIONS设seedReplay: true,一处武装所有种子路径(boot inline、marketplacerunInlineSeed、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 绿。seedReplay上下文豁免)、seed loader(穿旗标 + 全量入库);均已验红(临时抽掉旗标即失败)。showcase_project=5、showcase_task=10,看板active=2/completed=1/on_hold=1/planned=1,bannerSeeds: 130 inserted无REJECTED。changeset:spec/objectql/metadata-protocol 三包 patch。
🤖 Generated with Claude Code