A service reads the levels its service.ncl declares, each `{ project, path }` written by whoever deploys it (adr-002, adr-014); its menu offers those projects and nothing else. The principal's reader declared one level, `code`, so no other project could be reached from the face. The principal asked, 2026-10-08, where the projects SpecDossier may read are declared, and then set the direction: «each project should declare its governance folders, and a script (Nushell) collect them to tell the SpecDossier server which projects to use and which governances, with the mode and authority each one has — ontoref already does something like it, collecting from an NCL and passing it as JSON to the ontoref daemon; this could be changed to something better and more fitting»; «as in ontoref's daemon, changing project changes the logo in the top left corner, and each project's logo is shown on its card on the home page, where its governance folders are shown too»; «the governance of the project itself that ontoref does with its panel and SpecDossier's could communicate, for now at least, as links opening in separate windows».
What exists, measured 2026-10-08: - ontoref's machine registry, `~/.config/ontoref/projects.ncl`, generated by `ontoref project-add` and the daemon's boot (gen-projects.nu), never edited by hand; each entry's root is the registry's, never the project's (ontoref adr-129). The daemon reads it, with ~/.config/ontoref/config.ncl (`daemon.port` 7890), and offers every registered project. ontoref publishes of it only `ontoref project root <id>`; a listing was asked of ontoref, in session, 2026-10-08. - A project's identity, its logo included, is declared on its beacon, `.ontoref/card.ncl`, typed by ontoref's ProjectCard (specdossier: `logo = "assets/branding/specdossier-logo-light.svg"`); `.ontoref/config.ncl` `ui.logo` is the daemon's configuration. Neither is a published surface: card.ncl imports its schema through a layout-specific relative path that differs between ontoref's checkout and a consumer install; the published surface is `ontoref describe project --fmt json`, which carries no logo yet — its publication there is asked of ontoref (ontoref-6d, 2026-10-08). - ontoref's panel serves each project at `/{slug}/` (ontoref ui/mod.rs:75): a link to it needs nothing from ontoref but the project's id. - A name ontoref holds (ontoref-6d, 2026-10-08): `reflection/levels.ncl` is ontoref's level source registry (ontoref adr-045, adr-046), so a second file named levels.ncl breaks one name per tree (ontoref adr-116). ontoref adr-124 holds the SOW, its schema and the acts that move it as ontoref's — not every file of a governance level — and leaves open how a project declares the channel it grants; `.governance/dossiers.ncl` (adr-002) is plausibly that grant, an open question for the principal, not a violation. - A governance level already says its own mode: `authority/offline.ncl` and `witness.pub` (offline) or `authority/pins.json` (an authority's project and keys), and whether it holds dossiers (`dossiers.ncl`, adr-002). No project says which levels it has: specdossier has two (the spine's `.governance/` and code's), found by hand. - Twenty projects are registered on the principal's machine; eight hold a `.governance/` at their root. - The spine's reader recipe (`just reader members="code ."`) declares several levels by hand — the deployer's list, kept in step by hand.
EACH PROJECT DECLARES ITS GOVERNANCES, IN SPECDOSSIER'S NAMESPACE. A project that SpecDossier may read writes `.specdossier/governances.ncl` at its root, typed by SpecDossier's `schemas/governances.ncl`: each governance level's path relative to the project's root (`.governance`, `code/.governance`) and its name. It lives in SpecDossier's own directory, under a name no other tool holds, so it neither shadows ontoref's `levels.ncl` nor adds a SpecDossier file to a level whose files ontoref's formats read. The project declares which levels it has and what they are called — nothing it could only repeat: each level's mode, its authority and its dossiers are read from the level's own files, as they are today.
A SCRIPT COLLECTS THEM INTO THE FILE THE SERVICE READS. `scripts/governances.nu collect` (Nushell) takes the projects to read — ontoref's published listing when ontoref publishes it, else the list the operator gives — reads each project's `.specdossier/governances.ncl`, and writes one generated file, `governances.generated.ncl`, that a service.ncl imports (`levels = import "governances.generated.ncl"`): for each level its project, root, path, name, mode (offline or authority) and authority (endpoint, the pins' project), and the project's identity — its name, description and logo — as `ontoref describe project --fmt json` publishes it; the collector reads no file of `.ontoref/`, and a project whose logo ontoref does not publish is shown with SpecDossier's. The file is generated, never edited by hand, and typed: exporting the service.ncl checks it against `Service`. Running the script is the deployer's act, where the projects are; its file is carried to where the service runs. The service still searches nothing and reads only what it declares (adr-002, adr-014).
A PROJECT IS SHOWN WITH ITS LOGO AND ITS LEVELS. The main menu shows the logo of the project being read in its top left corner, changing with the project; with none, SpecDossier's own. Each project's card on the home page shows its logo, its description and each of its levels — its name, its mode, its authority, its SOWs in force, in draft and archived — each level linking to its list. The logo is the file the generated declaration names, served from it; the service reads nothing of `.ontoref/`.
ONTOREF'S PANEL AND SPECDOSSIER LINK TO EACH OTHER, AND ONLY LINK. Where the deployment declares ontoref's panel (`ontoref_panel = "<url>"` in service.ncl), each project's card and the menu link to that project's page on the panel, `<panel>/{id}/`, opening in another window; that ontoref's panel links back to SpecDossier is ontoref's to decide. Neither reads the other's data through the link.
WHAT THIS AMENDS: it settles adr-002's open question — a deployed service learns which projects and levels to read from the generated declaration its service.ncl imports; levels declared by hand in service.ncl stay valid beside it, a level declared by hand winning over a collected one with the same project and path.
WHAT THIS DOES NOT DECIDE: the listing of projects, which is ontoref's to publish; whether ontoref publishes which governance levels a project has (a question for the principal in ontoref) — until then the project declares them in SpecDossier's namespace; where `.governance/dossiers.ncl` belongs (adr-002), an open question under ontoref adr-124's undecided channel grant; which levels a service that acts may answer for — its authority's projects bind it (adr-004); a dashboard across projects; any exchange between ontoref's panel and SpecDossier beyond links.
The levels a service collects for a project are those its `.specdossier/governances.ncl` declares, typed by schemas/governances.ncl; a level's mode and authority are read from its own files, never declared; the collector reads no file of `.ontoref/`, a project's identity only as `describe project --fmt json` publishes it
A service learns collected levels only from the generated file its service.ncl imports; no source of specdossierd lists projects, reads ~/.config/ontoref/ or a project's .ontoref/
The link from a project's card or the menu to ontoref's panel opens it in another window and carries nothing but the project's address on the panel
The service asks ontoref for the machine's projects when it starts (this ADR's first draft)
Rejected: Ties the service at run time to ontoref and to the projects' machine; a deployed service on another host has no such registry. Collecting ahead, by the deployer, keeps the service a reader of its own declaration.
JSON passed to the service, as ontoref's daemon receives its config
Rejected: A JSON is checked by nothing until the service parses it; the generated NCL is checked by `Service` when it is exported and reads as a diff.
`.governance/levels.ncl` (this ADR's second draft)
Rejected: levels.ncl is ontoref's name (reflection/levels.ncl, its level source registry): a second file of that name breaks one name per tree (ontoref adr-116).
Export `.ontoref/card.ncl` for the logo
Rejected: It reads an ontoref file, not a published surface, and its schema import path differs between ontoref's checkout and a consumer install; the logo waits for `describe project`.
Read ~/.config/ontoref/projects.ncl or each .ontoref/config.ncl directly
Rejected: Binds SpecDossier to ontoref's files and formats; SpecDossier reads what ontoref publishes.
Search the disk for .governance/ directories
Rejected: adr-002: SpecDossier finds nothing by searching a tree; a level is declared.
Keep levels declared only by hand in service.ncl
Rejected: A second list of roots kept in step by hand; it is what left the principal's reader with one project.