- #/orgs/<id> with no page and no trailing slash now opens #/orgs/<id>/organization instead of the
system dashboard.
- The system dashboard resolves its own appearance (this browser's choice made
there, else the default) under mosaic-console-appearance-system; it no
longer shows the theme of the organization opened last.
- A stopped organization's page shows one bus banner: the page's own down
banner now carries the restart action, and the shell's "Bus unavailable"
banner hides on that page (display.js paintBus and app.js busDown).
- The dashboard row for a stopped organization no longer repeats "the bus is
not running" under "bus stopped"; the last start time still shows.
- Organizations table figures keep to one line (white-space, no font change).
- The Active agents status cell was class "st", which picked up the global
.st::before "?" glyph; it is now ws-st.
- Tests: red-first browser tests for each item, plus the test sp1 lacked: a
read still in flight at an organization switch keeps nothing.
- org-switch-browser: a stopped organization's page asserts one banner; the
shell's "Bus unavailable" is checked on its tasks page instead.
- First run (no organization yet) keeps #/ as its board; the router no longer rewrites it to
#/dashboard, which first run cannot draw.
- An organization switch stops the agents section's request poll and clears what it held. A
route-change restart chain finishes on the organization it started in.
- A write in flight at a switch drops its answer: an org epoch in bus.js, checked after each
await. The switch clears every busy flag, receipt and reply, and the doc drafts.
- The bus banner reads org state again only when the route crosses /dashboard, not on every
hashchange inside one organization.
- The down banner does not repeat its heading as the reason.
- Tests: first run wordmark, poll stop on switch, restart pinned to its organization, settings
save in flight at a switch, banner without a repeated reason. The org-switch test comment and
wait match the in-place switch.
#/dashboard is the system landing route: one row per organization with its bus
state, agent count (organization files), project count and needs-you count,
each only when a read gave it, and active agents. Opening an organization from
the sidebar or a dashboard row is a route inside the same page: no reload, a
Dashboard / <organization> breadcrumb, and later /api reads scoped to it through
the existing fetch wrapper, whose organization is now a variable the router sets
(mosaic-org-switch event). #/orgs/<id>/... stays the address. An organization
whose bus is down says so on the dashboard and on its page, with the reason the
workspace read gives.
In organization mode #/ is the cross-organization dashboard (sample 02),
#/projects lists every organization's projects with sort, filters and the
shared By org / Flat grouping (sample 04), and #/inbox lists decisions
across organizations with per-organization decide paths and terminal
commands carrying --org and the full id (sample 05). The per-organization
board moves to #/board and the organization's own project list to #/chat,
which keeps the project surface. Reads go through workspace-data.js; a
read an organization could not make says not read, never zero. Polling
repaints in place and keeps focus, caret and scroll.
Finishes the U2 WIP (37b0891a3) to samples 01, 03 and 08 of the
2026-11-09 unified workspace set:
- workspace.js: sidebar Organizations and Projects groups (collapsible,
state remembered), the org dashboard, the Agents levels.
- workspace-data.js: every read these screens make, GET no-store,
redirect manual; a refused read shows unavailable for that part only.
- shell.css: the html[data-organizations] .ws-* block from the sample.
- bus.js: org-mode sidebar order, pinned Settings, no project tree under
Projects, focus kept across repaint.
- Honest empty states where the Console has no data (KPIs, metrics, kind).
- Tests: unified-workspace-browser (10), picker/delete/switch browser tests
follow the sidebar, browser.test script pin.
F1: the org list shows a broken org as invalid only when the failure
came after the owner check passed (ownerVerified). A broken root or
marker on someone else's org stays hidden.
F2: /api/orgs answers a registry read failure with a fixed message.
The parser text could quote private registry bytes.
F3: selected-org pages keep the list error, paint one replaceable
header banner, and Retry always re-reads the list. The Board shows the
registry message once.
New tests org-list-privacy and org-list-refresh-browser fail on
0e9b2c505 for F1, F2 and F3 and pass here. Serial batch over all 134
webui files plus business org-* and cli org: only failures were the
known pinned-copy EISDIR (8) and an org-switch assertion on the old
pass-through text, updated here.
#867: organization reads no longer take the registry writer lock; they
retry while the lock exists or the registry changed during the read.
#868: a broken organization is listed as invalid with a path-masked
reason instead of disappearing; the Board, header and picker show it,
and /api/orgs 503 carries the reason. Orgs the principal may not see and
archived orgs still give an empty list.
#869: a Console with no board says "No board", not "Board: null".
#866 (save-path validation at bus admission) is left out: it refused
documents the bus accepted before and needs a migration story first.
Every bus, business, cli and webui file run serially; failures are only
the known EISDIR node_modules-link files.
Settings marked every page except appearance and business read only when
send was off. Organization mode always turns send off, so the read-only
style hid New organization and Save organization. Organizations now stays
writable when the server allows org setup. The browser test asserts both
buttons are visible, not only clickable.