Skip to content

moooon

Motir

Vibe your whole project. Bring an idea — Motir's three AI layers plan it, track it, and ship it, end to end. You're looking at Motir, built in Motir.

  • Vibe Project
  • Open Source
  • AI Agent
  • AI Loop
1
requests
0
upvotes
145
planned
1,361
shipped

Motir · Work items

MOTIR-3306Done

Seed test — idempotent on sourceRef, TOTAL over the corpus with no hardcoded range, and every row carries legal axes

The seed's contract is additive and idempotent on sourceRef — a re-run inserts nothing and removes nothing. That already holds for 70 rows; this proves it at roughly 250, adds the axis assertions the backfill needs, and closes the totality hole that made the drift silent in the first place.

Four properties:

  1. Idempotency at the new size — apply the migration, count, apply again, assert the count is unchanged and no sourceRef appears twice.
  2. TOTALITY, derived rather than restated. Today tests/lessonsBaseSeed.test.ts:83 asserts seeded ∪ EXCLUDED_ENTRIES == 1..111 exhaustively and then checks a hardcoded for (const n of [156, 157, 158]). Everything above 111 that nobody typed into that list is unchecked — which is exactly how #112–#155 went un-accounted for months under a green suite. Replace the hardcoded list with a check that derives the corpus's upper bound instead of restating it, so adding an entry to notes.html without accounting for it fails a test. notes.html lives in another repo, so if the bound cannot be derived at test time, assert an explicit, deliberately-maintained ceiling constant and make the failure message say what to do — a legible chore beats an invisible drift. Either way the test's own coverage must be total over 1..<bound>, with no numeric range exempt.
  3. Axis vocabulary — every value appearing in kinds, types or phases across all rows is legal. This is the assertion that earns its place: a typo (desing, Code, deepening) produces a row that is syntactically fine, passes every other check, and never matches any query for the rest of its life. The suite also reports the coverage split — how many rows constrain each axis, how many are unconstrained on all three — without asserting a target, so it documents the corpus rather than freezing it.
  4. Genericity — no row contains a repo name, a MOTIR-<n> key, or a date, mirroring the ban the shipped rule constant already enforces.

Acceptance criteria

  • Applying the migration twice leaves the row count unchanged with no duplicate sourceRef, asserted against the real test database.
  • The totality assertion covers 1..<bound> with no exempt range and no hardcoded list of entry numbers; adding an unaccounted entry fails, and the failure message names the entry and says what to do.
  • Every value in kinds / types / phases is in the legal vocabulary; the assertion names the offending row and value when it fails.
  • The suite reports the per-axis coverage split without asserting a target.
  • No row matches the forbidden vocabulary; the assertion names the offending row.
  • The suite runs in CI with the other lesson suites; only the changed files are run locally.

Context refs

  • motir-ai tests/lessonsBaseSeed.test.ts — the existing idempotency suite, and (line 83) the totality hole this card closes.
  • motir-ai src/seed/seedBaseLessons.ts — the upsert keyed on sourceRef.
  • motir-ai tests/planningRulePacks.test.ts — the genericity ban this mirrors.
  • MOTIR-1948 — retired; its scope item 3 is the totality fix this card absorbs, and its body carries the original diagnosis.
  • MOTIR-3299 — the three axes and their legal vocabularies.