@bongos/core 1.24.44 → 1.24.46
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.
- package/.bongos-core.json +179 -144
- package/clients/bongos-client/README.md +1 -1
- package/clients/bongos-client/bongos-client.global.js +4 -0
- package/clients/bongos-client/index.cjs +4 -0
- package/clients/bongos-client/index.d.ts +8 -0
- package/clients/bongos-client/index.mjs +4 -0
- package/docs/adr/0307-autobongos-a-deterministic-supervisor-and-agentic-workers.md +15 -0
- package/docs/api/openapi.json +152 -3
- package/docs/api-reference.md +4 -2
- package/docs/copy-inventory.md +1111 -1111
- package/docs/copy-registry.json +1547 -1547
- package/docs/module-api-changelog.md +4 -0
- package/docs/onboarding/diagrams/assertions.json +2 -2
- package/docs/page-inventory.json +11 -0
- package/docs/page-readings.json +823 -823
- package/migrations/core_295_runner_logins.sql +50 -0
- package/modules/government/session-scopes.json +5 -0
- package/modules/hall-ui/public/ai-studio.html +1 -1
- package/modules/hall-ui/public/ai-studio.states.json +2 -0
- package/modules/hall-ui/public/atlas.html +1 -1
- package/modules/hall-ui/public/atlas.states.json +2 -0
- package/modules/hall-ui/public/blockers.html +1 -1
- package/modules/hall-ui/public/board-room.html +1 -1
- package/modules/hall-ui/public/board-room.states.json +2 -0
- package/modules/hall-ui/public/city.html +1 -1
- package/modules/hall-ui/public/city.states.json +2 -0
- package/modules/hall-ui/public/collab.html +1 -1
- package/modules/hall-ui/public/collab.states.json +2 -0
- package/modules/hall-ui/public/commands.html +1 -1
- package/modules/hall-ui/public/commands.states.json +2 -0
- package/modules/hall-ui/public/copy-desk.html +1 -1
- package/modules/hall-ui/public/copy-desk.states.json +2 -0
- package/modules/hall-ui/public/craft-mode.js +4 -1
- package/modules/hall-ui/public/deploy.html +1 -1
- package/modules/hall-ui/public/deploy.states.json +2 -0
- package/modules/hall-ui/public/goal-map.html +1 -1
- package/modules/hall-ui/public/goal-map.states.json +2 -0
- package/modules/hall-ui/public/goals.css +1 -0
- package/modules/hall-ui/public/goals.html +1 -1
- package/modules/hall-ui/public/goals.states.json +2 -0
- package/modules/hall-ui/public/government.html +1 -1
- package/modules/hall-ui/public/government.states.json +2 -0
- package/modules/hall-ui/public/idea.html +1 -1
- package/modules/hall-ui/public/idea.states.json +2 -0
- package/modules/hall-ui/public/ideas.html +1 -1
- package/modules/hall-ui/public/ideas.states.json +2 -0
- package/modules/hall-ui/public/index-founding.states.json +2 -0
- package/modules/hall-ui/public/index-genesis-decide.states.json +2 -0
- package/modules/hall-ui/public/index-genesis-demo.states.json +2 -0
- package/modules/hall-ui/public/index-genesis.states.json +2 -0
- package/modules/hall-ui/public/index.html +1 -1
- package/modules/hall-ui/public/index.states.json +5 -0
- package/modules/hall-ui/public/market-watch-item.html +1 -1
- package/modules/hall-ui/public/market-watch-item.states.json +2 -0
- package/modules/hall-ui/public/market-watch-rules.html +1 -1
- package/modules/hall-ui/public/market-watch-rules.states.json +2 -0
- package/modules/hall-ui/public/market-watch.html +1 -1
- package/modules/hall-ui/public/market-watch.states.json +2 -0
- package/modules/hall-ui/public/modules.html +1 -1
- package/modules/hall-ui/public/modules.states.json +2 -0
- package/modules/hall-ui/public/money.html +1 -1
- package/modules/hall-ui/public/money.states.json +2 -0
- package/modules/hall-ui/public/my-agents.html +1 -1
- package/modules/hall-ui/public/my-agents.states.json +2 -0
- package/modules/hall-ui/public/notes-panel.css +1 -1
- package/modules/hall-ui/public/primer.html +1 -1
- package/modules/hall-ui/public/primer.states.json +2 -0
- package/modules/hall-ui/public/profile.html +1 -1
- package/modules/hall-ui/public/profile.states.json +2 -0
- package/modules/hall-ui/public/project-settings.html +1 -1
- package/modules/hall-ui/public/roster.html +1 -1
- package/modules/hall-ui/public/roster.states.json +2 -0
- package/modules/hall-ui/public/settings.html +1 -1
- package/modules/hall-ui/public/settings.states.json +2 -0
- package/modules/hall-ui/public/shell.js +21 -1
- package/modules/hall-ui/public/street-card.states.json +2 -0
- package/modules/hall-ui/public/street.html +1 -1
- package/modules/hall-ui/public/street.states.json +2 -0
- package/modules/hall-ui/public/studio.html +1 -1
- package/modules/hall-ui/public/studio.states.json +2 -0
- package/modules/hall-ui/public/style.css +27 -24
- package/modules/hall-ui/public/task.html +1 -1
- package/modules/hall-ui/public/task.states.json +2 -0
- package/modules/hall-ui/public/thinking.html +1 -1
- package/modules/hall-ui/public/thinking.states.json +2 -0
- package/modules/hall-ui/public/tweak-editor.html +1 -1
- package/modules/hall-ui/public/tweak-editor.states.json +2 -0
- package/modules/hall-ui/public/watch.html +1 -1
- package/modules/hall-ui/public/watch.states.json +2 -0
- package/modules/hall-ui/public/welcome-boot.js +6 -2
- package/modules/hall-ui/public/work-founding.states.json +2 -0
- package/modules/hall-ui/public/work.html +1 -1
- package/modules/hall-ui/public/work.states.json +3 -1
- package/modules/hall-ui/records/hall-navigation.md +5 -0
- package/modules/lifecycle/db-claims.js +6 -3
- package/modules/lifecycle/routes/claims.js +10 -0
- package/modules/lifecycle/routes/tasks.js +1 -1
- package/modules/lifecycle/runner-self-guard.js +19 -10
- package/modules/platform-identity/platform-identity.js +1 -1
- package/modules/platform-identity/tests/platform-identity.mjs +13 -2
- package/modules/provisioning/core-upgrade-authz.js +8 -0
- package/modules/public-landing/public/account.html +1 -0
- package/modules/public-landing/public/community.html +1 -0
- package/modules/public-landing/public/connections.html +1 -0
- package/modules/public-landing/public/contact.html +1 -0
- package/modules/public-landing/public/guild.html +1 -0
- package/modules/public-landing/public/index.html +1 -0
- package/modules/public-landing/public/invitations.html +1 -0
- package/modules/public-landing/public/privacy.html +1 -0
- package/modules/public-landing/public/projects.html +1 -0
- package/modules/public-landing/public/terms.html +1 -0
- package/modules/raise/views/gate.html +1 -0
- package/modules/raise/views/nda.html +1 -0
- package/modules/raise/views/page.html +1 -0
- package/modules/status-ui/public/index.html +1 -0
- package/modules/ui-design/kit/README.md +1 -1
- package/modules/ui-design/kit/fixtures/versions.json +1 -0
- package/modules/ui-design/kit/lib.js +48 -3
- package/modules/ui-design/kit/probe.js +1 -0
- package/modules/ui-design/kit/render.js +2 -0
- package/modules/ui-design/kit/serve.js +1 -0
- package/modules/ui-design/module.json +1 -1
- package/modules/ui-design/public/tokens.css +125 -0
- package/package-lock.json +2 -2
- package/package.json +1 -1
- package/release-notes.json +20 -0
- package/scripts/bongos/fitness.js +1 -1
- package/scripts/bongos/gen-hall-sitemap.js +3 -1
- package/scripts/bongos/run-unit-tests.js +3 -0
- package/src/bongos/auth.js +25 -4
- package/src/bongos/route-rank-check.js +5 -0
- package/src/bongos/routes/auth.js +48 -0
- package/src/bongos/runner-login.js +151 -0
- package/src/bongos/serve-internal.js +6 -1
- package/src/module-api.js +1 -1
- package/tests/autobongos_runner_login.mjs +296 -0
- package/tests/autobongos_runner_login_db.mjs +105 -0
- package/tests/craft_mode_nav.mjs +51 -3
- package/tests/design_tokens_shared.mjs +183 -0
- package/tests/government_session_scope.mjs +2 -1
- package/tests/hall_reading_world.mjs +5 -1
- package/tests/hall_tokens.mjs +22 -3
- package/tests/nav_permission_atoms.mjs +2 -1
- package/tests/ui_design_kit.mjs +30 -0
- package/tests/welcome_boot_browser.mjs +4 -0
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
.np-note__body { margin: 0; white-space: pre-wrap; overflow-wrap: anywhere; }
|
|
12
12
|
.np-note__meta { margin: var(--sp-xs) 0 0; font-size: 12px; color: var(--ink-soft); display: flex; gap: var(--sp-md); flex-wrap: wrap; align-items: center; }
|
|
13
13
|
.np-move select { font-size: 12px; }
|
|
14
|
-
.np-link { background: none; border: 0; padding: 0; color: var(--accent); cursor: pointer; font: inherit; font-size: 12px; text-decoration: underline; }
|
|
14
|
+
.np-link { background: none; border: 0; padding: 0; color: var(--accent); cursor: pointer; font: inherit; font-size: 12px; text-decoration: underline; min-height: 24px; min-width: 24px; display: inline-flex; align-items: center; } /* the 24px target floor (task 1005080) */
|
|
15
15
|
.np-empty { color: var(--ink-soft); }
|
|
16
16
|
.np-form { margin: var(--sp-lg) 0 0; display: grid; gap: var(--sp-sm); }
|
|
17
17
|
.np-field { display: grid; gap: var(--sp-xs); font-size: 13px; }
|
|
@@ -113,7 +113,7 @@
|
|
|
113
113
|
<script src="/builders/dom-utils.js?v=2026-11-05-numbers"></script>
|
|
114
114
|
<script src="/builders/shell-trail.js?v=2026-11-05-numbers"></script>
|
|
115
115
|
<script src="/builders/craft-mode.js?v=2026-11-05-goals"></script>
|
|
116
|
-
<script src="/builders/shell.js?v=2026-11-
|
|
116
|
+
<script src="/builders/shell.js?v=2026-11-06-sidebar"></script>
|
|
117
117
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
118
118
|
<script src="/builders/palette.js" defer></script>
|
|
119
119
|
<!-- the shared markdown reader (window.OTBMdReader) — primer.js renders through
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"_": "The hall's primer through modules/ui-design/kit/render.js (task 1003306). Written with the reading-room re-skin so the room's failure state and its table of contents are MEASURED at 1440/390/320 in both modes, not just looked at.",
|
|
3
3
|
"page": "/builders/primer",
|
|
4
|
+
"_storage": "The hall asks a first-visit question (the session mode picker, craft-mode.js) over every page; seeding \"already asked\" renders the page a returning builder sees (task 1005080).",
|
|
5
|
+
"storage": { "session": { "hall-craft-asked": "1" } },
|
|
4
6
|
"surface": "hall-ui",
|
|
5
7
|
"stub": {
|
|
6
8
|
"prefix": "/builders/"
|
|
@@ -249,7 +249,7 @@
|
|
|
249
249
|
<script src="/builders/dom-utils.js?v=2026-11-05-numbers"></script>
|
|
250
250
|
<script src="/builders/shell-trail.js?v=2026-11-05-numbers"></script>
|
|
251
251
|
<script src="/builders/craft-mode.js?v=2026-11-05-goals"></script>
|
|
252
|
-
<script src="/builders/shell.js?v=2026-11-
|
|
252
|
+
<script src="/builders/shell.js?v=2026-11-06-sidebar"></script>
|
|
253
253
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
254
254
|
<script src="/builders/palette.js" defer></script>
|
|
255
255
|
<!-- task 1004727: the ONE karma vote control every task/idea list renders -->
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"_": "The hall's PROFILE page through modules/ui-design/kit/render.js (task 1003308; four screens behind the section rail since task 1003489 — overview, works, activity, connections). The identity band, the charts, the works ledger and the activity ledgers only exist once a profile has LOADED, so the floors run against the hall-preview harness (see settings.states.json for the two commands; pass --base-in/--base-out at it). One rail key renders at a time, so each key is its own state. `out` is a real state here rather than a redirect: a signed-out visitor with no ?id= gets the empty state, not a bounce — under the harness's --fixture-me the /me read still answers, so `out` renders the own profile there and the empty state only under the kit's own stub.",
|
|
3
3
|
"page": "/profile",
|
|
4
|
+
"_storage": "The hall asks a first-visit question (the session mode picker, craft-mode.js) over every page; seeding \"already asked\" renders the page a returning builder sees (task 1005080).",
|
|
5
|
+
"storage": { "session": { "hall-craft-asked": "1" } },
|
|
4
6
|
"surface": "hall-ui",
|
|
5
7
|
"stub": {
|
|
6
8
|
"prefix": "/builders/"
|
|
@@ -77,7 +77,7 @@
|
|
|
77
77
|
<script src="/builders/dom-utils.js?v=2026-11-05-numbers"></script>
|
|
78
78
|
<script src="/builders/shell-trail.js?v=2026-11-05-numbers"></script>
|
|
79
79
|
<script src="/builders/craft-mode.js?v=2026-11-05-goals"></script>
|
|
80
|
-
<script src="/builders/shell.js?v=2026-11-
|
|
80
|
+
<script src="/builders/shell.js?v=2026-11-06-sidebar"></script>
|
|
81
81
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
82
82
|
<script src="/builders/palette.js" defer></script>
|
|
83
83
|
<script src="/builders/hall-kit.js"></script>
|
|
@@ -59,7 +59,7 @@
|
|
|
59
59
|
<script src="/builders/dom-utils.js?v=2026-11-05-numbers"></script>
|
|
60
60
|
<script src="/builders/shell-trail.js?v=2026-11-05-numbers"></script>
|
|
61
61
|
<script src="/builders/craft-mode.js?v=2026-11-05-goals"></script>
|
|
62
|
-
<script src="/builders/shell.js?v=2026-11-
|
|
62
|
+
<script src="/builders/shell.js?v=2026-11-06-sidebar"></script>
|
|
63
63
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
64
64
|
<script src="/builders/palette.js" defer></script>
|
|
65
65
|
<!-- the branding pack's currency label, loaded BEFORE roster.js. -->
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"_": "Builders — this project's OWN roster, ranked by credits earned (task 1003441, goal 1000075). Was the #leaderboard hash view on index.html; /#leaderboard now redirects here. Deliberately UNGATED, because its one data source (GET /leaderboard) is deliberately unauthenticated and mirrors the public status surface — so unlike a gated page's states file the `out` state below renders the real page rather than a seal. Populated look: the hall-preview harness (scripts/hall-preview/fixtures/public__leaderboard.json, since task 1004437 the list the page reads: fifteen builders with avatars, ranks, karma, tokens and each one's roles, including an artist and an ideator with no AI sessions).",
|
|
3
3
|
"page": "/builders/roster",
|
|
4
|
+
"_storage": "The hall asks a first-visit question (the session mode picker, craft-mode.js) over every page; seeding \"already asked\" renders the page a returning builder sees (task 1005080).",
|
|
5
|
+
"storage": { "session": { "hall-craft-asked": "1" } },
|
|
4
6
|
"surface": "hall-ui",
|
|
5
7
|
"stub": {
|
|
6
8
|
"prefix": "/builders/"
|
|
@@ -394,7 +394,7 @@
|
|
|
394
394
|
<script src="/builders/dom-utils.js?v=2026-11-05-numbers"></script>
|
|
395
395
|
<script src="/builders/shell-trail.js?v=2026-11-05-numbers"></script>
|
|
396
396
|
<script src="/builders/craft-mode.js?v=2026-11-05-goals"></script>
|
|
397
|
-
<script src="/builders/shell.js?v=2026-11-
|
|
397
|
+
<script src="/builders/shell.js?v=2026-11-06-sidebar"></script>
|
|
398
398
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
399
399
|
<script src="/builders/palette.js" defer></script>
|
|
400
400
|
<!-- shared component kit (window.OTBKit) — section rail (task 2166). -->
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"_": "The hall's SETTINGS page through modules/ui-design/kit/render.js (task 1003308). Every panel on it is a form the page script fills from a dozen /me/* reads, so the floors run against the hall-preview harness rather than the kit's own stub:\n\n node scripts/hall-preview/server.js --port 4621 --fixture-me\n node modules/ui-design/kit/render.js --states modules/hall-ui/public/settings.states.json --base-in http://builders.localhost:4621 --base-out http://builders.localhost:4621\n\nOne group renders at a time behind the section rail, so each rail group is its own state. There is no `out` state on purpose: settings.js answers a 401 by navigating to the sign-in flow, and a state whose page navigates away measures the destination, not this page (the not-signed-in gate panel is the non-401 failure render, pinned statically in tests/hall_settings_world.mjs).",
|
|
3
3
|
"page": "/settings",
|
|
4
|
+
"_storage": "The hall asks a first-visit question (the session mode picker, craft-mode.js) over every page; seeding \"already asked\" renders the page a returning builder sees (task 1005080).",
|
|
5
|
+
"storage": { "session": { "hall-craft-asked": "1" } },
|
|
4
6
|
"surface": "hall-ui",
|
|
5
7
|
"stub": { "prefix": "/builders/" },
|
|
6
8
|
"modeQuery": false,
|
|
@@ -877,6 +877,23 @@
|
|
|
877
877
|
// task 1004685: `positions` (seats held, null while unknown), `simRank` (?as=nobody's).
|
|
878
878
|
var access = { authed: null, rank: null, graduated: false, showWork: false, permissions: null, needs: null, founding: null, positions: null, simRank: null };
|
|
879
879
|
|
|
880
|
+
// THE REMEMBERED NAV (task 1005070): pages are full loads and the gate waits on /me, so the rail booted empty. The last
|
|
881
|
+
// settled access paints at boot, /me settles the rest; cosmetic (ADR 0016), no needs roster; a 401/403 or sign-out forgets it.
|
|
882
|
+
var NAV_KEY = 'hall-nav-access', NAV_TTL = 24 * 60 * 60 * 1000;
|
|
883
|
+
function rememberAccess(b) {
|
|
884
|
+
if (access.authed !== true || !b || b.id == null) return;
|
|
885
|
+
var who = { id: b.id, rank: b.rank, display_name: b.display_name, github_login: b.github_login, avatar_url: b.avatar_url, preferred_disciplines: b.preferred_disciplines };
|
|
886
|
+
try { window.localStorage.setItem(NAV_KEY, JSON.stringify({ at: Date.now(), rank: access.rank, graduated: access.graduated, showWork: access.showWork, permissions: access.permissions, builder: who })); } catch (_) { /* private mode: wait for /me */ }
|
|
887
|
+
}
|
|
888
|
+
function forgetAccess() { try { window.localStorage.removeItem(NAV_KEY); } catch (_) { /* nothing kept */ } }
|
|
889
|
+
function recallAccess() {
|
|
890
|
+
var c; try { c = JSON.parse(window.localStorage.getItem(NAV_KEY) || 'null'); } catch (_) { return; }
|
|
891
|
+
if (!c || !c.builder || c.builder.id == null || !(Date.now() - c.at < NAV_TTL)) return;
|
|
892
|
+
access.authed = true; access.rank = c.rank ? String(c.rank).toLowerCase() : null; access.graduated = !!c.graduated; access.showWork = !!c.showWork;
|
|
893
|
+
access.permissions = (c.permissions && typeof c.permissions === 'object') ? c.permissions : null;
|
|
894
|
+
renderUser(c.builder); applyCraftEmphasis(c.builder);
|
|
895
|
+
}
|
|
896
|
+
|
|
880
897
|
function gateAllows(gate) {
|
|
881
898
|
var authed = access.authed === true;
|
|
882
899
|
// ?as=nobody's stand-in rank only ever sits BELOW the real one (gov-positions.js).
|
|
@@ -1154,6 +1171,7 @@
|
|
|
1154
1171
|
if (state.builder) { renderUser(state.builder); applyCraftEmphasis(state.builder); }
|
|
1155
1172
|
// task 1004713: which seats this builder holds — /me's server-resolved block.
|
|
1156
1173
|
if (state.builder && access.authed === true) { loadPositions(state.builder, state.positions); loadGithubChip(state.builder); }
|
|
1174
|
+
if (state.builder && access.authed === true) rememberAccess(state.builder); else if (access.authed === false) forgetAccess(); // task 1005070
|
|
1157
1175
|
}
|
|
1158
1176
|
document.querySelectorAll('#app-sidebar [data-gate]').forEach(function (el) {
|
|
1159
1177
|
var ok = gateAllows(el.dataset.gate);
|
|
@@ -1301,6 +1319,7 @@
|
|
|
1301
1319
|
// live here, not only on the index (builders.js used to own it alone). Convert
|
|
1302
1320
|
// the click into the real POST, then bounce home.
|
|
1303
1321
|
function doLogout() {
|
|
1322
|
+
forgetAccess(); // task 1005070: the next visitor's rail is not this builder's
|
|
1304
1323
|
var finish = function () {
|
|
1305
1324
|
// Mirror the SERVER logout (src/bongos/routes/auth.js): expire BOTH the
|
|
1306
1325
|
// current gds_session and the legacy pms_session, each in BOTH the
|
|
@@ -1396,7 +1415,7 @@
|
|
|
1396
1415
|
// the governor pages' living model reads /me too: it takes this answer (gov-feeds.js)
|
|
1397
1416
|
HALL_READS['/me'] = meRead.then(function (res) { return res && res.ok ? res.data : (res && res.status === 403 ? false : null); }, function () { return null; });
|
|
1398
1417
|
meRead.then(function (res) {
|
|
1399
|
-
if (res.status === 401) { applyAccess({ authed: false }); return null; }
|
|
1418
|
+
if (res.status === 401 || res.status === 403) { applyAccess({ authed: false }); return null; }
|
|
1400
1419
|
if (!res.ok) return null;
|
|
1401
1420
|
return res.data;
|
|
1402
1421
|
}).then(function (me) {
|
|
@@ -1442,6 +1461,7 @@
|
|
|
1442
1461
|
applyZoom();
|
|
1443
1462
|
if (CRAFT) CRAFT.mount();
|
|
1444
1463
|
applyFullscreen(storedFullscreen());
|
|
1464
|
+
recallAccess(); // task 1005070: the last settled nav, so the rail paints before /me
|
|
1445
1465
|
applyAccess(null); // default: everything gated until access is known
|
|
1446
1466
|
wire();
|
|
1447
1467
|
TRAIL.fillExits();
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"_": "THE MATTER CARD THAT ACTS (task 1004528, goal 1000125) on the street page, through modules/ui-design/kit/render.js. Kept beside street.states.json rather than inside it, so the street and its interiors (task 1004526) and the card each own their states. The populated card needs the hall-preview harness, whose government__docket.json puts the review-seat amendment on the board source (board:47) and whose government__board__items.json carries its ballot (item 47), with a canned answer for a vote:\n\n node scripts/hall-preview/server.js --port 4625 --fixture-me\n node modules/ui-design/kit/render.js --states modules/hall-ui/public/street-card.states.json --base-in http://localhost:4625 --base-out http://localhost:4625\n\nTask 1004566 adds a card per kind the docket carries (blocker, red-team report, core update, module re-check, a Full Idea and the review queue), each compact and with \"more\" open; the harness fixture carries them. Against the kit stub there is no docket and no pin, so these states are for the harness.",
|
|
3
3
|
"page": "/builders/street",
|
|
4
|
+
"_storage": "The hall asks a first-visit question (the session mode picker, craft-mode.js) over every page; seeding \"already asked\" renders the page a returning builder sees (task 1005080).",
|
|
5
|
+
"storage": { "session": { "hall-craft-asked": "1" } },
|
|
4
6
|
"surface": "hall-ui",
|
|
5
7
|
"stub": {
|
|
6
8
|
"prefix": "/builders/"
|
|
@@ -231,7 +231,7 @@
|
|
|
231
231
|
<script src="/builders/dom-utils.js?v=2026-11-05-numbers"></script>
|
|
232
232
|
<script src="/builders/shell-trail.js?v=2026-11-05-numbers"></script>
|
|
233
233
|
<script src="/builders/craft-mode.js?v=2026-11-05-goals"></script>
|
|
234
|
-
<script src="/builders/shell.js?v=2026-11-
|
|
234
|
+
<script src="/builders/shell.js?v=2026-11-06-sidebar"></script>
|
|
235
235
|
<script src="/builders/palette.js" defer></script>
|
|
236
236
|
<script src="/builders/gov-living.js?v=2026-10-09-positions1"></script>
|
|
237
237
|
<script src="/builders/gov-feeds.js?v=2026-10-09-living3"></script>
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"_": "THE STREET (task 1004525, goal 1000125) and inside every building and district (task 1004526) through modules/ui-design/kit/render.js. The page draws GET /government/docket, GET /goals, GET /goals/rollups and the viewer's GET /builders/:id/earnings; against the kit's own stub none exists, so every state renders the bare street (the nine civic buildings, no districts, no pins) with the readings saying the docket could not be read: a real state the floors must hold in. To look at the populated street, run it against the hall-preview harness, whose government__docket.json fixture carries the reference design's seven sample matters (3 need you, 2 moving, 2 settled) and whose goals fixtures carry the open goals:\n\n node scripts/hall-preview/server.js --port 4625 --fixture-me\n node modules/ui-design/kit/render.js --states modules/hall-ui/public/street.states.json --base-in http://localhost:4625 --base-out http://localhost:4625\n\nThe page follows the OS mode until the switch is pressed (then the hall's own 'hall-theme' preference), so the kit's dark/light emulation renders both modes.",
|
|
3
3
|
"page": "/builders/street",
|
|
4
|
+
"_storage": "The hall asks a first-visit question (the session mode picker, craft-mode.js) over every page; seeding \"already asked\" renders the page a returning builder sees (task 1005080).",
|
|
5
|
+
"storage": { "session": { "hall-craft-asked": "1" } },
|
|
4
6
|
"surface": "hall-ui",
|
|
5
7
|
"stub": {
|
|
6
8
|
"prefix": "/builders/",
|
|
@@ -225,7 +225,7 @@
|
|
|
225
225
|
<script src="/builders/dom-utils.js?v=2026-11-05-numbers"></script>
|
|
226
226
|
<script src="/builders/shell-trail.js?v=2026-11-05-numbers"></script>
|
|
227
227
|
<script src="/builders/craft-mode.js?v=2026-11-05-goals"></script>
|
|
228
|
-
<script src="/builders/shell.js?v=2026-11-
|
|
228
|
+
<script src="/builders/shell.js?v=2026-11-06-sidebar"></script>
|
|
229
229
|
<script src="/builders/palette.js" defer></script>
|
|
230
230
|
<!-- The kit, for its ONE renderer: the full-size ship-time visual figure
|
|
231
231
|
(task 1003829), which the older reviews still show. -->
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"_": "The studio home (task 1003971 / BV2.TW16), built 1:1 on docs/design/mocks/tweak-mode/Main.dc.html: the night room, the greeting and its sub-line (editable in place as a tweak of builders:studio), the tally, Resume, and three quick actions opening glass panels (the Tweak/CopyWrite Flow, the Approval queue, Artist Review Status). Behind a quiet door, the older reviews (R06 of goal 1000074, task 1003117; retired in TW14) still answer the reviews filed before Tweak Mode. Against the kit's own stub the page renders its unread states (no copy-desk feeds). TO SEE IT POPULATED, point the kit at the hall-preview harness: `node scripts/hall-preview/server.js --port 4636 --fixture-me` then `render.js --base-in http://builders.localhost:4636 --base-out http://builders.localhost:4636`. The harness answers the tally, the pages and the next page from copy-desk__tally.json, copy-desk__pages.json and copy-desk__next.json (built by the real composers), Resume's counter from copy-desk__pages__draft.json, the studio's own lines from copy-desk__pages__draft-studio.json, the claim and the draft save from its CANNED WRITES, and the older reviews from tasks.json (whose first row IS a cascade artist review).",
|
|
3
3
|
"page": "/builders/studio",
|
|
4
|
+
"_storage": "The hall asks a first-visit question (the session mode picker, craft-mode.js) over every page; seeding \"already asked\" renders the page a returning builder sees (task 1005080).",
|
|
5
|
+
"storage": { "session": { "hall-craft-asked": "1" } },
|
|
4
6
|
"surface": "hall-ui",
|
|
5
7
|
"stub": {
|
|
6
8
|
"prefix": "/builders/"
|
|
@@ -56,6 +56,10 @@
|
|
|
56
56
|
here. It lives on the shell rules below and on a page's own body, because a
|
|
57
57
|
body declaration beats an inherited :root value at every width and a token
|
|
58
58
|
tier that carries a breakpoint silently defeats its own media query. */
|
|
59
|
+
/* The shared token sheet (task 1005081): the scales — type, spacing, corners,
|
|
60
|
+
shadows, motion, stacking — every surface loads. Imported FIRST so this
|
|
61
|
+
sheet's own rules follow it; the hall's scale names below are aliases of it. */
|
|
62
|
+
@import url("/modules/ui-design/public/tokens.css");
|
|
59
63
|
@import url("page-notes.css");
|
|
60
64
|
@import url("craft-review.css");
|
|
61
65
|
|
|
@@ -158,7 +162,7 @@
|
|
|
158
162
|
thin on black, so light takes the mono and dark takes the body face.
|
|
159
163
|
Take the token, never the family. ---- */
|
|
160
164
|
--label-face: var(--font-mono);
|
|
161
|
-
--label-size:
|
|
165
|
+
--label-size: var(--ds-text-2xs);
|
|
162
166
|
--label-space: .12em;
|
|
163
167
|
--label-case: uppercase;
|
|
164
168
|
|
|
@@ -166,11 +170,12 @@
|
|
|
166
170
|
there is nothing behind it. Never a coloured glow. ---- */
|
|
167
171
|
--type-halo: none;
|
|
168
172
|
|
|
169
|
-
/* ---- structure. --line is a WIDTH (note c).
|
|
170
|
-
|
|
171
|
-
--
|
|
172
|
-
--radius-
|
|
173
|
-
--radius-
|
|
173
|
+
/* ---- structure. --line is a WIDTH (note c). The values live in the shared
|
|
174
|
+
token sheet (task 1005081); these names are the hall's aliases. ---- */
|
|
175
|
+
--line: var(--ds-line);
|
|
176
|
+
--radius: var(--ds-radius-panel);
|
|
177
|
+
--radius-sm: var(--ds-radius-tile);
|
|
178
|
+
--radius-pill: var(--ds-radius-pill);
|
|
174
179
|
|
|
175
180
|
/* ---- the shell's metrics. --topbar-h stays under the kit's 80px top-bar
|
|
176
181
|
floor; --sidebar-w IS the rail, because v3 pins the rail at every
|
|
@@ -195,12 +200,12 @@
|
|
|
195
200
|
/* ---- spacing: DESIGN.md's rhythm (6/10/14/22/34/52). The four-step
|
|
196
201
|
--space-* scale task 2179 named aliases onto it, so no ported rule
|
|
197
202
|
breaks; hairlines separate, padding does not. ---- */
|
|
198
|
-
--sp-hair:
|
|
199
|
-
--sp-xs:
|
|
200
|
-
--sp-sm:
|
|
201
|
-
--sp-md:
|
|
202
|
-
--sp-lg:
|
|
203
|
-
--sp-xl:
|
|
203
|
+
--sp-hair: var(--ds-space-hair);
|
|
204
|
+
--sp-xs: var(--ds-space-xs);
|
|
205
|
+
--sp-sm: var(--ds-space-sm);
|
|
206
|
+
--sp-md: var(--ds-space-md);
|
|
207
|
+
--sp-lg: var(--ds-space-lg);
|
|
208
|
+
--sp-xl: var(--ds-space-xl);
|
|
204
209
|
--space-1: var(--sp-hair);
|
|
205
210
|
--space-2: var(--sp-xs);
|
|
206
211
|
--space-3: var(--sp-sm);
|
|
@@ -216,7 +221,7 @@
|
|
|
216
221
|
/* The world has no shadow vocabulary for UI, so this is spent only where an
|
|
217
222
|
element floats over a scrim (the phone drawer, the deep-link card). Pure
|
|
218
223
|
black with alpha is the one literal the Fifteen Rule allows, as a scrim. */
|
|
219
|
-
--shadow-pop:
|
|
224
|
+
--shadow-pop: var(--ds-shadow-pop);
|
|
220
225
|
|
|
221
226
|
/* ---- z ladder — content overlays (rank tips z-50, modals z-50, toast z-100,
|
|
222
227
|
copy-toast z-1000, deeplink z-2000) must beat the chrome; the mobile drawer
|
|
@@ -225,17 +230,17 @@
|
|
|
225
230
|
reading hairline sits UNDER the topbar so it reads as the article's
|
|
226
231
|
progress and not as app chrome, and the diagram's fullscreen canvas is the
|
|
227
232
|
top of the whole ladder because it covers the shell entirely. ---- */
|
|
228
|
-
--z-progress:
|
|
229
|
-
--z-topbar:
|
|
230
|
-
--z-sidebar:
|
|
231
|
-
--z-scrim:
|
|
232
|
-
--z-drawer:
|
|
233
|
+
--z-progress: var(--ds-z-progress);
|
|
234
|
+
--z-topbar: var(--ds-z-topbar);
|
|
235
|
+
--z-sidebar: var(--ds-z-sidebar);
|
|
236
|
+
--z-scrim: var(--ds-z-scrim);
|
|
237
|
+
--z-drawer: var(--ds-z-drawer);
|
|
233
238
|
/* A confirm dialog is the one thing that must sit above the drawer: it is
|
|
234
239
|
asking a question the drawer's content cannot answer. Added by task 1003307
|
|
235
240
|
because two pages had each guessed a bare number for exactly this
|
|
236
241
|
(200 and 50), which is what a missing layer looks like. */
|
|
237
|
-
--z-modal:
|
|
238
|
-
--z-diagram-full:
|
|
242
|
+
--z-modal: var(--ds-z-modal);
|
|
243
|
+
--z-diagram-full: var(--ds-z-diagram-full);
|
|
239
244
|
|
|
240
245
|
/* ---- the hall's own plate: the declared seam, deferred by the owner
|
|
241
246
|
("decide after the shell lands", 2026-08-30). The hall's plate was
|
|
@@ -286,11 +291,10 @@ html[data-theme="dark"] {
|
|
|
286
291
|
--info-weak: color-mix(in srgb, var(--info) 14%, var(--bg-card));
|
|
287
292
|
--focus: var(--accent);
|
|
288
293
|
--label-face: var(--font-body);
|
|
289
|
-
--label-size:
|
|
294
|
+
--label-size: var(--ds-text-2xs-plus);
|
|
290
295
|
--label-space: .1em;
|
|
291
296
|
--type-halo: 0 2px 18px rgba(0, 0, 0, .94), 0 0 54px rgba(0, 0, 0, .72);
|
|
292
297
|
--surface-2: color-mix(in srgb, var(--ink) 6%, var(--bg-card));
|
|
293
|
-
--shadow-pop: 0 18px 40px rgba(0, 0, 0, .62);
|
|
294
298
|
--plate-veil: linear-gradient(to bottom, rgba(0, 0, 0, .82), rgba(0, 0, 0, .93));
|
|
295
299
|
}
|
|
296
300
|
html[data-theme="dark"] body { background: var(--bg); }
|
|
@@ -327,11 +331,10 @@ html[data-theme="dark"] body { background: var(--bg); }
|
|
|
327
331
|
--info-weak: color-mix(in srgb, var(--info) 14%, var(--bg-card));
|
|
328
332
|
--focus: var(--accent);
|
|
329
333
|
--label-face: var(--font-body);
|
|
330
|
-
--label-size:
|
|
334
|
+
--label-size: var(--ds-text-2xs-plus);
|
|
331
335
|
--label-space: .1em;
|
|
332
336
|
--type-halo: 0 2px 18px rgba(0, 0, 0, .94), 0 0 54px rgba(0, 0, 0, .72);
|
|
333
337
|
--surface-2: color-mix(in srgb, var(--ink) 6%, var(--bg-card));
|
|
334
|
-
--shadow-pop: 0 18px 40px rgba(0, 0, 0, .62);
|
|
335
338
|
--plate-veil: linear-gradient(to bottom, rgba(0, 0, 0, .82), rgba(0, 0, 0, .93));
|
|
336
339
|
}
|
|
337
340
|
html:not([data-theme]) body { background: var(--bg); }
|
|
@@ -59,7 +59,7 @@
|
|
|
59
59
|
<script src="/builders/dom-utils.js?v=2026-11-05-numbers"></script>
|
|
60
60
|
<script src="/builders/shell-trail.js?v=2026-11-05-numbers"></script>
|
|
61
61
|
<script src="/builders/craft-mode.js?v=2026-11-05-goals"></script>
|
|
62
|
-
<script src="/builders/shell.js?v=2026-11-
|
|
62
|
+
<script src="/builders/shell.js?v=2026-11-06-sidebar"></script>
|
|
63
63
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
64
64
|
<script src="/builders/palette.js" defer></script>
|
|
65
65
|
<!-- task-detail.js still owns the #/idea/N and #/blocker/N deep-link overlay
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"_": "The hall's TASK RECORD through modules/ui-design/kit/render.js (task 1003305). The record's own controls — the dependency links, the lifecycle buttons, the figure band, the way back — only exist once a task has LOADED, so the floors here are run against the hall-preview harness rather than the kit's own stub, which carries the public-landing feeds and not the hall's:\n\n node scripts/hall-preview/server.js --port 4612 --fixture-me\n node modules/ui-design/kit/render.js --states modules/hall-ui/public/task.states.json --base-in http://builders.localhost:4612 --base-out http://builders.localhost:4612\n\nRun against the kit's own stubs instead and every state renders `no such task`, which is a real state and is the `missing` one below — just not the one the re-skin changed.",
|
|
3
3
|
"page": "/task/2166",
|
|
4
|
+
"_storage": "The hall asks a first-visit question (the session mode picker, craft-mode.js) over every page; seeding \"already asked\" renders the page a returning builder sees (task 1005080).",
|
|
5
|
+
"storage": { "session": { "hall-craft-asked": "1" } },
|
|
4
6
|
"surface": "hall-ui",
|
|
5
7
|
"stub": { "prefix": "/builders/" },
|
|
6
8
|
"modeQuery": false,
|
|
@@ -141,7 +141,7 @@
|
|
|
141
141
|
<script src="/builders/dom-utils.js?v=2026-11-05-numbers"></script>
|
|
142
142
|
<script src="/builders/shell-trail.js?v=2026-11-05-numbers"></script>
|
|
143
143
|
<script src="/builders/craft-mode.js?v=2026-11-05-goals"></script>
|
|
144
|
-
<script src="/builders/shell.js?v=2026-11-
|
|
144
|
+
<script src="/builders/shell.js?v=2026-11-06-sidebar"></script>
|
|
145
145
|
<script src="/builders/palette.js" defer></script>
|
|
146
146
|
|
|
147
147
|
<script src="/builders/idea-objects.js?v=2026-09-27-split"></script>
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"_": "THE SKY (task 1004231 / sky part 3 of 5, goal 1000095; ADR 0331) through modules/ui-design/kit/render.js. 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 composer, the tour, the list drawer and the lenses all exist with no thought filed). To look at the populated sky, run it against the hall-preview harness, whose sky.json + sky__mine.json fixtures carry the wells and one of each of the five objects:\n\n node scripts/hall-preview/server.js --port 4615 --fixture-me\n node modules/ui-design/kit/render.js --states modules/hall-ui/public/thinking.states.json --base-in http://localhost:4615 --base-out http://localhost:4615\n\nThe tour opens by itself on a first visit (sky-tour-seen), so states that want the bare sky skip it first.\n\nIN THE HALL (task 1004327): the page sits in the hall chrome, so it renders in BOTH modes — the chrome follows the hall theme and the sky's stage stays the void in both. The full-* states press the shell's full-screen switch: the sidebar and the top bar leave, and the one button that brings them back floats top right.",
|
|
3
3
|
"page": "/builders/thinking",
|
|
4
|
+
"_storage": "The hall asks a first-visit question (the session mode picker, craft-mode.js) over every page; seeding \"already asked\" renders the page a returning builder sees (task 1005080).",
|
|
5
|
+
"storage": { "session": { "hall-craft-asked": "1" } },
|
|
4
6
|
"surface": "hall-ui",
|
|
5
7
|
"stub": { "prefix": "/builders/" },
|
|
6
8
|
"modeQuery": false,
|
|
@@ -145,7 +145,7 @@
|
|
|
145
145
|
<script src="/builders/dom-utils.js?v=2026-11-05-numbers"></script>
|
|
146
146
|
<script src="/builders/shell-trail.js?v=2026-11-05-numbers"></script>
|
|
147
147
|
<script src="/builders/craft-mode.js?v=2026-11-05-goals"></script>
|
|
148
|
-
<script src="/builders/shell.js?v=2026-11-
|
|
148
|
+
<script src="/builders/shell.js?v=2026-11-06-sidebar"></script>
|
|
149
149
|
<script src="/builders/palette.js" defer></script>
|
|
150
150
|
<script src="/builders/brand-holes.js?v=2026-09-29-aqfix"></script>
|
|
151
151
|
<script src="/builders/tweak-editor-lib.js?v=2026-09-29-tw27"></script>
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"_": "The tweak editor (task 1004321 / BV2.TW10), built 1:1 on docs/design/mocks/tweak-mode/Editor.dc.html. Against the kit's own stub the page renders its could-not-read state (no /copy-desk feed), a state the floors must hold in. TO SEE IT POPULATED, point the kit at the hall-preview harness: `node scripts/hall-preview/server.js --port 4631 --fixture-me`, then `render.js --page '/builders/tweak-editor?page=landing:index' --base-in http://builders.localhost:4631 --base-out http://builders.localhost:4631`. The harness answers the read from fixtures/copy-desk__pages__draft.json (the real landing:index reading with the artboard's two rewrites as the saved draft), next up from copy-desk__next.json, and the autosave, the submit and the claim from its canned writes.",
|
|
3
3
|
"page": "/builders/tweak-editor?page=landing:index",
|
|
4
|
+
"_storage": "The hall asks a first-visit question (the session mode picker, craft-mode.js) over every page; seeding \"already asked\" renders the page a returning builder sees (task 1005080).",
|
|
5
|
+
"storage": { "session": { "hall-craft-asked": "1" } },
|
|
4
6
|
"surface": "hall-ui",
|
|
5
7
|
"stub": {
|
|
6
8
|
"prefix": "/builders/"
|
|
@@ -271,7 +271,7 @@
|
|
|
271
271
|
<script src="/builders/dom-utils.js?v=2026-11-05-numbers"></script>
|
|
272
272
|
<script src="/builders/shell-trail.js?v=2026-11-05-numbers"></script>
|
|
273
273
|
<script src="/builders/craft-mode.js?v=2026-11-05-goals"></script>
|
|
274
|
-
<script src="/builders/shell.js?v=2026-11-
|
|
274
|
+
<script src="/builders/shell.js?v=2026-11-06-sidebar"></script>
|
|
275
275
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
276
276
|
<script src="/builders/palette.js" defer></script>
|
|
277
277
|
<!-- shared component kit (window.OTBKit) — tabs, ledger, pager (task 2166). -->
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"_": "Watch — the attention board behind requireGovernmentPage. The SEALED state (a viewer below the gate) is a real render, not an error page, so it is a state here. Written with the re-skin (task 1003307) so this page is MEASURED at three widths in both modes rather than looked at once.",
|
|
3
3
|
"page": "/builders/watch",
|
|
4
|
+
"_storage": "The hall asks a first-visit question (the session mode picker, craft-mode.js) over every page; seeding \"already asked\" renders the page a returning builder sees (task 1005080).",
|
|
5
|
+
"storage": { "session": { "hall-craft-asked": "1" } },
|
|
4
6
|
"surface": "hall-ui",
|
|
5
7
|
"stub": {
|
|
6
8
|
"prefix": "/builders/"
|
|
@@ -166,14 +166,18 @@
|
|
|
166
166
|
|
|
167
167
|
var root = null, timers = [], returnFocus = null, shown = false, leaving = false;
|
|
168
168
|
|
|
169
|
+
function bannerTag(builder) { return builder ? 'div' : 'header'; }
|
|
169
170
|
function overlayHtml(builder, now, when) {
|
|
170
171
|
return '<div class="wb__art" aria-hidden="true"><div class="wb__pan">' +
|
|
171
172
|
'<img class="wb__img" alt="" src="' + artFor(when) + '" decoding="async">' +
|
|
172
173
|
'<div class="wb__fx" id="wb-fx"></div>' +
|
|
173
174
|
'</div></div>' +
|
|
174
175
|
'<div class="wb__cloud wb__cloud--a" aria-hidden="true"></div><div class="wb__cloud wb__cloud--b" aria-hidden="true"></div>' +
|
|
175
|
-
|
|
176
|
-
|
|
176
|
+
// For a visitor the welcome IS the page (the shell draws no header for them), so its logo
|
|
177
|
+
// banner is the page's one <header>; over a signed-in hall the shell's header stands, and the
|
|
178
|
+
// banner stays a plain block (task 1005080).
|
|
179
|
+
'<' + bannerTag(builder) + ' class="wb__banner">' + logoHtml(window.__BRANDING__) +
|
|
180
|
+
'<span class="wb__version" id="wb-version" hidden></span></' + bannerTag(builder) + '>' +
|
|
177
181
|
'<div class="wb__veil" aria-hidden="true"></div>' +
|
|
178
182
|
'<button class="wb__skip" type="button" data-wb-skip>Skip</button>' +
|
|
179
183
|
'<a class="wb__built" href="' + BUILT_ON.href + '" target="_blank" rel="noopener">Built on <b>' + BUILT_ON.label + '</b></a>' +
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"_": "Project founding mode (task 1004422) on an ordinary hall page: the founding band above the topbar and today's nav items asleep, rendered from a /me that says founding (kit fixture me-founding.json, the real server shaper's output at stage strategize). The page itself is work.states.json's; only the identity differs. The no-founding case is every other hall states file.",
|
|
3
3
|
"page": "/builders/work",
|
|
4
|
+
"_storage": "The hall asks a first-visit question (the session mode picker, craft-mode.js) over every page; seeding \"already asked\" renders the page a returning builder sees (task 1005080).",
|
|
5
|
+
"storage": { "session": { "hall-craft-asked": "1" } },
|
|
4
6
|
"surface": "hall-ui",
|
|
5
7
|
"stub": {
|
|
6
8
|
"prefix": "/builders/",
|
|
@@ -174,7 +174,7 @@
|
|
|
174
174
|
<script src="/builders/dom-utils.js?v=2026-11-05-numbers"></script>
|
|
175
175
|
<script src="/builders/shell-trail.js?v=2026-11-05-numbers"></script>
|
|
176
176
|
<script src="/builders/craft-mode.js?v=2026-11-05-goals"></script>
|
|
177
|
-
<script src="/builders/shell.js?v=2026-11-
|
|
177
|
+
<script src="/builders/shell.js?v=2026-11-06-sidebar"></script>
|
|
178
178
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
179
179
|
<script src="/builders/palette.js" defer></script>
|
|
180
180
|
<!-- task 1004727: the ONE karma vote control every task/idea list renders -->
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"_": "The hall's Work Board through modules/ui-design/kit/render.js (task 1003304). Written with the re-skin so the board's four tabs and its selection state are measured at 1440/390/320 in both modes, not just looked at. The populated look is the hall-preview harness (scripts/hall-preview/server.js); this file is the FLOORS.",
|
|
3
3
|
"page": "/builders/work",
|
|
4
|
+
"_storage": "The hall asks a first-visit question (the session mode picker, craft-mode.js) over every page; seeding \"already asked\" renders the page a returning builder sees (task 1005080).",
|
|
5
|
+
"storage": { "session": { "hall-craft-asked": "1" } },
|
|
4
6
|
"surface": "hall-ui",
|
|
5
7
|
"stub": { "prefix": "/builders/" },
|
|
6
8
|
"modeQuery": false,
|
|
7
9
|
"_feeds": "The kit's stub carries a small fixture set, not the hall's task feeds, so the board renders its EMPTY and SKELETON states here — which is the point: an empty queue is a state the floors must hold in. The feed 404s are declared, never hidden.",
|
|
8
|
-
"ignoreRequests": ["/api/(gds|bongos)/me$", "/api/(gds|bongos)/me/", "/api/(gds|bongos)/tasks", "/api/(gds|bongos)/claims", "/api/(gds|bongos)/goals", "/api/(gds|bongos)/inbox/", "/api/(gds|bongos)/versions"],
|
|
10
|
+
"ignoreRequests": ["/api/(gds|bongos)/live", "/api/(gds|bongos)/me$", "/api/(gds|bongos)/me/", "/api/(gds|bongos)/tasks", "/api/(gds|bongos)/claims", "/api/(gds|bongos)/goals", "/api/(gds|bongos)/inbox/", "/api/(gds|bongos)/versions"],
|
|
9
11
|
"ignoreConsole": ["/api/(gds|bongos)/", "\\b401\\b", "\\b404\\b", "Unauthorized", "Not Found", "load failed"],
|
|
10
12
|
"states": {
|
|
11
13
|
"ready": { "auth": true, "expect": { "visible": ["#claim-scroll"], "hidden": ["#wip-scroll", "#backlog-scroll", "#history-scroll"] } },
|
|
@@ -28,3 +28,8 @@ Covers: every shelled hall page (`shell.js`, `style.css`), plus `goal-map.html`
|
|
|
28
28
|
`goal-map.html` now uses thinking.html's structure: sidebar and top-bar mounts, `style.css`, `shell.js`, the sky inside `<main id="hall-main" class="sky-stage">`, and a `<div class="brand">` because the shell's bar is the page's one `<header>`. In `thinking.css` both pages share one stage rule, `body[data-page] .sky-stage`. No hall page is standalone any more (`tests/hall_audit.mjs` `STANDALONE_EXEMPT` is empty).
|
|
29
29
|
|
|
30
30
|
Tests: `tests/hall_fullscreen.mjs` (the standard switch, `plain`, Back link, trail, fallback and exit cases), `tests/hall_record_world.mjs` §10 (the record places its exit), `tests/goal_map_page.mjs`, `tests/hall_audit.mjs` §8.
|
|
31
|
+
|
|
32
|
+
## The rail paints at once, and Home is one button (task 1005070)
|
|
33
|
+
|
|
34
|
+
- Every hall page is a full load, and the gate waits on `/me`, so the rail used to boot with only Home and pop the rest in once `/me` answered — longest for the owner, whose `/me` is the heaviest. `shell.js` now keeps the last settled access in `localStorage['hall-nav-access']` (rank, graduated/showWork, the nav permission map, the user chip; never the needs roster, so no badge is stale) and paints from it at boot. `/me` still settles the real state. It is forgotten on any signed-out settle (a 401 or a refused 403) and by the sign-out link, and is not painted once a day old.
|
|
35
|
+
- In a craft the plate under the brand is the Home button (task 1005065), so no mode's tab list names `home` — Building used to, which drew two home icons. With no craft chosen there is no plate and the Home tab shows. Pinned in `tests/craft_mode_nav.mjs`.
|
|
@@ -108,7 +108,7 @@ function isRebaseGateExempt(task) {
|
|
|
108
108
|
return Boolean(task) && task.kind === 'infra' && Number(task.priority) === 1;
|
|
109
109
|
}
|
|
110
110
|
|
|
111
|
-
async function claimTask({ taskId, builderId, worktreeName, headSha, creatorSessionId, enforceOverlap = false, autoPickup = false }) {
|
|
111
|
+
async function claimTask({ taskId, builderId, worktreeName, headSha, creatorSessionId, enforceOverlap = false, autoPickup = false, autonomous = false }) {
|
|
112
112
|
const heldPermissions = await claimPermissionsFor(builderId); // BV1.R106 — before the tx opens
|
|
113
113
|
// ADR 0371 D5: a marked claim needs the project's switch and cap, read before the
|
|
114
114
|
// tx like the permissions above; the COUNT runs inside it, under the lock.
|
|
@@ -433,9 +433,12 @@ async function claimTask({ taskId, builderId, worktreeName, headSha, creatorSess
|
|
|
433
433
|
|
|
434
434
|
// The column is named only on a marked claim, so an ordinary claim's insert is
|
|
435
435
|
// byte-identical to before core_275.
|
|
436
|
+
// `autonomous` (core_295, task 1004547) is the server's mark that an Autobongos
|
|
437
|
+
// runner's own login made this claim — set by the claims route from the SESSION,
|
|
438
|
+
// never from the body. Like auto_pickup, the column is named only when true.
|
|
436
439
|
const insertClaim = await client.query(
|
|
437
|
-
`INSERT INTO claims (task_id, builder_id, worktree_name, requested_worktree_name, head_sha, reserved_migration_number, creator_session_id${autoPickup ? ', auto_pickup' : ''})
|
|
438
|
-
VALUES ($1, $2, $3, $4, $5, $6, $7${autoPickup ? ', TRUE' : ''})
|
|
440
|
+
`INSERT INTO claims (task_id, builder_id, worktree_name, requested_worktree_name, head_sha, reserved_migration_number, creator_session_id${autoPickup ? ', auto_pickup' : ''}${autonomous ? ', autonomous' : ''})
|
|
441
|
+
VALUES ($1, $2, $3, $4, $5, $6, $7${autoPickup ? ', TRUE' : ''}${autonomous ? ', TRUE' : ''})
|
|
439
442
|
RETURNING id, task_id, builder_id, worktree_name, requested_worktree_name, claimed_at, head_sha, reserved_migration_number`,
|
|
440
443
|
[taskId, builderId, finalWorktreeName, requestedWorktreeName, headSha ?? null, reservedMigrationNumber, creatorSessionId ?? null]
|
|
441
444
|
);
|
|
@@ -305,6 +305,10 @@ module.exports = function buildClaimsRouter() {
|
|
|
305
305
|
creatorSessionId: resolveCreatorSessionId(bindSession, req.gdsSession?.session_id),
|
|
306
306
|
enforceOverlap: enforceTouches === true,
|
|
307
307
|
autoPickup: autoPickup === true,
|
|
308
|
+
// task 1004547: an Autobongos runner's own login marks its claim
|
|
309
|
+
// autonomous. Read from the SESSION (auth.requireBuilder), never the body,
|
|
310
|
+
// so a worker cannot claim its way out of the runner-only walls.
|
|
311
|
+
autonomous: !!(req.builder && req.builder.runner),
|
|
308
312
|
});
|
|
309
313
|
const { just_unlocked: justUnlocked, overlap_warning: overlapWarning, sibling_overlap_warning: siblingOverlapWarning, page_notice: pageNotice, ...claim } = claimResult;
|
|
310
314
|
const task = await db.getTask(Number(taskId));
|
|
@@ -476,6 +480,12 @@ module.exports = function buildClaimsRouter() {
|
|
|
476
480
|
if (taskIds.length === 0) {
|
|
477
481
|
return res.fail('task_ids_required', 400);
|
|
478
482
|
}
|
|
483
|
+
// task 1004547: a batch claim binds only its first row to the session, so it
|
|
484
|
+
// cannot carry the autonomous mark row by row. A runner works one task per
|
|
485
|
+
// worker and never batch-claims, so its own login is refused here outright.
|
|
486
|
+
if (req.builder && req.builder.runner) {
|
|
487
|
+
return res.fail('runner_batch_refused', { status: 403, message: 'An Autobongos runner claims one task at a time. Use POST /claims.' });
|
|
488
|
+
}
|
|
479
489
|
if (taskIds.length > 20) {
|
|
480
490
|
// Safety cap. The optimizer doesn't return more than a handful at a time,
|
|
481
491
|
// and unlimited batches let one slow transaction lock up the table.
|
|
@@ -1184,7 +1184,7 @@ module.exports = function buildTasksRouter() {
|
|
|
1184
1184
|
`Merging triggers .github/workflows/deploy-prod.yml -> ${branding().domains.publicOrigin}. ` +
|
|
1185
1185
|
prMergeSentence(held);
|
|
1186
1186
|
const pr = await githubPush.openOrFindPullRequest({ branch, title, body });
|
|
1187
|
-
const prReads = sharedPrReads(); for (const [guard, refusalFor] of [[autoPickupFiles, autoPickupFiles.autoPickupFileRefusal], [runnerSelfGuard, runnerSelfGuard.runnerSelfEditRefusal]]) { const refusal = await refusalFor({ taskId: id, prNumber: pr.number, branch }, { getPullRequestFiles: prReads.getPullRequestFiles }); if (refusal) { await githubPrClose.closePullRequest({ number: pr.number }).catch(() => null); return res.fail(refusal.code, 409, { ...refusal, message: guard.refusalMessage(refusal) }); } } // the PR's own files: an auto-pickup round stays on its page (ADR 0371 D8, task 1004678); a runner never changes its own files (task 1004546)
|
|
1187
|
+
const prReads = sharedPrReads(); for (const [guard, refusalFor] of [[autoPickupFiles, autoPickupFiles.autoPickupFileRefusal], [runnerSelfGuard, runnerSelfGuard.runnerSelfEditRefusal]]) { const refusal = await refusalFor({ taskId: id, prNumber: pr.number, branch, publisherIsRunner: !!(req.builder && req.builder.runner) }, { getPullRequestFiles: prReads.getPullRequestFiles }); if (refusal) { await githubPrClose.closePullRequest({ number: pr.number }).catch(() => null); return res.fail(refusal.code, 409, { ...refusal, message: guard.refusalMessage(refusal) }); } } // the PR's own files: an auto-pickup round stays on its page (ADR 0371 D8, task 1004678); a runner never changes its own files (task 1004546), whoever's claim it is when a runner login publishes (task 1004547)
|
|
1188
1188
|
// Best-effort by contract (pr-assign.js never rejects); the catch is for a future
|
|
1189
1189
|
// edit that forgets — an assignment must not be able to fail a pushed ship.
|
|
1190
1190
|
const assignment = await prAssign.assignPullRequest({ number: pr.number, login: builderLogin })
|