@bongos/core 1.19.1014 → 1.19.1016

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (104) hide show
  1. package/.bongos-core.json +145 -140
  2. package/.claude/skills/planning-session/SKILL.md +1 -1
  3. package/clients/bongos-client/index.d.ts +1 -1
  4. package/docs/adr/0227-a-task-network-map-is-refused-the-goal-graph-is-the-map.md +4 -1
  5. package/docs/adr/0331-the-sky-is-the-ideators-home.md +18 -1
  6. package/docs/adr/0335-an-invite-is-a-pre-approved-row-on-the-projects-own-instance.md +113 -0
  7. package/docs/adr/0336-a-guilds-record-is-the-sum-of-what-its-members-already-show.md +201 -0
  8. package/docs/adr/README.md +2 -0
  9. package/docs/api/openapi.json +4 -0
  10. package/docs/api-reference.md +1 -1
  11. package/docs/architecture.md +4 -1
  12. package/docs/copy-inventory.md +139 -110
  13. package/docs/copy-registry.json +872 -296
  14. package/docs/file-map.md +0 -1
  15. package/docs/module-api-changelog.md +4 -0
  16. package/migrations/core_253_idea_filed_via.sql +59 -0
  17. package/modules/agents/pollers/event-router.js +2 -0
  18. package/modules/discord/discord-bugs.js +2 -0
  19. package/modules/discord/discord-inbound.js +3 -0
  20. package/modules/hall-ui/public/atlas.html +1 -1
  21. package/modules/hall-ui/public/blockers.html +1 -1
  22. package/modules/hall-ui/public/board-room.html +1 -1
  23. package/modules/hall-ui/public/collab.html +1 -1
  24. package/modules/hall-ui/public/copy-desk.html +1 -1
  25. package/modules/hall-ui/public/deploy.html +1 -1
  26. package/modules/hall-ui/public/diagrams.html +1 -1
  27. package/modules/hall-ui/public/drachmae.html +1 -1
  28. package/modules/hall-ui/public/fleet.html +1 -1
  29. package/modules/hall-ui/public/gate.html +1 -1
  30. package/modules/hall-ui/public/goal-map.html +125 -52
  31. package/modules/hall-ui/public/goal-map.states.json +29 -5
  32. package/modules/hall-ui/public/goals.html +1 -1
  33. package/modules/hall-ui/public/government.html +1 -1
  34. package/modules/hall-ui/public/idea.html +1 -1
  35. package/modules/hall-ui/public/ideas.html +1 -1
  36. package/modules/hall-ui/public/index.html +1 -1
  37. package/modules/hall-ui/public/modules.html +1 -1
  38. package/modules/hall-ui/public/people.html +1 -1
  39. package/modules/hall-ui/public/primer.html +1 -1
  40. package/modules/hall-ui/public/profile.html +1 -1
  41. package/modules/hall-ui/public/project-settings.html +1 -1
  42. package/modules/hall-ui/public/ranks.html +1 -1
  43. package/modules/hall-ui/public/roadmap.html +1 -1
  44. package/modules/hall-ui/public/roster.html +1 -1
  45. package/modules/hall-ui/public/sessions.html +1 -1
  46. package/modules/hall-ui/public/settings.html +1 -1
  47. package/modules/hall-ui/public/shell.js +11 -0
  48. package/modules/hall-ui/public/sky-data.js +41 -9
  49. package/modules/hall-ui/public/sky-draw.js +3 -2
  50. package/modules/hall-ui/public/sky-interaction.js +14 -7
  51. package/modules/hall-ui/public/sky-layout.js +2 -1
  52. package/modules/hall-ui/public/sky-panel.js +1 -1
  53. package/modules/hall-ui/public/sky-tour.js +10 -6
  54. package/modules/hall-ui/public/studio.html +1 -1
  55. package/modules/hall-ui/public/task.html +1 -1
  56. package/modules/hall-ui/public/thinking.css +6 -3
  57. package/modules/hall-ui/public/thinking.html +16 -10
  58. package/modules/hall-ui/public/watch.html +1 -1
  59. package/modules/hall-ui/public/work.html +1 -1
  60. package/modules/ideas/born-of.js +55 -0
  61. package/modules/ideas/inbox.js +23 -8
  62. package/modules/ideas/projection.js +48 -0
  63. package/modules/ideas/routes/inbox.js +20 -0
  64. package/modules/lifecycle/sky.js +25 -4
  65. package/modules/platform-identity/activity-snapshots.js +47 -0
  66. package/modules/platform-identity/migrations/platform_identity_022_activity_snapshots.sql +46 -0
  67. package/modules/platform-identity/platform-identity.js +13 -0
  68. package/modules/platform-identity/tests/activity-snapshots.mjs +68 -0
  69. package/modules/platform-identity/tests/platform-identity.mjs +21 -0
  70. package/modules/ui-design/skills/impeccable/SKILL.md +1 -1
  71. package/package-lock.json +2 -2
  72. package/package.json +1 -1
  73. package/scripts/gds/capture.js +11 -0
  74. package/scripts/gds/run-unit-tests.js +4 -0
  75. package/src/bongos/serve-internal.js +4 -0
  76. package/src/module-api.js +1 -1
  77. package/tests/activity_snapshots_db.mjs +97 -0
  78. package/tests/discord_bugs.mjs +1 -0
  79. package/tests/discord_inbound.mjs +1 -0
  80. package/tests/goal_map_page.mjs +360 -211
  81. package/tests/guild_namespace_reserved.mjs +76 -0
  82. package/tests/hall_audit.mjs +1 -0
  83. package/tests/hall_nav.mjs +6 -1
  84. package/tests/hall_page_gate_map.mjs +3 -2
  85. package/tests/hall_sky.mjs +33 -16
  86. package/tests/helpers.mjs +21 -5
  87. package/tests/idea_filed_via.mjs +185 -0
  88. package/tests/landing_page.mjs +8 -0
  89. package/tests/nav_permission_atoms.mjs +1 -1
  90. package/tests/profile_rollup_consent.mjs +5 -1
  91. package/tests/project_admin_console_model.mjs +105 -0
  92. package/tests/render_check.mjs +6 -4
  93. package/tests/sky_read.mjs +19 -2
  94. package/tests/ui_design_skills.mjs +9 -0
  95. package/modules/hall-ui/public/goal-map-lib.js +0 -349
  96. package/modules/hall-ui/public/goal-map.css +0 -117
  97. package/modules/hall-ui/public/goal-map.js +0 -232
  98. package/modules/public-landing/public/world/assets/clouds/cloud-island-large.png +0 -0
  99. package/modules/public-landing/public/world/assets/clouds/cloud-puff.png +0 -0
  100. package/modules/public-landing/public/world/assets/creatures/creature-whale-cargo.png +0 -0
  101. package/modules/public-landing/public/world/assets/creatures/creature-whale-glide.png +0 -0
  102. package/modules/public-landing/public/world/assets/plates/plate-clouds-near.png +0 -0
  103. package/modules/public-landing/public/world/assets/plates/scene-establishing.png +0 -0
  104. package/tests/goal_map_lib.mjs +0 -214
package/docs/file-map.md CHANGED
@@ -283,7 +283,6 @@
283
283
  │ │ ├── world/ ← the six production plates + <file>.json provenance sidecars (embed-prompt.mjs --scan clean): r2-chrome-blobs-set.jpg, r2-chrome-blob-one.jpg, r2-bongos-chrome-b.jpg (black plates, dark mode, lighten) and their -cut.webp alpha twins (light mode); og-card.jpg (the social card, captured from the page)
284
284
  │ │ ├── cosmos.css ← the HUB component sheet (task 1002696): contract tier synced to the pack, its own derived + dark tiers, the .btn/.chip/.strip/.proj/.tbl vocabulary; measured by tests/cosmos_token_contrast.mjs
285
285
  │ │ └── verro-medallion.png ← the Verro Labs mark (apex-only block)
286
- │ └── world/assets/ ← the RETIRED gate's clouds/creatures/plates (task 1002407; the gate folded into / in 1003233) — not the chrome plates
287
286
  │
288
287
  ├── public/ ← example.com — the game (product)
289
288
  │ ├── index.html
@@ -2502,5 +2502,9 @@ is load-bearing: the script throws rather than guess if it is missing, and
2502
2502
  landed since 1.19.1012 with no explicit bump. run 36072935774. (task 1002620)
2503
2503
  1.19.1014 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
2504
2504
  landed since 1.19.1013 with no explicit bump. run 36076310606. (task 1002620)
2505
+ 1.19.1015 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
2506
+ landed since 1.19.1014 with no explicit bump. run 36078624472. (task 1002620)
2507
+ 1.19.1016 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
2508
+ landed since 1.19.1015 with no explicit bump. run 36080388706. (task 1002620)
2505
2509
  ---------------------------------------------------------------------------
2506
2510
  ```
@@ -0,0 +1,59 @@
1
+ -- core_253_idea_filed_via.sql — WHERE AN IDEA WAS FILED FROM (task 1004233, sky part 5 of 5;
2
+ -- goal 1000095; ADR 0331 §4).
3
+ --
4
+ -- The sky draws a thought differently when a session filed it under a person's
5
+ -- name rather than the person filing it themselves (the "claude layer", off by
6
+ -- default). The prototype GUESSED that from the idea's text; this column makes
7
+ -- it a ledger fact, written by every door an idea can come through:
8
+ -- 'hall' — the hall's ideas form or the sky's composer (a web session)
9
+ -- 'cli' — scripts/gds/capture.js and spark.js (a CLI session)
10
+ -- 'discord' — the Discord inbound bot (#ideas, #bugs)
11
+ -- 'planning' — a planning session's captures (capture.js --via planning)
12
+ -- 'api' — anything else through POST /inbox, or a program on the port
13
+ -- The closed set lives in modules/ideas/projection.js (FILED_VIA_VALUES); the
14
+ -- CHECK mirrors it so a bad value is a named 400 at the route and never a
15
+ -- constraint-violation 500 (the ideas_grades recommendation precedent). The
16
+ -- server reads the value off the SESSION that filed (a web cookie is the hall,
17
+ -- a device-flow token is the CLI, anything else the API); the one value a body
18
+ -- may add is 'planning', which no session can tell from 'cli'.
19
+ --
20
+ -- NULLABLE, NO DEFAULT, NO BACKFILL — and that is the point. Every row that
21
+ -- predates this column was filed before the ledger recorded where, and the sky
22
+ -- says exactly that ("filed before the ledger recorded where"; such rows SHOW
23
+ -- by default — owner, 2026-09-24). NULL is not 'cli'. Guessing a value for
24
+ -- historic rows from their text would put the prototype's heuristic INTO the
25
+ -- ledger, which is precisely what this part exists to end.
26
+ --
27
+ -- CORE, not modules/ideas/migrations/: idea_inbox is a core table and a module
28
+ -- migration may touch only its own ideas_-prefixed objects (ADR 0083 §Decision
29
+ -- #5; the core_195 / core_222 precedent). Forward-safe by construction: an
30
+ -- additive nullable column every existing reader selects by explicit list
31
+ -- (tests/migrations_forward_safe.mjs).
32
+
33
+ BEGIN;
34
+
35
+ ALTER TABLE idea_inbox
36
+ ADD COLUMN IF NOT EXISTS filed_via text;
37
+
38
+ -- CHECK constraints have no ADD ... IF NOT EXISTS, so guard the add (the
39
+ -- migration 042 / core_195 idiom) and keep the file replay-safe.
40
+ DO $$
41
+ BEGIN
42
+ IF NOT EXISTS (
43
+ SELECT 1 FROM pg_constraint
44
+ WHERE conrelid = 'idea_inbox'::regclass
45
+ AND conname = 'idea_inbox_filed_via_known'
46
+ ) THEN
47
+ ALTER TABLE idea_inbox
48
+ ADD CONSTRAINT idea_inbox_filed_via_known
49
+ CHECK (filed_via IS NULL OR filed_via IN ('hall', 'cli', 'discord', 'planning', 'api'));
50
+ END IF;
51
+ END $$;
52
+
53
+ COMMENT ON COLUMN idea_inbox.filed_via IS
54
+ 'Which door filed this idea: hall | cli | discord | planning | api. NULL = filed before the column existed; never backfilled by guessing.';
55
+
56
+ INSERT INTO schema_migrations (version) VALUES ('core_253_idea_filed_via')
57
+ ON CONFLICT DO NOTHING;
58
+
59
+ COMMIT;
@@ -385,6 +385,8 @@ async function deliverToInbox(deliver, parts) {
385
385
  title: parts.title,
386
386
  bodyMd: `${parts.provenance}\n\n${parts.body}`,
387
387
  capturedBy: null,
388
+ // task 1004233 (sky part 5): a poller is a program on the port — 'api'.
389
+ filedVia: 'api',
388
390
  });
389
391
  const id = idea && idea.id;
390
392
  return id !== null && id !== undefined ? `idea:${id}` : null;
@@ -242,6 +242,8 @@ async function recordInboundBug({ discordUserId, content, imageUrls = [], messag
242
242
  bodyMd: description,
243
243
  kind: 'bug',
244
244
  capturedBy: builder ? builder.id : null,
245
+ // task 1004233 (sky part 5): the door — a port caller names its own.
246
+ filedVia: 'discord',
245
247
  filerRank,
246
248
  goalId: goal ? goal.id : null,
247
249
  suggestedPriority: 3,
@@ -175,6 +175,9 @@ async function recordInboundIdea({ discordUserId, content, imageUrls = [], messa
175
175
  title: derived.title,
176
176
  bodyMd,
177
177
  capturedBy: builder ? builder.id : null,
178
+ // task 1004233 (sky part 5): the door, named here because this path calls
179
+ // the port, not the route — there is no session to read it off.
180
+ filedVia: 'discord',
178
181
  // kind left null → inbox.captureIdea auto-classifies. We never pass
179
182
  // 'criterion-proposal' (the rank-gated kind) from this path.
180
183
  // suggestedGoalId/suggestedVersion are ADVISORY-ONLY columns — this call
@@ -91,7 +91,7 @@
91
91
 
92
92
  <div id="toast" class="toast" role="status" aria-live="polite" data-visible="0"></div>
93
93
 
94
- <script src="/builders/shell.js?v=2026-09-24-fleetcosts1"></script>
94
+ <script src="/builders/shell.js?v=2026-09-25-sky4b"></script>
95
95
  <!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
96
96
  <script src="/builders/palette.js" defer></script>
97
97
  <script src="/builders/atlas.js?v=2026-09-02-index" defer></script>
@@ -50,7 +50,7 @@
50
50
 
51
51
  <!-- The app shell (sidebar + top bar). Dependency-free; loaded FIRST so the
52
52
  chrome exists before the page script runs. -->
53
- <script src="/builders/shell.js?v=2026-09-24-fleetcosts1"></script>
53
+ <script src="/builders/shell.js?v=2026-09-25-sky4b"></script>
54
54
  <!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
55
55
  <script src="/builders/palette.js" defer></script>
56
56
  <!-- shared frontend toolkit (window.OTB — rank labels, number formats) + the
@@ -60,7 +60,7 @@
60
60
 
61
61
  <div id="toast" class="toast" role="status" aria-live="polite" data-visible="0"></div>
62
62
 
63
- <script src="/builders/shell.js?v=2026-09-24-fleetcosts1"></script>
63
+ <script src="/builders/shell.js?v=2026-09-25-sky4b"></script>
64
64
  <!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
65
65
  <script src="/builders/palette.js" defer></script>
66
66
  <script src="/builders/dom-utils.js?v=2026-06-16-board"></script>
@@ -148,7 +148,7 @@
148
148
 
149
149
  <div id="toast" class="toast" role="status" aria-live="polite" data-visible="0"></div>
150
150
 
151
- <script src="/builders/shell.js?v=2026-09-24-fleetcosts1"></script>
151
+ <script src="/builders/shell.js?v=2026-09-25-sky4b"></script>
152
152
  <script src="/builders/palette.js" defer></script>
153
153
  <script src="/builders/dom-utils.js?v=2026-06-23-contrib"></script>
154
154
  <script src="/builders/collab-lib.js?v=2026-09-24-archive"></script>
@@ -177,7 +177,7 @@
177
177
 
178
178
  <div id="toast" class="toast" role="status" aria-live="polite" data-visible="0"></div>
179
179
 
180
- <script src="/builders/shell.js?v=2026-09-24-fleetcosts1"></script>
180
+ <script src="/builders/shell.js?v=2026-09-25-sky4b"></script>
181
181
  <script src="/builders/palette.js" defer></script>
182
182
  <script src="/builders/dom-utils.js?v=2026-06-23-contrib"></script>
183
183
  <script src="/builders/hall-kit.js"></script>
@@ -60,7 +60,7 @@
60
60
 
61
61
  <div id="toast" class="toast" role="status" aria-live="polite" data-visible="0"></div>
62
62
 
63
- <script src="/builders/shell.js?v=2026-09-24-fleetcosts1"></script>
63
+ <script src="/builders/shell.js?v=2026-09-25-sky4b"></script>
64
64
  <script src="/builders/palette.js" defer></script>
65
65
  <script src="/builders/dom-utils.js?v=2026-06-16-gate"></script>
66
66
  <script src="/builders/hall-kit.js"></script>
@@ -97,7 +97,7 @@
97
97
 
98
98
  <!-- The app shell (sidebar + top bar + footer). Dependency-free; runs at parse
99
99
  time so the chrome exists before the deferred page scripts execute. -->
100
- <script src="/builders/shell.js?v=2026-09-24-fleetcosts1"></script>
100
+ <script src="/builders/shell.js?v=2026-09-25-sky4b"></script>
101
101
  <!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
102
102
  <script src="/builders/palette.js" defer></script>
103
103
  <script src="/builders/diagram-viewer.js?v=2026-06-14-diagviewer-1" defer></script>
@@ -98,7 +98,7 @@
98
98
 
99
99
  <div id="toast" class="toast" role="status" aria-live="polite" data-visible="0"></div>
100
100
 
101
- <script src="/builders/shell.js?v=2026-09-24-fleetcosts1"></script>
101
+ <script src="/builders/shell.js?v=2026-09-25-sky4b"></script>
102
102
  <!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
103
103
  <script src="/builders/palette.js" defer></script>
104
104
  <script src="/builders/md-reader.js?v=2026-09-02-mdreader-2"></script>
@@ -54,7 +54,7 @@
54
54
 
55
55
  <div id="toast" class="toast" role="status" aria-live="polite" data-visible="0"></div>
56
56
 
57
- <script src="/builders/shell.js?v=2026-09-24-fleetcosts1"></script>
57
+ <script src="/builders/shell.js?v=2026-09-25-sky4b"></script>
58
58
  <script src="/builders/palette.js" defer></script>
59
59
  <script src="/builders/dom-utils.js?v=2026-06-16-gate"></script>
60
60
  <script src="/builders/hall-kit.js"></script>
@@ -76,7 +76,7 @@
76
76
  <div id="gate-modal-root"></div>
77
77
  <div id="toast" class="toast" role="status" aria-live="polite" data-visible="0"></div>
78
78
 
79
- <script src="/builders/shell.js?v=2026-09-24-fleetcosts1"></script>
79
+ <script src="/builders/shell.js?v=2026-09-25-sky4b"></script>
80
80
  <!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
81
81
  <script src="/builders/palette.js" defer></script>
82
82
  <script src="/builders/dom-utils.js?v=2026-06-16-gate"></script>
@@ -2,69 +2,142 @@
2
2
  <html lang="en">
3
3
  <head>
4
4
  <meta charset="utf-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1">
6
- <title>Goal map — {{worldName}}</title>
7
- <meta name="description" content="Which goals wait on which other goals: the goals that are tied together drawn as a map, the goals that stand alone listed beside it, and every goal in a table.">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
6
+ <title>The sky — {{worldName}}</title>
7
+ <meta name="description" content="The whole project, drawn from the ledger: every goal a gravity well sized by its credits, the routes between goals that wait on each other, and a ledger drawer that lists all of it.">
8
8
  <link rel="icon" href="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'><text x='16' y='24' font-size='24' text-anchor='middle' font-family='sans-serif'>⌂</text></svg>">
9
9
  <link rel="preconnect" href="https://fonts.googleapis.com">
10
10
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
11
- <link rel="stylesheet" href="/builders/style.css?v=2026-07-02-shell1">
12
- <link rel="stylesheet" href="/builders/goal-map.css">
11
+ <!-- The faces (Manrope, JetBrains Mono) come from the branding pack's font
12
+ links, injected into this head by the server like every hall page's
13
+ (tests/hall_tokens.mjs: no hall page hardcodes a web-font stylesheet). -->
14
+ <link rel="stylesheet" href="/builders/thinking.css?v=2026-09-25-sky4">
13
15
  </head>
14
- <!-- THE GOAL MAP (task 1003479, goal 1000089; ADR 0227 §6 item 3 + §10.4). The
15
- picture is the ENHANCEMENT and the table is the page: every fact the map
16
- draws is a cell in the table under it, on screen by default and not behind a
17
- toggle (ADR 0227 §5). It takes no nav slot — like the sky, it is reached from
18
- the page it maps (Goals) and is never the only path to anything it shows. -->
19
- <body data-page="goal-map" data-page-title="Goal map">
16
+ <!-- THE PROJECT SKY (task 1004232 / sky part 4 of 5, goal 1000095; ADR 0331,
17
+ ADR 0227 §11). The SAME page as /thinking — docs/design/mocks/sky/
18
+ sky.template.html, the prototype the owner adopted as the design of record
19
+ — opened in its "the whole project" lens: goals as wells sized by credits,
20
+ settled and collapsed goals with mass, alive wells glowing, routes as rim
21
+ arrows charted by a shuttle, explore on by default, the clock, "my ideas"
22
+ off by default, and the ledger drawer (L) — every goal, both directions of
23
+ each dependency by name — which is what the old goal map's table said and
24
+ is the accessible path. It replaced that goal map (task 1003479) at this
25
+ URL and took the nav slot the map was denied, under Goals (owner,
26
+ 2026-09-24; ADR 0227 §11).
20
27
 
21
- <div class="app">
22
- <aside class="app-sidebar" id="app-sidebar" aria-label="Primary"></aside>
23
- <div class="app-scrim" id="app-scrim" hidden></div>
24
- <div class="app-body">
25
- <header class="app-topbar" id="app-topbar"></header>
26
- <div class="app-content">
27
- <div class="page-head page-head--board">
28
- <h1 class="page-head__h">Goal map</h1>
29
- <p class="page-head__sub" id="gm-sub">Reading the goals…</p>
30
- </div>
28
+ The markup is thinking.html's, verbatim but for three things: the body
29
+ says which lens is home (`data-sky-lens="all"` — sky-tour.js boots into it
30
+ and the tour hands back to it), the brand line and the lens switcher start
31
+ in that lens, and the canvas's own words say what this sky draws. The
32
+ sheet and the seven sky-*.js files are SHARED with /thinking, never
33
+ copied: the switcher's "simple" and "your thinking" leave for /thinking,
34
+ and /thinking's "the whole project" leaves for here. The same rule as
35
+ /thinking on chrome: none — the sky is a full-screen surface with its own
36
+ header, and the hall's doors (the goal, the task, the record) open from
37
+ the panel.
31
38
 
32
- <main id="hall-main">
33
- <section class="scroll" id="gm-graph-scroll" aria-labelledby="gm-graph-h">
34
- <h2 id="gm-graph-h" class="scroll__h">Goals that wait on each other</h2>
35
- <div id="gm-graph"><p class="profile__placeholder">Loading…</p></div>
36
- <ul id="gm-legend" class="gm-legend" aria-label="Categories" hidden></ul>
37
- </section>
39
+ ADR 0227 §1's refusal stands here: tasks are drawn only inside ONE goal
40
+ once its well is past the zoom threshold (dust density on its rings below
41
+ it), never for every goal at once, and there is no "show every task"
42
+ control — tests/goal_map_page.mjs pins both. -->
43
+ <body data-page="goal-map" data-page-title="The sky" data-sky-lens="all">
38
44
 
39
- <section class="scroll" id="gm-alone-scroll" aria-labelledby="gm-alone-h" hidden>
40
- <h2 id="gm-alone-h" class="scroll__h">Goals that stand alone</h2>
41
- <p class="scroll__lede" id="gm-alone-lede"></p>
42
- <ul id="gm-alone" class="gm-alone"></ul>
43
- </section>
45
+ <!-- The one <main> landmark the kit's a11y floor asks of every hall page
46
+ (one-header-main-h1). The canvas is the page's content, and the landmark
47
+ wraps it with no rule of its own, so nothing moves — the canvas is
48
+ position: fixed. -->
49
+ <main>
50
+ <canvas id="sky" tabindex="0" role="img" aria-label="The sky, drawn from the ledger: every goal a gravity well, every dependency a route. Every goal here is also a row in the ledger; press L to open it, ? to take the tour."></canvas>
51
+ </main>
44
52
 
45
- <section class="scroll" id="gm-table-scroll" aria-labelledby="gm-table-h" hidden>
46
- <h2 id="gm-table-h" class="scroll__h">Every goal, as a table</h2>
47
- <p class="scroll__lede">The same facts as the map, and more of them: with this many separate clusters the table holds more of the structure than the picture does. Each goal lists, by name, the goals it waits on and the goals that wait on it, with how many tasks the dependency runs through.</p>
48
- <div id="gm-table"></div>
49
- </section>
50
- </main>
51
-
52
- <footer class="app-foot" id="app-foot"></footer>
53
- </div>
53
+ <!-- The <header> is the BRAND (the h1 and the figures) and the lens and tools
54
+ stay its siblings inside the same .top strip — the kit's phone floor
55
+ (top-bar-80px) measures the page's <header>. thinking.html's shape. -->
56
+ <div class="top">
57
+ <header class="brand">
58
+ <h1>the sky <em id="lensWord">— the whole project</em></h1>
59
+ <div class="stats" id="stats"></div>
60
+ </header>
61
+ <div class="lens" role="group" aria-label="Filter" id="lensGroup">
62
+ <button type="button" id="lensSimple" aria-pressed="false">simple</button>
63
+ <button type="button" id="lensMine" aria-pressed="false">your thinking</button>
64
+ <button type="button" id="lensAll" aria-pressed="true">the whole project</button>
65
+ </div>
66
+ <div class="tools" id="tools">
67
+ <button type="button" class="pill" id="roomBtn" aria-pressed="false" title="The same sky, as a list (L)">list</button>
68
+ <button type="button" class="pill" id="recentBtn" aria-pressed="false" hidden title="Only the thoughts of the last thirty days.">recent</button>
69
+ <button type="button" class="pill" id="claudeBtn" aria-pressed="false" hidden title="Show the thoughts a session filed under your name. Off by default: only what a person filed.">claude layer</button>
70
+ <button type="button" class="pill" id="influenceBtn" aria-pressed="false" hidden title="Only the goals your thoughts touched — everything else fades.">my influence</button>
71
+ <button type="button" class="pill" id="exploreBtn" aria-pressed="true" title="Explore: the sky reveals itself as you follow routes from where you begin.">explore</button>
72
+ <button type="button" class="pill" id="ideasBtn" aria-pressed="false" title="Lay your thoughts over the project map.">my ideas</button>
73
+ <button type="button" class="pill" id="rehearse" aria-pressed="false" hidden title="What if: invents removals, dimming and nods — none has happened in the ledger yet — so you can see how the dead would read. Sizes are never invented.">what if</button>
74
+ <button type="button" class="pill icon" id="clockBtn" title="Show or hide the clock" aria-label="Show or hide the clock">◷</button>
75
+ <button type="button" class="pill icon" id="tourBtn" title="How to read the sky (?)" aria-label="How to read the sky">?</button>
76
+ <button type="button" class="pill icon" id="fitBtn" title="Fit the sky (0)" aria-label="Fit the whole sky">⌂</button>
54
77
  </div>
55
78
  </div>
56
79
 
57
- <div id="toast" class="toast" role="status" aria-live="polite" data-visible="0"></div>
80
+ <div class="jump">
81
+ <input type="search" id="jump" placeholder="jump to a goal or a thought" autocomplete="off" aria-label="Jump to a goal or a thought">
82
+ <ul id="jumpList" hidden></ul>
83
+ </div>
84
+
85
+ <div class="composer" id="composerWrap">
86
+ <form id="file" autocomplete="off">
87
+ <input type="text" id="thought" placeholder="release a thought — one line" aria-label="Release a thought" maxlength="180">
88
+ <button type="button" class="mode" id="fullToggle" aria-pressed="false" title="File it as a Full Idea: the line, then five questions, scored on completeness. Off = a quick idea, one line.">full idea</button>
89
+ <button type="submit" class="go" id="fileGo">file</button>
90
+ </form>
91
+ <div class="gravity" id="gravity" aria-live="polite">gravity — the goal that catches it lights as you type; letting it float is a real answer</div>
92
+ <div class="steps" id="fullSteps" hidden></div>
93
+ <div class="receipt" id="receipt" hidden role="status"><span class="dot"></span><span id="receiptText"></span><button type="button" id="receiptGo">see it</button><button type="button" id="receiptX" aria-label="Dismiss">×</button></div>
94
+ </div>
95
+
96
+ <div class="card glass" id="card" role="tooltip" aria-hidden="true"></div>
97
+ <div class="menu glass" id="menu" hidden role="menu" aria-label="Chart the routes"></div>
98
+
99
+ <aside class="room" id="room" hidden aria-label="The list">
100
+ <div class="head"><h2 id="roomTitle">the ledger</h2><span class="lbl" id="roomCount"></span></div>
101
+ <div class="filters" id="filters" role="group" aria-label="Filter"></div>
102
+ <div class="rows" id="rows"></div>
103
+ </aside>
104
+
105
+ <aside class="panel" id="panel" hidden aria-live="polite"></aside>
106
+
107
+ <div class="start glass" id="start" hidden role="dialog" aria-label="Where do you begin?">
108
+ <span class="lbl">explore</span>
109
+ <h3>Where do you begin?</h3>
110
+ <p>The sky reveals itself as you go. Pick a well to start in; every route you chart brings the goal at its far end into view.</p>
111
+ <div class="opts" id="startOpts"></div>
112
+ </div>
113
+
114
+ <div class="tour glass" id="tour" hidden role="dialog" aria-label="How to read the sky">
115
+ <div class="step"><span class="lbl" id="tourN"></span><span class="dots" id="tourDots"></span></div>
116
+ <h3 id="tourH"></h3>
117
+ <p id="tourP"></p>
118
+ <div class="acts"><button type="button" class="door primary" id="tourNext">next</button><button type="button" class="door" id="tourBack">back</button><button type="button" class="skip" id="tourSkip">skip the tour</button></div>
119
+ </div>
120
+
121
+ <footer class="foot">
122
+ <div class="time" id="time">
123
+ <button type="button" class="play" id="play" aria-pressed="false" aria-label="Replay the sky from the first day">▶</button>
124
+ <input type="range" id="clock" min="0" max="1000" value="1000" aria-label="The day the sky is drawn for">
125
+ <span class="when" id="when">today</span>
126
+ <button type="button" class="hide" id="timeHide" aria-label="Hide the clock">×</button>
127
+ </div>
128
+ <div class="footrow">
129
+ <div class="legend" id="legend"></div>
130
+ <div class="alt" id="alt"></div>
131
+ </div>
132
+ </footer>
58
133
 
59
- <script src="/builders/shell.js?v=2026-09-24-fleetcosts1"></script>
60
- <script src="/builders/palette.js" defer></script>
61
- <script src="/builders/dom-utils.js?v=2026-06-23-contrib"></script>
62
- <script src="/builders/hall-kit.js"></script>
63
- <!-- The model and layout are a pure lib so a test runs the real arithmetic; the
64
- page script keeps only the drawing and the table. Lib BEFORE page. -->
65
- <script src="/builders/goal-map-lib.js"></script>
66
- <!-- task 1004204: measured-width text fitting, shared with the goal forest. -->
67
- <script src="/builders/text-fit.js"></script>
68
- <script src="/builders/goal-map.js"></script>
134
+ <script src="/builders/idea-objects.js?v=2026-09-25-sky4"></script>
135
+ <script src="/builders/sky-data.js?v=2026-09-25-sky4"></script>
136
+ <script src="/builders/sky-layout.js?v=2026-09-25-sky4"></script>
137
+ <script src="/builders/sky-draw.js?v=2026-09-25-sky4"></script>
138
+ <script src="/builders/sky-interaction.js?v=2026-09-25-sky4"></script>
139
+ <script src="/builders/sky-panel.js?v=2026-09-25-sky4"></script>
140
+ <script src="/builders/sky-composer.js?v=2026-09-25-sky4"></script>
141
+ <script src="/builders/sky-tour.js?v=2026-09-25-sky4"></script>
69
142
  </body>
70
143
  </html>
@@ -1,14 +1,38 @@
1
1
  {
2
- "_": "THE GOAL MAP (task 1003479, goal 1000089; ADR 0227 §6 item 3) through modules/ui-design/kit/render.js. The page reads ONE authenticated aggregate, GET /goals/graph, so against the kit's own stub it renders its signed-out / failed-read state — a state the floors must hold in and is rendered here deliberately. To look at the populated map (the layered picture, the stand-alone chips, the table), run it against the hall-preview harness, whose goals__graph.json fixture carries one large cluster, a triple, pairs, a mutual pair (a loop) and a private goal beside the stand-alone majority:\n\n node scripts/hall-preview/server.js --port 4620 --fixture-me\n node modules/ui-design/kit/render.js --states modules/hall-ui/public/goal-map.states.json --base-in http://localhost:4620 --base-out http://localhost:4620",
2
+ "_": "THE PROJECT SKY (task 1004232 / sky part 4 of 5, goal 1000095; ADR 0331, ADR 0227 §11) through modules/ui-design/kit/render.js — the same page as /thinking (thinking.states.json) opened in its 'the whole project' lens. The page draws GET /sky + GET /sky/mine; against the kit's own stub neither exists, so every state below renders the EMPTY sky — a real state the floors must hold in (the lenses, the tools, the ledger drawer and the tour all exist with no goal read). To look at the populated sky — the wells sized by credits, the routes, the shuttle menu, explore's 'where do you begin' — run it against the hall-preview harness, whose sky.json + sky__mine.json fixtures carry the wells and the routes:\n\n node scripts/hall-preview/server.js --port 4620 --fixture-me\n node modules/ui-design/kit/render.js --states modules/hall-ui/public/goal-map.states.json --base-in http://localhost:4620 --base-out http://localhost:4620\n\nThe tour opens by itself on a first visit (sky-tour-seen), so states that want the bare sky skip it first; explore is on by default and asks where you begin the first time (sky-seen), so the 'sky' state renders that prompt on purpose.",
3
3
  "page": "/builders/goal-map",
4
4
  "surface": "hall-ui",
5
5
  "stub": { "prefix": "/builders/" },
6
+ "modes": ["dark"],
6
7
  "modeQuery": false,
7
- "ignoreRequests": ["/api/(gds|bongos)/"],
8
- "ignoreConsole": ["/api/(gds|bongos)/", "\\b401\\b", "\\b404\\b", "Unauthorized", "Not Found", "load failed"],
8
+ "ignoreRequests": ["/api/(gds|bongos)/", "fonts\\.g(oogleapis|static)\\.com"],
9
+ "ignoreConsole": ["/api/(gds|bongos)/", "\\b401\\b", "\\b404\\b", "Unauthorized", "Not Found", "load failed", "fonts\\.g(oogleapis|static)\\.com"],
9
10
  "states": {
10
- "map": { "auth": true, "actions": [["wait", 1200]], "expect": { "visible": ["#gm-graph"] } },
11
+ "tour": {
12
+ "auth": true,
13
+ "_": "The first visit: the project sky with the tour's first step over it.",
14
+ "actions": [["wait", 1400]],
15
+ "expect": { "visible": ["#sky", "#tour"] }
16
+ },
17
+ "sky": {
18
+ "auth": true,
19
+ "_": "The 'the whole project' lens, bare: the brand line, the lenses, explore + my ideas + the clock in the tools, the legend — and explore's 'where do you begin' prompt on a first visit.",
20
+ "actions": [["wait", 1200], ["clickIfVisible", "#tourSkip"], ["wait", 300]],
21
+ "expect": { "visible": ["#sky", "#exploreBtn", "#ideasBtn"] }
22
+ },
23
+ "wells": {
24
+ "auth": true,
25
+ "_": "The whole sky at once: 'show me everything' answers the prompt, explore goes off, and every well is drawn — the shot to compare with the old goal map.",
26
+ "actions": [["wait", 1200], ["clickIfVisible", "#tourSkip"], ["wait", 200], ["clickIfVisible", "#startOpts [data-start=\"all\"]"], ["wait", 700]],
27
+ "expect": { "visible": ["#sky", "#exploreBtn"] }
28
+ },
29
+ "ledger": {
30
+ "auth": true,
31
+ "_": "The ledger drawer — every goal as a row, with the alive / wells / settled / collapsed / with-routes filters — opened by the L key.",
32
+ "actions": [["wait", 1200], ["clickIfVisible", "#tourSkip"], ["wait", 200], ["press", "l"], ["wait", 300]],
33
+ "expect": { "visible": ["#room", "#rows"] }
34
+ },
11
35
  "out": { "auth": false, "actions": [["wait", 600]] }
12
36
  },
13
- "reducedMotion": { "auth": true, "actions": [["wait", 1200]] }
37
+ "reducedMotion": { "auth": true, "actions": [["wait", 1200], ["clickIfVisible", "#tourSkip"], ["wait", 200]] }
14
38
  }
@@ -235,7 +235,7 @@
235
235
 
236
236
  <div id="toast" class="toast" role="status" aria-live="polite" data-visible="0"></div>
237
237
 
238
- <script src="/builders/shell.js?v=2026-09-24-fleetcosts1"></script>
238
+ <script src="/builders/shell.js?v=2026-09-25-sky4b"></script>
239
239
  <!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
240
240
  <script src="/builders/palette.js" defer></script>
241
241
  <script src="/builders/dom-utils.js?v=2026-06-14-domutils"></script>
@@ -134,7 +134,7 @@
134
134
 
135
135
  <div id="toast" class="toast" role="status" aria-live="polite" data-visible="0"></div>
136
136
 
137
- <script src="/builders/shell.js?v=2026-09-24-fleetcosts1"></script>
137
+ <script src="/builders/shell.js?v=2026-09-25-sky4b"></script>
138
138
  <!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
139
139
  <script src="/builders/palette.js" defer></script>
140
140
  <script src="/builders/dom-utils.js?v=2026-06-16-gate"></script>
@@ -52,7 +52,7 @@
52
52
 
53
53
  <div id="toast" class="toast" role="status" aria-live="polite" data-visible="0"></div>
54
54
 
55
- <script src="/builders/shell.js?v=2026-09-24-fleetcosts1"></script>
55
+ <script src="/builders/shell.js?v=2026-09-25-sky4b"></script>
56
56
  <script src="/builders/palette.js" defer></script>
57
57
  <script src="/builders/dom-utils.js?v=2026-06-23-contrib" defer></script>
58
58
  <!-- task-detail.js still owns the #/idea/N and #/blocker/N overlay, so a ref
@@ -225,7 +225,7 @@
225
225
 
226
226
  <div id="toast" class="toast" role="status" aria-live="polite" data-visible="0"></div>
227
227
 
228
- <script src="/builders/shell.js?v=2026-09-24-fleetcosts1"></script>
228
+ <script src="/builders/shell.js?v=2026-09-25-sky4b"></script>
229
229
  <script src="/builders/palette.js" defer></script>
230
230
  <script src="/builders/dom-utils.js?v=2026-06-23-contrib"></script>
231
231
  <!-- task 1003069 (R08) — the quick-filing form's routed result links a task
@@ -102,7 +102,7 @@
102
102
  <script src="/builders/brand-apply.js?v=2026-06-27-r75" defer></script>
103
103
  <!-- The app shell (sidebar + top bar + view router). Dependency-free; loaded
104
104
  BEFORE builders.js so the chrome ids exist when events are wired. -->
105
- <script src="/builders/shell.js?v=2026-09-24-fleetcosts1" defer></script>
105
+ <script src="/builders/shell.js?v=2026-09-25-sky4b" defer></script>
106
106
  <!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
107
107
  <script src="/builders/palette.js" defer></script>
108
108
  <!-- task 2166: the shared component kit (window.OTBKit) — pager/ledger/rail.
@@ -80,7 +80,7 @@
80
80
 
81
81
  <div id="toast" class="toast" role="status" aria-live="polite" data-visible="0"></div>
82
82
 
83
- <script src="/builders/shell.js?v=2026-09-24-fleetcosts1"></script>
83
+ <script src="/builders/shell.js?v=2026-09-25-sky4b"></script>
84
84
  <!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
85
85
  <script src="/builders/palette.js" defer></script>
86
86
  <script src="/builders/dom-utils.js?v=2026-06-23-contrib"></script>
@@ -55,7 +55,7 @@
55
55
 
56
56
  <!-- The app shell (sidebar + top bar). Dependency-free; loaded FIRST so the
57
57
  chrome exists before the page script runs. -->
58
- <script src="/builders/shell.js?v=2026-09-24-fleetcosts1"></script>
58
+ <script src="/builders/shell.js?v=2026-09-25-sky4b"></script>
59
59
  <!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
60
60
  <script src="/builders/palette.js" defer></script>
61
61
  <!-- shared frontend toolkit (window.OTB — rank labels, number formats) + the
@@ -115,7 +115,7 @@
115
115
 
116
116
  <div id="toast" class="toast" role="status" aria-live="polite" data-visible="0"></div>
117
117
 
118
- <script src="/builders/shell.js?v=2026-09-24-fleetcosts1"></script>
118
+ <script src="/builders/shell.js?v=2026-09-25-sky4b"></script>
119
119
  <!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
120
120
  <script src="/builders/palette.js" defer></script>
121
121
  <!-- the shared markdown reader (window.OTBMdReader) — primer.js renders through
@@ -187,7 +187,7 @@
187
187
 
188
188
  <!-- The app shell (sidebar + top bar). Dependency-free; loaded FIRST so the
189
189
  chrome exists before the page script runs. -->
190
- <script src="/builders/shell.js?v=2026-09-24-fleetcosts1"></script>
190
+ <script src="/builders/shell.js?v=2026-09-25-sky4b"></script>
191
191
  <!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
192
192
  <script src="/builders/palette.js" defer></script>
193
193
  <!-- shared frontend toolkit (window.OTB) — loaded before profile.js, which pulls from it. -->
@@ -58,7 +58,7 @@
58
58
 
59
59
  <div id="toast" class="toast" role="status" aria-live="polite" data-visible="0"></div>
60
60
 
61
- <script src="/builders/shell.js?v=2026-09-24-fleetcosts1"></script>
61
+ <script src="/builders/shell.js?v=2026-09-25-sky4b"></script>
62
62
  <!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
63
63
  <script src="/builders/palette.js" defer></script>
64
64
  <script src="/builders/dom-utils.js?v=2026-06-16-gate"></script>
@@ -68,7 +68,7 @@
68
68
 
69
69
  <!-- The app shell (sidebar + top bar). Dependency-free; loaded FIRST so the
70
70
  chrome exists before the page script runs. -->
71
- <script src="/builders/shell.js?v=2026-09-24-fleetcosts1"></script>
71
+ <script src="/builders/shell.js?v=2026-09-25-sky4b"></script>
72
72
  <!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
73
73
  <script src="/builders/palette.js" defer></script>
74
74
  <!-- shared frontend toolkit (window.OTB) — loaded before ranks.js, which pulls from it. -->
@@ -41,7 +41,7 @@
41
41
 
42
42
  <div id="toast" class="toast" role="status" aria-live="polite" data-visible="0"></div>
43
43
 
44
- <script src="/builders/shell.js?v=2026-09-24-fleetcosts1"></script>
44
+ <script src="/builders/shell.js?v=2026-09-25-sky4b"></script>
45
45
  <!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
46
46
  <script src="/builders/palette.js" defer></script>
47
47
  <script src="/builders/dom-utils.js?v=2026-06-14-domutils"></script>