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-3873

Planning bug: MOTIR-3868's AC 1 required a diff against `work_item.targetRepoRole`, a column retired 11 days earlier — the enumeration was verified, the column behind it was not

To Do
Description

Filed while running MOTIR-3868 (PR #2451). The card was overwhelmingly correct and shipped; one clause of its first acceptance criterion was unbuildable as written.

What the card asked for

buildChanges emits a change row for targetRepo and one for targetRepoRole when the patch carries either and the value differs from the target's

Why the struck clause could not hold

work_item.targetRepoRole does not exist. It was retired by Story MOTIR-2732 · MOTIR-3040 (ADR work-item-repository-set.md "Amendment 2026-08-18" §A3) on 2026-08-18 — eleven days before MOTIR-3868 was authored (2026-08-29T00:40:53Z).

Verified on origin/main @ c5d11f7f1, prisma/schema.prisma, where the retirement note sits in the column's own former place:

⚠️ targetRepoRole WAS HERE AND IS RETIRED … PlanItemProposedFields.targetRepoRole REMAINS: a plan still pins by role before any row exists; it is resolved to a reference at materialize instead of being copied onto the item.

So buildChanges(patch, target: WorkItem, …) has no from side to read for that key, and "differs from the target's" cannot be evaluated. The card's supporting sentence — "applyModify reads and applies both" — is true, and that is exactly what made the clause look verified: applyModify does read patch.targetRepoRole, but it applies it by resolving a repository reference (proposalRepoRef(name, role, refs)), never by writing a role onto the item.

The planning defect, stated as a rule

The card verified the ENUMERATION and not the FIELD. Its "Measured on origin/main" table is a genuine, correct measurement of which patch keys buildChanges emits — the producer side. From that it inferred a symmetric consumer-side fact (the target has a value to diff against) that it never measured, on a field whose column had been deleted in the interim.

This is the re-measure the PREDICATE, not only the REF shape one field over: the ref was right, the command was right, the answer was right, and the sentence built on it named a second entity nobody checked. A criterion of the form "row X differs from the target's Y" asserts that Y exists on the target, and that is a schema claim owed a grep of schema.prisma — one command, and it was the same file the card's own retirement evidence would have come from.

Cost was small and the shape is what matters: the run had to stop, verify the retirement, choose a disposition (emit on key presence, from: null), amend the criterion on the record, and file this. A dispatched agent hitting the same clause would more likely have invented a from or dropped the role half silently.

Acceptance criteria

  • plan-rules/phase-deepen.md's precondition-verification rule gains a limb: a criterion that compares a proposed value against "the target's" asserts the target CARRIES that field — verify the column/property exists on the entity, at the ref, before sealing the card. The producer-side enumeration being correct is not evidence for the consumer side.
  • The limb names this fixture — a card whose key-set table was measured correctly on origin/main while the column its criterion diffed against had been dropped 11 days before — and states the one-command check (grep the model in prisma/schema.prisma, or the interface at the ref).
  • Cross-referenced from the ENUMERATION limb it is the twin of, so a reader arriving at either meets both: one secures the ref a count was taken on, this one secures that the compared-to field exists at all.

Context refs

  • motir-meta prompts/plan-rules/phase-deepen.md — the precondition-verification rule and its NEGATIVE / ENUMERATION limbs
  • motir-core prisma/schema.prisma — the targetRepoRole retirement note, in the column's former position
  • motir-core lib/services/plansService.tsapplyModify / proposalRepoRef — what a role patch actually does now
  • PR #2451 — the disposition as built, and the amended criterion