MotirBuilding in public
MOTIR · moooon
onMotir
You’re viewing a public project. Anyone can view it — no account needed. Sign in to submit, upvote, or comment on requests.View-only — you can’t edit work items
MOTIR-3428

Planning bug: MOTIR-3414/3422 assert "84 step.run call sites across 37 files, incl. services outside lib/jobs/" — measured 58 across 26, ALL inside lib/jobs/

Done
Description

Found by motir run MOTIR-3414, 2026-08-23, before the first line of work — the run-time re-measure of a card's own enumeration (run.md: a card whose count carries no ref is a card to RE-MEASURE before the first line of work).

The claim

Story MOTIR-3414 and its child MOTIR-3422 both state, as a load-bearing figure:

All 84 step.run call sites across 37 files change by zero characters.

and MOTIR-3414's explanationMd extends it into the story's cost argument:

84 step.run call sites live across 37 files, including services well outside lib/jobs/. Rewriting them would be the real work of this epic and would touch code that has nothing to do with queueing.

The measurement

Taken on the ref, not on a working tree (git grep against origin/main@165f1485, the commit the run branched from):

$ git grep -c 'step\.run(' origin/main -- '*.ts' '*.tsx'
  60 occurrences across 27 files

$ git grep -c 'step\.run(' origin/main -- '*.ts' '*.tsx' ':!tests/*'
  58 occurrences across 26 files

$ git grep -l 'step\.run(' origin/main -- '*.ts' '*.tsx' ':!tests/*'
  lib/jobs/defineJob.ts
  lib/jobs/definitions/*.ts            (24 files)
  lib/jobs/indexFleetSteps.ts
  scripts/plan-seed/data/story-1.6.ts  ← seed FIXTURE DATA, not a service

Two falsifications, and they are different in kind

  1. The COUNT is ~45% high. 84/37 against a measured 58/26 (60/27 including the one test file). An overcount alone would be drift worth an amendment and little more.

  2. The RATIONALE's premise is false, and this is the one that matters. "including services well outside lib/jobs/"25 of the 26 files are under lib/jobs/, and the 26th is plan-seed fixture data. Zero service files outside lib/jobs/ call step.run. The story's argument for the shim's value rests on a blast radius that does not exist: rewriting the call sites would touch lib/jobs/ and nothing else, which is exactly where the seam already is.

Why this is a planning bug and not a card defect

The conclusion the numbers were recruited to support — build the shim — survives both falsifications: 58 call sites are still 58 that should not be rewritten, and compatibility with the existing job definitions is a good enough reason on its own. So no deliverable changes and nothing is re-scoped. What went wrong is upstream of the deliverable: a figure was asserted with a precision it was never measured to (84, 37 — not round numbers, which is what makes them read as counted), and then reasoned FROM in the explanation. A reader weighing whether this epic is worth its cost was handed a blast-radius argument that a single git grep refutes.

The likely mechanism, and it is worth recording because it is reproducible: lib/jobs/registry.ts exports 37 job functions across 24 definition files. 37 is almost certainly the registered FUNCTION count, re-labelled as a file count of step.run callers. Two real populations, correctly observed, fused into one sentence about a third.

The rule this should have been caught by

plan-rules/phase-deepen.md's ENUMERATION limb already says a card counting a population owes the ref the count was taken on. It exists and it was not applied — so the corpus gap, if there is one, is about ENFORCEMENT at deepen time rather than a missing rule. Worth checking whether validate_work_item can carry an advisory for a bare integer in a card body that names no ref, the way likely-repo-straddle mechanised the repo/path check.

Disposition already taken by the run

  • MOTIR-3414 and MOTIR-3422 amended on the record with the measured figures, the command, and the ref — the original sentences preserved beneath the amendment rather than silently rewritten.
  • The story is not re-planned: no deliverable, edge, repo pin or estimate changes.
  • The falsification is carried into the story's pull-request body.

Acceptance criteria

  • MOTIR-3414 and MOTIR-3422 carry the corrected figures with the ref they were measured on.
  • The explanationMd claim about services outside lib/jobs/ is corrected rather than deleted, and the weakened cost argument is stated as such.
  • A decision is recorded on whether the deepen-time enumeration rule needs a mechanised advisory, or whether the existing prose rule is sufficient and this was a one-off miss.

Evidence provenance

Every figure above was measured with git grep against origin/main@165f1485 — a ref, not a working tree, and not the run's own branch. No number here was taken on unmerged work.

Advisory disposition (validate_work_item, at filing)

Two reference advisories fired, both likely-missing-edge: this card names MOTIR-3414 and MOTIR-3422 in its acceptance criteria with no blocked_by edge to either.

Both are DELIBERATE EXCLUSIONS, not missing edges — stated here because an absent edge and a considered exclusion are the same absent edge, and only saying so distinguishes them. This card does not CONSUME either item's output; it consumes their card text, and the amendment it asks for was applied by the same run that filed it, minutes after the measurement. A blocked_by on MOTIR-3414 would hold this card unstartable until an eight-child story merges — exactly backwards for a defect record whose corrective work is already done. No edge is owed in either direction.