You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Observation-class. Spun out of #5957 / PR #6636, whose ruling put this family explicitly out of scope: it is a different shape and a different question (a lint-capability judgement), so it is filed standalone rather than folded into that card. Unassigned, for triage. Nobody is hitting it today.
The shape
flow-trigger-unknown-event only ever looks at tokens that already start with record-. The engine's binding resolver decides that first:
// packages/services/service-automation/src/engine.ts, resolveTriggerBindingconsttriggerType=typeofconfig.triggerType==='string' ? config.triggerType : undefined;if(triggerType&&triggerType.startsWith('record-')){return{triggerType: 'record_change',binding: {/* ... event: triggerType */}};}// ... array form, time_relative, schedule, api ...// falls through: the flow is simply not record-triggered
So the two families fail differently:
authored token
engine verdict
diagnostic today
record-created (in-prefix, out-of-grammar)
binds to record-change, maps to zero hook events, never fires
The second row is the strictly quieter failure of the two, and it is the one with no diagnostic. An author who writes onCreate gets a flow that looks authored, validates clean, boots clean, and simply never runs.
Measured census (origin/main at the time of filing)
git grep over the tracked tree finds 4 non-record--prefixed triggerType tokens. They sit in three different positions, and only one is the shape above — worth stating, because #5957's body counted them as one group and only a third of that count is actionable:
A genuine flow start node — the real instance. packages/cli/test/authoring-rule-command-parity.test.ts:60 config: { objectName: 'parity_task', triggerType: 'onCreate' } on a type: 'record_change' flow. This is exactly the silent-degradation shape. (The fixture's subject is approval-expression-invalid parity, so its own assertions do not depend on the token.)
The FlowRuntimeState inventory shape — a different field that happens to share the name.packages/runtime/src/domain-handler-registry.test.ts:663 and :670, triggerType: 'on_create' inside { name, enabled, bound, status, triggerType, object }. That position carries the resolved trigger kind (record_change / schedule / time_relative / api), not an authored token. The test is a pass-through assertion (toEqual against the same literal), so the value is arbitrary by construction.
Should a non-record--prefixed triggerType on a type: 'record_change' flow produce a diagnostic?
The tension is real in both directions, which is why this is filed rather than fixed:
For: it is a strictly quieter failure than the one lint never-fire 族 severity 复审:两条 warning 实感更接近 error(#5496/#5647 dev 报告建议)—— 同批升、单独 PR,不逐条搭车 #5762 raised to error, on the same authoring surface, and "declared = enforced" says a flow that declares a trigger and binds to nothing should say so. A record_change flow whose start node names a trigger the engine cannot route is not an ambiguous intent.
Against: the prefix check is also the mechanism by which a flow legitimately is manual, and lint-flow-patterns.test.ts already carries a deliberate does NOT flag record_change — undecidable at authoring time, caught at run time case. A new rule here risks flagging the intentional shape. There may also be no business pull: nothing in the example apps authors this, and the only in-repo instance is one CLI test fixture.
A narrower framing worth considering instead of a new rule: the check could be scoped to flows that declare type: 'record_change'and a start-node triggerType that resolves to no binding at all — which is decidable at authoring time and cannot catch a genuinely manual flow, because a manual flow does not declare record_change.
If triage decides yes, the runtime half (#3481 established the precedent that a silently-dead trigger form deserves a signal at some layer) and the lint half should be decided together.
Related: #5957 / PR #6636 (origin), #5762 (the severity upgrade that made the in-prefix family loud), #3427 / #3457 / #3481 (the three sources of flow-trigger-unknown-event).
Observation-class. Spun out of #5957 / PR #6636, whose ruling put this family explicitly out of scope: it is a different shape and a different question (a lint-capability judgement), so it is filed standalone rather than folded into that card. Unassigned, for triage. Nobody is hitting it today.
The shape
flow-trigger-unknown-eventonly ever looks at tokens that already start withrecord-. The engine's binding resolver decides that first:So the two families fail differently:
record-created(in-prefix, out-of-grammar)flow-trigger-unknown-event, error since #5762onCreate(out-of-prefix)The second row is the strictly quieter failure of the two, and it is the one with no diagnostic. An author who writes
onCreategets a flow that looks authored, validates clean, boots clean, and simply never runs.Measured census (
origin/mainat the time of filing)git grepover the tracked tree finds 4 non-record--prefixedtriggerTypetokens. They sit in three different positions, and only one is the shape above — worth stating, because #5957's body counted them as one group and only a third of that count is actionable:A genuine flow start node — the real instance.
packages/cli/test/authoring-rule-command-parity.test.ts:60config: { objectName: 'parity_task', triggerType: 'onCreate' }on atype: 'record_change'flow. This is exactly the silent-degradation shape. (The fixture's subject isapproval-expression-invalidparity, so its own assertions do not depend on the token.)The
FlowRuntimeStateinventory shape — a different field that happens to share the name.packages/runtime/src/domain-handler-registry.test.ts:663and:670,triggerType: 'on_create'inside{ name, enabled, bound, status, triggerType, object }. That position carries the resolved trigger kind (record_change/schedule/time_relative/api), not an authored token. The test is a pass-through assertion (toEqualagainst the same literal), so the value is arbitrary by construction.A deliberately-invalid literal — correct as written, do not touch.
packages/spec/src/data/object.test.ts:1003,workflows: [{ name: 'stamp', triggerType: 'on_update', actions: [] }]. This is the Object-levelworkflows: [...](and any unknown ObjectSchema key) is silently stripped at build — no error/warning (ADR-0032 'no silent failure', metadata layer) #1535 unknown-key rejection test; the wholeworkflowskey is rejected on purpose and the literal carries a@ts-expect-error. Not a flow start node at all.So: 1 site of the described shape, not 4.
The question for triage
Should a non-
record--prefixedtriggerTypeon atype: 'record_change'flow produce a diagnostic?The tension is real in both directions, which is why this is filed rather than fixed:
error, on the same authoring surface, and "declared = enforced" says a flow that declares a trigger and binds to nothing should say so. Arecord_changeflow whose start node names a trigger the engine cannot route is not an ambiguous intent.lint-flow-patterns.test.tsalready carries a deliberatedoes NOT flag record_change — undecidable at authoring time, caught at run timecase. A new rule here risks flagging the intentional shape. There may also be no business pull: nothing in the example apps authors this, and the only in-repo instance is one CLI test fixture.A narrower framing worth considering instead of a new rule: the check could be scoped to flows that declare
type: 'record_change'and a start-nodetriggerTypethat resolves to no binding at all — which is decidable at authoring time and cannot catch a genuinely manual flow, because a manual flow does not declarerecord_change.If triage decides yes, the
runtimehalf (#3481 established the precedent that a silently-dead trigger form deserves a signal at some layer) and thelinthalf should be decided together.Related: #5957 / PR #6636 (origin), #5762 (the severity upgrade that made the in-prefix family loud), #3427 / #3457 / #3481 (the three sources of
flow-trigger-unknown-event).