(motir-ai) MIRROR the design-area-is-a-FOLDER limb into `SHARED_PLANNING_RULES` — the shipped planner must scope an asset-defect grep to the directory, not the file it opened
Repo: motir-ai. One PR. The SHIPPED half of MOTIR-2504 — lift its gate-8 limb into the planner the product actually runs.
Why this card exists
A standing planning RULE has two homes, and a card naming only one is under-scoped:
motir-meta/prompts/plan-rules.md— the MANUAL planner. Landed by MOTIR-2504 (motir-meta#151).SHARED_PLANNING_RULESinsrc/llm/treeGeneration.ts— the SHIPPED planner. Its own comment calls it "the encoding ofplan-rules.md", and it is composed by both fresh tree generation and re-planning (src/jobs/handlers/replan.tsimports it), so a rule missing there is missing from every plan the product generates.
Verified this is a real gap, not a duplicate (rung 2, origin/main): the constant already carries gate 8's sibling limbs — the migration/call-sites limb verbatim ("EACH CALLER IS IN THIS CARD'S SCOPE OR IS A NAMED SIBLING CARD, AND THERE IS NO THIRD OPTION", mirrored by MOTIR-2146) and the design-allocation TAKES limb (MOTIR-2156) — and carries nothing about scoping an asset-defect measurement to the design AREA. The one design/<area>/ mention in the file belongs to the design gate, not to the sweep.
The rule to mirror
Lift the wording from the plan-rules.md limb "A DESIGN AREA IS A FOLDER, AND YOUR GREP NAMED A FILE" — it is written to be liftable without re-deriving intent. Condense for prompt budget, but do not drop either operative tell:
- The PATH in an acceptance-criterion grep is the CLAIM, and it is the half nobody re-reads because attention goes to the pattern. A surface's panels are routinely split across sibling
*.mock.htmlfiles (main / filtered / at-scale / empty) and every sibling redraws the same rows, so a per-FILE measurement of an asset defect is incomplete by construction. Measure at AUTHORING time withgrep -rc '<pattern>' design/<area>/, LIST every file that hits, and give each the same two dispositions the migration limb already allows — this card's scope, or a named sibling, no third. - The area's
design-notes.mdsurface table is an INDEX, not an ANSWER. It enumerates the sibling mocks, but a sibling's own one-line self-description is a statement of INTENT the markup routinely contradicts (backlog-filter.mock.htmlis described as "does NOT redraw the … ranked rows" and holds nine of them). Take the FILE NAMES from the table and the COUNTS from the grep.
Acceptance criteria
SHARED_PLANNING_RULEScarries the limb in the constant's existing voice and placement — attached to the same mechanism-sweep section that already holds the migration/call-sites limb, not appended as a foreign block.- Both operative tells survive the condensation: the path is the claim / measure with
grep -rcover the area, each hit in scope or a named sibling, and the surface table is an index, not an answer. - The wording is checked against the motir-meta original so the two homes do not drift; the PR body notes which lines correspond.
- A vitest asserts the rule is present in the composed prompt for fresh generation AND re-plan —
replan.tsimports the same constant, and a rule that reaches only one path is half-landed. - Any frozen-contract / doc guard that covers this constant is updated in the same PR — verify whether one exists before assuming either way.
- PR title carries
MOTIR-<id>(motir-ai is a code repo — the status-sync rule).
⚠️ Working in treeGeneration.ts
grep silently finds nothing in this file — it has very long lines. Search with python or node instead, or you will conclude the constant does not exist.
Context refs
src/llm/treeGeneration.ts—SHARED_PLANNING_RULES, the constant edited.src/jobs/handlers/replan.ts— the second consumer; the reason the test must cover both paths.- MOTIR-2504 — the motir-meta half and the source wording; motir-meta#151.
- MOTIR-2146 / MOTIR-2156 — the two sibling limbs already mirrored; match their placement and register.
motir-meta/notes.html#246 — the incident the limb encodes.