@bongos/core 1.24.40 → 1.24.42
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 +103 -103
- package/docs/canonical-permissions.md +2 -1
- package/docs/copy-inventory.md +198 -223
- package/docs/copy-registry.json +316 -580
- package/docs/module-api-changelog.md +4 -0
- package/docs/page-inventory.json +11 -69
- package/docs/page-readings.json +348 -728
- package/modules/hall-ui/public/ai-studio.html +2 -2
- package/modules/hall-ui/public/atlas.html +2 -2
- package/modules/hall-ui/public/blockers.html +2 -2
- package/modules/hall-ui/public/board-room.html +2 -2
- package/modules/hall-ui/public/builders.js +17 -262
- package/modules/hall-ui/public/city.html +2 -2
- package/modules/hall-ui/public/collab.html +2 -2
- package/modules/hall-ui/public/commands.html +2 -2
- package/modules/hall-ui/public/copy-desk.html +2 -2
- package/modules/hall-ui/public/craft-mode.js +1 -1
- package/modules/hall-ui/public/deploy.html +2 -2
- package/modules/hall-ui/public/gate.js +12 -5
- package/modules/hall-ui/public/goal-map.html +2 -2
- package/modules/hall-ui/public/goals.html +2 -2
- package/modules/hall-ui/public/government.html +2 -2
- package/modules/hall-ui/public/hall-render.js +3 -248
- package/modules/hall-ui/public/hall-widgets.js +3 -14
- package/modules/hall-ui/public/idea.html +2 -2
- package/modules/hall-ui/public/ideas.html +2 -2
- package/modules/hall-ui/public/index.html +4 -5
- package/modules/hall-ui/public/market-watch-item.html +2 -2
- package/modules/hall-ui/public/market-watch-rules.html +2 -2
- package/modules/hall-ui/public/market-watch.html +2 -2
- package/modules/hall-ui/public/modules.html +2 -2
- package/modules/hall-ui/public/money.html +2 -2
- package/modules/hall-ui/public/my-agents.html +2 -2
- package/modules/hall-ui/public/palette.js +10 -0
- package/modules/hall-ui/public/primer.html +2 -2
- package/modules/hall-ui/public/profile.html +2 -2
- package/modules/hall-ui/public/project-settings.html +2 -2
- package/modules/hall-ui/public/roadmap.html +2 -2
- package/modules/hall-ui/public/roster.html +2 -2
- package/modules/hall-ui/public/sessions.js +21 -10
- package/modules/hall-ui/public/settings.html +2 -2
- package/modules/hall-ui/public/setup-gate.js +156 -0
- package/modules/hall-ui/public/shell.js +17 -3
- package/modules/hall-ui/public/street.html +2 -2
- package/modules/hall-ui/public/studio.html +2 -2
- package/modules/hall-ui/public/style.css +85 -117
- package/modules/hall-ui/public/task.html +2 -2
- package/modules/hall-ui/public/thinking.html +2 -2
- package/modules/hall-ui/public/tweak-editor.html +2 -2
- package/modules/hall-ui/public/watch.html +120 -7
- package/modules/hall-ui/public/watch.js +11 -0
- package/modules/hall-ui/public/watch.states.json +49 -1
- package/modules/hall-ui/public/work.html +2 -2
- package/modules/hall-ui/records/setup-gate.md +43 -0
- package/modules/lifecycle/routes/tasks.js +2 -2
- package/modules/onboarding/onboarding-state.js +41 -20
- package/package-lock.json +2 -2
- package/package.json +1 -1
- package/release-notes.json +12 -0
- package/scripts/bongos/gen-hall-sitemap.js +2 -0
- package/src/bongos/routes/me.js +2 -2
- package/src/bongos/serve-internal.js +15 -22
- package/src/module-api.js +1 -1
- package/tests/autonomy_builder_scope.mjs +2 -1
- package/tests/hall_audit.mjs +1 -1
- package/tests/hall_board_world.mjs +1 -1
- package/tests/hall_landing_boot.mjs +2 -3
- package/tests/hall_loading.mjs +13 -2
- package/tests/hall_nav.mjs +5 -2
- package/tests/hall_onboarding_bongos_setup.mjs +14 -14
- package/tests/hall_oversight_tabs.mjs +162 -0
- package/tests/hall_oversight_world.mjs +23 -9
- package/tests/hall_page_gate_map.mjs +7 -2
- package/tests/hall_roster_world.mjs +14 -9
- package/tests/hall_sessions_ledger.mjs +2 -1
- package/tests/module_contributions.mjs +4 -2
- package/tests/nav_permission_atoms.mjs +4 -2
- package/tests/onboarding_state.mjs +33 -0
- package/tests/sessions_kit_pager.mjs +8 -4
- package/tests/setup_flow.mjs +242 -0
- package/tests/welcome_boot.mjs +3 -2
- package/modules/hall-ui/public/gate.html +0 -76
- package/modules/hall-ui/public/gate.states.json +0 -60
- package/modules/hall-ui/public/sessions.html +0 -128
- package/modules/hall-ui/public/sessions.states.json +0 -59
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
<meta charset="utf-8">
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
6
6
|
<title>Watch — {{worldName}}</title>
|
|
7
|
-
<meta name="description" content="Archon oversight for {{worldName}} — access requests, security, stale claims, reviews, and
|
|
7
|
+
<meta name="description" content="Archon oversight for {{worldName}} — access requests, security, stale claims, reviews, repo health, sessions and the Autobongos runner.">
|
|
8
8
|
<!-- The hub's origin, for the link from a guild's head in the applications queue to
|
|
9
9
|
its page on the hub (task 1002304). Empty on a vanilla instance: no link. -->
|
|
10
10
|
<meta name="hub-origin" content="{{hubOrigin}}">
|
|
@@ -18,6 +18,9 @@
|
|
|
18
18
|
shared .stat-row/.stat-tile + hall-kit rules. -->
|
|
19
19
|
<link rel="stylesheet" href="/builders/oversight.css">
|
|
20
20
|
<link rel="stylesheet" href="/builders/watch.css">
|
|
21
|
+
<!-- task 1005049: the Sessions and Autobongos tabs bring their pages' own sheets. -->
|
|
22
|
+
<link rel="stylesheet" href="/builders/sessions.css">
|
|
23
|
+
<link rel="stylesheet" href="/builders/gate.css">
|
|
21
24
|
</head>
|
|
22
25
|
<body data-page="watch" data-page-title="Watch">
|
|
23
26
|
|
|
@@ -49,7 +52,7 @@
|
|
|
49
52
|
<a class="stat-tile" href="#people"><span class="stat-tile__label">Access requests</span><span class="stat-tile__num" id="att-access">—</span><span class="stat-tile__sub">pending, on the People tab</span></a>
|
|
50
53
|
<a class="stat-tile" href="#security"><span class="stat-tile__label">Security reports</span><span class="stat-tile__num" id="att-security">—</span><span class="stat-tile__sub">open, on the Security tab</span></a>
|
|
51
54
|
<a class="stat-tile" href="/roster?claims=stale"><span class="stat-tile__label">Stale claims</span><span class="stat-tile__num" id="att-stale">—</span><span class="stat-tile__sub">builders, on the Builders page</span></a>
|
|
52
|
-
<a class="stat-tile" href="#
|
|
55
|
+
<a class="stat-tile" href="#sessions"><span class="stat-tile__label">Sessions</span><span class="stat-tile__num" id="att-sessions">—</span><span class="stat-tile__sub">recorded, on the Sessions tab</span></a>
|
|
53
56
|
</div>
|
|
54
57
|
|
|
55
58
|
<!-- task 2173: the nine surfaces sit behind three OTBKit tabs, hash-synced
|
|
@@ -89,10 +92,10 @@
|
|
|
89
92
|
always fetched and used to throw away (task 1003469). -->
|
|
90
93
|
<section class="scroll" id="sessions-scroll" aria-labelledby="sessions-h" hidden>
|
|
91
94
|
<h2 id="sessions-h" class="scroll__h">Sessions</h2>
|
|
92
|
-
<p class="scroll__lede">A tally of recorded work sessions, and the latest five. The full record
|
|
95
|
+
<p class="scroll__lede">A tally of recorded work sessions, and the latest five. The full record is on the Sessions tab.</p>
|
|
93
96
|
<div id="sessions-stats" class="ov-figs"><span class="kit-skel"></span></div>
|
|
94
97
|
<div id="sessions-recent"></div>
|
|
95
|
-
<p class="ov-foot"><a href="
|
|
98
|
+
<p class="ov-foot"><a href="#sessions">View all sessions</a></p>
|
|
96
99
|
</section>
|
|
97
100
|
|
|
98
101
|
<!-- 7. REPO HEALTH -->
|
|
@@ -147,6 +150,113 @@
|
|
|
147
150
|
<div id="surveyor-body"></div>
|
|
148
151
|
</section>
|
|
149
152
|
</div>
|
|
153
|
+
<!-- ============ tab: Sessions (task 1005049: was the /sessions page) ============ -->
|
|
154
|
+
<div id="pane-sessions" role="tabpanel" aria-labelledby="tab-sessions" hidden>
|
|
155
|
+
<!-- Every section below starts hidden, so the tab says it is loading until one shows. -->
|
|
156
|
+
<p class="hall-loading hall-loading--page hall-loading--wait" role="status">Loading…</p>
|
|
157
|
+
<!-- Access notice — shown by sessions.js when the viewer is below the
|
|
158
|
+
floor. The heading and the line are written from the pack's rank
|
|
159
|
+
label (ADR 0157: metic and up), so the static text never renders. -->
|
|
160
|
+
<section class="scroll" id="sess-sealed" aria-labelledby="sess-sealed-h" hidden>
|
|
161
|
+
<h2 id="sess-sealed-h" class="scroll__h">Higher ranks only</h2>
|
|
162
|
+
<p class="scroll__lede" id="sess-sealed-body">The session log opens from a higher rank.</p>
|
|
163
|
+
</section>
|
|
164
|
+
|
|
165
|
+
<!-- Totals — the shell's glass strip at the top of the page (the way
|
|
166
|
+
Watch and Gate carry theirs), not a strip inside a panel. -->
|
|
167
|
+
<section class="ov-summary" id="stats-scroll" aria-labelledby="stats-h" hidden>
|
|
168
|
+
<h2 id="stats-h" class="sr-only">Totals</h2>
|
|
169
|
+
<div class="stat-row" id="stats-body"></div>
|
|
170
|
+
</section>
|
|
171
|
+
|
|
172
|
+
<!-- Every recorded session — the corpus table. No wrapper: the shell's
|
|
173
|
+
card strip scrolls a wide ledger on a phone, and the old wrapper
|
|
174
|
+
turned the sticky header into a scrollport overlay on desktop. -->
|
|
175
|
+
<section class="scroll" id="sess-ledger-scroll" aria-labelledby="sess-ledger-h" hidden>
|
|
176
|
+
<h2 id="sess-ledger-h" class="scroll__h">Recorded sessions</h2>
|
|
177
|
+
<!-- The count, and a failed load, sit here: the page head that used to carry
|
|
178
|
+
them is hidden (task 1004829). -->
|
|
179
|
+
<p class="scroll__lede" id="ledger-status" role="status" aria-live="polite">Loading sessions…</p>
|
|
180
|
+
<!-- task 1003975: the ledger's first filter. It LOOKS like the pager's
|
|
181
|
+
per-page control on purpose (one control grammar per page) but wears
|
|
182
|
+
its own class — the hall_audit guard reads `class="pager…"` as a
|
|
183
|
+
hand-rolled pager, and it is right to: borrowing that family is how a
|
|
184
|
+
second pager implementation starts. Its options are filled from the
|
|
185
|
+
server's vocabulary in sessions.js, never hardcoded here, where they
|
|
186
|
+
would drift from what the route accepts. -->
|
|
187
|
+
<div class="ledger-filters">
|
|
188
|
+
<label class="ledger-filter">
|
|
189
|
+
<span>Kind</span>
|
|
190
|
+
<select id="session-type-filter" aria-label="Filter sessions by kind"></select>
|
|
191
|
+
</label>
|
|
192
|
+
</div>
|
|
193
|
+
<table class="ledger" id="sessions-table">
|
|
194
|
+
<thead>
|
|
195
|
+
<tr>
|
|
196
|
+
<th>Session</th><th>Builder</th>
|
|
197
|
+
<th title="What the session did, derived from its own transcript: whether it wrote files, used tools, and how many prompts a person actually sent.">Kind</th>
|
|
198
|
+
<th>Tasks</th>
|
|
199
|
+
<th class="ledger__num">Earned</th><th class="ledger__num">Turns</th><th class="ledger__num">Tokens</th><th class="ledger__num">Tool errors</th>
|
|
200
|
+
<th class="ledger__num">Duration</th>
|
|
201
|
+
<th class="ledger__num" title="How the session read to this builder, scored against their own interaction profile. Advisory — it gates nothing.">Plain speech</th>
|
|
202
|
+
<th>Recorded</th>
|
|
203
|
+
</tr>
|
|
204
|
+
</thead>
|
|
205
|
+
<tbody id="sessions-body"></tbody>
|
|
206
|
+
</table>
|
|
207
|
+
<!-- The kit stamps the pager bar here (sessions.js, OTBKit.pagerBarHtml).
|
|
208
|
+
makeLedger is deliberately NOT used: it stamps table + pager into one
|
|
209
|
+
mount, and this page keeps them separate so the bar sits below the
|
|
210
|
+
ledger rather than inside whatever scrollport the table is in. -->
|
|
211
|
+
<div id="sessions-pager-mount"></div>
|
|
212
|
+
<p class="ledger__note" id="ledger-foot"></p>
|
|
213
|
+
</section>
|
|
214
|
+
|
|
215
|
+
<!-- task 1002830: the narrative. Opened from a row's Read door; the SAME page
|
|
216
|
+
and the same gate as the ledger above (ADR 0051 — no second page). The
|
|
217
|
+
server decides who may read a transcript and records an administrator's
|
|
218
|
+
cross-builder read BEFORE serving it; this panel only displays. -->
|
|
219
|
+
<section class="scroll" id="transcript-scroll" aria-labelledby="transcript-h" hidden>
|
|
220
|
+
<h2 id="transcript-h" class="scroll__h">Transcript</h2>
|
|
221
|
+
<p class="scroll__lede" id="transcript-sub"></p>
|
|
222
|
+
<p><button type="button" class="btn" id="transcript-close">Close transcript</button></p>
|
|
223
|
+
<div id="transcript-body" class="transcript"></div>
|
|
224
|
+
<p><button type="button" class="btn" id="transcript-more" hidden>Load more turns</button></p>
|
|
225
|
+
</section>
|
|
226
|
+
|
|
227
|
+
</div>
|
|
228
|
+
|
|
229
|
+
<!-- ============ tab: Autobongos (task 1005049: was the /gate page) ============ -->
|
|
230
|
+
<div id="pane-autobongos" role="tabpanel" aria-labelledby="tab-autobongos" hidden>
|
|
231
|
+
<p class="hall-loading hall-loading--page hall-loading--wait" role="status">Loading…</p>
|
|
232
|
+
<!-- task 1003469: the sealed state is a panel with a heading, not a bare
|
|
233
|
+
line on the ground. gate.js writes the real floor into the lede from
|
|
234
|
+
the pack's rank label, so the copy cannot drift from ADR 0157. -->
|
|
235
|
+
<section class="scroll" id="gate-sealed" aria-labelledby="gate-sealed-h" hidden>
|
|
236
|
+
<h2 class="scroll__h" id="gate-sealed-h">Restricted</h2>
|
|
237
|
+
<p class="scroll__lede" id="gate-sealed-body">This page opens at a higher rank.</p>
|
|
238
|
+
</section>
|
|
239
|
+
|
|
240
|
+
<section id="runner-body" hidden>
|
|
241
|
+
<!-- The Autobongos fence (task 1003908, ADR 0307 §6): what is allowed to
|
|
242
|
+
reach main unattended. This page held the held-PR list too until task
|
|
243
|
+
1004859 removed it; the URL stays /gate so bookmarks keep working.
|
|
244
|
+
Archon-only — a Metic gets the note below instead, and the routes
|
|
245
|
+
behind the panel are system:true/archon server-side regardless. -->
|
|
246
|
+
<p class="scroll__lede" id="gate-archon-only" hidden></p>
|
|
247
|
+
<section class="scroll" id="fence-panel" aria-labelledby="fence-h" hidden>
|
|
248
|
+
<h2 class="scroll__h" id="fence-h">Autobongos runner</h2>
|
|
249
|
+
<!-- One panel (task 1004509): a checklist while anything the runner
|
|
250
|
+
needs is missing, one status line with the switch once it is all
|
|
251
|
+
ticked. Drawn from /autonomy/runners + /autonomy/fence together. -->
|
|
252
|
+
<div id="fence-body"><span class="kit-skel"></span></div>
|
|
253
|
+
<!-- Every builder's runner (task 1004501): what each one picked to
|
|
254
|
+
work, whether you paused it, and whether it is checking in. -->
|
|
255
|
+
<div id="fence-builders"></div>
|
|
256
|
+
</section>
|
|
257
|
+
</section>
|
|
258
|
+
|
|
259
|
+
</div>
|
|
150
260
|
</main>
|
|
151
261
|
|
|
152
262
|
<footer class="app-foot" id="app-foot"></footer>
|
|
@@ -160,14 +270,17 @@
|
|
|
160
270
|
chrome exists before the page script runs. -->
|
|
161
271
|
<script src="/builders/dom-utils.js?v=2026-10-25-escape"></script>
|
|
162
272
|
<script src="/builders/shell-trail.js?v=2026-10-08-city-tab"></script>
|
|
163
|
-
<script src="/builders/craft-mode.js?v=2026-11-05-
|
|
164
|
-
<script src="/builders/shell.js?v=2026-11-05-
|
|
273
|
+
<script src="/builders/craft-mode.js?v=2026-11-05-oversight"></script>
|
|
274
|
+
<script src="/builders/shell.js?v=2026-11-05-setup-gate"></script>
|
|
165
275
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
166
276
|
<script src="/builders/palette.js" defer></script>
|
|
167
277
|
<!-- shared component kit (window.OTBKit) — tabs, ledger, pager (task 2166). -->
|
|
168
278
|
<script src="/builders/hall-kit.js"></script>
|
|
169
279
|
<script src="/builders/task-detail.js?v=2026-07-03-taskdetail"></script>
|
|
170
280
|
<script src="/builders/brand-apply.js?v=2026-06-19-r56"></script>
|
|
171
|
-
|
|
281
|
+
<!-- task 1005049: the two tabs' scripts, booted by watch.js when their tab first opens. -->
|
|
282
|
+
<script src="/builders/sessions.js?v=2026-11-05-tab"></script>
|
|
283
|
+
<script src="/builders/gate.js?v=2026-11-05-tab"></script>
|
|
284
|
+
<script src="/builders/watch.js?v=2026-11-05-tabs"></script>
|
|
172
285
|
</body>
|
|
173
286
|
</html>
|
|
@@ -21,6 +21,9 @@
|
|
|
21
21
|
// loads independently in its own try/catch so one failing endpoint cannot
|
|
22
22
|
// break the others.
|
|
23
23
|
//
|
|
24
|
+
// TASK 1005049 folded the Sessions page (sessions.js) and the Autobongos runner
|
|
25
|
+
// panel (gate.js) in as two more tabs; /sessions and /gate redirect to them.
|
|
26
|
+
//
|
|
24
27
|
// TASK 1003469 put the page in the chrome world's composition: every list is
|
|
25
28
|
// the kit's .ledger through makeLedger (eight of nine were a page-local table
|
|
26
29
|
// that duplicated it with a hand-rolled th voice), every figure row is the oversight
|
|
@@ -1283,7 +1286,15 @@
|
|
|
1283
1286
|
{ id: 'people', label: 'People', panel: 'pane-people' },
|
|
1284
1287
|
{ id: 'operations', label: 'Operations', panel: 'pane-operations' },
|
|
1285
1288
|
{ id: 'security', label: 'Security', panel: 'pane-security' },
|
|
1289
|
+
// task 1005049 (owner decision 2026-11-03, idea 1001315): the Sessions and
|
|
1290
|
+
// Autobongos pages are tabs here. Each boots the first time it opens.
|
|
1291
|
+
{ id: 'sessions', label: 'Sessions', panel: 'pane-sessions' },
|
|
1292
|
+
{ id: 'autobongos', label: 'Autobongos', panel: 'pane-autobongos' },
|
|
1286
1293
|
],
|
|
1294
|
+
onChange: (id) => {
|
|
1295
|
+
const boot = window.OTBWatchTabs && window.OTBWatchTabs[id];
|
|
1296
|
+
if (boot) boot();
|
|
1297
|
+
},
|
|
1287
1298
|
});
|
|
1288
1299
|
}
|
|
1289
1300
|
}
|
|
@@ -15,7 +15,9 @@
|
|
|
15
15
|
"/api/(gds|bongos)/versions",
|
|
16
16
|
"/api/(gds|bongos)/watch",
|
|
17
17
|
"/api/(gds|bongos)/analytics",
|
|
18
|
-
"/api/(gds|bongos)/tasks"
|
|
18
|
+
"/api/(gds|bongos)/tasks",
|
|
19
|
+
"/api/(gds|bongos)/sessions",
|
|
20
|
+
"/api/(gds|bongos)/autonomy/"
|
|
19
21
|
],
|
|
20
22
|
"ignoreConsole": [
|
|
21
23
|
"/api/(gds|bongos)/",
|
|
@@ -92,6 +94,52 @@
|
|
|
92
94
|
"#watch-scroll"
|
|
93
95
|
]
|
|
94
96
|
}
|
|
97
|
+
},
|
|
98
|
+
"sessions": {
|
|
99
|
+
"auth": true,
|
|
100
|
+
"actions": [
|
|
101
|
+
[
|
|
102
|
+
"wait",
|
|
103
|
+
700
|
|
104
|
+
],
|
|
105
|
+
[
|
|
106
|
+
"click",
|
|
107
|
+
"#tab-sessions"
|
|
108
|
+
],
|
|
109
|
+
[
|
|
110
|
+
"wait",
|
|
111
|
+
500
|
|
112
|
+
]
|
|
113
|
+
],
|
|
114
|
+
"expect": {
|
|
115
|
+
"visible": [
|
|
116
|
+
"#pane-sessions",
|
|
117
|
+
"#stats-scroll",
|
|
118
|
+
"#sess-ledger-scroll"
|
|
119
|
+
]
|
|
120
|
+
}
|
|
121
|
+
},
|
|
122
|
+
"autobongos": {
|
|
123
|
+
"auth": true,
|
|
124
|
+
"actions": [
|
|
125
|
+
[
|
|
126
|
+
"wait",
|
|
127
|
+
700
|
|
128
|
+
],
|
|
129
|
+
[
|
|
130
|
+
"click",
|
|
131
|
+
"#tab-autobongos"
|
|
132
|
+
],
|
|
133
|
+
[
|
|
134
|
+
"wait",
|
|
135
|
+
500
|
|
136
|
+
]
|
|
137
|
+
],
|
|
138
|
+
"expect": {
|
|
139
|
+
"visible": [
|
|
140
|
+
"#pane-autobongos"
|
|
141
|
+
]
|
|
142
|
+
}
|
|
95
143
|
}
|
|
96
144
|
},
|
|
97
145
|
"reducedMotion": {
|
|
@@ -173,8 +173,8 @@
|
|
|
173
173
|
time so the chrome exists before the deferred page scripts execute. -->
|
|
174
174
|
<script src="/builders/dom-utils.js?v=2026-10-25-escape"></script>
|
|
175
175
|
<script src="/builders/shell-trail.js?v=2026-10-08-city-tab"></script>
|
|
176
|
-
<script src="/builders/craft-mode.js?v=2026-11-05-
|
|
177
|
-
<script src="/builders/shell.js?v=2026-11-05-
|
|
176
|
+
<script src="/builders/craft-mode.js?v=2026-11-05-oversight"></script>
|
|
177
|
+
<script src="/builders/shell.js?v=2026-11-05-setup-gate"></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 -->
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# The setup flow — one screen a new builder finishes once, and no setup banner on Home (task 1005076)
|
|
2
|
+
|
|
3
|
+
The owner, 2026-11-05: Home's Welcome banner (the clone / `npx bongos setup` / download Claude steps) and the
|
|
4
|
+
Getting started checklist below it stayed until a builder had shipped THREE tasks, so builders who were fully
|
|
5
|
+
set up kept seeing a setup banner across the top of the hall. The decision: a new builder is held on a setup
|
|
6
|
+
flow when they get in and goes through each step; once set up they are in for good, with no banner and no
|
|
7
|
+
reminders.
|
|
8
|
+
|
|
9
|
+
**What people see.** While `/me`'s `onboarding.setup.complete` is false, every hall page shows only
|
|
10
|
+
`setup-gate.js`'s screen: "N of 4 done", the four steps in order, the current one open with what to do, a Sign
|
|
11
|
+
out link. Each step ticks itself; the screen re-reads `/me` every 8 seconds and reloads into the hall the moment
|
|
12
|
+
setup is complete.
|
|
13
|
+
|
|
14
|
+
1. **Sign in** — always done by the time the screen can draw.
|
|
15
|
+
2. **Get the project and Claude on your machine, and link it** — a CLI session exists (`npx bongos setup`).
|
|
16
|
+
3. **Choose your role** — chosen on the screen itself, saved through `PATCH /me/disciplines`.
|
|
17
|
+
4. **Run /builder-start in Claude** — the `first_start` stage, which `GET /tasks/claimable` now marks only for
|
|
18
|
+
a CLI session (the hall's own pages read that feed from the browser and used to tick it for everyone).
|
|
19
|
+
|
|
20
|
+
**Who is never held.** Anyone graduated, anyone who has claimed a task, and any rank above xenos — every existing
|
|
21
|
+
builder goes straight in. An older server that sends no `setup` holds nobody. The rule is
|
|
22
|
+
`modules/onboarding/onboarding-state.js` `setupForApi`; the hall never re-derives it.
|
|
23
|
+
|
|
24
|
+
**How it is wired.** `shell.js` `holdForSetup` loads `setup-gate.js` on demand (`loadHallScript`, the
|
|
25
|
+
core-move-notice way), so a set-up builder never downloads it, and while it holds, neither the daily welcome
|
|
26
|
+
(`welcome-boot.js`) nor the craft picker is asked. Both `applyAccess` callers pass `setup` (`shell.js`'s own
|
|
27
|
+
`/me` probe and Home's `hall-render.js`). Its styles are `.setup-gate*` in `style.css`, on the hall tokens in
|
|
28
|
+
both modes; the overlay sits one above `--z-modal`.
|
|
29
|
+
|
|
30
|
+
**Removed.** The `welcome-scroll` and `onboarding-scroll` Home widgets, the "Show the setup guide again" link,
|
|
31
|
+
and everything that drew them: `renderWelcomeCore` / `renderOnboarding` and their helpers in `hall-render.js`;
|
|
32
|
+
`renderWelcome`, `reopenWelcomeFromNav`, `pickDiscipline`, the instance-repo loader and the checklist's /me poll
|
|
33
|
+
in `builders.js`; the `.welcome*` / `.onboarding-item*` styles. The clone block (this project's own repository
|
|
34
|
+
from `GET /instance`, never a hardcoded one) now lives on the setup screen's machine step, with Node and
|
|
35
|
+
`npm install` named before `npx bongos setup`, as the welcome panel had them. The role step says "role", the
|
|
36
|
+
word ADR 0174 fixed for that axis, through `OTB.roleAxisLabel` / `OTB.roleLabel`.
|
|
37
|
+
|
|
38
|
+
**Loaded once.** `applyAccess` can run several times before the script lands; `holdForSetup` asks for it once
|
|
39
|
+
(`setupGateLoading`), or two screens would stack.
|
|
40
|
+
|
|
41
|
+
**Tests.** `tests/setup_flow.mjs` (the claimable guard run for a CLI and a web session, the screen drawn and
|
|
42
|
+
driven, the shell loading it with nothing over it, Home with no banner), `tests/onboarding_state.mjs` (the
|
|
43
|
+
rule), `tests/welcome_boot.mjs` (the shell's ask order). Each was mutation-checked against its half of the change.
|
|
@@ -237,8 +237,8 @@ module.exports = function buildTasksRouter() {
|
|
|
237
237
|
// and forget — the response should never wait on or fail because of the
|
|
238
238
|
// onboarding write. safeMarkStage swallows errors and handles the
|
|
239
239
|
// graduation broadcast. Through the `onboarding` kernel port (BV1.R81 / ADR
|
|
240
|
-
// 0093 §1); ?. degrades to a no-op when the module is off.
|
|
241
|
-
seams.resolveOptional('onboarding')?.safeMarkStage(pool, req.builder.id, 'first_start', req.builder);
|
|
240
|
+
// 0093 §1); ?. degrades to a no-op when the module is off. CLI only (task 1005076: the hall reads this feed too).
|
|
241
|
+
if (req.gdsSession && req.gdsSession.source === 'cli') seams.resolveOptional('onboarding')?.safeMarkStage(pool, req.builder.id, 'first_start', req.builder);
|
|
242
242
|
// `claimable_total` keeps the limit honest: the length of the sliced array, never a
|
|
243
243
|
// second count query (ADR 0197).
|
|
244
244
|
res.json({ claimable, claimable_total: feed.length, active_claims: active });
|
|
@@ -79,23 +79,6 @@ const STAGES = [
|
|
|
79
79
|
const GRADUATED = 'graduated';
|
|
80
80
|
const ALL_STAGES = [...STAGES, GRADUATED];
|
|
81
81
|
|
|
82
|
-
// The pre-auth, INFORMATIONAL step that sits AHEAD of auth_complete (task 470).
|
|
83
|
-
// The state machine's first ENGINE stage is auth_complete, but the genuine
|
|
84
|
-
// first action a newcomer takes is "obtain the repo" — clone it locally. That
|
|
85
|
-
// step is manual/external
|
|
86
|
-
// (there is no server event for it) and intentionally NOT a member of STAGES, so
|
|
87
|
-
// it never gates graduation, never advances current_stage, and never appears in
|
|
88
|
-
// shapeForApi's tracked checklist. It exists purely so the system's own model of
|
|
89
|
-
// "the path into the city" begins where the path really begins. The hall renders
|
|
90
|
-
// it as a static lead-in line on the displayed checklist; the auth_complete hint
|
|
91
|
-
// above also surfaces the same clone instruction.
|
|
92
|
-
const PRE_AUTH_STEP = {
|
|
93
|
-
id: 'obtain_repo',
|
|
94
|
-
label: 'Obtain the repo',
|
|
95
|
-
hint: 'Clone the project to thy machine and run npm install in it. The build commands live inside the repo, so this comes first.',
|
|
96
|
-
informational: true,
|
|
97
|
-
};
|
|
98
|
-
|
|
99
82
|
// How many shipped tasks the terminal 'ship_three' stage requires. Kept in
|
|
100
83
|
// lockstep with db.THETES_GRADUATION_THRESHOLD (#692 / ADR 0034) so the
|
|
101
84
|
// checklist's graduation coincides with the xenos→thetes promotion. Used only
|
|
@@ -124,7 +107,7 @@ const STAGE_LABELS = {
|
|
|
124
107
|
// machine you'll build from — the /builder-* commands live INSIDE the repo, so
|
|
125
108
|
// nothing (not even sign-in via the CLI) can happen before it exists. The
|
|
126
109
|
// onboarding model never named that step, so the hint now points at it ahead of
|
|
127
|
-
// the sign-in itself.
|
|
110
|
+
// the sign-in itself. The setup flow's cli_setup step (task 1005076) carries it too.
|
|
128
111
|
const STAGE_HINTS = {
|
|
129
112
|
auth_complete: 'First obtain the repo — clone it — then sign in with npx bongos setup in that folder.',
|
|
130
113
|
pick_disciplines: 'Pick the work that calls thee — engineer, artist, ideator, or any mix.',
|
|
@@ -189,6 +172,42 @@ const DISPLAY_HINTS = {
|
|
|
189
172
|
ship_three: 'Carry three tasks through with /builder-ship — the third makes thee a Thetes.',
|
|
190
173
|
};
|
|
191
174
|
|
|
175
|
+
// ---- the setup flow (task 1005076) -------------------------------------------
|
|
176
|
+
//
|
|
177
|
+
// What a newcomer must finish before the hall opens to them (owner, 2026-11-05):
|
|
178
|
+
// the hall holds them on one setup screen until every step below is cleared, and
|
|
179
|
+
// after that they are in for good — no banner, no reminders. Each step ticks
|
|
180
|
+
// itself from a signal the server already records:
|
|
181
|
+
//
|
|
182
|
+
// signed_in — they are reading /me, so always cleared.
|
|
183
|
+
// cli_setup — a source='cli' session exists (ran `npx bongos setup`).
|
|
184
|
+
// pick_disciplines — the engine stage choosing a role marks (PATCH /me/disciplines).
|
|
185
|
+
// first_start — the engine stage, which GET /tasks/claimable marks only for a
|
|
186
|
+
// CLI session: proof /builder-start ran from Claude.
|
|
187
|
+
//
|
|
188
|
+
// Setup is also complete for anyone already past it: graduated, claimed a task
|
|
189
|
+
// (first_claim cleared), or holding any rank above xenos. Existing builders go
|
|
190
|
+
// straight in and are never held.
|
|
191
|
+
const SETUP_STEPS = [
|
|
192
|
+
{ id: 'signed_in', label: 'Sign in', hint: 'Done — you are signed in.' },
|
|
193
|
+
{ id: 'cli_setup', label: 'Get the project and Claude on your machine, and link it', hint: 'Three things on your own computer. This ticks itself once your machine is linked.' },
|
|
194
|
+
{ id: 'pick_disciplines', label: 'Choose your role', hint: 'Pick the work you want to do — engineer, artist, ideator, or any mix.' },
|
|
195
|
+
{ id: 'first_start', label: 'Run /builder-start in Claude', hint: 'Open the project in Claude and type /builder-start. This ticks itself the first time it runs, which proves everything works.' },
|
|
196
|
+
];
|
|
197
|
+
|
|
198
|
+
function setupForApi(state, { cliAuthed = false, rank = null } = {}) {
|
|
199
|
+
const completed = new Set((state && state.completed_stages) || []);
|
|
200
|
+
const current = (state && state.current_stage) || STAGES[0];
|
|
201
|
+
const cleared = (stage) => current === GRADUATED || completed.has(stage)
|
|
202
|
+
|| (STAGES.indexOf(current) > STAGES.indexOf(stage) && STAGES.indexOf(stage) >= 0);
|
|
203
|
+
const steps = SETUP_STEPS.map((s) => ({
|
|
204
|
+
...s,
|
|
205
|
+
cleared: s.id === 'signed_in' ? true : s.id === 'cli_setup' ? !!cliAuthed : cleared(s.id),
|
|
206
|
+
}));
|
|
207
|
+
const pastIt = current === GRADUATED || cleared('first_claim') || (!!rank && rank !== 'xenos');
|
|
208
|
+
return { complete: pastIt || steps.every((s) => s.cleared), steps };
|
|
209
|
+
}
|
|
210
|
+
|
|
192
211
|
// Pick the first uncompleted stage from STAGES (canonical order), or
|
|
193
212
|
// GRADUATED if all six are done. Mirrors the migration 045 backfill CASE so
|
|
194
213
|
// app-layer behaviour matches DB-layer reconstruction.
|
|
@@ -441,7 +460,9 @@ function stageDetail(stageId, shipCount) {
|
|
|
441
460
|
// 'join_discord' step (the OAuth flow sets the link).
|
|
442
461
|
// opts.cliAuthed — whether the builder has ever authenticated the GDS CLI
|
|
443
462
|
// (db.hasCliSession). Clears the 'cli_setup' step.
|
|
444
|
-
|
|
463
|
+
// opts.rank — the builder's rank; any rank above xenos counts as set up
|
|
464
|
+
// (the `setup` block, task 1005076).
|
|
465
|
+
function shapeForApi(state, { shipCount = null, discordLinked = false, cliAuthed = false, rank = null } = {}) {
|
|
445
466
|
const completed = new Set((state && state.completed_stages) || []);
|
|
446
467
|
const currentReal = (state && state.current_stage) || STAGES[0];
|
|
447
468
|
const graduated = currentReal === GRADUATED;
|
|
@@ -487,6 +508,7 @@ function shapeForApi(state, { shipCount = null, discordLinked = false, cliAuthed
|
|
|
487
508
|
progress: { cleared: clearedCount, total: DISPLAY_STEPS.length },
|
|
488
509
|
stages: display,
|
|
489
510
|
graduated,
|
|
511
|
+
setup: setupForApi(state, { cliAuthed, rank }),
|
|
490
512
|
};
|
|
491
513
|
}
|
|
492
514
|
|
|
@@ -494,7 +516,6 @@ module.exports = {
|
|
|
494
516
|
STAGES,
|
|
495
517
|
GRADUATED,
|
|
496
518
|
ALL_STAGES,
|
|
497
|
-
PRE_AUTH_STEP,
|
|
498
519
|
STAGE_HINTS,
|
|
499
520
|
DISPLAY_LABELS,
|
|
500
521
|
isKnownStage,
|
package/package-lock.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bongos/core",
|
|
3
|
-
"version": "1.24.
|
|
3
|
+
"version": "1.24.42",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@bongos/core",
|
|
9
|
-
"version": "1.24.
|
|
9
|
+
"version": "1.24.42",
|
|
10
10
|
"license": "AGPL-3.0-or-later",
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"express": "^4.21.2",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bongos/core",
|
|
3
|
-
"version": "1.24.
|
|
3
|
+
"version": "1.24.42",
|
|
4
4
|
"description": "Cloud Bongos — the AI-first build platform core (GDS + platform surfaces + module system), installed as a versioned dependency (ADR 0108).",
|
|
5
5
|
"license": "AGPL-3.0-or-later",
|
|
6
6
|
"main": "src/platform-server.js",
|
package/release-notes.json
CHANGED
|
@@ -11203,5 +11203,17 @@
|
|
|
11203
11203
|
"id": "1005048",
|
|
11204
11204
|
"text": "The Builders page is now the one list of everyone who builds here. If you hold a government seat you also see each builder's active claims, any stale claim, their standing, and the controls to change a rank or offboard someone"
|
|
11205
11205
|
}
|
|
11206
|
+
],
|
|
11207
|
+
"1.24.41": [
|
|
11208
|
+
{
|
|
11209
|
+
"id": "1005049",
|
|
11210
|
+
"text": "Watch is now the one oversight page. Sessions and Autobongos moved off the sidebar and became two tabs on Watch, next to People, Operations and Security. Old links to /sessions and /gate open the right tab. Who can see and pre"
|
|
11211
|
+
}
|
|
11212
|
+
],
|
|
11213
|
+
"1.24.42": [
|
|
11214
|
+
{
|
|
11215
|
+
"id": "1005076",
|
|
11216
|
+
"text": "New builders now get one clear setup screen they finish once, and everyone already set up no longer sees a setup banner across the top of Home."
|
|
11217
|
+
}
|
|
11206
11218
|
]
|
|
11207
11219
|
}
|
|
@@ -62,6 +62,8 @@ const ROUTES = {
|
|
|
62
62
|
'/ranks': { to: '/primer', why: 'now a Primer chapter, redirects (task 1005046)' },
|
|
63
63
|
'/drachmae': { to: '/primer', why: 'now a Primer chapter, redirects (task 1005046)' },
|
|
64
64
|
'/diagrams': { to: '/primer', why: 'now a Primer chapter, redirects; its images still serve (task 1005046)' },
|
|
65
|
+
'/sessions': { to: '/watch', why: 'now a Watch tab, redirects (task 1005049)' },
|
|
66
|
+
'/gate': { to: '/watch', why: 'Autobongos, now a Watch tab, redirects (task 1005049)' },
|
|
65
67
|
};
|
|
66
68
|
// Targets that leave the hall on purpose: sign-in, the hub's /account (platform-server.js;
|
|
67
69
|
// settings.js points the link at the hub), the API, module assets, and any file with an extension.
|
package/src/bongos/routes/me.js
CHANGED
|
@@ -535,7 +535,7 @@ module.exports = function buildMeRouter() {
|
|
|
535
535
|
// returns a stage-1 "nothing cleared" view so the client renders the
|
|
536
536
|
// checklist either way. Through the `onboarding` port (BV1.R81); null when
|
|
537
537
|
// the module is off.
|
|
538
|
-
onboarding: onboarding ? onboarding.shapeForApi(onboardingRow, { shipCount, discordLinked: !!discordLink, cliAuthed: !!cliAuthed }) : null,
|
|
538
|
+
onboarding: onboarding ? onboarding.shapeForApi(onboardingRow, { shipCount, discordLinked: !!discordLink, cliAuthed: !!cliAuthed, rank: req.builder.rank }) : null,
|
|
539
539
|
// F7 (ADR 0033): Discord link state for the hall's Connect/Unlink UI.
|
|
540
540
|
// `configured` tells the client whether the server even has Discord OAuth
|
|
541
541
|
// creds — when false the hall renders nothing (the start route 503s).
|
|
@@ -714,7 +714,7 @@ module.exports = function buildMeRouter() {
|
|
|
714
714
|
discordIsLinked(req.builder.id),
|
|
715
715
|
db.hasCliSession(req.builder.id),
|
|
716
716
|
]);
|
|
717
|
-
const onboarding = onboardingPort ? onboardingPort.shapeForApi(state, { shipCount, discordLinked: !!discordLink, cliAuthed: !!cliAuthed }) : null;
|
|
717
|
+
const onboarding = onboardingPort ? onboardingPort.shapeForApi(state, { shipCount, discordLinked: !!discordLink, cliAuthed: !!cliAuthed, rank: req.builder.rank }) : null;
|
|
718
718
|
res.json({ builder, onboarding });
|
|
719
719
|
} catch (err) {
|
|
720
720
|
if (err.code === 'invalid_discipline' || err.code === 'invalid_main_discipline') {
|
|
@@ -927,23 +927,13 @@ function mountInternalSurfaces(app) {
|
|
|
927
927
|
// The apex hands /builders/* (ADR 0036) and /deploy (task 1004736) to the hall's own host.
|
|
928
928
|
mountApexHallRedirects(app, { skip: (req) => isModuleSurfaceHost(req) || isBuildersHost(req), hostOf: (req) => siteOf(req).host });
|
|
929
929
|
|
|
930
|
-
// The /watch monitoring page
|
|
931
|
-
//
|
|
932
|
-
//
|
|
933
|
-
//
|
|
934
|
-
//
|
|
935
|
-
//
|
|
936
|
-
// (Defense in depth: every data endpoint these pages call carries its own
|
|
937
|
-
// server-side gate.)
|
|
930
|
+
// The /watch monitoring page sits behind `page.view.government` — Metic and up
|
|
931
|
+
// since ADR 0157: a builder without the permission never receives the shell
|
|
932
|
+
// (requireGovernmentPage redirects them to the hall, and an unauthenticated
|
|
933
|
+
// visitor into sign-in). Its Sessions and Autobongos tabs were the /sessions and
|
|
934
|
+
// /gate pages until task 1005049, behind this same gate. (Defense in depth: every
|
|
935
|
+
// data endpoint the page calls carries its own server-side gate.)
|
|
938
936
|
const WATCH_PAGE_RE = /^\/builders\/watch(?:\.html)?\/?$/;
|
|
939
|
-
const GATE_PAGE_RE = /^\/builders\/gate(?:\.html)?\/?$/;
|
|
940
|
-
// /sessions (the session-log ledger) belongs to that same Governance group and
|
|
941
|
-
// its data route (`session.search`) carries the same metic floor since ADR 0157
|
|
942
|
-
// — but it had NO page gate at all: sessions.js only called showSealed() after
|
|
943
|
-
// /api/bongos/me, so the shell was served to anyone who asked for the URL. The
|
|
944
|
-
// data never leaked (the route gate held), but the page was the one item in the
|
|
945
|
-
// group without a wall. Gated here so the group is uniform (task 1002710).
|
|
946
|
-
const SESSIONS_PAGE_RE = /^\/builders\/sessions(?:\.html)?\/?$/;
|
|
947
937
|
// /project-settings — the five fundamentals of the project (task 1003280, goal
|
|
948
938
|
// 1000072). Government tier, beside /watch and /sessions: it is a STEERING surface,
|
|
949
939
|
// and ADR 0157 put that floor at metic. Both writes behind it gate independently on
|
|
@@ -1049,14 +1039,18 @@ function mountInternalSurfaces(app) {
|
|
|
1049
1039
|
return res.redirect(302, `${isBuildersHost(req) ? '' : '/builders'}/market-watch${qs}#settings`);
|
|
1050
1040
|
});
|
|
1051
1041
|
|
|
1052
|
-
//
|
|
1053
|
-
|
|
1042
|
+
// Pages folded into a section of another page; 302 and no gate, as above. Task 1005047:
|
|
1043
|
+
// Fleet costs is /money#hosting. Task 1005049: Sessions and Autobongos are Watch tabs.
|
|
1044
|
+
const RETIRED_TO_SECTION = Object.freeze({ fleet: 'money#hosting', sessions: 'watch#sessions', gate: 'watch#autobongos' });
|
|
1045
|
+
const RETIRED_SECTION_RE = /^\/builders\/(fleet|sessions|gate)(?:\.html)?\/?$/;
|
|
1054
1046
|
app.use((req, res, next) => {
|
|
1055
1047
|
if (isModuleSurfaceHost(req)) return next();
|
|
1056
1048
|
if (req.method !== 'GET' && req.method !== 'HEAD') return next();
|
|
1057
|
-
|
|
1049
|
+
const m = RETIRED_SECTION_RE.exec(path.posix.normalize(req.path));
|
|
1050
|
+
if (!m) return next();
|
|
1058
1051
|
const qs = req.url.includes('?') ? req.url.slice(req.url.indexOf('?')) : '';
|
|
1059
|
-
|
|
1052
|
+
const [page, section] = RETIRED_TO_SECTION[m[1]].split('#');
|
|
1053
|
+
return res.redirect(302, `${isBuildersHost(req) ? '' : '/builders'}/${page}${qs}#${section}`);
|
|
1060
1054
|
});
|
|
1061
1055
|
|
|
1062
1056
|
// task 1005046 (owner decision 2026-11-03, idea 1001311): ONE reading room. Ranks,
|
|
@@ -1104,8 +1098,7 @@ function mountInternalSurfaces(app) {
|
|
|
1104
1098
|
if (isModuleSurfaceHost(req)) return next();
|
|
1105
1099
|
if (!req.path.startsWith('/builders')) return next();
|
|
1106
1100
|
const norm = path.posix.normalize(req.path);
|
|
1107
|
-
if (WATCH_PAGE_RE.test(norm) ||
|
|
1108
|
-
|| SESSIONS_PAGE_RE.test(norm) || PROJECT_SETTINGS_PAGE_RE.test(norm)
|
|
1101
|
+
if (WATCH_PAGE_RE.test(norm) || PROJECT_SETTINGS_PAGE_RE.test(norm)
|
|
1109
1102
|
|| MONEY_PAGE_RE.test(norm)) {
|
|
1110
1103
|
return gdsAuth.requireGovernmentPage(req, res, next);
|
|
1111
1104
|
}
|
package/src/module-api.js
CHANGED
|
@@ -81,7 +81,7 @@ const { sleep } = require('./sleep');
|
|
|
81
81
|
// MAJOR (see allowBoxScope below): passes the request through untouched.
|
|
82
82
|
function deprecatedNoopMiddleware(_req, _res, next) { next(); }
|
|
83
83
|
|
|
84
|
-
const CORE_VERSION = '1.24.
|
|
84
|
+
const CORE_VERSION = '1.24.42'; // CI auto-patch carrier (ADR 0161); changelog: docs/module-api-changelog.md
|
|
85
85
|
|
|
86
86
|
// A namespaced logger so a module's log lines are attributable + consistent.
|
|
87
87
|
// Usage: const log = api.logger('discord'); log.info('mounted');
|
|
@@ -460,7 +460,8 @@ test('the owner page draws the PROJECT fence and pauses one builder; the setting
|
|
|
460
460
|
assert.match(gate, /const fence = raw\.project \|\| raw;/, 'the switch panel must not draw the owner’s own narrowed picks as the project list');
|
|
461
461
|
assert.match(gate, /\/autonomy\/runners\/all/);
|
|
462
462
|
assert.match(gate, /\/autonomy\/builders\/\$\{encodeURIComponent\(id\)\}\/pause/);
|
|
463
|
-
|
|
463
|
+
// task 1005049: the owner panel is Watch's Autobongos tab.
|
|
464
|
+
const html = fs.readFileSync(path.join(ROOT, 'modules/hall-ui/public/watch.html'), 'utf8');
|
|
464
465
|
assert.match(html, /id="fence-builders"/);
|
|
465
466
|
|
|
466
467
|
const panel = fs.readFileSync(path.join(ROOT, 'modules/hall-ui/public/settings-autobongos.js'), 'utf8');
|
package/tests/hall_audit.mjs
CHANGED
|
@@ -233,7 +233,7 @@ test('the session log pages on the kit — the last hand-roll is gone', () => {
|
|
|
233
233
|
assert.match(js, new RegExp(`kit\\.${fn}\\(`), `sessions.js must page through the kit's ${fn}`);
|
|
234
234
|
}
|
|
235
235
|
assert.doesNotMatch(js, /const PAGE_SIZE\b/, 'its fixed page size is gone — per-page is the kit\'s now');
|
|
236
|
-
assert.match(read('
|
|
236
|
+
assert.match(read('watch.html'), /hall-kit\.js/, 'and Watch, whose Sessions tab it is (task 1005049), has to load the kit');
|
|
237
237
|
});
|
|
238
238
|
|
|
239
239
|
// ---- 6b. every hall bar series is drawn by the kit (task 1003445) ---------
|
|
@@ -350,7 +350,7 @@ function bootHallRender({ me, progress = null, leaderboard = [], ctxExtra = {} }
|
|
|
350
350
|
curLabel: (caps) => (caps ? 'Credits' : 'credits'), emptyRow: () => '', fmtDate: (d) => String(d).slice(0, 10),
|
|
351
351
|
mins: (m) => `${m}m`, normalizeRank: (r) => String(r || '').toLowerCase(), pct: (n) => `${n}%`, postJSON: async () => ({}),
|
|
352
352
|
rankLabel: (r) => r, rankWeight: () => 0, signClasses: () => '', toast() {}, usd: (n) => `$${n}`,
|
|
353
|
-
|
|
353
|
+
newcomerGated: false,
|
|
354
354
|
get lastMeState() { return me; }, get lastCostState() { return me.cost || null; }, get lastKarmaState() { return me.karma || null; },
|
|
355
355
|
get lastNeedsState() { return me.needs || null; }, get lastRebaseState() { return me.needs_rebase_tasks || null; },
|
|
356
356
|
get lastProgressState() { return progress; },
|