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
144
planned
1,362
shipped

Motir · Work items

MOTIR-2950Done

Planning bug: 8.1.5 shipped a checkout endpoint that could never work, because the deferral was written into a CODE COMMENT ("EITHER … OR …") instead of a card — the orphaned-deferral shape, on the revenue path

A record card. The product defects are MOTIR-2948 (motir-ai) and MOTIR-2949 (motir-core); this card exists only to hold what the plan should have done differently. Discovered 2026-08-17 while running MOTIR-2940's AC 2.

What happened

MOTIR-1146 (8.1.5, done) shipped POST /v1/stripe/checkout-session. It cannot create a Session for any price the catalog offers: motir-core sends a price LOOKUP KEY, motir-ai passes it into Stripe's line_items[].price, which requires a price_… id. Proven read-only against the deployed key: GET /v1/prices/pro_pool_monthly404 resource_missing.

The gap was known and written down at the time — in a code comment, in the other repo. motir-core/lib/billing/catalog.ts:9-20 (corrected at close-out from 9-21; line 21 is blank), authored by MOTIR-1147 (8.1.6) in 14a330cc, 2026-06-22:

"So for LIVE checkout one of two things must hold, and is tracked as a seam (see the PR / the 8.1.5-side follow-up): EITHER the motir-ai checkout resolves a lookup key → Price (prices.list({ lookup_keys })), OR these keys are mapped to the sandbox price_… ids via config."

There is no 8.1.5-side follow-up. A search_work_items sweep for lookup_keys / priceLookupKey / price_… / top-up over the whole project returns no card that owns either branch of that "EITHER … OR". The seam was named, a resolution was deferred to a card that was never created, and billingService.ts:278 was then written asserting the deferral had already been resolved the other way — "motir-ai resolves it to the concrete Price."

What the plan should have done

This is the orphaned-deferral shape (plan-rules/core.mda deferral is a card) on the revenue path. Three specific misses — each re-checked at close-out; the framing survives, the attribution does not (see "Close-out verification" below):

  1. A deferral recorded in a code comment is not a deferral, it is a leak. The comment even names the two candidate fixes and the phrase "tracked as a seam" — everything except the one artifact that would make it real. The rule already exists; what failed is that nothing checks a shipped comment against the card set. AMENDED 2026-08-17, MOTIR-2950 close-out: the rule did NOT exist. A deferral is a promise; only a card is a plan landed 57f0122 2026-07-29 and A DEFERRAL IS A CARD, FILED IN THE SAME ACTION THAT WRITES IT landed e81d5c8 2026-08-04; these cards were authored 2026-06-19T14:11:40Z. And the sharper miss is not that the deferral went unfiled — it is that the comment MIS-SCOPED the defect to a mode. "So for LIVE checkout one of two things must hold" turns a present-tense contradiction into a future-tense environment condition, and MOTIR-2948 measured that the failure is mode-independent ("it fails in the sandbox today and would fail identically against a live key"). A defect scoped to an environment nobody is in yet reads as provisioning, which already had an owner (8.1.2 / the Stripe account) — so filing nothing was locally reasonable. See notes.html #303.
  2. A two-repo contract shipped with no card owning the SEAM. 8.1.5 (motir-ai) and the catalog card (motir-core) each did their half correctly under their own assumption about who resolves the identifier, and the assumptions were opposite. A cross-repo contract needs an owning card that asserts the two halves compose (a seam needs an owner / contract = two PRs).
  3. Story 8.1's acceptance never traversed the path. 8.1 is done with a webhook handler, an idempotency table, a seat-resync job, a portal, a catalog, a paywall and an entitlement gate — and no evidence that a single Checkout Session was ever created. That is the same shape as MOTIR-2935 (a service token set nowhere) and MOTIR-2940 (a sandbox key in production): three defects on one story, all of them "every component present, the chain never once traversed end to end". Per plan-rules/kind-bug.md's repeat-defect trigger, the third instance is the point at which the SHAPE is the thing to fix, not the row. AMENDED 2026-08-17, close-out — the family does not hold at this grain, and the trigger postdates the defect anyway. Re-derived by content: 2935 (an env var set in neither deployment) is kind-leaf-deepen.md's wiring limb and 2940 (a sandbox account in production) is its platform-read limb — both deployment-state defects, both already covered. This one is a code-contract defect: a wire that is connected, typed, documented and read, whose two ends assign the value opposite semantics — a sixth data-seam failure mode that passes all five existing ones. Honest family for this shape: one. The repeat-defect trigger itself landed c3e7b70 2026-08-04, 46 days after these cards were authored.

The correction

Applied by filing 2948 and 2949 with the seam owned on both sides. Verified 2026-08-17: MOTIR-2948 is done and shipped (d4d0e78, motir-ai PR #242) — prices.list({ lookup_keys }) resolves the key, mode is derived from price.recurring, quantity is carried, and docs/contract.md §2.4 now states that priceId is a lookup key; MOTIR-2949 owns the motir-core half, blocked_by 2948, and is in flight.

The standing question this card leaves open — for Yue, not for a coding agent — is whether the rule changes: whether an acceptance criterion of the form "a real Session/charge/event was produced, not merely a component that would produce one" becomes a required gate for any Story whose subject is an external service. Three instances on one story argues yes.

SETTLED 2026-08-17 (motir run never asks; a deferred question is settled on evidence): NO — LESSON, not a plan-rules/ sharpening. The argument for promotion rested on a premise the ORDER test falsifies, and the corpus already contains the rule being asked for. Grounds in "Close-out verification" below. Landed as notes.html #303 (motir-meta#228). Do not restore the conditional form — a record card ending in "if it recurs, the sharpening is …" is the notes.html #221 trap, which re-arms the question for the next reader as though it were undone.

Out of scope

  • Both fixes. This card ships no code and closes on the decision above being recorded.

Close-out verification (2026-08-17, motir run MOTIR-2950)

Correction held. 2948 done + merged, 2949 owned and in flight, both halves of the seam carried. The disposition claim on this card is accurate — checked per the MOTIR-2907 rule (read the SUBJECT's description, not the record's account of it).

Citations, re-executed. catalog.ts seam block is at 9–20, not 9–21 (line 21 is blank) — the quote is verbatim. billingService.ts:278 is exact for priceId: input.priceLookupKey; the quoted comment sits at 274–275, in the same block. The negative sweep was re-run and holds: search_work_items for lookup_keys / priceLookupKey / lookup key returns 9 cards — four are this defect's own filing family (2940/2948/2949/2950), five are unrelated (864, 1303, 1310, 2044, 2726). No card owned either branch of the EITHER…OR at filing time.

⚠️ The ORDER test falsifies this card's own "why nothing caught it". The explanation says the rules existed and were scoped to plan time. They did not exist. Cards authored 2026-06-19T14:11:40Z, shipped 14a330cc / 5f4438d 2026-06-22:

Rule this card names or that would cover the shapeLanded on mainΔ
a deferral is a promise; only a card is a plan57f0122 2026-07-29+40d
data-seam — verify the READ, not the WRITEfcddcbd 2026-08-01+43d
closing-time SEAM trigger (kind-story.md)a28bc8b 2026-08-02+44d
artifact-obtainable — PULL it, don't cite the lane5aeba6f 2026-08-03+45d
A DEFERRAL IS A CARD, FILED IN THE SAME ACTIONe81d5c8 2026-08-04+46d
repeat-defect trigger (kind-bug.md)c3e7b70 2026-08-04+46d

A rule that ran and under-delivered is a trigger problem; a rule nobody ran is a diligence problem; a rule that did not yet exist is neither, and cannot support a widening — zero post-rule occurrences of this shape.

The corpus already contains the gate this card asks for. kind-story.md's closing-time trigger describes this defect in advance, from a different incident six weeks later: "the code is locally right at every step — a correct implementation authoring a correct contract, with a careful comment explaining it — so there is no defect to find in either card; the gap is the SEAM, and only a closing-time trigger stands on it." Its discharge is lexical ("the closing pass diffs the card's OWN PR for new process.env reads") and does not reach a seam that introduced no env var — but that is a trigger with zero occurrences on this shape, not one that failed.

The family, re-derived by content, is not three of a kind. MOTIR-2935 (an env var set in neither deployment) is the wiring limb and MOTIR-2940 (a sandbox account in production) is the platform-read limb of kind-leaf-deepen.md — both deployment-state defects. This one is a code-contract defect: a wire that is connected, typed, documented and read, whose two ends assign the value opposite semantics. Honest family for this shape: one.

What the substrate could have told anyone, at zero cost. docs/contract.md §2.4 read "priceId": "price_123" at the very commit — and the catalog comment cites that exact line before shipping the opposite. A shared contract document that contradicts the code being written is a defect the moment it merges; citing it accurately is not discharging it.