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

A `lessons` retrieval family — the planner searches by axis AND composes the query text, because the text picks which 8 arrive

The planner has a retrieval tool system and lessons are not in it.

RETRIEVAL_FAMILIES = ['plan_tree', 'code_graph', 'code_health', 'web']

Four families, a call budget (RETRIEVAL_TOOL_CALL_BUDGET_DEFAULT = 24, …_PLAN_EDIT = 10) and an audit frame — and no way for the planner to ask for a lesson. Lessons arrive only as a section the harness pushes in, so the model cannot look when it knows it is somewhere unfamiliar, which is exactly when a past mistake is worth having.

Add the fifth family. The union is the wiring guard — assembleRetrievalTools builds a total record over it, "so adding a member here without wiring it there is a compile error, the guard that keeps a new family from shipping unobservable."

The axes are not the retrieval — the TEXT is

WHERE  … kinds/types/phases overlap …          ← chooses the candidate POOL
ORDER BY "embedding" <=> query ASC             ← chooses which 8 arrive
LIMIT  8                                        (INJECTION_LIMIT_DEFAULT)

At a few hundred lessons the axes might cut the pool to eighty. The query text then does the remaining selection, and a weak one returns eight near-arbitrary lessons from a correctly-filtered slice — which reads as the mechanism working while delivering noise. So the instruction is not "search by axis"; it is "narrow by axis, then ask a real question."

Query in the LESSON's vocabulary, not the card's. A lesson is written as a takeaway — "a count taken from a working tree is not a property of the ref", "a criterion that reads on post-merge state belongs to another card". A card's title is written as a feature — "board filter at scale". Embedding the title queries the wrong register and ranks by accident. Describe the ACTION about to be taken and the SHAPE of what could go wrong, in the words a takeaway would use.

Search more than once when the card has more than one risk. One call returns eight; a card that enumerates a population, names a test home and touches a migration has three distinct risk shapes and one query cannot rank for all of them. The budget allows it — spend it deliberately rather than issuing one vague search.

Acceptance criteria

  • RETRIEVAL_FAMILIES gains lessons; the compile-error guard forces the wiring — no parallel list.
  • The tool takes kinds, types, phases and a query string, and goes through selectForInjection rather than a second retrieval implementation.
  • The planner's rules instruct: narrow by the card's axes, then compose the query in takeaway register — the action and the risk shape, never the feature name — and issue a separate search per distinct risk on the card.
  • The rules state the arithmetic that makes this matter: the axes filter, the ranker returns eight, so the text decides what arrives.
  • A test measures it rather than asserting the instruction exists: with a seeded corpus, a risk-shaped query returns the known-relevant lesson inside the limit while the card's bare title does not.
  • A test proves a skeleton query and a deepen query on the same card return different lessons.
  • Calls count against the existing budget and appear in the audit frame; exhaustion degrades as for every other family.
  • A test drives one case per family off the union itself, lessons included.

Context refs

  • motir-ai src/repositories/lessonRepository.tsINJECTION_LIMIT_DEFAULT = 8, the ORDER BY "embedding" <=> … ranking, and the axis WHERE clauses.
  • motir-ai src/llm/retrievalTools.tsRETRIEVAL_FAMILIES, assembleRetrievalTools, the budget constants, RETRIEVAL_BUDGET_EXHAUSTED_MESSAGE.
  • motir-ai src/services/lessonService.tsselectForInjection, the path this tool reuses.
  • motir-ai src/llm/planningRulePacks.ts — where the instruction lands for the shipped planner.
  • MOTIR-3302 — the push half; this is the pull half.