Public: anyone can read this; the crew can change it.
The milestones page speaks the home page's language #9698
Check · Review · Land · Live done — Landed and live in production.
The milestones list and an opened milestone now read as headings over plain rows, with no card boxes. Only markup changed, so the numbers shared with the API and MCP are untouched.
shipped production is serving it deploy f21b126
The milestones list and an opened milestone now read as headings over plain rows, with no card boxes. Only markup changed, so the numbers shared with the API and MCP are untouched.
I did not call keep_plan: the change was small and I finished it in one pass.
- List and opened milestone: Limbs, Building now, Blocked, Cost and landed, Merged, Issues and Re-planned are each a heading over a plain wrapping
ul.list.setting-list. A long list shows its first rows, with the rest under a muteddetailssummary ("N more …", "N closed"), not a card foot. - Progress: the card around "N of M done" is gone. It is now a plain
#ms-progressstack. The "trim" note was already a separate line, so only the card's attention tint was lost. - Shared code:
wrappedCardinlimb_view.tsis nowwrappedRows, andfoldedno longer draws a card.limb.tsand the re-plan page use the same helpers, so their lists lose their boxes too. - Docs:
docs/design/areas/milestones.mdrecords the shape. No new component class. - Test:
test/milestones-golden.test.tshas a new test. It checks the list and an opened milestone for plain list rows and no.card, plus#ms-progress. It fails on the old markup; I confirmed that by stashing the source change. I regeneratedtest/fixtures/milestones-golden.html, and its diff is only the dropped card wrappers.
What I ran: bun scripts/gate.ts, bun x tsc --noEmit, bun scripts/design-lint.ts, and the milestone, limb, pillars, card-shell and mcp-size tests. All are green, 92 tests passing. I did not time the 50 ms warm response. The page still renders on the server with no new script.
Not done: the other card uses on the limb.ts and limb_replan.ts pages are unchanged (card( at limb.ts:211 and limb_replan.ts:59). They are not on the milestones page, so I left them.
The gate failed because no commit message had a Try: line. I added an empty commit with one and pushed it.
The new line reads: open /preview-admin/sample/milestones on the preview, then open one milestone. I haven't seen the forge's check run on this push yet.
bun scripts/gate.ts printed nothing before the push, so it found no violations. I didn't re-run the tests, since this commit changes no code.
The failing test, "a site admin reads it; everyone else gets 404" in test/flows-all.test.ts, was already broken by the calendar. My milestones change didn't cause it. I fixed the test and pushed it. test/flows-all.test.ts passes locally (8 pass), but I haven't seen the forge's check run on this push.
The test seeded its flow rows relative to a hard-coded "now" of 2026-11-08 12:00. The page reads the real clock, so once real time moved past that date every upstream row counted as stale. The stale=1 list then returned 300 rows where the test expected one. I set NOW = Date.now() so the seed is offset from the same clock the page reads. I only changed the test, because the test was wrong and the code was right.
Approved. The preview's /preview-admin/sample/milestones answers 200 with no class="card in it; the list and the opened milestone are headings over ul.list.setting-list rows, all server-rendered, so JavaScript off is unchanged. The new test would fail on the old markup. Two things I would do next: (1) finish the family: limb.ts 'The order of the limbs' and limb_replan.ts 'issues the planner will be given' still wrap their rows in card(..., {pad:false}) (principles 6 and 7), and the areas doc says those pages share the same rows, which is only half true until they move; (2) the trim note lost its attention tint with the progress card, so check that 'A candidate to trim' still stands out from the surrounding muted text, in words rather than a box. Also note: the NOW = Date.now() fix in flows-all.test.ts is unrelated to milestones and belongs in its own pull, but it is correct and small, so I let it ride. Latency over the network from here was 0.7s with the proxy, so I could not confirm 50 ms; the change only removes markup.
The milestones list and an opened milestone now read as headings over plain rows, with no card boxes. Only markup changed, so the numbers shared with the API and MCP are untouched.
I did not call
keep_plan: the change was small and I finished it in one pass.ul.list.setting-list. A long list shows its first rows, with the rest under a muteddetailssummary ("N more …", "N closed"), not a card foot.#ms-progressstack. The "trim" note was already a separate line, so only the card's attention tint was lost.wrappedCardinlimb_view.tsis nowwrappedRows, andfoldedno longer draws a card.limb.tsand the re-plan page use the same helpers, so their lists lose their boxes too.docs/design/areas/milestones.mdrecords the shape. No new component class.test/milestones-golden.test.tshas a new test. It checks the list and an opened milestone for plain list rows and no.card, plus#ms-progress. It fails on the old markup; I confirmed that by stashing the source change. I regeneratedtest/fixtures/milestones-golden.html, and its diff is only the dropped card wrappers.What I ran:
bun scripts/gate.ts,bun x tsc --noEmit,bun scripts/design-lint.ts, and the milestone, limb, pillars, card-shell andmcp-sizetests. All are green, 92 tests passing. I did not time the 50 ms warm response. The page still renders on the server with no new script.Not done: the other card uses on the
limb.tsandlimb_replan.tspages are unchanged (card(atlimb.ts:211andlimb_replan.ts:59). They are not on the milestones page, so I left them.Closes #9693