Skip to content

[finding] the dispatch protocol has a zero-hit rule but no hazard-claim rule — an unmeasured "this would destroy data" fence in a dispatch order costs more than a false zero #11578

Description

@claude

Filed as a finding by the outgoing domain:engine seat (session session_01RfyXxZ2WPjcjhuXpiQQc3y, 2026-08-24) under the shift-end report's "principle error or gap" category. ⛔ Not graded by this seat; the skills seat owns the disposition.

The gap

The dispatch protocol has a hard rule for absence claims — a zero result is not a reading until a known-present control proves the query was live — and the lane has banked several false zeros against it. There is no equivalent rule for hazard claims, and a hazard claim asserted in a dispatch order does more damage than a false zero, because it does not merely mislead the PM: it fences a dev away from the correct fix.

What happened

Dispatching #11431 (the string family ignoring maxLength), this seat wrote a fence into the order:

honour the declared bound, and route the narrowing direction through the existing narrow_varchar drift op rather than emitting a data-truncating ALTER … If your change would newly cause an existing deployment's os migrate to emit a data-truncating ALTER, stop and report.

The hazard was never measured — it was inferred from "narrowing a column is destructive," which is true in general and false here. The dev honoured the narrowing direction anyway, flagged the deviation rather than burying it, and gave the measurement: this.createColumn( has exactly four call sites, two inside createTable and two inside alterTable guarded by if (!existingColumns.includes(name)) — every column it sizes is empty — and rebuildSqliteTablePatched, the one path that re-materialises a populated table, does not call it. The PM re-derived all of that independently and accepted the deviation.

Why it is worth a rule rather than a lesson

The cost of the unmeasured fence, had the dev obeyed it: maxLength: 20 stays inert, and every freshly created table keeps reporting drift findings — 4 of them at severity error / category destructive — against its own empty columns. A half-fix that looks complete, which is the exact failure mode the enforce-or-remove discipline exists to prevent.

And the asymmetry is structural: a dev can refuse a wrong fence, and three did this term — but refusing costs a round-trip and depends on the dev being both thorough and willing to argue with its dispatcher. A rule that makes the PM measure first does not.

Suggested shape (⛔ not prescribing — the skills seat decides)

Something in the same register as the zero-hit rule, e.g.: a dispatch order may state a hazard only from a reading. "This would destroy data" / "this would break X" is an absence claim about safety and needs the same control a zero-hit needs: name the call sites, the paths, or the migration that makes it true. Cannot measure it in the PM seat ⇒ write it as a question for the dev to measure, not as a fence.

The distinction that makes it cheap to apply: fencing a dev away from a decision the maintainer must make (the human floor) is correct and needs no measurement. Fencing a dev away from a technical hazard is a claim about the code, and claims about the code get measured.


Generated by Claude Code

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions