@bongos/core 1.17.3 → 1.18.3
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 +212 -332
- package/.devcontainer/healthcheck.sh +0 -0
- package/.devcontainer/init-firewall.sh +0 -0
- package/.devcontainer/post-create.sh +0 -0
- package/GOVERNANCE.md +1 -1
- package/README.md +26 -22
- package/bin/bongos.js +0 -0
- package/config/branding.neutral.json +5 -1
- package/docker-entrypoint.sh +0 -0
- package/docs/adr/0142-project-context-is-prose-only.md +41 -0
- package/docs/adr/0143-onboarding-repo-picker-oauth-scope.md +35 -0
- package/docs/adr/README.md +6 -0
- package/docs/api/openapi.json +1630 -632
- package/docs/api-reference.md +50 -15
- package/docs/file-map.md +0 -18
- package/docs/onboarding/diagrams/05-versioning.mmd +4 -6
- package/docs/onboarding/diagrams/assertions.json +5 -9
- package/docs/recipes/packaging-the-core.md +13 -0
- package/docs/recipes/upgrading-the-core.md +5 -2
- package/migrations/039_newcomer_friendly_column.sql +5 -0
- package/migrations/102_remove_box_first_provision_approval.sql +4 -0
- package/migrations/core_192_github_oauth_tokens.sql +33 -0
- package/modules/hall-ui/public/builders.js +37 -0
- package/modules/hall-ui/public/goals-page.js +98 -176
- package/modules/hall-ui/public/goals.css +183 -0
- package/modules/hall-ui/public/goals.html +35 -261
- package/modules/hall-ui/public/goals.js +7 -2
- package/modules/hall-ui/public/hall-widgets.js +12 -4
- package/modules/hall-ui/public/my-projects.html +78 -0
- package/modules/hall-ui/public/my-projects.js +142 -0
- package/modules/hall-ui/public/scouting.html +45 -0
- package/modules/hall-ui/public/scouting.js +73 -0
- package/modules/hall-ui/public/settings.css +355 -0
- package/modules/hall-ui/public/settings.html +86 -414
- package/modules/hall-ui/public/settings.js +96 -35
- package/modules/hall-ui/public/style.css +31 -0
- package/modules/hall-ui/public/watch.css +184 -0
- package/modules/hall-ui/public/watch.html +111 -285
- package/modules/hall-ui/public/watch.js +59 -21
- package/modules/status-ui/public/explore.html +54 -0
- package/modules/status-ui/public/explore.js +67 -0
- package/package-lock.json +2 -2
- package/package.json +1 -1
- package/public-landing/create.html +292 -19
- package/public-landing/index.html +11 -76
- package/scripts/cron/style_guide_audit.sh +0 -0
- package/scripts/gds/api.js +0 -0
- package/scripts/gds/architect-audit.js +0 -0
- package/scripts/gds/audit-authorship.sh +0 -0
- package/scripts/gds/audit-replay.sh +0 -0
- package/scripts/gds/box.js +0 -0
- package/scripts/gds/capture.js +0 -0
- package/scripts/gds/cli-lib.js +11 -5
- package/scripts/gds/conductor-dispatch.js +0 -0
- package/scripts/gds/coreB-carve-proof.sh +0 -0
- package/scripts/gds/db-backup-nightly.sh +0 -0
- package/scripts/gds/db-backup-offsite.sh +0 -0
- package/scripts/gds/doctor.js +0 -0
- package/scripts/gds/grade-smoke.js +0 -0
- package/scripts/gds/hooks/pre-push.js +0 -0
- package/scripts/gds/install-git-hooks.js +0 -0
- package/scripts/gds/lint-migrations.js +102 -0
- package/scripts/gds/login.js +42 -10
- package/scripts/gds/main-audit.js +0 -0
- package/scripts/gds/mirror-redact.js +5 -0
- package/scripts/gds/oauth-secret.js +0 -0
- package/scripts/gds/onboarding-analyze.js +0 -0
- package/scripts/gds/onboarding-ship.js +0 -0
- package/scripts/gds/package-core.js +263 -4
- package/scripts/gds/paste-token.js +0 -0
- package/scripts/gds/portability-smoke-art.sh +0 -0
- package/scripts/gds/portability-smoke-memory.sh +0 -0
- package/scripts/gds/provision.js +270 -11
- package/scripts/gds/publish-manifest.js +15 -0
- package/scripts/gds/push-main.js +0 -0
- package/scripts/gds/render-ideas.js +0 -0
- package/scripts/gds/run-unit-tests.js +38 -14
- package/scripts/gds/security-baseline-check.sh +0 -0
- package/scripts/gds/session.js +0 -0
- package/scripts/gds/setup.js +41 -0
- package/scripts/gds/ship.js +126 -32
- package/scripts/gds/smoke-batch-claim.sh +0 -0
- package/scripts/gds/smoke-batch-release.sh +0 -0
- package/scripts/gds/smoke-box.sh +0 -0
- package/scripts/gds/smoke-claim-consistency.sh +0 -0
- package/scripts/gds/smoke-dependencies.sh +0 -0
- package/scripts/gds/smoke-write.sh +0 -0
- package/scripts/gds/upgrade.js +147 -5
- package/scripts/hall-preview/server.js +18 -1
- package/scripts/migrate.sh +10 -0
- package/scripts/migrate_cost_ledger.sh +0 -0
- package/scripts/render-diagrams.sh +0 -0
- package/scripts/security/dep-audit.js +0 -0
- package/scripts/setup-builder.js +0 -0
- package/scripts/setup-builder.sh +0 -0
- package/scripts/snapshots/maybe-render-on-deploy.sh +0 -0
- package/src/bongos/auth.js +362 -5
- package/src/bongos/db.js +66 -0
- package/src/bongos/github-repos.js +93 -0
- package/src/bongos/routes/auth.js +93 -11
- package/src/bongos/routes/github.js +90 -0
- package/src/bongos/routes/instance.js +15 -3
- package/src/bongos/routes.js +2 -0
- package/src/branding.js +17 -2
- package/src/instance-config.js +16 -0
- package/src/module-api.js +48 -1
- package/tests/branding.mjs +29 -23
- package/tests/github_repos_helpers.mjs +91 -0
- package/tests/github_token_store.mjs +121 -0
- package/tests/idp_device_exchange.mjs +105 -0
- package/tests/idp_federation.mjs +100 -0
- package/tests/migrations_forward_safe.mjs +86 -0
- package/tests/module_api.mjs +1 -1
- package/tests/package_core.mjs +246 -1
- package/tests/provision.mjs +226 -0
- package/tests/pruned_lockfile_integrity.mjs +79 -0
- package/tests/ship_ci_deploy.mjs +60 -0
- package/tests/upgrade.mjs +254 -5
- package/.gitignore +0 -91
- package/scripts/hall-preview/fixtures/access-requests.json +0 -1
- package/scripts/hall-preview/fixtures/achievements.json +0 -76
- package/scripts/hall-preview/fixtures/analytics__builder.json +0 -251
- package/scripts/hall-preview/fixtures/audit-log.json +0 -1
- package/scripts/hall-preview/fixtures/boxes__cost-ledger.json +0 -1
- package/scripts/hall-preview/fixtures/builders__active-claims.json +0 -1
- package/scripts/hall-preview/fixtures/builders__directory.json +0 -81
- package/scripts/hall-preview/fixtures/builders__roster.json +0 -1
- package/scripts/hall-preview/fixtures/goals.json +0 -502
- package/scripts/hall-preview/fixtures/goals__25.json +0 -96
- package/scripts/hall-preview/fixtures/goals__26.json +0 -67
- package/scripts/hall-preview/fixtures/goals__3.json +0 -103
- package/scripts/hall-preview/fixtures/goals__35.json +0 -49
- package/scripts/hall-preview/fixtures/goals__conflicts.json +0 -154
- package/scripts/hall-preview/fixtures/goals__detail.json +0 -96
- package/scripts/hall-preview/fixtures/goals__inbox.json +0 -5
- package/scripts/hall-preview/fixtures/goals__requests.json +0 -3
- package/scripts/hall-preview/fixtures/grades__by-builder.json +0 -1
- package/scripts/hall-preview/fixtures/inbox.json +0 -330
- package/scripts/hall-preview/fixtures/instance.json +0 -124
- package/scripts/hall-preview/fixtures/leaderboard.json +0 -184
- package/scripts/hall-preview/fixtures/me.json +0 -476
- package/scripts/hall-preview/fixtures/me__recent-ships.json +0 -304
- package/scripts/hall-preview/fixtures/override-requests.json +0 -1
- package/scripts/hall-preview/fixtures/provisioning__fleet.json +0 -1
- package/scripts/hall-preview/fixtures/provisioning__fleet__cost-ledger.json +0 -1
- package/scripts/hall-preview/fixtures/provisioning__instances.json +0 -1
- package/scripts/hall-preview/fixtures/public__analytics__ecosystem.json +0 -516
- package/scripts/hall-preview/fixtures/public__bounty-table.json +0 -37
- package/scripts/hall-preview/fixtures/public__cost-summary.json +0 -742
- package/scripts/hall-preview/fixtures/public__estimation-drift.json +0 -41
- package/scripts/hall-preview/fixtures/public__grades.json +0 -50
- package/scripts/hall-preview/fixtures/public__progress.json +0 -124
- package/scripts/hall-preview/fixtures/public__recent-shipped.json +0 -426
- package/scripts/hall-preview/fixtures/public__repo-health.json +0 -160
- package/scripts/hall-preview/fixtures/public__repo-info.json +0 -5
- package/scripts/hall-preview/fixtures/security__docs.json +0 -1
- package/scripts/hall-preview/fixtures/security__reports.json +0 -1
- package/scripts/hall-preview/fixtures/sessions__search.json +0 -1
- package/scripts/hall-preview/fixtures/tasks.json +0 -2420
- package/scripts/hall-preview/fixtures/tasks__claimable.json +0 -2555
- package/scripts/hall-preview/fixtures/tasks__detail.json +0 -111
- package/scripts/hall-preview/fixtures/tasks__peer-votes__feed.json +0 -330
- package/scripts/hall-preview/fixtures/versions.json +0 -89
package/docs/api-reference.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
# GDS API reference
|
|
4
4
|
|
|
5
|
-
> **Generated from the live route files** — the route file is authoritative.
|
|
5
|
+
> **Generated from the live route files** — the route file is authoritative. 245 endpoints across 41 route files.
|
|
6
6
|
> Machine-readable spec: [`docs/api/openapi.json`](api/openapi.json) (OpenAPI 3.1). Rendered docs site: **`/docs`** (e.g. `cloudbongos.com/docs`).
|
|
7
7
|
|
|
8
8
|
Base path: `/api/bongos`. Ranks (enforced server-side, [ADR 0016](adr/<redacted>.md)): `public` < `any-builder` < `metic+archon` < `archon`.
|
|
@@ -34,7 +34,7 @@ Base path: `/api/bongos`. Ranks (enforced server-side, [ADR 0016](adr/<redacted>
|
|
|
34
34
|
|---|---|---|---|---|
|
|
35
35
|
| GET | `/api/bongos/audit-log` | `archon` | — | GET /api/gds/audit-log?limit=&offset=&builder_id=&method= Paginated, newest-first. |
|
|
36
36
|
|
|
37
|
-
## `auth` (
|
|
37
|
+
## `auth` (16)
|
|
38
38
|
|
|
39
39
|
| Method | Path | Rank | Body | Description |
|
|
40
40
|
|---|---|---|---|---|
|
|
@@ -43,6 +43,7 @@ Base path: `/api/bongos`. Ranks (enforced server-side, [ADR 0016](adr/<redacted>
|
|
|
43
43
|
| POST | `/api/bongos/auth/app-pair/poll` | `public` | `poll_token` | poll with the secret poll_token; the token IS the bearer (mirrors /auth/device/poll, where the device_code is the bearer). |
|
|
44
44
|
| POST | `/api/bongos/auth/app-pair/start` | `public` | `device_name`, `platform` | starts a pairing; returns opaque codes only, no identity. |
|
|
45
45
|
| POST | `/api/bongos/auth/cli-token/issue` | `any-builder` | — | POST /auth/cli-token/issue — V3.R91 / task 401. |
|
|
46
|
+
| POST | `/api/bongos/auth/device/exchange` | `public` | `assertion` | POST /auth/device/exchange — CLI federation (ADR 0141 §1). |
|
|
46
47
|
| POST | `/api/bongos/auth/device/poll` | `public` | `device_code` | auth flow; the device code itself is the bearer. |
|
|
47
48
|
| POST | `/api/bongos/auth/device/start` | `public` | — | /auth/device — CLI flow rank: public — auth flow itself; identity establishment, not authorization. |
|
|
48
49
|
| GET | `/api/bongos/auth/discord/callback` | `any-builder` | — | completes the link to the caller's own identity. |
|
|
@@ -145,13 +146,6 @@ Base path: `/api/bongos`. Ranks (enforced server-side, [ADR 0016](adr/<redacted>
|
|
|
145
146
|
|---|---|---|---|---|
|
|
146
147
|
| POST | `/api/bongos/cost` | `any-builder` | `task_id`, `amount_usd`, `category`, `description`, `source`, `source_ref`, `recorded_at`, `fresh_input_usd`, `cache_read_usd`, `cache_write_usd`, `output_usd`, `builder_id`, `skill_name` | log cost on own claim (idempotent via source/source_ref). |
|
|
147
148
|
|
|
148
|
-
## `demo` (2)
|
|
149
|
-
|
|
150
|
-
| Method | Path | Rank | Body | Description |
|
|
151
|
-
|---|---|---|---|---|
|
|
152
|
-
| GET | `/api/bongos/demo/health` | `public` | — | READ — liveness + the core version this module was mounted against. |
|
|
153
|
-
| POST | `/api/bongos/demo/ping` | `metic+archon` | `note` | WRITE — EVERY module write route MUST be rank-gated (the BV1.R44 fitness check reds the build on an ungated module write route). |
|
|
154
|
-
|
|
155
149
|
## `dependencies` (2)
|
|
156
150
|
|
|
157
151
|
| Method | Path | Rank | Body | Description |
|
|
@@ -181,6 +175,13 @@ Base path: `/api/bongos`. Ranks (enforced server-side, [ADR 0016](adr/<redacted>
|
|
|
181
175
|
| GET | `/api/bongos/gate-approvals` | `archon` | — | GET /gate-approvals — open PRs awaiting owner approval (gate-review red), with the verdict + per-file reasons + changed files + diff link. |
|
|
182
176
|
| POST | `/api/bongos/gate-approvals/:pr/approve` | `archon` | — | POST /gate-approvals/:pr/approve — record owner approval for a stuck gate PR and re-run the gate-review check so it clears. |
|
|
183
177
|
|
|
178
|
+
## `github` (2)
|
|
179
|
+
|
|
180
|
+
| Method | Path | Rank | Body | Description |
|
|
181
|
+
|---|---|---|---|---|
|
|
182
|
+
| GET | `/api/bongos/github/repos` | `any-builder` | — | acts only on the caller's OWN GitHub identity (the token they granted). |
|
|
183
|
+
| POST | `/api/bongos/github/repos` | `any-builder` | `name` | creates a repo in the caller's OWN account. |
|
|
184
|
+
|
|
184
185
|
## `goals` (24)
|
|
185
186
|
|
|
186
187
|
| Method | Path | Rank | Body | Description |
|
|
@@ -263,18 +264,13 @@ Base path: `/api/bongos`. Ranks (enforced server-side, [ADR 0016](adr/<redacted>
|
|
|
263
264
|
| POST | `/api/bongos/llm-cache/lookup` | `metic+archon` | `cache_key`, `tokens_saved_est` | POST /llm-cache/lookup — hit/miss + atomic hit_count bump. |
|
|
264
265
|
| POST | `/api/bongos/llm-cache/store` | `metic+archon` | `spec`, `result_stdout`, `result_cost_usd` | POST /llm-cache/store — upsert a freshly-produced result. |
|
|
265
266
|
|
|
266
|
-
## `me` (
|
|
267
|
+
## `me` (21)
|
|
267
268
|
|
|
268
269
|
| Method | Path | Rank | Body | Description |
|
|
269
270
|
|---|---|---|---|---|
|
|
270
271
|
| GET | `/api/bongos/me` | `any-builder` | — | PMS-V2 task 188: response now also carries `unlocked` (server-joined achievement metadata) + `locked_with_progress` (server-computed huma… |
|
|
271
272
|
| GET | `/api/bongos/me/achievements` | `any-builder` | — | The builder's unlocked achievements (joined to achievement metadata). |
|
|
272
273
|
| POST | `/api/bongos/me/anthropic-link` | `any-builder` | `anthropic_email`, `anthropic_user_id` | V3.R10 (task 235), criterion C3 — link the authed builder's Anthropic account. |
|
|
273
|
-
| GET | `/api/bongos/me/art-key` | `any-builder` | — | Shared art key for newcomers (task 1281 / ADR 0068). |
|
|
274
|
-
| GET | `/api/bongos/me/art-key/own` | `any-builder` | — | Masked metadata for the browser: { set, last4, set_at, storage_configured }. |
|
|
275
|
-
| PUT | `/api/bongos/me/art-key/own` | `any-builder` | `key` | Set or replace the builder's own key. |
|
|
276
|
-
| DELETE | `/api/bongos/me/art-key/own` | `any-builder` | — | Remove the builder's own key (back to "not set"). |
|
|
277
|
-
| POST | `/api/bongos/me/art-key/storage-init` | `archon` | — | Archon-only: provision the server's secret-box master key so per-builder key storage can turn on (task 1398, blocker 41). |
|
|
278
274
|
| PATCH | `/api/bongos/me/disciplines` | `any-builder` | `preferred_disciplines` | Self-service edit of the authenticated builder's preferred disciplines (migrations 027 + 086 / V3.R80). |
|
|
279
275
|
| GET | `/api/bongos/me/display-name` | `any-builder` | — | Per-builder DISPLAY NAME (task 1669). |
|
|
280
276
|
| PATCH | `/api/bongos/me/display-name` | `any-builder` | _undocumented_ | PATCH the display name. |
|
|
@@ -315,6 +311,17 @@ Base path: `/api/bongos`. Ranks (enforced server-side, [ADR 0016](adr/<redacted>
|
|
|
315
311
|
| POST | `/api/bongos/modules/:key/submit` | `metic+archon` | `signed_by` | POST /api/gds/modules/:key/submit — ADR 0107 §1 upstreaming submission. |
|
|
316
312
|
| GET | `/api/bongos/modules/submissions` | `metic+archon` | — | GET /api/gds/modules/submissions?status=&module_key= — the upstreaming review queue (task 1771 reads this). |
|
|
317
313
|
|
|
314
|
+
## `my-projects` (6)
|
|
315
|
+
|
|
316
|
+
| Method | Path | Rank | Body | Description |
|
|
317
|
+
|---|---|---|---|---|
|
|
318
|
+
| GET | `/api/bongos/my-projects` | `any-builder` | — | the caller's OWN cross-project memberships (own data). |
|
|
319
|
+
| POST | `/api/bongos/my-projects/:clientId/leave` | `any-builder` | — | leave a project from the caller's OWN membership list. |
|
|
320
|
+
| GET | `/api/bongos/my-projects/invites` | `any-builder` | — | the caller's OWN pending invitations (ADR 0141 §5). |
|
|
321
|
+
| POST | `/api/bongos/my-projects/invites/:clientId/accept` | `any-builder` | — | accept an invite (pending → builder) for the caller's OWN account. |
|
|
322
|
+
| POST | `/api/bongos/my-projects/invites/:clientId/decline` | `any-builder` | — | decline an invite (delete the pending row) for the caller's OWN account. |
|
|
323
|
+
| POST | `/api/bongos/my-projects/join` | `any-builder` | `origin` | request to join a project. |
|
|
324
|
+
|
|
318
325
|
## `override-requests` (2)
|
|
319
326
|
|
|
320
327
|
| Method | Path | Rank | Body | Description |
|
|
@@ -322,6 +329,16 @@ Base path: `/api/bongos`. Ranks (enforced server-side, [ADR 0016](adr/<redacted>
|
|
|
322
329
|
| GET | `/api/bongos/override-requests` | `archon` | — | GET /override-requests?status=open — Archon queue. |
|
|
323
330
|
| POST | `/api/bongos/override-requests/:id/decide` | `archon` | `decision`, `note` | POST /override-requests/:id/decide — body: { decision: 'approve'\|'deny', note? } On approve, atomically flips the task completed→confirme… |
|
|
324
331
|
|
|
332
|
+
## `projects` (5)
|
|
333
|
+
|
|
334
|
+
| Method | Path | Rank | Body | Description |
|
|
335
|
+
|---|---|---|---|---|
|
|
336
|
+
| GET | `/api/bongos/projects` | `archon` | — | the full curation list (includes unfeatured + owner attribution). |
|
|
337
|
+
| POST | `/api/bongos/projects` | `archon` | `origin`, `name`, `tagline`, `art_url` | create / update a catalog entry (manual seed for hand-wired instances; federated projects auto-catalogue at registration). |
|
|
338
|
+
| PATCH | `/api/bongos/projects/:id/featured` | `archon` | `featured` | the feature / unfeature control (the ADR 0141 §5 curation gate). |
|
|
339
|
+
| GET | `/api/bongos/projects/featured` | `public` | — | a curated public showcase; no auth by design. |
|
|
340
|
+
| POST | `/api/bongos/projects/invite` | `archon` | `client_id`, `github_login` | invite a builder into a project (ADR 0141 §5, task #1002115). |
|
|
341
|
+
|
|
325
342
|
## `provisioning` (13)
|
|
326
343
|
|
|
327
344
|
| Method | Path | Rank | Body | Description |
|
|
@@ -363,6 +380,12 @@ Base path: `/api/bongos`. Ranks (enforced server-side, [ADR 0016](adr/<redacted>
|
|
|
363
380
|
| GET | `/api/bongos/public/uptime` | `public` | — | Uptime: current status + 90-day history bucketed by hour. |
|
|
364
381
|
| GET | `/api/bongos/public/versions` | `public` | — | read-only surface for status.example.com. |
|
|
365
382
|
|
|
383
|
+
## `scouting` (1)
|
|
384
|
+
|
|
385
|
+
| Method | Path | Rank | Body | Description |
|
|
386
|
+
|---|---|---|---|---|
|
|
387
|
+
| GET | `/api/bongos/scouting` | `archon` | — | the internal talent directory across every project. |
|
|
388
|
+
|
|
366
389
|
## `search` (2)
|
|
367
390
|
|
|
368
391
|
| Method | Path | Rank | Body | Description |
|
|
@@ -393,6 +416,18 @@ Base path: `/api/bongos`. Ranks (enforced server-side, [ADR 0016](adr/<redacted>
|
|
|
393
416
|
| GET | `/api/bongos/sessions/mine` | `any-builder` | — | your OWN sessions (self-serve; no audit needed). |
|
|
394
417
|
| GET | `/api/bongos/sessions/search` | `archon` | — | cross-builder corpus search (BFG-principal posture until 6C.1). |
|
|
395
418
|
|
|
419
|
+
## `sso` (7)
|
|
420
|
+
|
|
421
|
+
| Method | Path | Rank | Body | Description |
|
|
422
|
+
|---|---|---|---|---|
|
|
423
|
+
| POST | `/api/bongos/sso/activity/rollup` | `public` | `client_id`, `client_secret`, `github_id`, `credits`, `tasks_shipped`, `karma`, `rank`, `disciplines` | POST /sso/activity/rollup — a federated instance reports a builder's activity snapshot (ADR 0141 §4). |
|
|
424
|
+
| GET | `/api/bongos/sso/authorize` | `public` | — | GET /sso/authorize?client_id=&redirect_uri=&state= — the browser authorize leg. |
|
|
425
|
+
| POST | `/api/bongos/sso/device/poll` | `public` | `device_code` | POST /sso/device/poll — poll the hub device flow. |
|
|
426
|
+
| POST | `/api/bongos/sso/device/start` | `public` | `origin` | POST /sso/device/start — begin CLI federation. |
|
|
427
|
+
| POST | `/api/bongos/sso/membership/check-in` | `public` | `client_id`, `client_secret`, `github_id`, `github_login`, `display_name`, `avatar_url`, `role` | POST /sso/membership/check-in — a federated instance reports, on every sign-in, that a builder builds on its project (ADR 0141 §3). |
|
|
428
|
+
| GET | `/api/bongos/sso/pubkey` | `public` | — | GET /sso/pubkey — the hub's Ed25519 assertion-verification key (public). |
|
|
429
|
+
| POST | `/api/bongos/sso/token` | `public` | `client_id`, `client_secret`, `code`, `redirect_uri` | POST /sso/token — server-to-server code redemption. |
|
|
430
|
+
|
|
396
431
|
## `tasks` (27)
|
|
397
432
|
|
|
398
433
|
| Method | Path | Rank | Body | Description |
|
package/docs/file-map.md
CHANGED
|
@@ -364,24 +364,6 @@ tests/
|
|
|
364
364
|
<!-- BEGIN GENERATED FILE-MAP .claude/scheduled-tasks/ (scripts/gds/gen-file-map.js — do not hand-edit; notes live in docs/file-map.notes.json) -->
|
|
365
365
|
```
|
|
366
366
|
.claude/scheduled-tasks/
|
|
367
|
-
├── bfg/SKILL.md ← (MAS Phase 6, ADR 0026) BFG hygiene + read-the-room + steward routine: doc-vs-reality checks, memory hygiene, cross-builder learning. Read-mostly.
|
|
368
|
-
├── bfg-session-eval/SKILL.md ← (6D.3, ADR 0027) BFG session-inefficiency evaluator: search the session corpus, deep-dive wasteful sessions (ceremony-vs-work + footguns), file systemic findings. Read-only.
|
|
369
|
-
├── box-dormant-reclaim/SKILL.md ← (#598/ADR 0031) daily: deprovision dev boxes parked past the dormant threshold (pings the builder). Drives `box.js sweep-dormant --apply`. Control-plane only.
|
|
370
|
-
├── box-idle-suspend/SKILL.md ← (#598/ADR 0031) every 15 min: snapshot-and-park dev boxes idle past the idle threshold. Drives `box.js sweep-idle --apply`. Control-plane only.
|
|
371
|
-
├── core-update-subscription/SKILL.md ← (task 2150 / ADR 0136) daily: patch-only auto-upgrade of subscribed consumer instances (config/update-subscriptions.json) via `bongos upgrade --registry` with auto-rollback. Deterministic; opt-in + autonomy-gated (default OFF). Control-plane only.
|
|
372
|
-
├── dep-audit-nightly/SKILL.md ← autonomous nightly dependency-vulnerability scan on the droplet (`scripts/security/dep-audit.js --report-mode=nightly`) across npm + the devbox app
|
|
373
|
-
├── diagram-drift/SKILL.md ← belt-and-braces backstop for the onboarding diagrams — all five auto-regenerate on deploy, so this only flags any residual staleness
|
|
374
|
-
├── idea-triage-nightly/SKILL.md ← nightly autonomous walk of the idea_inbox; promotes high-confidence bugs/cleanups, discards obvious noise, defers ambiguous ideas
|
|
375
|
-
├── main-audit/SKILL.md ← (SEC #863 / ADR 0043) nightly post-push audit of `main` — flags commits where a sub-Metic builder edited a permission-sensitive surface
|
|
376
|
-
├── newcomer-floor/SKILL.md ← deterministic on-claim replenisher for the three evergreen newcomer chores (engineer/artist/ideator) — no cron; restocks when one is claimed (task 1168)
|
|
377
|
-
├── newcomer-generator/SKILL.md ← keep the newcomer_friendly task queue populated (C1) — deterministic generator tops the queue back up to its floor
|
|
378
|
-
├── overnight-builder/SKILL.md ← (#358) autonomous overnight session-runner: claims the highest-priority autonomous-fit task, works it in a fresh sub-agent, ships, re-polls. Archon-only. Runbook: docs/recipes/overnight-builder.md
|
|
379
|
-
├── overnight-code-review/SKILL.md ← nightly read-only code review; routes each finding into the idea_inbox (one row per finding; title prefix `[review YYYY-MM-DD]`)
|
|
380
|
-
├── peer-vote-tally/SKILL.md ← (V3.R25 / #245, C2) weekly tally of builder-on-builder peer votes into karma; folds votes ≥7 days old into karma_log
|
|
381
|
-
├── repo-simplify-sweep/SKILL.md ← weekly autonomous repo-cleanliness janitor: runs repo-metrics, files dead-code findings to the idea_inbox, auto-fixes the narrow safe class (unused vars/imports)
|
|
382
|
-
├── security-review-weekly/SKILL.md ← (V3.R69 / #288) autonomous weekly security-state review — surfaces stale vulnerability_reports + other stale-security signals
|
|
383
|
-
├── skill-usage-review/SKILL.md ← nightly skill-usage feedback loop: aggregates 24h of skill invocations, detects friction (over-invocation, errors), files findings
|
|
384
|
-
└── stale-claim-release/SKILL.md ← auto-release GDS claims whose session_pulses heartbeat went silent ≥ GDS_STALE_CLAIM_HOURS (default 6h); runs every 15 min on the droplet
|
|
385
367
|
```
|
|
386
368
|
<!-- END GENERATED FILE-MAP .claude/scheduled-tasks/ -->
|
|
387
369
|
|
|
@@ -7,21 +7,19 @@ flowchart TB
|
|
|
7
7
|
POOL --> VERSIONS
|
|
8
8
|
subgraph VERSIONS["Every task inherits its version; role/discipline is the work-type axis"]
|
|
9
9
|
direction TB
|
|
10
|
-
v_V1["V1 —
|
|
10
|
+
v_V1["V1 — building"]
|
|
11
11
|
v_PMS_V1["PMS-V1 — shipped"]
|
|
12
12
|
v_V1 --> v_PMS_V1
|
|
13
13
|
v_PMS_V2["PMS-V2 — shipped"]
|
|
14
14
|
v_PMS_V1 --> v_PMS_V2
|
|
15
15
|
v_GDS_V3["GDS-V3 — shipped"]
|
|
16
16
|
v_PMS_V2 --> v_GDS_V3
|
|
17
|
-
v_V2["V2 — planning"]
|
|
18
|
-
v_GDS_V3 --> v_V2
|
|
19
|
-
v_V3["V3 — planning"]
|
|
20
|
-
v_V2 --> v_V3
|
|
21
17
|
v_GDS_V4["GDS-V4 — frozen"]
|
|
22
|
-
|
|
18
|
+
v_GDS_V3 --> v_GDS_V4
|
|
23
19
|
v_BONGOS_V1["BONGOS-V1 — building"]
|
|
24
20
|
v_GDS_V4 --> v_BONGOS_V1
|
|
21
|
+
v_CB_V1["CB-V1 — building"]
|
|
22
|
+
v_BONGOS_V1 --> v_CB_V1
|
|
25
23
|
end
|
|
26
24
|
VERSIONS --> CLOSE["Version close — all done_when_criteria satisfied"]
|
|
27
25
|
CLOSE --> ARCHIVE["Archive scope to limitations/*.md; status=shipped"]
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
"versions": [
|
|
48
48
|
{
|
|
49
49
|
"id": "V1",
|
|
50
|
-
"status": "
|
|
50
|
+
"status": "building"
|
|
51
51
|
},
|
|
52
52
|
{
|
|
53
53
|
"id": "PMS-V1",
|
|
@@ -61,14 +61,6 @@
|
|
|
61
61
|
"id": "GDS-V3",
|
|
62
62
|
"status": "shipped"
|
|
63
63
|
},
|
|
64
|
-
{
|
|
65
|
-
"id": "V2",
|
|
66
|
-
"status": "planning"
|
|
67
|
-
},
|
|
68
|
-
{
|
|
69
|
-
"id": "V3",
|
|
70
|
-
"status": "planning"
|
|
71
|
-
},
|
|
72
64
|
{
|
|
73
65
|
"id": "GDS-V4",
|
|
74
66
|
"status": "frozen"
|
|
@@ -76,6 +68,10 @@
|
|
|
76
68
|
{
|
|
77
69
|
"id": "BONGOS-V1",
|
|
78
70
|
"status": "building"
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
"id": "CB-V1",
|
|
74
|
+
"status": "building"
|
|
79
75
|
}
|
|
80
76
|
]
|
|
81
77
|
},
|
|
@@ -26,12 +26,25 @@ Every file is **redacted** through the same fail-closed pipeline the public mirr
|
|
|
26
26
|
bongos package-core # from HEAD, version = platform CORE_VERSION
|
|
27
27
|
bongos package-core --ref origin/main --version 1.13.0
|
|
28
28
|
node scripts/gds/package-core.js --droplet-ip <ip> # add the prod IP as an exact gate literal
|
|
29
|
+
bongos package-core --self-verify # after building, prove the artifact reproduces its pin
|
|
30
|
+
bongos package-core --self-verify --self-verify-boot # ALSO npm-install the .tgz + boot /healthz
|
|
29
31
|
```
|
|
30
32
|
|
|
31
33
|
`--ref` chooses the source commit (default `HEAD`), `--out-dir` the output dir (default `dist`), `--version` overrides the stamped version. `stdout` carries a one-line JSON pin (`{ core_version, source_commit, tree_sha256, tarball }`) for CI/scripts to capture; human detail goes to `stderr`.
|
|
32
34
|
|
|
35
|
+
`--self-verify` (task [#1002218](https://example.com/builders#/task/1002218), audit H3) closes the produce-side of the integrity loop: after writing the artifact it **unpacks the built `.tgz` and recomputes `tree_sha256`, asserting it equals the manifest** (+ the on-disk `.tgz` bytes vs `tarball.sha256`) — proving the packager's own output reproduces its pin before it is trusted or published (a mismatch exits non-zero, ahead of the `--publish` leg). It is deterministic and network-free. Add `--self-verify-boot` to *also* `npm install` the tarball into a throwaway consumer and boot `/healthz` (reuses [`tests/consumer_layout_boot.mjs`](../../tests/consumer_layout_boot.mjs); needs npm/registry access — the deeper standing CI gate is task [#1002221](https://example.com/builders#/task/1002221)).
|
|
36
|
+
|
|
33
37
|
If the no-leak gate fails, it names the file + the residual literal. Fix the redaction rules ([`scripts/gds/mirror-redact.js`](../../scripts/gds/mirror-redact.js)) or the manifest exclusions ([`scripts/gds/publish-manifest.js`](../../scripts/gds/publish-manifest.js)) and re-run — do not weaken the gate to force a pass.
|
|
34
38
|
|
|
39
|
+
**The neutral floor** (task [#1002217](https://example.com/builders#/task/1002217), audit H4). Because the trunk carries no `config/branding.json`, the *branding-derived* redaction would strip nothing — so `package-core.js` always injects a fixed **`PRIOR_INSTANCE_FLOOR`** (prior-instance tokens/owners) into the doc-redaction + no-leak gate. Published **docs** are de-branded against it and the gate **fails closed** if a floor literal survives, even with no branding.json. **Functional** files still ship verbatim (the R88 fix) and are instead surfaced by the non-fatal `[leak-scan]` (task 1002220). To retire a new prior-instance token, add it to `PRIOR_INSTANCE_FLOOR` (kept in `package-core.js`, never in `mirror-redact.js` — that file's self-leak invariant forbids hardcoded literals).
|
|
40
|
+
|
|
41
|
+
## Prove it boots (the standing PROVE-PUBLISH gates)
|
|
42
|
+
|
|
43
|
+
Two standing gates keep "a published core boots clean from a bare install" honest (task [#1002221](https://example.com/builders#/task/1002221), audit H1/H2):
|
|
44
|
+
|
|
45
|
+
- **`node scripts/gds/run-unit-tests.js --integration`** — the integration-smoke gate. Runs the heavier integration set (longer per-test budget), including [`tests/consumer_layout_boot.mjs`](../../tests/consumer_layout_boot.mjs), which packages the core, `npm install`s the `.tgz`, and boots `/healthz` from the real consumer layout. Run it per release / on a schedule in an env that provides the services (network, and — for the deeper DB leg tracked as a follow-up — Postgres). The default `run-unit-tests.js` (no flag) stays the fast DB-free unit gate and *excludes* this set.
|
|
46
|
+
- **[`tests/pruned_lockfile_integrity.mjs`](../../tests/pruned_lockfile_integrity.mjs)** — a network-free unit guard (runs in the default gate every PR) that rebuilds the shipped pruned lockfile and asserts every registry package keeps a **well-formed, verbatim `integrity` hash**. This is the exact R88 regression (redaction once blanked those base64 hashes → `npm ci` could no longer verify) caught before a consumer's install ever fails.
|
|
47
|
+
|
|
35
48
|
## Consume + pin it (the R85 side)
|
|
36
49
|
|
|
37
50
|
A downstream instance repo:
|
|
@@ -9,11 +9,12 @@
|
|
|
9
9
|
1. **pre-flight** — module-compat vs the target core + a clean git tree (skip with `--force`).
|
|
10
10
|
2. **bump the pin** — vendor the new `bongos-core-<version>.tgz` and rewrite the `"@bongos/core": "file:vendor/…"` dependency.
|
|
11
11
|
3. **`npm install`** — `node_modules/@bongos/core` becomes the new version.
|
|
12
|
+
3b. **verify the integrity pin** (task [#1002216](https://example.com/builders#/task/1002216)) — recompute `tree_sha256` over the installed core and check the vendored `.tgz` bytes against `tarball.sha256`, comparing to the trusted reference manifest (the committed `vendor/…manifest.json`; the installed inner manifest for `--registry`). Runs **before** migrate so a corrupted core never touches the DB. A **mismatch is fatal → rollback**; a missing reference warns (fatal with `--require-pin`); opt out with `--skip-pin-verify`.
|
|
12
13
|
4. **`npm run migrate`** — the core's `migrate.sh` applies additive `core_*` migrations (merged three-root: core + instance + modules).
|
|
13
14
|
5. **materialize `.claude/`** — refresh skills/settings/hooks from the new core (`materializeClaude`), rewriting invocations to the `bongos` bin.
|
|
14
15
|
6. **restart** — `--service <unit>` or `--restart-cmd "<cmd>"`.
|
|
15
|
-
7. **verify** — installed version == target
|
|
16
|
-
8. **auto-rollback on failure** (task [#2149](https://example.com/builders#/task/2149), default ON) — if `npm install
|
|
16
|
+
7. **verify** — installed version == target + the **mandatory post-restart health check** (task [#1002222](https://example.com/builders#/task/1002222)): a bump that restarts the service **requires `--health-url <url>`** (it can't report success without confirming the new core serves). Opt out explicitly with `--no-health-check`; a bump with no managed restart needs no URL (it reports the new core installed-but-unconfirmed). A still-failing health poll fails the bump (auto-rollback).
|
|
17
|
+
8. **auto-rollback on failure** (task [#2149](https://example.com/builders#/task/2149), default ON) — if `npm install`/pin-verify/`migrate` fails or the step-7 health check fails, revert the pin → reinstall the previous core → restart → re-verify → write a `rolled_back:` ledger row. Opt out with `--no-rollback-on-failure`. See the section below.
|
|
17
18
|
|
|
18
19
|
Run bare (`bongos upgrade`, no `--to`) it stays the module-compat **pre-check** only.
|
|
19
20
|
|
|
@@ -63,6 +64,8 @@ By default (`--rollback-on-failure`, ON unless `--no-rollback-on-failure`) the c
|
|
|
63
64
|
|
|
64
65
|
**The DB is NOT rolled back — only the code pin.** Core migrations are additive + forward-safe (the core migration rule), so an already-applied migration is left in place; a *failed* migration is never recorded in `schema_migrations`, so a retry re-runs it cleanly. The reversal is recorded via the always-present `note` column (not a new `outcome` column) so it lands even in the failed-migrate path — where a newer column wouldn't yet exist on that instance.
|
|
65
66
|
|
|
67
|
+
> **The forward-safe rule is now enforced, not just documented** (task [#1002223](https://example.com/builders#/task/1002223), audit H10). A core migration that DROPs/RENAMEs/retypes existing state (which would strand the rolled-back old code on the new schema) fails the [`tests/migrations_forward_safe.mjs`](../../tests/migrations_forward_safe.mjs) unit gate unless it carries an explicit `-- forward-unsafe: <reason>` acknowledgement pragma. `migrate.sh` also prints a non-fatal notice at apply time (via [`scripts/gds/lint-migrations.js`](../../scripts/gds/lint-migrations.js)). Additive migrations (the norm) need no annotation.
|
|
68
|
+
|
|
66
69
|
**Proven live on demo.cloudbongos.com** (task [#2157](https://example.com/builders#/task/2157)): demo, on rollback-capable 1.17.3, was upgraded to a canary carrying a deliberately-failing migration. Migrate raised → the channel auto-reverted the pin to 1.17.3, reinstalled + restarted it, `/healthz` stayed 200 (**zero downtime** — the failure was at migrate, before the restart), and a `rolled_back` ledger row was written. This is the safety gate the unattended patch-only auto-upgrade subscription (task [#2150](https://example.com/builders#/task/2150)) depends on.
|
|
67
70
|
|
|
68
71
|
## Subscribing to updates — unattended patch-only auto-upgrade (task 2150 / ADR 0136)
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
-- 039_newcomer_friendly_column.sql — V3.R15: tasks.newcomer_friendly column +
|
|
2
2
|
-- view-level filter + Xenos claim-policy error code.
|
|
3
3
|
--
|
|
4
|
+
-- forward-unsafe: rename-column (RENAME tasks.xenos_claimable → newcomer_friendly). Historical
|
|
5
|
+
-- (V3.R15, 2026), already applied on every instance long before `bongos upgrade`'s code-only
|
|
6
|
+
-- rollback existed — no core version a current rollback could revert to reads the old column
|
|
7
|
+
-- name. Acknowledged per audit H10 / task 1002223 (scripts/gds/lint-migrations.js).
|
|
8
|
+
--
|
|
4
9
|
-- Context: V3.R15 (#239) was planned as the row-level "newcomer-friendly task"
|
|
5
10
|
-- gate for the Xenos rank. In parallel, #360 / ADR 0018 (migration 029) shipped
|
|
6
11
|
-- the same idea under the name `xenos_claimable`. Now V3.R15 closes by:
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
-- 102_remove_box_first_provision_approval.sql — ADR 0059 (task 1141): REMOVE the
|
|
2
2
|
-- dev-box "first-box Archon approval" gate. Reverts migration 071.
|
|
3
3
|
--
|
|
4
|
+
-- forward-unsafe: drop-column (box_intents.approved_by / approved_at). Historical (ADR 0059, task
|
|
5
|
+
-- 1141); the code that read those columns was removed in the SAME change, and it predates
|
|
6
|
+
-- `bongos upgrade`'s code-only rollback. Acknowledged per audit H10 / task 1002223.
|
|
7
|
+
--
|
|
4
8
|
-- Context
|
|
5
9
|
-- -------
|
|
6
10
|
-- Migration 071 (#717, ADR 0035 Decision 2) added a 'pending_approval' state to
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
-- core_192_github_oauth_tokens.sql — short-lived, encrypted GitHub repo tokens for
|
|
2
|
+
-- the onboarding wizard (task 1002099, ADR 0143).
|
|
3
|
+
--
|
|
4
|
+
-- The wizard (public-landing/create.html) opts into `public_repo` at GitHub sign-in
|
|
5
|
+
-- so it can LIST the signed-in user's repos (adopt) and CREATE an empty repo (fresh)
|
|
6
|
+
-- — things `read:user` cannot do. That user-to-server GitHub token is held here
|
|
7
|
+
-- BRIEFLY: one row per builder, the token encrypted with secret-box (master key in
|
|
8
|
+
-- server env only — a DB dump alone decrypts nothing), with a short expires_at (one
|
|
9
|
+
-- wizard sitting). It is read back by the repo picker/creator over the next few
|
|
10
|
+
-- minutes and deleted on use; getGithubToken lazily sweeps an expired row so the
|
|
11
|
+
-- table self-cleans without a cron. ON DELETE CASCADE ties a token to its builder.
|
|
12
|
+
--
|
|
13
|
+
-- This is the AUTH system's OWN handshake token (not a feature's third-party API
|
|
14
|
+
-- key like the art module's Gemini key, ADR 0102), so it lives in core. When
|
|
15
|
+
-- secret-box is unconfigured no row is ever written and the wizard falls back to
|
|
16
|
+
-- manual repo entry (ADR 0143).
|
|
17
|
+
--
|
|
18
|
+
-- Idempotent: safe to re-run.
|
|
19
|
+
|
|
20
|
+
CREATE TABLE IF NOT EXISTS github_oauth_tokens (
|
|
21
|
+
builder_id bigint PRIMARY KEY REFERENCES builders(id) ON DELETE CASCADE,
|
|
22
|
+
token_enc text NOT NULL,
|
|
23
|
+
scope text,
|
|
24
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
25
|
+
expires_at timestamptz NOT NULL
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
-- The read/sweep hot path filters on expiry.
|
|
29
|
+
CREATE INDEX IF NOT EXISTS idx_github_oauth_tokens_expires
|
|
30
|
+
ON github_oauth_tokens (expires_at);
|
|
31
|
+
|
|
32
|
+
INSERT INTO schema_migrations (version) VALUES ('core_192_github_oauth_tokens')
|
|
33
|
+
ON CONFLICT (version) DO NOTHING;
|
|
@@ -1886,6 +1886,39 @@
|
|
|
1886
1886
|
window.OTBAttention?.refresh();
|
|
1887
1887
|
}
|
|
1888
1888
|
|
|
1889
|
+
// ---- Home "Next up" slice (task 2184) -------------------------------------
|
|
1890
|
+
|
|
1891
|
+
// Fill the top of the "Your work" card with the first two rows of the
|
|
1892
|
+
// claimable queue (server order: priority, then calibrated estimate) so Home
|
|
1893
|
+
// answers "what's my next action". Best-effort: a primer-gated 403, an auth
|
|
1894
|
+
// hiccup, or an empty queue hides the slice — Home never shows an error for
|
|
1895
|
+
// it. Re-runs with every loadAll (SSE nudges keep it current).
|
|
1896
|
+
async function loadNextUp() {
|
|
1897
|
+
const wrap = document.getElementById('home-next');
|
|
1898
|
+
const list = document.getElementById('home-next-list');
|
|
1899
|
+
const subhead = document.getElementById('home-recent-subh');
|
|
1900
|
+
if (!wrap || !list) return;
|
|
1901
|
+
try {
|
|
1902
|
+
const resp = await getJSON(`${API}/tasks/claimable`, { softAuth: true });
|
|
1903
|
+
const rows = (resp && Array.isArray(resp.claimable) ? resp.claimable : []).slice(0, 2);
|
|
1904
|
+
if (!rows.length) { wrap.hidden = true; if (subhead) subhead.hidden = true; return; }
|
|
1905
|
+
const cur = (window.__BRANDING__ && window.__BRANDING__.currency && window.__BRANDING__.currency.label) || 'credits';
|
|
1906
|
+
list.innerHTML = rows.map((t) => {
|
|
1907
|
+
const credits = window.OTBBranding?.taskCreditValue?.(t) ?? t.credits_reward;
|
|
1908
|
+
const mins = t.est_minutes ? ` · ~${escapeHtml(String(t.est_minutes))}m` : '';
|
|
1909
|
+
return `<li class="next-up__item">
|
|
1910
|
+
<a class="next-up__title" href="/task/${encodeURIComponent(t.id)}">${escapeHtml(t.title || `task ${t.id}`)}</a>
|
|
1911
|
+
<span class="next-up__meta">#${escapeHtml(String(t.id))}${mins} · ${fmtNum(credits)} ${escapeHtml(cur)} est.</span>
|
|
1912
|
+
</li>`;
|
|
1913
|
+
}).join('');
|
|
1914
|
+
wrap.hidden = false;
|
|
1915
|
+
if (subhead) subhead.hidden = false;
|
|
1916
|
+
} catch (_) {
|
|
1917
|
+
wrap.hidden = true;
|
|
1918
|
+
if (subhead) subhead.hidden = true;
|
|
1919
|
+
}
|
|
1920
|
+
}
|
|
1921
|
+
|
|
1889
1922
|
// ---- leaderboard ---------------------------------------------------------
|
|
1890
1923
|
|
|
1891
1924
|
// Locked at 8 for V2 (per limitations/pms-v2.md). Hardcoding here avoids an
|
|
@@ -2225,6 +2258,10 @@
|
|
|
2225
2258
|
// /me because it spans all builders' work), loaded fire-and-forget so a
|
|
2226
2259
|
// slow/failed feed can't hold up the rest of the hall.
|
|
2227
2260
|
loadAcclaimFeed();
|
|
2261
|
+
// task 2184: the Home "Next up" slice — top of the claimable queue, so the
|
|
2262
|
+
// page answers "what's my next action" without a trip to the Work board.
|
|
2263
|
+
// Fire-and-forget; hides itself when the feed is gated (primer 403) or empty.
|
|
2264
|
+
loadNextUp();
|
|
2228
2265
|
|
|
2229
2266
|
// #408: build the sticky nav now that every section has settled its
|
|
2230
2267
|
// hidden state (welcome → karma → onboarding → security/roster).
|