现象(可复现)
当前 main,空库 objectstack dev --seed-admin 起 examples/app-showcase:
showcase_project 只种进 1/5 (唯一 status:'planned' 的 'Mobile App')
showcase_task 只种进 1/10 (唯一引用幸存 project 的任务;其余 9 条因 required project lookup 悬空级联被 drop)
同一份种子在 7 月 17 日的构建上是 5/5、10/10 全量入库 。整个失败在默认 log-level 下零信号 (行级错误被 [Seeder] info 摘要吞掉,另有 boot stdout 静默窗口;参见 #3430 )。REST 端同样可复现:POST /api/v1/data/showcase_project with status:'active' → 400 VALIDATION_FAILED / invalid_initial_state。
机制
feat(validation): state_machine.initialStates enforces the FSM entry point on INSERT (#3165) #3188 (feat enhancement: state_machine 校验规则在 INSERT 上是 no-op —— 无法强制记录的初始状态(declared ≠ enforced) #3165 )让 state_machine.initialStates 在 INSERT 上强制 FSM 入口:packages/objectql/src/validation/rule-validator.ts(创建值必须 ∈ initialStates,fail-closed)。
docs + examples: bring guides and showcase current with 16.0 #3359 给 showcase_project 声明了 project_status_flow:events:['insert','update']、initialStates:['planned'](examples/app-showcase/src/data/objects/project.object.ts)。
但 showcase 种子(src/data/seed/index.ts)刻意让 project 铺满 active/on_hold/completed 各状态、让每个看板列都有卡——对象自己的状态机与自己的种子自相矛盾 ,种子重放没有任何豁免,4/5 project 在出生态校验上被拒。
影响面
候选修法(需拍板)
A. SeedLoader 写路径豁免 state_machine 校验 (isSystem/seed context 明确跳过 rule-validator 的 FSM 规则,或只跳过 initialStates 保留 transitions):平台级修,一次解决 showcase + 全部模板 + heal/replay 路径。需配套:os build/os validate 增加「种子值须显式标注绕过或通过对象校验」的 lint,避免种子变成无声后门。
B. 只改 showcase 种子为合法出生态:演示价值尽失(看板只剩一列),且救不了第三方模板,不推荐单独采用。
倾向 A(+可选的 validate 门)。修复验收:空库 boot 后 showcase_project=5、showcase_task=10;hotcrm 安装/heal 在对象声明 initialStates 的假想包上不丢行;新增回归测试覆盖「seed 含非初始态行」。
参考
🤖 Generated with Claude Code
现象(可复现)
当前 main,空库
objectstack dev --seed-admin起 examples/app-showcase:showcase_project只种进 1/5(唯一status:'planned'的 'Mobile App')showcase_task只种进 1/10(唯一引用幸存 project 的任务;其余 9 条因 requiredprojectlookup 悬空级联被 drop)同一份种子在 7 月 17 日的构建上是 5/5、10/10 全量入库。整个失败在默认 log-level 下零信号(行级错误被 [Seeder] info 摘要吞掉,另有 boot stdout 静默窗口;参见 #3430)。REST 端同样可复现:
POST /api/v1/data/showcase_projectwithstatus:'active'→400 VALIDATION_FAILED / invalid_initial_state。机制
state_machine校验规则在 INSERT 上是 no-op —— 无法强制记录的初始状态(declared ≠ enforced) #3165)让state_machine.initialStates在 INSERT 上强制 FSM 入口:packages/objectql/src/validation/rule-validator.ts(创建值必须 ∈ initialStates,fail-closed)。showcase_project声明了project_status_flow:events:['insert','update']、initialStates:['planned'](examples/app-showcase/src/data/objects/project.object.ts)。影响面
候选修法(需拍板)
A. SeedLoader 写路径豁免 state_machine 校验(isSystem/seed context 明确跳过 rule-validator 的 FSM 规则,或只跳过 initialStates 保留 transitions):平台级修,一次解决 showcase + 全部模板 + heal/replay 路径。需配套:
os build/os validate增加「种子值须显式标注绕过或通过对象校验」的 lint,避免种子变成无声后门。B. 只改 showcase 种子为合法出生态:演示价值尽失(看板只剩一列),且救不了第三方模板,不推荐单独采用。
倾向 A(+可选的 validate 门)。修复验收:空库 boot 后 showcase_project=5、showcase_task=10;hotcrm 安装/heal 在对象声明 initialStates 的假想包上不丢行;新增回归测试覆盖「seed 含非初始态行」。
参考
state_machine校验规则在 INSERT 上是 no-op —— 无法强制记录的初始状态(declared ≠ enforced) #3165(initialStates 强制)、docs + examples: bring guides and showcase current with 16.0 #3359(showcase 声明)、fix(marketplace): heal missing sample data when rehydrating installed packages onto a new database #3421(rehydrate heal,同受影响)、fix(seed-loader): resolve seed references for marketplace-installed objects (engine-registry fallback) #3422(seed lookup 解析)、os dev: surface seed / sample-data-heal outcomes in the boot summary (info logs are swallowed by the default warn log level) #3430(种子结果可观测性——本次三个 bug 均因它排查翻倍耗时)🤖 Generated with Claude Code