motir-ai: gate tenant capture on the setting — off means no lesson, and bugs still file
The consumer half: read the flag off the job context and make it actually stop the write.
Gate the capture path, not the tool's availability alone. A planner that is simply not offered log_planning_mistake is the right first move, but the guard belongs at captureMistake too — a setting enforced only by what the prompt was told is a setting the model can be argued out of.
Gate captureMistake, not createFromCorrection. They are one level apart and the lower one is shared: createFromCorrection is also what POST /v1/lessons reaches, so a guard placed there would switch off the deliberate add_lesson path as a side effect. The setting is about the planner drawing its own conclusions, and that is captureMistake exactly.
What OFF does not touch, all four asserted, because the natural implementation over-reaches:
- Planning bugs still file. The bug is the defect record; the setting is about writing a lesson. Someone switching off capture has not asked to stop reporting.
- Existing lessons keep applying. This governs new writes, not the store. Turning it off is not a bulk retire.
- Recurrence still reinforces. A recurrence bumps an existing lesson's clock — that is not a new lesson, and stopping it would silently expire a project's corpus as a side effect of a setting that says nothing about retirement.
- The
add_lessontool still works. Turning off automatic capture says stop drawing your own conclusions; it does not say this project may no longer write anything down.
An ABSENT flag is not OFF. An envelope from a producer that predates the field carries nothing, and treating that as off would switch capture off for every job in flight across a deploy. Absent means the old default: on. Only an explicit false disables.
Agree on the field name by reading, not by running. There is no shared type across the repositories and a mismatch fails silently — quote the exact name in the PR body and check it against the producer card's.
Acceptance criteria
- The flag is read from the job context using the name the producer sends, quoted in the PR body.
- With it
false, no tenant lesson is written by that run — asserted atcaptureMistake, not only by the tool being unavailable. - The guard is at
captureMistake;createFromCorrectionis unchanged, and a test asserts a create through it still succeeds with the flagfalse. - With it
false, a planning bug is still filed, asserted. - With it
false, existing lessons are still injected and a recurrence still reinforces, both asserted. - An absent flag behaves as ON, asserted with an envelope that omits it.
- The tool is also withheld from the planner when the setting is off, so the model is not asked to comply with a rule it cannot see.
Context refs
motir-aisrc/services/lessonService.ts—captureMistake,createFromCorrection,filePlanningBug,recordRecurrence.motir-aisrc/llm/treeGeneration.ts— where the tool set is assembled.motir-aisrc/jobs/— where the envelope'scontextis read.- MOTIR-3350 — the producer whose field name this must match exactly.
- MOTIR-3359 — the route that calls
createFromCorrection, and must keep working with the flag off. - MOTIR-3327 — the tenant-only narrowing this gate sits on top of.