(motir-core) Three MORE seeders write a `position` the product cannot mint — `scripts/seed-large.ts` pads to 8, and the two board E2E specs write `p0000001` (invalid LENGTH, not head)
Found while running MOTIR-2196 (the createTestWorkItem fixture fix). An out-of-scope finding logged rather than absorbed (notes.html #27): MOTIR-2196's blast-radius grep turned up three MORE sites writing a position no shipped code path can emit. They are deliberately NOT in that card's diff — see "Why this is separate" below.
The three sites
| site | written | why it is invalid |
|---|---|---|
scripts/seed-large.ts:301 | String(key).padStart(8, '0') | head '0' → invalid order key head: 0 |
tests/e2e/board-load.spec.ts:100 | `p${String(key).padStart(7, '0')}` | head 'p' demands a 17-digit integer part; 7 digits → invalid order key: p0000001 |
tests/e2e/board-at-scale.spec.ts:196 | `p${String(i + 1).padStart(7, '0')}` | same |
Verified, not reasoned:
$ node -e "const{generateKeyBetween}=require('fractional-indexing');
for (const k of ['000001','p0000001','a0'])
{ try{generateKeyBetween(k,null);console.log(k,'VALID')}catch(e){console.log(k,'INVALID:',e.message)} }"
000001 INVALID: invalid order key head: 0
p0000001 INVALID: invalid order key: p0000001
a0 VALID
What each one costs
scripts/seed-large.tsis the worse of the two shapes, because a HUMAN uses its output.pnpm db:seed:largefills a dev database, and the first board drag that lands next to one of those cards callskeyForAppend/keyBetweenon a head-'0'key → the move API 500s and the board renders "Move not allowed". That is exactly the failurescripts/plan-seed/seed.ts:396-412was fixed for and wrote five lines of comment about; the sibling large-seeder never got the message. (scripts/seedLargeBoard.ts:155DID — it carries the warning.)- The two board E2E specs are latent rather than live:
keyBetweenSafe(lib/workItems/positioning.ts) treats an invalid bound as an open end, so a drag in those specs currently degrades to an append instead of throwing. Nothing is red today. What is wrong is that the rows are not the system under test — a board-at-scale spec is asserting reorder behaviour over a key space the product cannot produce, so the tolerance path is what is under test rather than the ordinary one.
Why this is separate from MOTIR-2196
MOTIR-2196 fixed the shared createTestWorkItem fixture and the four vitest seeders that copied it, all verified locally against the real Postgres. These three are a different risk shape:
scripts/seed-large.tsis not a test fixture at all — it is a dev-data script, the other half of the pairplan-seed/seed.tsalready fixed.- The E2E seeds change behaviour, not just data: with valid bounds
keyBetweenSafemints a key strictly BETWEEN the neighbours instead of falling back to an append, so a spec asserting post-drag card order can legitimately move. That has to be validated by running the board E2E specs, which MOTIR-2196's run could not do locally (the sandbox's/dev/shmand the shared inngest port make heavy board E2E unreliable —prodect-e2e-run-harness-oom).
Absorbing them would have put an unverifiable E2E behaviour change inside a card whose whole point was a verified fixture fix.
Acceptance criteria
scripts/seed-large.tsmints itspositionvialib/workItems/positioning.ts, chained globally in creation order, and carries the same warningscripts/plan-seed/seed.ts:396-412does.- Both board E2E specs seed real fractional-index keys, chained so the seeded card order is unchanged.
- The board E2E specs pass — including any drag/reorder assertion, which now exercises
keyBetweenrather thankeyBetweenSafe's invalid-bound fallback. If an assertion moves, the PR body says which and why. - A grep for a
position:written as a padded or prefixed number returns nothing acrosstests/,scripts/andlib/— the whole class is gone, not three named files.
Context refs
lib/workItems/positioning.ts—keyForAppend/keyBetween/keyBetweenSafe(the tolerance path these currently lean on) /isValidOrderKey.scripts/plan-seed/seed.ts:396-412— the warning, and the global-chain argument these should mirror.scripts/seedLargeBoard.ts:155— the sibling script that already learned it.tests/fixtures/workItemFixtures.ts— MOTIR-2196'snextTestPosition, the shared helper to reuse where a test can reach it.