Skip to content

Commit e854bc8

Browse files
committed
docs(ui): state what happens when a nav contribution names an anchor that is not there
The Setup app page explains the shell/anchor mechanism — the shell publishes empty group anchors and capability plugins contribute into them — but stopped short of the failure the anchor id makes possible. A contributor cannot see the shell's ids at authoring time, so a typo is undetectable from its own source, and the platform relocates rather than refusing: the menu renders, a smoke test passes, and the entry has moved one level up. Documents the rule and the diagnostic that now reports it: the `warn`-level `nav_contribution_group_missing`, the per-app `getAppNavDiagnostics` reader, and the `os build --json` `navigationGroupDiagnostics` key — following the `bodyExtractionWarnings` precedent, which documents a build-only JSON key on the page that owns the behaviour rather than in a CLI schema dump. No hand-written page was falsified by the code change; this fills a gap rather than correcting an error. The `packages/spec` describe() for the key has the same gap and is filed separately — that string is embedded in ~14 generated artifacts, so it belongs in its own PR. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UHvF5hyiZjnCyExFnfQB8m
1 parent 2ab7f86 commit e854bc8

1 file changed

Lines changed: 29 additions & 0 deletions

File tree

content/docs/ui/setup-app.mdx

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,35 @@ group id + priority on read, so the rendered menu reflects exactly which
1717
capability plugins are loaded — a disabled capability contributes nothing
1818
and its slot stays empty.
1919

20+
### When a contribution names an anchor that is not there
21+
22+
Aiming at a `group` id the target app does not declare is **not** refused and
23+
the entry is **not** dropped: the items are appended at the app's **top level**
24+
and the merge continues. That is deliberate — the merge is a read-time fold
25+
precisely so registration order does not matter (a contributor may register
26+
before the app it aims at), and a contribution into an *optional* anchor has to
27+
keep working when the plugin owning that anchor is not loaded.
28+
29+
It is, however, **loud**. The relocation emits a
30+
`nav_contribution_group_missing` diagnostic at `warn` — naming the contributing
31+
package, the target app, the missing group id and the relocated items — so it
32+
survives `OS_REGISTRY_LOG=warn` and appears in boot output. The same finding is
33+
carried on the app itself, readable as
34+
`registry.getAppNavDiagnostics(appName)`, and it is raised once per distinct
35+
mis-aim rather than once per read of the app.
36+
37+
`os build` answers the same question at compile time whenever the contributing
38+
package and the target app are composed into one artifact, printing the finding
39+
and carrying it in `--json` under `navigationGroupDiagnostics` (an empty array
40+
when every contribution resolved). It **reports** there; it does not fail the
41+
build.
42+
43+
⚠️ The anchor id is the whole contract between a shell and its contributors,
44+
and a contributor cannot see the shell's ids at authoring time. A typo
45+
therefore produces a menu that renders, passes a smoke test, and has silently
46+
moved the entry one level up — which is why the diagnostic exists rather than a
47+
refusal.
48+
2049
The app itself ships from the dedicated `@objectstack/setup` package
2150
(package id `com.objectstack.setup`), which registers it at runtime. Per
2251
ADR-0048 (one app per package), `/apps/setup` — resolvable as

0 commit comments

Comments
 (0)