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

The pass composes its lesson query per card — the query text, plus the kind, type and phase it is working in

Move the retrieval question from the pass down to the card, on all four coordinates.

selectForInjection takes queryText and its own comment calls it "the planning job's intent" — one string for the whole pass, so twelve cards planned in a run embed the same query twelve times and get identical lessons. This card replaces that with a per-card question:

  • queryText built from the card — title, kind, type, target repo, the deliverables its description enumerates.
  • kinds / types from the card being planned.
  • phases from what the pass is doing: skeleton while laying a level's children, deepen while writing a body. This is the coordinate only the pass knows and it has never been asked for.

Know what this half can and cannot do. The ranker returns INJECTION_LIMIT_DEFAULT = 8 ordered by cosine distance, so the query text does most of the selecting — and a harness composing text from card fields can only ever write in feature register ("board filter at scale"), while lessons are stored as takeaways ("a count taken from a working tree is not a property of the ref"). Those embed far apart.

So this card's job is a sound baseline, not the best possible retrieval: correct axes, a per-card query, no regression. The register translation — describing the risk rather than the feature — needs judgement the harness does not have, and belongs to the planner's own search (MOTIR-3321). Say so in the code rather than leaving a later reader to conclude the query builder is underdone.

Keep the composition in one shared helper beside selectForInjection; both planner call sites go through it today and the comment says why. Preserve the two properties the design leans on: selected ids stay recorded per card on the job record, and an empty selection still renders nothing.

Acceptance criteria

  • One exported helper builds the per-card query and the three axes; generate, augment and replan all call it and none constructs its own.
  • The phase passed reflects what the pass is doing — skeleton when laying children, deepen when writing a body — asserted for both.
  • selectForInjection is called once per card rather than once per pass.
  • Selected lesson ids are recorded per card on the job record.
  • A card with no type still produces a usable query and does not constrain that axis.
  • The helper's own comment states that its query is feature-register and that risk-register search is the planner's tool, so the limitation is recorded rather than read as an oversight.
  • An empty selection yields an empty promptSection and injects nothing.
  • pnpm typecheck clean; the planner-input suites pass.

Context refs

  • motir-ai src/jobs/plannerInputs.ts — where selectForInjection is called and queryText is filled today.
  • motir-ai src/repositories/lessonRepository.tsINJECTION_LIMIT_DEFAULT = 8 and the cosine ORDER BY that make query quality decisive.
  • motir-ai src/services/lessonService.tsSelectForInjectionInput, the one-shared-helper contract.
  • motir-ai src/jobs/handlers/generateTree.ts, src/jobs/handlers/replan.ts — the call sites.
  • MOTIR-3300 — the axes this passes · MOTIR-3321 — the pull half that supplies the register this one cannot.