fix(automation): kill the four-layer silence around record-change flows that never fire#3099
Merged
Merged
Conversation
…ws that never fire 2026-07-17 third-party eval: an auto-launched flow that failed to fire produced ZERO output at every layer. Root causes were two-fold: 1. serve's boot-quiet window swallows stdout entirely, and ObjectLogger routes debug/info/warn to stdout — so every flow-registration/binding log (success AND failure) vanished in `os dev`/`os start`. Only error/fatal (stderr) survive. 2. Each "didn't happen" path was itself silent: a trigger-fired execute() failure lived only in the run-history row; a flow whose objectName matches nothing armed a hook that never fires; a stack whose requires lacked automation/triggers just never bound anything. Fixes, layer by layer: - Startup banner `Flows:` section (post-restore, immune to the quiet window): counts + trigger types + ⚠ lines for engine-not-enabled, unbound triggered flows, and dead bindings (unknown object). - Trigger-fired run failures now log at ERROR (stderr): the engine no longer drops the AutomationResult of a trigger-fired execution. Condition-not-met skips stay at debug (high-frequency by design). - RecordChangeTrigger probes object existence at bind time and warns on an objectName that matches no registered object (exact-name match). - kernel:bootstrapped binding audit in the automation plugin: warn per enabled-but-unbound triggered flow with the actionable reason; new AutomationEngine.getTriggerBindingAudit() + extended getFlowRuntimeStates() (status/triggerType/object). - os validate: new lint rule validateFlowTriggerReadiness — warns when a record-triggered flow targets an object the stack does not define, and when an auto-triggered flow's status is draft (authored or defaulted; draft flows still fire — declare active/obsolete). Showcase flows now declare status: 'active' explicitly. - Removed the leftover boot-debug stderr writes (registerApp/AppPlugin/ StandaloneStack/AuditPlugin) that earlier debugging of this same silence left behind. Verified end-to-end on a real create-objectstack project (published- package layout): correct flows fire on REST PATCH across os start / os dev / restart; each mistake variant now produces its explicit signal. 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 7 package(s): 41 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:
|
The preview deploy for 59931e6 failed on Vercel's side while all 15 GitHub checks passed. The docs build graph is {@objectstack/docs, @objectstack/spec} — zero overlap with this branch's packages — and the commit touches no package.json/lockfile, so the failure cannot originate here (`turbo run build --filter=@objectstack/docs --force` passes locally). Vercel posts a commit status rather than a check run, so a new commit is the only way to retrigger the deployment. 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.
背景
2026-07-17 第三方评估(15.1.x 发布包、全新
create-objectstack项目):autolaunched record-after-update flow 配置齐全(插件已加载、/meta/flowstatus=active、triggerType 正确),REST PATCH 满足条件后 flow 不执行,且日志零输出——无注册、无绑定、无跳过、无错误。同样逻辑写成 lifecycle hook 正常。调查结论
在 15.1.1(本地构建 + npm 发布包逐字节一致)上完整复刻评估者场景:正确配置的 flow 在
os start/os dev/ 重启后 / 发布包脚手架项目上端到端全部正常触发。评估者遇到的"不触发"来自某个作者层失配(最可能:start 节点objectName与对象注册名不一致——实验证实该失配零日志、静默永不触发),而框架在每一层都沉默:serve.tsbootQuiet),而ObjectLogger的 debug/info/warn 全走 stdout——flow 注册/trigger 绑定恰好全部发生在该窗口内,OS_LOG_LEVEL=debug也救不回来;只有 error/fatal(stderr)幸存。连"绑定成功"都不可见,失败更不可见。AutomationResult被绑定回调丢弃——logger 层面零信号。objectName失配 → hook 订阅一个没人写的对象名,永不触发,零信号。requires缺automation/triggers→ flow 元数据照常注册(/meta/flow可见),但引擎/触发器不存在,零信号。附带发现:draft 状态的 flow 仍会触发(engine 只对 obsolete/invalid 禁用)——与直觉相反,已实验证实并纳入提示语义。
修复(按层)
Flows:一节(stdout 恢复后打印,不受静默窗口影响):flow 数、绑定数、已注册 trigger 类型、draft 数;外加 ⚠ 行:引擎未启用(附requires修复指引)、声明了 trigger 但未绑定、绑定了但对象未知(死绑定)。RecordChangeTrigger绑定时探测对象存在性(feature-detectgetObject),失配即 warn 点名。kernel:bootstrapped绑定审计(automation plugin):每个 enabled-but-unbound 的触发 flow 一条 warn(附原因),新增AutomationEngine.getTriggerBindingAudit()、扩展getFlowRuntimeStates()(status/triggerType/object)。os validate新增 flow 接线检查(@objectstack/lintvalidateFlowTriggerReadiness):record 触发 flow 指向本 stack 未定义对象 → warning(sys_* 豁免);自动触发 flow status 为 draft(显式或缺省)→ warning(明确"draft 仍会触发,声明 active/obsolete")。showcase 16 个自动触发 flow 补显式status: 'active'。registerApp/AppPlugin:init/StandaloneStack/AuditPlugin共 8 处 stderr 直写)——它们正是前人被同一个静默窗口坑过后的手工探针。验证
turbo build+test:60 tasks 全绿(service-automation 306、trigger-record-change 25 等)。examples/app-showcaseos validate干净通过。🤖 Generated with Claude Code