MotirBuilding in public
MOTIR · moooon
onMotir
You’re viewing a public project. Anyone can view it — no account needed. Sign in to submit, upvote, or comment on requests.View-only — you can’t edit work items
MOTIR-3493

(motir-core) Design — the roadmap ROOT level's non-epic rows: the grouped defects node, the level it drills into, and a cap that is visible rather than silent

Done
Description

Type · design · Repo motir-core · One PR.

Parent · MOTIR-3490 — the defect this unblocks. Why this card exists: motir run MOTIR-3490 reached run.md guard #3 and stopped. MOTIR-3490's acceptance criteria require two pieces of roadmap-canvas UI that design/roadmap/ does not depict — a grouped node on the ROOT level (its ACs 1, 2, 5) and a visible truncated state for the level cap (its AC 3) — and a run may not improvise UI.

What was checked before concluding the design is absent (the design-reference rule's own precondition): design/roadmap/ was listed — 19 .mock.html sheets, each with a .png, plus a 1 286-line design-notes.md. The notes were read and grepped; every .mock.html under design/roadmap/, design/backlog/ and design/triage/ was grepped for defect / truncat / parentless / unparented / +N more. Findings: the notes describe the root level as "the full root level (every epic)" (design-notes.md:507); the one + N more epics tile in the corpus (design-notes.md:200, grid-init.mock.html) belongs to the ONBOARDING init screen's plan-preview cluster, a different surface; triage.mock.html's "Unparented" is the triage inbox's promote-into-backlog popover. No sheet depicts a grouped root node, and none depicts a truncated level.

What to produce

A THREE-file design asset under design/roadmap/ — a new *.mock.html sheet built from the real design system, its same-basename .png export, and the design-notes.md section that carries the decisions. A NEW surface gets a NEW sheet; do not amend an existing one.

Design against SHIPPED REALITY — render it first. The roadmap canvas is implemented and running: screenshot the real /roadmap root level (or render the real ProjectRoadmapCanvas / WorkItemNode headlessly from their own source with the real globals.css) BEFORE drawing, and compose the sheet from the real shipped components rather than a stylised stand-in. The project's live tree already contains a parentless bug at the root, so the defect is reproducible on the running app.

The seven decisions the sheet must settle

Each is a choice the code card would otherwise make silently. Every one gets an explicit disposition in design-notes.md, in the numbered-decision style planning-origin-drill uses.

  1. WHICH rows group. MOTIR-3490 contradicts itself: its AC 1 says the root draws no bug node beside the epics, while its fix direction says collapse non-epic rows. story, task and bug are all legal roots (prisma/sql/work_item_triggers.sql:182 — only subtask is refused). Decide whether the group is bugs-only or every non-epic root, and the node's NAME follows: a parentless task inside a node labelled "Defects" is wrong. State the disposition for each of the four kinds.
  2. The node's CARD FACE. The canvas already ships four distinct treatments — WorkItemNode (container face, kind tile, meter, drill chevron), GhostAnchor, StationCard, and the wide plan-preview cluster. Pick one and say why; name the count copy and its format, and say which token carries its tile, since there is no --el-type-* hue for a node no kind backs.
  3. decorative, or a branch. ProjectRoadmapCanvas counts nodes.filter((n) => n.decorative !== true) to ask "does this level offer a CHOICE?" for autoDescendSingleParent (MOTIR-1807 / MOTIR-1824). The planning-origin card is decorative because it is provenance beside the road; a group node holding real work arguably is not. Decide it, and say what a one-epic project's root level does with the group node present.
  4. The DRILLED level (its AC 2). The grouped defects are ALREADY in the root read, so the level can be served synthetically from the same fetched data the way loadLevel intercepts ORIGIN_ID — or by a real fetch. Draw the level: its breadcrumb crumb label, whether each defect keeps the status chip / ready highlight / off-level-blocker treatment it has today, and what the level says when the group is empty.
  5. The TRUNCATION affordance (its AC 3). TREE_LEVEL_MAX_TAKE = 200 with DEFAULT_SORT key-ascending discards the HIGHEST keys — the newest epics — with no cursor and no affordance. Draw what the reader sees when a level is truncated: a + N more tile on the canvas, a header count, a paginate control, or a raised cap. countProjectTreeLevel already exists in workItemRepository, so a total is available to draw against. Draw the affordance at the LEVEL, not only at the root, if it is to be general.
  6. SPRINT scope (its AC 5). The sprint root level is re-rooted at the topmost in-sprint members (findProjectTreeLevel's topInSprintMembersSql), so a committed parentless defect IS a root there. Say whether the same group node appears in sprint scope, and what it shows when the group is the only root.
  7. The ACCESS PATH. The group node is itself the door to the defects — so the sheet must DRAW the root canvas with the node in place AND the level behind it, not describe the route in prose.

Acceptance criteria

  1. design/roadmap/<name>.mock.html exists and is built from the real design system — components/ui/* markup and --el-* element tokens only, no Tier-0 --color-* and no raw rounded-md / p-2 / h-9.
  2. A same-basename .png export sits beside it (Playwright chromium, light, deviceScaleFactor: 2, ~1200px — the convention design-notes.md's asset table records for this area).
  3. design/roadmap/design-notes.md gains a section for the new sheet: its row in the asset table, and one numbered disposition per decision 1–7 above, each stating what was decided and why. A decision left as "to be resolved by the code card" does not satisfy this.
  4. The sheet draws BOTH states of the drill — the root level with the group node among the epics, and the level the group opens onto — so a reader sees the door and the room.
  5. The sheet draws the truncated state decided in 5, with the copy it carries.
  6. Every element the sheet composes from an ALREADY-SHIPPED component reproduces that component's real markup and classes (or embeds the shipped screen), rather than a redrawn stand-in — checked against a render of the running canvas, and the render is cited in the notes.
  7. prettier --check is clean over the changed files, and the diff touches design/roadmap/** only.

Context refs

  • design/roadmap/design-notes.md — the asset table, the node vocabulary, and the numbered-decision style to follow; :507 is the "full root level (every epic)" line this card revises.
  • design/roadmap/planning-origin-drill.mock.html + its notes section — the closest precedent: a SYNTHETIC root node that is a door, with an explicit decision per station and an explicit decorative ruling.
  • design/roadmap/roadmap.mock.html, auto-drill.mock.html, scope-toggle.mock.html — the shipped root level, the auto-descend cases, and the sprint-scope root.
  • components/planning/WorkItemNode.tsx, ProjectRoadmapCanvas.tsx (:478 the decorative count), workItemLevel.tsx (ORIGIN_ID, buildWorkItemLevel), WorkItemRoadmap.tsx (loadLevel's ORIGIN_ID intercept) — the shipped components the sheet composes from.
  • lib/services/workItemsService.ts:828 (TREE_LEVEL_MAX_TAKE) · :3374 (getProjectRoadmap) · lib/issues/issueListView.ts:70 (DEFAULT_SORT) — what the cap does and which rows it drops.
  • lib/repositories/workItemRepository.tsfindProjectTreeLevel (no kind predicate at the root) and countProjectTreeLevel (the total a truncation affordance can draw against).
  • MOTIR-3490 — the defect this unblocks; its ACs 1, 2, 3 and 5 are what this sheet must make buildable.
Status
Done
Type
Feature