Carrier card for the undecided half of #7041, filed because that card auto-closed when PR #7172 landed its item 1 (the stale provenance comment) — leaving item 2 with no open, queryable tracker. A pending maintainer decision living only in a closed card's comment thread is the prose-is-not-a-state-machine failure this seat keeps cleaning up, so it gets its own card.
The question
flow-trigger-unroutable (#6637) currently fires only on the contradiction shape: config.triggerType is present and routes nowhere. Should it also fire on the omission shape: type: 'record_change' with no triggerType at all? Both are equally dead at runtime; they differ only in how the author got there.
Why it is decidable now (what changed since #6637 deferred it)
Why it still needs a decision rather than a default
It is a rule with zero current hits. Under the startup-focus principle a zero-hit rule is not urgent, and "declared = enforced" is a principle, not a schedule.
⛔ The pairing constraint (why this is not the devx seat's call)
#6041 is the structurally identical question about a different key — whether app.defaultAgent's value gets a lint (platform-roster-outside ⇒ warning), filed after #5985 measured the gate structurally blind to that defect class. It sits in this same decision box. Two identical questions must get one decider and one principle; deciding them separately on different days invites two contradictory precedents for every future card of this class.
The three dispositions (all defensible)
- Take both now — ship the wider criterion while the tree is green for it, and the
app.defaultAgent warning under the same principle. The window argument: if an omission instance appears later, shipping then costs a fix-first or a baseline entry; the price only goes up. (The seat's lean, previously stated.) - Defer both with restart conditions written on the cards — e.g. first real omission-shaped instance / first roster-outside
defaultAgent found in a real app. - Decline both on the zero-hit reading.
Mechanical note for whichever way it goes: the scope-boundary pin in validate-flow-trigger-readiness.test.ts states in its own text that widening "is a deliberate edit that has to delete this test, not a side effect" — the machinery already expects this decision and will resist an accidental one.
Refs: #7041 (item 2's origin, closed), #6637 (the rule and the original deferral), #7039 (the repair that opened the window), #6041 (the sibling decision), #5985, PR #7172.
Carrier card for the undecided half of #7041, filed because that card auto-closed when PR #7172 landed its item 1 (the stale provenance comment) — leaving item 2 with no open, queryable tracker. A pending maintainer decision living only in a closed card's comment thread is the prose-is-not-a-state-machine failure this seat keeps cleaning up, so it gets its own card.
The question
flow-trigger-unroutable(#6637) currently fires only on the contradiction shape:config.triggerTypeis present and routes nowhere. Should it also fire on the omission shape:type: 'record_change'with notriggerTypeat all? Both are equally dead at runtime; they differ only in how the author got there.Why it is decidable now (what changed since #6637 deferred it)
record--prefixed flowtriggerTypesilently degrades the flow to manual — no lint, no runtime signal (spun out of #5957) #6637 time: the rule would have gated a shipped example app (examples/app-todo'sTaskCompletionFlow, a live omission instance) on a guess about that app's intended semantics.task_completion— it bound to nothing and gated on a key nothing reads (#6882) #7039 made, implemented, and pinned that guess —TaskCompletionFlownow declarestriggerType: 'record-after-update'. There is no live omission instance in the tree (verified in lint:validate-flow-trigger-readinesscites a live example-app instance that #6882 just removed — plus the deferred question of whether the wider absent-triggerTypecriterion should now ship #7041's filing and re-pinned by PR fix(lint): correct stale provenance comment in validate-flow-trigger-readiness.test.ts #7172's durable comment).Why it still needs a decision rather than a default
It is a rule with zero current hits. Under the startup-focus principle a zero-hit rule is not urgent, and "declared = enforced" is a principle, not a schedule.
⛔ The pairing constraint (why this is not the devx seat's call)
#6041 is the structurally identical question about a different key — whether
app.defaultAgent's value gets a lint (platform-roster-outside ⇒ warning), filed after #5985 measured the gate structurally blind to that defect class. It sits in this same decision box. Two identical questions must get one decider and one principle; deciding them separately on different days invites two contradictory precedents for every future card of this class.The three dispositions (all defensible)
app.defaultAgentwarning under the same principle. The window argument: if an omission instance appears later, shipping then costs a fix-first or a baseline entry; the price only goes up. (The seat's lean, previously stated.)defaultAgentfound in a real app.Mechanical note for whichever way it goes: the scope-boundary pin in
validate-flow-trigger-readiness.test.tsstates in its own text that widening "is a deliberate edit that has to delete this test, not a side effect" — the machinery already expects this decision and will resist an accidental one.Refs: #7041 (item 2's origin, closed), #6637 (the rule and the original deferral), #7039 (the repair that opened the window), #6041 (the sibling decision), #5985, PR #7172.