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-4090To Do

Planning bug: `blocks` does not cross the AI boundary either — MOTIR-4055 enumerates THREE missing link kinds and there are FOUR

What the plan says

MOTIR-4055 enumerates the neighbourhood's links as blocked_by · blocks · relates_to · duplicates · clones and then states which of them the AI boundary cannot carry:

relates_to, duplicates and clones DO NOT CROSS THE AI BOUNDARY.

MOTIR-4063 — the producer half — is scoped to exactly those three, in its title and in its body. MOTIR-3942 says the same: "Three of them cannot cross the AI boundary today."

What is true

FOUR of the five cannot. blocks is missing for precisely the same reason as the other three, and nobody checked it because blocked_by is available and the two read as one pair.

Verified on origin/main, 2026-09-01:

  • get-itemaiBoundaryService.getItemworkItemsService.getWorkItemByIdentifiertoWorkItemDto, the LIGHT shape. It carries no link arrays at all — not relatesTo, not duplicates, not clones, and not blocks. The full set is assembled elsewhere in workItemsService for the MCP surface only.
  • blocked_by is available not because the item read carries it but because it has its OWN endpoint: walk-blockingworkItemsService.getBlockingClosure, whose response is { root, nodes, edges: { blockedKey, blockerKey }, truncated } and is documented as "the transitive is_blocked_by closure of a root: what must land before this." One direction, by construction. There is no walk-blocked-by, and no parameter that inverts it.

So the boundary's link inventory is: blocked_by yes (via its own read), blocks / relates_to / duplicates / clones no.

Why the enumeration went short — the shape, not the carelessness

The card correctly traced the LIGHT-shape defect through get-item and correctly named the three arms that read as a group (relatesTo / duplicates / clones are literally adjacent in workItemsService). blocks was then classified by its PAIR rather than by its ROUTE: blocked_by is reachable, blocks is its inverse, so blocks felt reachable. It is reachable by a different mechanism that does not have an inverse.

The general shape: an availability enumeration that groups by CONCEPT while availability is decided by ROUTE. The five link kinds are one concept and three routes — the item payload (4 kinds, all absent), a dedicated closure endpoint (1 kind, one direction), and nothing at all for the inverse.

What has already been done — the correction is applied, this is the record

Nothing is blocked. MOTIR-4055 shipped (PR #345) with the arm handled correctly rather than assumed:

  • NeighbourhoodLinks carries an unavailable list, so an absent arm is DECLARED. An empty blocks beside unavailable: ['blocks', …] says "not readable"; without it, it would say "there are none" — a different and false claim a planner would act on.
  • The consumer reads an arm the moment the boundary carries it, in either the skeleton-row shape or the MCP { linkId, item } shape, with no change on the motir-ai side. Asserted.
  • readNeighbourhood therefore reports unavailable: ['blocks', 'relatesTo', 'duplicates', 'clones'] today, and will report fewer as the producer lands — including blocks, free, if MOTIR-4063 widens to it.

What is left to decide, and it is a PLAN decision rather than a code one

MOTIR-4063's scope is short by one kind. Its title, body and acceptance criteria all name three. Whoever runs it should either widen it to four — the blocks half is a different read from the other three, since it is the INVERSE of an edge rather than a field on a DTO, so it is real work and not a fourth line in a list — or cut a sibling for it and say why.

Either is fine. Silence is not: with the enumeration standing at three, MOTIR-4063 can close green with blocks still unreadable and MOTIR-4062's gate criterion — "THE NEIGHBOURHOOD CARRIES ALL FIVE LINK KINDS" — unmeetable, with nothing in the graph recording why.

Acceptance criteria

  • MOTIR-4063 either covers blocks or names the card that does, on the record. The enumeration and the scope agree.
  • The decision states which ROUTE serves it — the item payload (a fourth arm beside the three) or an inverse of the blocking closure — because they are different work.
  • MOTIR-3942's "Three of them cannot cross the AI boundary today" is corrected to four in the same pass, since the story's own gate reads on all five.

Context refs

  • motir-core lib/services/aiBoundaryService.tsgetItem (the light shape) and walkBlocking (the one-direction closure).
  • motir-core lib/services/workItemsService.tsgetWorkItemByIdentifier, getBlockingClosure, and ~4596–4733 where the full link set IS assembled for the MCP surface.
  • motir-ai src/core/coreClient.tsBlockingClosureView, whose edges are { blockedKey, blockerKey } of the is_blocked_by closure.
  • motir-ai src/jobs/planningTarget.tsNeighbourhoodLinks.unavailable, where this is currently absorbed correctly.