Repository navigation
The navigation rail orders by file kind before course order — a page with children can never precede one without #3406
Description
Why MeshWeaver core — checked, not assumed
The rail is built and rendered here and nowhere else: src/MeshWeaver.Graph/SuppliedNavigationRail.cs (Plan, Render), whose only caller is src/MeshWeaver.Graph/MarkdownOverviewLayoutArea.cs. Verified by grepping SuppliedNavigationRail across MeshWeaver, MeshWeaver.Plugins and MeshWeaver.Education — it appears only under MeshWeaver/src/. The two alternatives were ruled out: Plugins owns the supplier (Edu's EduCourseNavigationProvider implements core's INodeNavigationProvider) but the split happens after the supplier hands over its already-ordered entries, and the only satellite-side workaround — stop declaring children — would cost the collapsible lessons; Education authors the Order values and owns neither side of the rendering. gh search issues --owner Systemorph on SuppliedNavigationRail / "navigation rail order" returns no prior report. Per the fleet's conserve-work-products rule the durable home is a page under src/MeshWeaver.Documentation/Data/Architecture/; this issue is the pointer.
How to reproduce
- On any mesh with the Edu package, open a course whose lessons have children —
https://memex.localhost:8443/AgenticOfficewill do; every course qualifies, since a lesson carriesExercise,Solution,Quiz. - Read the left rail top to bottom and compare with the
Ordervalues in the course's front matter (AgenticOffice/*.md,*/index.md,*.json). - Observed: every childless page first, in order; then every page with children, in order. Lessons 1–4 render after the coach, the assistant and the exercises.
- Unit-level: build a
NodeNavigationwhose first entry has children and whose second does not, callSuppliedNavigationRail.PlanthenRender, and read the emitted sequence — the second entry precedes the first.
What happens
Plan partitions the supplied entries into Pages (no children) and Groups (children), and Render emits Home → every Page → every Group. The supplied order — Order then Name, from CourseShellAreas.SelectCoursePages — survives within each bucket and is lost between them.
Measured
memex.localhost, AgenticOffice, 2026-09-06. One rail, two correctly-ordered blocks:
README 0 · Übungen 55 · Coach 70 · Assistent 75 · Treuhänderin 78 · Deine Übungen 80 · Erklärvideo 90
Lektion 1 (1) · Lektion 2 (2) · Lektion 3 (3) · Lektion 4 (4) · Musterfirma 50 · Die Agenten 85
The four lessons carry orders 1–4 and render tenth to thirteenth, because they have Exercise, Solution, Quiz and Dokumente beneath them. No Order value can fix this — the numbers are already right.
Why it matters
A course author's only lever over the rail is Order, and it silently cannot express a reading order that mixes leaf pages with lesson folders — which is every course. MeshWeaver.Education has the intended sequence ready for all nine courses (its issue links here); none of it can render until this does.
Suggested fix
Rail carries one ordered sequence of items — link or group — instead of Pages and Groups, and Render walks it once. Keep Plan pure so its tests keep pinning the contents, and keep the three properties the class documents as deliberate: the title is a link and never the collapsible root; an entry with children is a group and its own first link; the current entry stays in the tree as an active link.
🤖 Generated with Claude Code
Activity
sierragolflima commentedon Sep 6, 2026
The content side — the bands, the gate, and the numbers for all nine courses — is Systemorph/MeshWeaver.Education#272, with its diff attached. AgenticOffice's numbers are on Education#270 today; none of them can render in sequence until this lands.
fix(#3406): retire the rail's two buckets as [Obsolete] forwarders
rbuergi commentedon Sep 6, 2026
Fixed by #3414, merged.
The rail now preserves the order the supplier hands over, instead of re-grouping by file kind — so a page with children can precede one without, and
Edu's course order survives into the rendered rail. Fixed core-side inSuppliedNavigationRail, where the split happened after the supplier had already ordered its entries; the satellite-side workaround (stop declaring children, losing the collapsible lessons) was explicitly not taken.Closing by hand: the merge queue does not fire
Closeslinks, so the link in #3414's body could not close this itself.review(#3431): pin the resolver's API read with tests, and derive the…