Skip to content

[finding][devx] 8 traps values are used across areas/*.json but absent from RUNNER.md's trap table — the runner is told to rule out traps it has no definition for #10416

Description

@os-zhuang

Found while rewriting cli.migrate-meta-codemod for #9733 (PR #10412). Filed unassigned, out of that card's scope and not touched there.

The finding

docs/qa/platform-checklist/RUNNER.md rule 3 instructs a runner, for every item, to:

check the traps field and rule each listed trap out

That only works if every value an item can carry in traps is defined somewhere. RUNNER.md's trap table is the definition list — each row gives the trap name, what it fakes, and the counter the runner applies to rule it out. Eight values in use have no row.

Measured on main (900e48935), by parsing every docs/qa/platform-checklist/areas/*.json for traps values and matching them against the trap table's rows:

  • 11 traps documented in RUNNER.md: absence-inference, automation-input, dispatcher-vs-hono-route, hydration-race, seed-data-thin, shared-browser-tab, single-datapoint, stale-console-bundle, stale-dist, wrong-panel, wrong-persona.
  • 19 distinct traps in use across the 204 items.
  • 8 used but undocumented, with their current usage counts:
trapitems using it
auth-state-leak3
cache-staleness2
silent-coercion1
clock-skew1
timezone-boundary1
eventual-consistency1
destructive-in-place1
first-boot-cold-start1

Most are guessable from the name, which is exactly what makes this quiet: a runner who guesses wrong rules out the trap they imagined rather than the one the item's author meant, and the verdict still reads pass. silent-coercion and eventual-consistency in particular imply specific counters (compare the stored value against what was sent; re-read after a settle window) that a name alone does not supply.

scripts/check-platform-checklist.mjs does not validate traps against any vocabulary, so nothing catches a new undocumented value — or a typo in a documented one, which lands as a silently-unrulable trap the same way.

Suggested dispositions (triage's call)

  • A — document the 8. Add a row for each to RUNNER.md's table, written from the items that use them. Cheapest, and it makes the existing values usable; leaves the next undocumented value free to arrive the same way.
  • B — A, plus close the loop. Also have check:platform-checklist verify every traps value has a RUNNER.md row, so the table and the ledger cannot drift again. This is the same shape as the existing oracle enum check (which the validator does enforce) and would have caught all 8. Note the validator is not CI-wired by maintainer decision, so this gate fires on the manual cadence.
  • C — prune instead. Some of the 8 are one-off values that may be better folded into a documented sibling than defined (destructive-in-place is used by exactly one item and overlaps nothing today).

Refs: docs/qa/platform-checklist/RUNNER.md (rule 3 + the trap table) · scripts/check-platform-checklist.mjs (the oracle enum check is the precedent for B) · #9733 / #10412 (where this surfaced).


Generated by Claude Code

Metadata

Metadata

Assignees

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions