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-3326Done

Search the library BEFORE filing — the planning bug carries whether a lesson already exists, so a hit needs no new lesson

The search comes before the filing, and its result belongs on the bug.

filePlanningBug files and returns — no embedding, no lookup, no recordRecurrence. So the one moment we know a mistake just happened, we never ask whether we already knew about it.

The order matters, because the answer changes what is owed:

  1. Search the library first — the card's axes plus the planner's own description of what went wrong, through the same matcher and threshold capture uses. One matcher, not two.
  2. HIT — the same mistake has recurred. recordRecurrence: bump lastOccurredAt, re-assert enabled, so the lesson returns to the axis + text search even if it had aged out. No new lesson is needed, and therefore no new row in the authored source and no new migration. The corpus already knew; it just needs to know it is still happening.
  3. MISS — genuinely new. A lesson is owed: a row in lessons.base.ts and the migration the generator emits from it.
  4. The bug carries the answer either way — the matched lesson and how many times it has now recurred, or an explicit "no existing lesson matched, a new one is owed."

That last line is the deliverable, not decoration. A reader of the planner-bug home should be able to tell a third recurrence of one known mistake from a genuinely new one without re-deriving it, because the two need opposite work: one needs nothing written, the other needs a lesson authored and shipped.

Matching stays an enhancement: if the library cannot be reached, the bug is still filed, with the match recorded as unattempted rather than as a miss. A miss and a failed lookup must not look the same — one says write a lesson, the other says the check did not run.

Acceptance criteria

  • The library is searched before the bug is filed, using the same embedding, axis narrowing and distance threshold as capture.
  • A hit calls recordRecurrence and the bug names the matched lesson and its recurrence count.
  • A hit records that no new lesson is owed, so nobody authors a duplicate row or a redundant migration.
  • A miss records that a new lesson IS owed, and names what has to happen for it to ship.
  • A failed or unavailable lookup is recorded as unattempted, distinctly from a miss, and the bug still files.
  • A hit on an already-expired lesson brings it back into listForInjection results, asserted end to end.
  • Only fires on the agent-fired path — a user-initiated re-plan reaches none of this.

Context refs

  • motir-ai src/services/lessonService.tsfilePlanningBug, renderPlanningBugBody, captureMistake's matcher, CAPTURE_DEDUP_DISTANCE.
  • motir-ai src/repositories/lessonRepository.tsfindNearestTenant, recordRecurrence.
  • MOTIR-3324 — the trigger gate that decides whether this runs at all.
  • MOTIR-3323 — global reinforcement, without which a base lesson can never be the hit.
  • MOTIR-3307 — the generator whose migration a MISS ultimately owes.