@bongos/core 1.19.1033 → 1.19.1034

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (100) hide show
  1. package/.bongos-core.json +186 -86
  2. package/.claude/skills/builder-start/SKILL.md +1 -1
  3. package/.claude/skills/grade-recover/SKILL.md +2 -1
  4. package/.claude/skills/grader-health/SKILL.md +4 -0
  5. package/.claude/skills/merge-mode/SKILL.md +1 -1
  6. package/docs/adr/0089-modular-multi-model-adversarial-grader.md +15 -0
  7. package/docs/adr/README.md +1 -1
  8. package/docs/api/openapi.json +1 -1
  9. package/docs/architecture.md +3 -2
  10. package/docs/canonical-permissions.md +2 -2
  11. package/docs/copy-inventory.md +34 -30
  12. package/docs/copy-registry.json +69 -33
  13. package/docs/module-api-changelog.md +3 -1
  14. package/docs/recipes/local-dev.md +45 -3
  15. package/docs/recipes/packaging-the-core.md +1 -1
  16. package/modules/autonomy/cadence.js +52 -0
  17. package/modules/government/protected-surfaces.json +1 -0
  18. package/modules/grading/grade-engine.js +267 -0
  19. package/modules/grading/grader-subagent.js +4 -3
  20. package/modules/grading/grader-workers/index.js +67 -11
  21. package/modules/grading/grader-workers/worker-verdict.js +32 -2
  22. package/modules/grading/grader.js +109 -88
  23. package/modules/hall-ui/public/deploy.js +35 -0
  24. package/modules/hall-ui/public/project-settings.css +7 -0
  25. package/modules/lifecycle/routes/tasks.js +19 -4
  26. package/modules/provisioning/control-plane-guard.js +14 -13
  27. package/modules/provisioning/core-upgrade.js +30 -17
  28. package/modules/provisioning/public-refusal.js +44 -0
  29. package/modules/provisioning/routes/disconnect.js +2 -1
  30. package/modules/provisioning/routes/env-manifest.js +5 -4
  31. package/modules/provisioning/routes/provisioning.js +16 -15
  32. package/modules/provisioning/routes/repo-private.js +2 -1
  33. package/package-lock.json +2 -2
  34. package/package.json +1 -1
  35. package/release-notes.json +70 -0
  36. package/scripts/gds/autobongos-run.js +10 -2
  37. package/scripts/gds/backfill-cost.js +20 -9
  38. package/scripts/gds/claim.js +2 -2
  39. package/scripts/gds/credential-presence.js +281 -0
  40. package/scripts/gds/deploy-main-audit-gate.sh +11 -4
  41. package/scripts/gds/dev-lib.js +212 -5
  42. package/scripts/gds/dev.js +102 -50
  43. package/scripts/gds/doctor.js +3 -2
  44. package/scripts/gds/grade-correlation-audit.js +280 -0
  45. package/scripts/gds/grade-replay.js +237 -0
  46. package/scripts/gds/hooks/pre-push.js +7 -3
  47. package/scripts/gds/main-audit.js +19 -10
  48. package/scripts/gds/memory-map.js +3 -1
  49. package/scripts/gds/onboarding-config.js +3 -2
  50. package/scripts/gds/plain-cards.js +4 -0
  51. package/scripts/gds/preflight.js +12 -4
  52. package/scripts/gds/provision-core-upgrade.js +155 -4
  53. package/scripts/gds/provision-repo-auth.js +15 -0
  54. package/scripts/gds/provision.js +1 -1
  55. package/scripts/gds/publish-credential-check.js +3 -0
  56. package/scripts/gds/push-main.js +14 -3
  57. package/scripts/gds/push-path-brief.js +3 -2
  58. package/scripts/gds/run-routine.js +18 -5
  59. package/scripts/gds/run-unit-tests.js +14 -3
  60. package/scripts/gds/session-cost.js +12 -3
  61. package/scripts/gds/ship-deploy-target.js +11 -6
  62. package/scripts/gds/ship-grade-steps.js +33 -0
  63. package/scripts/gds/ship-land.js +157 -11
  64. package/scripts/gds/ship-merge.js +3 -2
  65. package/scripts/gds/ship-preflight-steps.js +30 -8
  66. package/scripts/gds/ship.js +1 -1
  67. package/scripts/gds/upgrade.js +3 -3
  68. package/scripts/hall-preview/README.md +20 -3
  69. package/scripts/hall-preview/live-identity.js +1 -1
  70. package/scripts/hall-preview/refresh-fixtures.js +71 -11
  71. package/scripts/hall-preview/scrub-identity.js +296 -0
  72. package/src/bongos/routes/security.js +3 -3
  73. package/src/build-info.js +4 -2
  74. package/src/module-api.js +1 -1
  75. package/tests/adr_0089_scope.mjs +70 -0
  76. package/tests/autobongos_cadence.mjs +74 -0
  77. package/tests/consumer_layout_boot.mjs +363 -31
  78. package/tests/core_upgrade_door.mjs +40 -6
  79. package/tests/core_upgrade_runner.mjs +240 -4
  80. package/tests/credential_presence.mjs +153 -0
  81. package/tests/deploy_audit_gate.mjs +5 -2
  82. package/tests/deploy_page_projects.mjs +63 -2
  83. package/tests/dev_lib.mjs +2 -1
  84. package/tests/dev_windows.mjs +324 -0
  85. package/tests/env_knobs_neutral_prefix.mjs +203 -0
  86. package/tests/fixtures/grade-replay/recorded-panel-grades.json +27 -0
  87. package/tests/government_protected_surfaces.mjs +10 -0
  88. package/tests/grade_correlation_audit.mjs +159 -0
  89. package/tests/grade_engine.mjs +249 -0
  90. package/tests/grade_engine_replay.mjs +99 -0
  91. package/tests/grader_prompt_window_bound.mjs +132 -0
  92. package/tests/grader_unbacked_score.mjs +194 -0
  93. package/tests/hall_preview_scrub.mjs +214 -0
  94. package/tests/integration_parked_ratchet.mjs +24 -1
  95. package/tests/provisioning_public_refusal.mjs +195 -0
  96. package/tests/publish_status_branch.mjs +128 -0
  97. package/tests/ship_land_red_pr.mjs +236 -0
  98. package/tests/ship_preflight.mjs +67 -1
  99. package/tests/start_env_guard.mjs +16 -0
  100. package/tests/upgrade.mjs +20 -1
@@ -34,7 +34,7 @@ Delivery is now deterministic (task 1288). The **card-delivery hook** (`.claude/
34
34
 
35
35
  > **FIRST, read WHERE THIS INSTANCE'S BOARD LIVES — `config/branding.json` → `domains.buildersOrigin`.** Every route below branches on it, and getting it wrong is worse than an error. A **remote `https://` origin** means the board is **HOSTED**: it is a running website with the builder's real tasks in it. A **`localhost`** origin means the instance is genuinely local and has to be brought up. Prescribing the local cure on a hosted instance walks the builder through three obedient steps to a board that is not theirs.
36
36
 
37
- - **`bongos: command not found`, a "cannot find module" from `node scripts/gds/start.js`, or you can otherwise tell this is a fresh checkout** (a scaffolded instance whose `node_modules` is absent). The `bongos` CLI ships *inside* the not-yet-installed `@bongos/core` package, so nothing runs until deps are installed — this is the #1 fresh-clone wall. Note before prescribing anything: **`@bongos/core` is a PRIVATE package**, so a bare `npm install` **404s on any machine with no `NPM_TOKEN`**. That 404 is the expected tokenless outcome, **not** a yanked or missing version — never go hunting for "a version that still exists" to repoint the dependency at. Route by `buildersOrigin`:
37
+ - **`bongos: command not found`, a "cannot find module" from `node scripts/gds/start.js`, or you can otherwise tell this is a fresh checkout** (a scaffolded instance whose `node_modules` is absent). The `bongos` CLI ships *inside* the not-yet-installed `@bongos/core` package, so nothing runs until deps are installed — this is the #1 fresh-clone wall. Note before prescribing anything: **`@bongos/core` is a PUBLIC npm package** ([ADR 0283](../../../docs/adr/0283-the-core-publishes-publicly-because-access-was-never-the-thing-protecting-it.md), since 2026-09-13), so a bare `npm install` needs **no `NPM_TOKEN`** and no npm login. A 404 on `@bongos/core` is therefore **not** a normal outcome: it means the dependency in `package.json` names something the registry does not have (a version that was never published, a mistyped name). A local `file:` tarball that is missing fails differently (ENOENT, not a 404). Read the exact spec, tell the builder what it points at, and do not quietly repoint it at a different version. Route by `buildersOrigin`:
38
38
  - **Hosted (remote origin)** — lead with the fact that **nothing needs installing**: the board is a website, so open `<buildersOrigin>/builders` to see and claim work right now. The CLI is an optional second client and needs a token. **Never route to `bongos dev` here** — it stands up a *local* instance with its *own empty database*, so it cannot show the hosted board and quietly answers a different question than the one asked.
39
39
  - **Local (`localhost` origin)** — the instance really is local: `npm install`, then `bongos dev` (one-command local bring-up), then re-run `/builder-start`.
40
40
  Either way, don't hand-run internal scripts; the package isn't unpacked yet.
@@ -38,9 +38,10 @@ The panel could not run (worker infra outage or a pre-spawn bypass). This is **n
38
38
 
39
39
  ### Branch B — fabricated / server-shape fail: the guard tripped or an axis was forged by an error
40
40
 
41
- Two known sub-shapes, both recognizable because the "fail" carries **no substantive findings**:
41
+ Three known sub-shapes, all recognizable because the "fail" carries **no substantive findings**. First make sure it really carries none: read the top-level `issues[]` — the API has lifted the stored findings there since task 1003488 (2026-09-02). Before that, a grade READ BACK showed no `issues` at all even when the panel had filed some, which is how task 1002721's real (and wrong) Quality blocker was taken for an empty fail.
42
42
 
43
43
  - **Server-guard trip** (`signals.server_guard.tripped` non-empty, e.g. `implausible_pass`): the server downgraded a client-asserted pass it found implausible — historically this guard has fired on genuinely clean, unanimous zero-issue passes. Explain the downgrade honestly, then re-grade: `node scripts/gds/ship.js <id> --regrade`.
44
+ - **An unbacked low score** (`signals.unbacked_scores` lists it; the card reads `UNBACKED LOW SCORE`): a reviewer scored below threshold without a major/blocker finding, so the severity gate downgraded it to manual-confirm instead of a hard fail (task 1002903). There is nothing to fix. Re-grade once; if it repeats on a diff you can defend, take the override path below with your evidence.
44
45
  - **A FAIL scored around 4.5/10 with zero issues and a null/zero axis** (the errored-worker class): a worker error was forwarded as a real axis score. Same response — re-grade; the panel rerun replaces the forged shape with a real verdict. Since task 1003318 a Quality worker that never ran (a `Prompt is too long` window overflow, `error: PROMPT_TOO_LONG`) no longer forges a 0: the server records `signals.cq_lens_unavailable` with a json-null axis and the card reads `QUALITY LENS UNAVAILABLE` — re-grade or manual-confirm; a 4.5 with a 0 axis now only comes from a server predating it.
45
46
 
46
47
  If an honest re-grade re-trips the guard on a diff you can defend, use the **auditable override path** — file an override-request with a real rationale (≥20 chars; only the task's most-recent claim holder or an Archon may file; an Archon then decides it):
@@ -54,6 +54,10 @@ The evaluation found every grade ran on a generation-stale pin. Read the live pi
54
54
 
55
55
  With `--probe`, run the live panel calibration: `node scripts/gds/grade-smoke.js`. It grades known-good and known-bad fixtures against the real panel and reports miscalibration. **Costs ~$0.30–0.90 per run; Metic+ only.** Never run it implicitly — only when the user passed `--probe` or asked for a live calibration.
56
56
 
57
+ ## Related: do the workers fail differently?
58
+
59
+ This skill checks whether the grader is RUNNING well. Whether its four workers carry independent signal — or are four copies of one opinion — is a different question with its own read-only report: `node scripts/gds/grade-correlation-audit.js` (pairwise agreement + Cohen's kappa between workers, each worker's kappa against the owner's override and manual-confirm decisions, refused below a minimum sample; no model calls, Metic+ for the override read). Point the owner at it when the question is panel composition rather than health.
60
+
57
61
  ## Report shape
58
62
 
59
63
  End with a compact findings list, most severe first: axis, evidence (the numbers you read), verdict (outage / drift / anomaly / stale-pin / healthy), and the exact remediation command or the skill to hand off to (`/grade-recover` for a single stuck task; a Bongos task via `capture.js` for systemic fixes). A clean bill of health is one line per axis.
@@ -129,7 +129,7 @@ node scripts/gds/push-main.js # SEC #863: the sanctioned gated main-push (NOT
129
129
  ssh -o ConnectTimeout=10 lars@REDACTED_IP "~/deploy.sh"
130
130
  ```
131
131
 
132
- > **SEC #863 (ADR 0043):** push `main` only via `node scripts/gds/push-main.js`. A raw `git push origin main` is now blocked by the pre-push permission gate — that block is the friction that stops an ad-hoc bypass like the Builder 25 incident. `push-main.js` carries the `OTB_ALLOW_MAIN_PUSH` override because /merge-mode only ever lands tasks that already passed the grader + the Archon confirm gate. The post-push main audit (`node scripts/gds/main-audit.js`) re-checks regardless.
132
+ > **SEC #863 (ADR 0043):** push `main` only via `node scripts/gds/push-main.js`. A raw `git push origin main` is now blocked by the pre-push permission gate — that block is the friction that stops an ad-hoc bypass like the Builder 25 incident. `push-main.js` carries the `<PREFIX>_ALLOW_MAIN_PUSH` override (`BONGOS_` on a vanilla instance) because /merge-mode only ever lands tasks that already passed the grader + the Archon confirm gate. The post-push main audit (`node scripts/gds/main-audit.js`) re-checks regardless.
133
133
 
134
134
  The deploy script applies any new migrations, restarts the service, and curls /healthz.
135
135
 
@@ -114,6 +114,19 @@ The two deterministic server-side guards — route-rank ([ADR 0016](0016-trust-b
114
114
 
115
115
  The worker-contract (`buildPrompt` / `extractJson` / `computeVerdict`), the `runWorker` parallel runner, the `task_grades` + `grade_attempts` schema, the trivial-diff fast-path, and the server-side guard envelope are **kept**. This ADR generalizes their *inputs* (which model, which rubric, which evidence) — it does not throw them away. The content-addressed LLM cache ([ADR 0077](0077-content-addressed-llm-cache.md)) applies unchanged and now memoizes open-model calls too.
116
116
 
117
+ ### 8. Scope: what the engine does NOT own
118
+
119
+ Four other surfaces spend model tokens reading the repository, or stand guard over the build pipeline, so anyone planning the unification can mistake them for graders. They are deliberately **outside** the engine. None of them registers as a `grader.workType.<key>` provider, and none is migrated onto the engine. Each shares at most plumbing, and none shares the grade path, the verdict or the rubric. Verified against `main` on 2026-09-26 (task 1002844):
120
+
121
+ | Surface | What it is | What it shares with the grader | The one contract it preserves |
122
+ |---|---|---|---|
123
+ | **BFG session evaluator**: `scripts/gds/session-eval.js` ([ADR 0027](0027-bfg-session-inefficiency-evaluator.md)) | Scores how a builder *session* worked (ceremony vs work, footguns) from its uploaded digest | Nothing. It imports no grading code. | It judges the **session**, never the ship. It cannot change a grade or move a task's status. |
124
+ | **gate-review**: `scripts/gds/gate-review.js` | The gatekeeper ([ADR 0058](0058-automatic-gate-surface-gatekeeper.md)) that escalates a change **to the gate itself** before it lands | No grader call. It lists `modules/grading/grader.js`, `grader-workers/` and `grader-rubric.json` among its hard-floor paths, and reads the protected set from `src/bongos/permission-path-check.js`. | A change to the grader is reviewed by something **outside** the grader. It must never depend on the code it reviews. |
125
+ | **main-audit**: `scripts/gds/main-audit.js` ([ADR 0043](0043-git-ssh-trust-boundary-and-rank-floor-on-permission-paths.md)) | The post-push audit of `main` (layer 3): real git history against real builder ranks | The rank/permission classifier `src/bongos/permission-path-check.js`. This is the same kernel checker the grader's permission-path pre-pass reaches through the module doorway. It is not grading code. | It runs **after the fact, whether or not a grade ran**, so it catches what bypassed the grader (a raw push, `--no-verify`). It must never assume the grade happened. |
126
+ | **Architect audit**: `scripts/gds/architect-audit.js` | First-principles "what to delete" audits that feed ideas into scope | Three subprocess/parse helpers from `modules/grading/grader.js`: `runSubagentCached`, `extractAssistantResult` and `extractJson`. This is plumbing: spawn a model, read its JSON. | It produces **ideas for a human to triage**, never a verdict on a ship. If the engine ever moves those helpers, the Architect needs the same three functions, not a work-type. |
127
+
128
+ **How to apply it.** An LLM call that decides whether a ship lands belongs in the engine. Everything else stays out, and a new exception is claimed by adding a row here. The one coupling to watch when the engine grows is the Architect's three plumbing helpers: keep them exported, or move the Architect's import in the same change.
129
+
117
130
  ---
118
131
 
119
132
  ## Consequences
@@ -172,6 +185,8 @@ A build cluster under GDS-V4 (or its successor), staged so nothing destabilizes
172
185
 
173
186
  Roll out behind a flag (the [ADR 0079](0079-value-gated-autonomous-engagement.md) "build disabled, arm later" pattern); the deterministic security gate is never flagged off.
174
187
 
188
+ **Progress (2026-09-25).** Step 3's engine and registry landed first, ahead of steps 1–2, because both build on it: `modules/grading/grade-engine.js` names the pipeline (`select → pre_pass → evidence → fan_out → aggregate → gate → persist`), owns both deterministic pre-passes and a deterministic veto no work-type's aggregate can override, and resolves work-types from its own registry or a module's `grader.workType.<key>` seam provider. The code panel is registered as work-type `code`, the default. Proven a no-op: a before/after run of 27 grading scenarios came out byte-identical, and a replay of 376 recorded production grades reproduced every stored decision except 22 from June 2026, which an older grader produced before two deliberate gate changes (the task 943 "grader unavailable" outcome and the task 574 missing-security-lens block). Task 1002839; the replay tool is `scripts/gds/grade-replay.js`.
189
+
175
190
  ---
176
191
 
177
192
  ## Sources
@@ -160,7 +160,7 @@ This keeps the decision history honest and traceable.
160
160
  | 0087-a | [Bongos app architecture + the model-agnostic feedback handoff contract (BONGOS-V1 / C4). Records the umbrella desktop app that absorbs the Dev Box app as a module, the capture→synthesize→handoff pipeline (R04–R14), and the Rung-3 *visual* capture floor (pixels + voice + freeze-frame markup over any app) with element-level reads deferred to V2 (Accessibility requested lazily, never up front). The contract: a bundle is a self-contained `~/CloudBongos/feedback/<id>/` dir where every screenshot is referenced by ABSOLUTE FILE PATH, never base64 — so the text prompt stays ~5–11k tokens and any agent opens the frames with its own file read. One shared `latest` pointer (atomic `latest.json` + best-effort symlink, self-healing) feeds three readers that can't drift: Claude Desktop (clipboard + open folder, R12), Claude Code (`/feedback` slash command cats prompt.md + Reads the frame paths, R13), and an optional zero-dependency stdio MCP server (`get_latest_feedback` returns text + file paths, never base64, R14). Hand-rolled MCP (newline-delimited JSON-RPC, no SDK dep) keeps the install surface flat. Bongos succeeds the GDS as the primary builder surface after GDS-V4; a fourth agent is an adapter, not a redesign. $0 new recurring cost.](0087-bongos-app-architecture-and-handoff-contract.md) | Bongos app / feedback loop |
161
161
  | 0087-b | [Compete with Cursor on governance, not tooling](0087-compete-on-governance-not-tooling-cursor.md) | strategy / positioning |
162
162
  | 0088 | [Consistent-character generative animation — a generate→grade→audit→regenerate loop built by EXTENDING the existing family pipeline (ADR 0008: `run_family` + cross-frame coherence + the `character_identity` Gemini review + `t5_anchor_refine`), not a new grader/loop (the owner's "don't reinvent the loop"). Decision (with the owner, 2026-06-26): option A — Gemini + grade/audit with a PLUGGABLE generator backend (the ADR 0062/0081 adapter pattern) — over a per-character LoRA, which is deferred as "level-2" (needs GPU training + an open model). The family pipeline is already a consistent-character multi-frame loop (walk/peck cycles ship through it) but tuned for 32×32 pixel-art; this adds a painterly `character_anim` family kind (drops palette-snap/32×32), the two genuinely-new criteria `pose_match` + order-aware transition-coherence (existing checks are order-agnostic — they'd pass a shuffled animation), a recursive Gemini inbetween layer for high frame counts (≈12–24 "on twos"/"on ones"), a painterly cutout/register post-process, and packaging as a Cloud Bongos module (ADR 0083). First consumer = the Bongo Buddha's 8 actions → widget (task 1523). Implementation epic: tasks 1549–1559.](0088-consistent-character-generative-animation.md) | GDS / art pipeline |
163
- | 0089 | [Modular, multi-model adversarial grader (open-weight ensemble) — refactor the ship-gate into a central, work-type-parameterized engine (gather evidence → deterministic pre-passes → judge ensemble → normalize+aggregate → gate → persist) where each MODULE contributes only its rubric + evidence-gatherer + specialist critics through the ADR 0083 seam (`grader.workType.<key>`), answering the owner's "per-module or general?" as central-engine + module-plugged. Adds open-weight LLM judges from a DIFFERENT model family than the author (Claude stays as the quality floor, never the sole judge) to kill same-family self-preference inflation (10–25%); judges run via a `ModelProvider` adapter (`openai-compatible` → DeepInfra/OpenRouter/vLLM/Ollama, the ADR 0062 neutral-contract pattern) on a hosted pay-per-call API (~$1–5/mo, owner spend-gated). Small (2–3) audited panel — z-score/rank-normalize then median + hard-veto aggregation; an error-correlation audit routine (Cohen's κ vs owner decisions) keeps the jury failing DIFFERENTLY (the "Nine Judges, Two Effective Votes" finding) rather than assuming vendor-diversity. Deterministic route-rank + permission-path pre-passes stay ZERO-LLM and authoritative (no LLM verdict, Claude or open, can upgrade a fail over a protected path; ADR 0016/0043/0080); VLM judges advisory on art, deterministic palette/grid checks authoritative. Owner decisions 2026-06-26: central-engine + module-plugged; ensemble vote; hosted API. Reuses the worker-contract + task_grades schema + LLM cache (ADR 0077); rolls out advisory-first behind a flag. Build cluster task-pending (task 1561).](0089-modular-multi-model-adversarial-grader.md) | GDS / grader + quality gate |
163
+ | 0089 | [Modular, multi-model adversarial grader (open-weight ensemble) — refactor the ship-gate into a central, work-type-parameterized engine (gather evidence → deterministic pre-passes → judge ensemble → normalize+aggregate → gate → persist) where each MODULE contributes only its rubric + evidence-gatherer + specialist critics through the ADR 0083 seam (`grader.workType.<key>`), answering the owner's "per-module or general?" as central-engine + module-plugged. Adds open-weight LLM judges from a DIFFERENT model family than the author (Claude stays as the quality floor, never the sole judge) to kill same-family self-preference inflation (10–25%); judges run via a `ModelProvider` adapter (`openai-compatible` → DeepInfra/OpenRouter/vLLM/Ollama, the ADR 0062 neutral-contract pattern) on a hosted pay-per-call API (~$1–5/mo, owner spend-gated). Small (2–3) audited panel — z-score/rank-normalize then median + hard-veto aggregation; an error-correlation audit routine (Cohen's κ vs owner decisions) keeps the jury failing DIFFERENTLY (the "Nine Judges, Two Effective Votes" finding) rather than assuming vendor-diversity. Deterministic route-rank + permission-path pre-passes stay ZERO-LLM and authoritative (no LLM verdict, Claude or open, can upgrade a fail over a protected path; ADR 0016/0043/0080); VLM judges advisory on art, deterministic palette/grid checks authoritative. Owner decisions 2026-06-26: central-engine + module-plugged; ensemble vote; hosted API. Reuses the worker-contract + task_grades schema + LLM cache (ADR 0077); rolls out advisory-first behind a flag. Build cluster in progress: the central engine + work-type registry landed first (task 1002839, `modules/grading/grade-engine.js`, the code panel registered as work-type `code`). Deliberately OUTSIDE the engine (§8): the BFG session evaluator, gate-review, main-audit and the Architect audit — none grades a ship; the Architect shares only three subprocess/parse helpers, and main-audit and gate-review only the rank-permission checker.](0089-modular-multi-model-adversarial-grader.md) | GDS / grader + quality gate |
164
164
  | 0090 | [Metic gains task authoring — re-ranks `POST /tasks`, `PATCH /tasks/:id`, `POST /tasks/:id/promote`, and the `tasks/:id/{dependencies,criteria}` CRUD from Archon-only to `requireRank('metic','archon')` (owner decision 2026-06-26: a rank trusted to triage ideas is trusted to seed + shape the tasks they become). Moves the two `EXPECTED_RANKS` pins in lockstep and updates the `// rank:` annotations so the route-rank audit stays green. Keeps Archon-only: rank-setting, version-close, abandon, grader-bypass confirm, and the ADR 0086 cross-tier `POST /dependencies` + goal-scope edges. Amends ADR 0018's table row 7; sits beside ADR 0086, which remains the module-fenced authoring path for sub-Metic ranks. "Tighten later" debt explicitly accepted — no per-version/module/goal fence on a Metic's authoring.](0090-metic-task-authoring.md) | GDS / permissions |
165
165
  | 0091 | [Bounding the kernel and carving `db.js` per-domain (Config-B core decomposition) — amends ADR 0083 to extend the strangler from the four FEATURE modules into the CORE itself (BONGOS-V1 C7). Answers the three questions the audit opened: (1) WHAT IS THE KERNEL — replaces the 6-file machinery-only `fitness.js` `KERNEL_FILES` with an enumerated ~3.5k-LOC trust roster (auth · route-rank-check · permission-path-check · secret-box · pool · the new `db-kernel.js` identity/audit/rank/`withTx` slice · instance-config/branding/build-info · routes/_helpers · the module-system machinery + module-scope-map); everything else in `src/bongos/` is a domain destined to become a module or to stay inside the un-split lifecycle state machine. (2) HOW A DOMAIN OWNS ITS SQL — ratifies the proven `modules/discord/db.js` + `modules/game/db.js` pattern (own queries lifted verbatim + deleted from core, reached through the doorway `pool`/`withTx`; kernel helpers re-exported behind the same `db.*` namespace; boundary-forced twins allowed + documented) as THE per-domain carve mechanism; `db.js` shrinks toward a kernel slice + the lifecycle residue. (3) WHAT THE DOORWAY EXPOSES — classifies `module-api.js` re-exports into kernel (stays: identity/audit/rank/auth/seams/config + `withTx`), domain-leak-with-a-home (relocate now: `setBuilderBoxBlocked`→dev-box, gemini-key trio→art-pipeline), and domain-leak-pending-carve (`createTask`/`captureIdea`/`VOTABLE_TASK_STATUSES` stay as MARKED temporary re-exports until lifecycle/ideas are carved in tranche 2 — named, owned, tracked debt, not pretend-kernel). A lifecycle-invoked capability resolves through a kernel PORT, never a direct import (R73 replaces `routes/tasks.js`→`grader.js` with `resolve('grade')`). Deliverable = this decision + the seeded, dependency-wired R68–R74 sub-task shape; OTB byte-identical at every step. Tranche 2 (the other ~8 core domains) deferred per owner.](0091-bounding-the-kernel-and-db-carve.md) | GDS / architecture |
166
166
  | 0092 | [Hosting module + on-prem (warehouse) hosting target — scopes a portable Cloud Bongos `hosting` module (default-OFF, fail-to-vanilla) that brokers compute + storage workloads (inference / imagegen / embeddings / training / storage) to configured hosting *targets* through kernel seams, resolving each via `resolveOptional(port, cloudDefaultFn)` so a box-less / module-off instance degrades to cloud automatically. The warehouse GPU box is OTB's first ON-PREM target — one adapter backend declared in HOST-instance config (the ADR 0062 / 0081 core↔host + swappable-adapter pattern), shared across all Example instances, reached over an outbound tunnel the box initiates (no open ports / no static IP), sitting OUTSIDE the trust boundary like Discord (ADR 0033): it computes, it never grants rank or lands code (ADR 0016 / 0043). Inference REUSES the ADR 0089 `ModelProvider` openai-compatible adapter (the on-prem box = one more vLLM / Ollama endpoint) and adopts 0089's decisive finding that low-volume work is cheaper on pay-per-call APIs — so the GPU's honest justification narrows to GPU-bound batch generation, open-model fine-tuning / LoRA (the ADR 0088 deferred level-2), and always-busy bulk, plus the non-GPU wins of backups / storage + an unmetered sandbox; code that ships stays on Claude. Owner decisions 2026-06-27: serve all instances, conservative posture, proceed. Phased: scope use ✅ → build (task 1619) → hardware (task 1620) → software; the cost read-out (task 1621) is an independent input.](0092-hosting-module-and-on-prem-target.md) | Cloud Bongos / hosting |
@@ -19391,7 +19391,7 @@
19391
19391
  "tasks"
19392
19392
  ],
19393
19393
  "summary": "GET /tasks/:id/publish-status",
19394
- "description": "GET /tasks/:id/publish-status?branch=<branch> — poll the PR + prod-deploy state for a server-mediated publish so ship.js can confirm the land WITHOUT gh on the box. Ownership-gated like the POST. Derives state live from GitHub.\n\n**Rank:** `any-builder` — Any authenticated builder (row-level ownership enforced in-handler).",
19394
+ "description": "GET /tasks/:id/publish-status?branch=<branch> — poll the PR + prod-deploy state for a server-mediated publish so ship.js can confirm the land WITHOUT gh on the box. Ownership-gated like the POST. Derives state live from GitHub. `branch` is optional (task 1003764): without it the server finds the task's own PR (both publish paths title it \"task <id>: …\") and the answer names the `branch` it used and its `branch_source`, so the check agents are sent to instead of git probes never refuses a live publish for want of a branch name.\n\n**Rank:** `any-builder` — Any authenticated builder (row-level ownership enforced in-handler).",
19395
19395
  "x-rank": "any-builder",
19396
19396
  "x-source": "modules/lifecycle/routes/tasks.js",
19397
19397
  "parameters": [
@@ -14,6 +14,7 @@
14
14
  - **Cloud Bongos control-plane droplet (NEW 2026-07-05, [ADR 0126](adr/0126-dedicated-cloudbongos-control-plane-droplet.md), task [#2063](https://example.com/builders#/task/2063)):** DigitalOcean, hostname `cloudbongos`, IPv4 `REDACTED_IP`, NYC3, `s-1vcpu-2gb` (2 GB / 1 vCPU), Ubuntu 24.04, ~$12/mo, tag `cloudbongos-control`. Runs **cloudbongos.com + `builders.` + `status.`** (`src/platform-server.js`, Cloud Bongos brand, port 3002, own `cloudbongos` DB, checkout `/home/lars/cloudbongos-instance`, the root subscribed to the nightly core-patch sweep) and is the **sole token-holding control plane** — a SECOND root, `/home/lars/cloudbongos`, survives only to vendor `infra/` (the box cloud-init the core package does not ship, ADR 0150); it is not subscribed, so nothing may resolve core code from it (task 1002738, [ADR 0144](adr/0144-devbox-rehome-onto-cloudbongos-plane.md) follow-up 5) — `/etc/cloudbongos/box.env` holds the account-wide Cloudflare token (IP-locked to this box) + the DigitalOcean token; this is where `provision.js` provisions instance subdomains. **Structurally separate SSH** (own `cloudbongos_ed25519` key). IPv6 egress disabled so the IPv4-locked CF token can't be spuriously rejected. cloudbongos.com was previously a co-tenant on the co-hosting box; that unit was decommissioned at cutover. **Follow-ups:** deploy automation (task [#2064](https://example.com/builders#/task/2064)) + fully stripping cloud tokens off the co-hosting box (task [#2065](https://example.com/builders#/task/2065)).
15
15
  - **Server stack:** Node.js 22 LTS · PostgreSQL 16 · Caddy 2.11.2. `example.service` (systemd) runs `node server.js` as user `lars` on `127.0.0.1:3000`; restart-on-failure.
16
16
  - **Hardening:** `lars` user with passwordless sudo; SSH key-only (root login disabled, password auth disabled); ufw allows 22/80/443; fail2ban active; unattended-upgrades enabled; timezone `America/New_York`.
17
+ - **Credentials:** every credential the instance needs — what it is for, which env file holds it (`web.env` · `box.env` · `spaces.env`), GitHub Actions secrets and builder-machine logins — is listed in [`docs/credentials.md`](credentials.md), names only. Whether each is SET on a host is one command run there: `node scripts/gds/credential-presence.js` (task 1002880). Check both before asking the owner for a credential.
17
18
  - **TLS:** Origin cert at `/etc/caddy/origin.crt` + `/etc/caddy/origin.key` for the example apexes on the co-hosting box. **cloudbongos.com's apexes moved to the dedicated control-plane droplet** ([ADR 0126](adr/0126-dedicated-cloudbongos-control-plane-droplet.md)) with their own copy of the Cloudflare Origin Cert (SAN `*.cloudbongos.com, cloudbongos.com`) at `/etc/caddy/cloudbongos-origin.{crt,key}` on `REDACTED_IP`. Cloudflare SSL/TLS mode = Full (strict). Renewal is a non-issue for ~15 years. **Provisioned instance hosts use a different, coexisting posture** ([ADR 0111](adr/0111-instance-hosting-provisioning-module.md) §4 / task P4): Caddy **on-demand ACME** (Let's Encrypt) via the global `on_demand_tls { ask … }` block, gated to hostnames the `provisioning` module actually stood up (`/api/bongos/provisioning/tls-check`). Their DNS records are **proxied=false (grey cloud)** so the ACME challenge reaches Caddy — the opposite of the origin-cert apexes; do not enable the proxy on them or renewal breaks silently ([ADR 0003](adr/0003-cloudflare-origin-cert-over-letsencrypt.md)). Per-instance site snippets live in `/etc/caddy/sites/*.caddy` (`import`ed by `infra/Caddyfile`); the provisioning runner verifies the box's resolved Caddy config carries that import and the `on_demand_tls` ask before it reports a domain wired, and refuses with the line to add rather than editing the base file ([ADR 0303](adr/0303-provisioning-verifies-the-base-caddyfile-and-never-edits-it.md)). **Tradeoff (accepted, SEC review of task 1945):** `proxied=false` publishes the box's real origin IP in public DNS for every co-tenant provisioned hostname — defeating, for those names, the Cloudflare-proxy IP-hiding the apexes enjoy (a co-tenant host resolves to the same `REDACTED_IP` that serves the main game). This is inherent to on-demand ACME (the challenge must hit the origin) and acceptable under the budget/trust model; prefer a **dedicated droplet** (its own IP) for any instance expected to draw hostile attention.
18
19
  - **Platform observability — REMOVED 2026-09-15 ([ADR 0284](adr/0284-the-control-plane-carries-no-metrics-stack.md), task 1003876):** the control plane runs **no Grafana and no Prometheus**, and `metrics.cloudbongos.com` has no Caddy site. They cost ~300 MB RSS + 2.5 GB of data on the box every provisioned project shares, and scraped none of those projects. Every instance still exports `/metrics` ([`src/bongos/metrics.js`](../src/bongos/metrics.js), loopback or `METRICS_TOKEN`), so a scraper can return from a box that is *not* the control plane. The rest of this bullet is the **historical** ADR 0127 layout, kept so its leftovers (co-hosting-box forwarders, instance `infra/` copies) can be found: this watched the **Bongos API** (`gds_http`/`tasks`/`claims`/`builders`/`auth`), not any one game, so it lived **on the control-plane box** (REDACTED_IP) at **`https://metrics.cloudbongos.com`** and observed the **whole fleet**. **Prometheus** (`127.0.0.1:9090`, loopback-only) scrapes every instance's `/metrics` ([`src/bongos/metrics.js`](../src/bongos/metrics.js)), each tagged with a `project` label (`infra/prometheus/prometheus.yml` (instance-side)): **cloudbongos** locally (`:3002`); **example + emersonian-circles** on the co-hosting box, reached over the **private VPC** via `socat` forwarders on `10.108.0.2:9101/9102` (→ their loopback `:3000`/`:3004`), ufw-locked to the control-plane box's private IP — raw TCP relays, so the exporter still sees a loopback request and needs no token; nothing is public. **Grafana** (`127.0.0.1:3003`, loopback-only) renders the 4 provisioned-as-code dashboards (folder **Cloud Bongos**: system-overview, error-watch, builder-activity, auth-security), each with a **`project`** template variable for per-instance / fleet views. Reverse-proxied on the `*.cloudbongos.com` origin cert — Archon-only, gated by Caddy `basic_auth` (user `archon`) **and** Grafana's own admin login (both secrets owner-held, never in the repo). Grafana config is a systemd `GF_*` env drop-in (`grafana-server.service.d/override.conf`, `chmod 600`). ~256 MB RAM. A future dedicated-droplet instance is added as a `METRICS_TOKEN` Bearer target instead of a VPC forwarder.
19
20
 
@@ -65,7 +66,7 @@ The product is organized as a small kernel (`src/`) + **19 modules** under `modu
65
66
  **Code & deploy:**
66
67
 
67
68
  - **Code repo:** [github.com/example-owner/example](https://github.com/example-owner/example) — **private**. Clone URL: `git@github.com:example-owner/example.git`. Default branch: `main`. GitHub user: `example-owner`.
68
- - **Deploy:** two modes, selected by `config/deploy.json` `mode` (env `OTB_DEPLOY_MODE` overrides), currently **`ci`** (flipped from `laptop` 2026-06-13, [#859](https://example.com/builders#/task/859)) — see [ADR 0042](adr/0042-builder-self-deploy-ci-auto-merge.md). **`laptop`** (legacy): `git push origin main` from the Mac → `ssh lars@REDACTED_IP ~/deploy.sh`. The droplet has a read-only deploy key at `~/.ssh/github_deploy` registered on the repo. `~/deploy.sh` does: `git fetch + reset --hard origin/main` → `npm ci --omit=dev` if `package-lock.json` changed → `./scripts/migrate.sh` → `sudo systemctl restart example` → `curl /healthz` smoke (**retried up to 15× @ 1s** — `systemctl` reports "active" before the Node process binds the port, so a single curl raced the bind and false-failed healthy deploys: [ADR 0056](adr/0056-prod-deploy-script-mirror-and-healthcheck-retry.md) / [#1026](https://example.com/builders#/task/1026)). Droplet checkout: `/home/lars/example/`. `~/deploy.sh` is hand-maintained on the droplet but now has a byte-faithful, reviewable repo mirror at `scripts/deploy/deploy-prod.sh` (instance-side) — **not** auto-installed (the ci deploy key is forced-command-locked, ADR 0042/0043; reinstall by hand on change: `scp scripts/deploy/deploy-prod.sh lars@…:deploy.sh`). **`ci`** (current, armed via [#679](https://example.com/builders#/task/679)): no builder box holds the droplet key — `ship.js` opens a PR + enables GitHub auto-merge, and `.github/workflows/deploy-prod.yml` (instance-side) runs the same `~/deploy.sh` from Actions on merge to `main`. Cutover preconditions (incl. a server-recorded **CI grade-gate**) are in ADR 0042.
69
+ - **Deploy:** two modes, selected by `config/deploy.json` `mode` (env `<PREFIX>_DEPLOY_MODE` overrides — `BONGOS_DEPLOY_MODE` on a vanilla instance; the legacy `OTB_DEPLOY_MODE` is still read), currently **`ci`** (flipped from `laptop` 2026-06-13, [#859](https://example.com/builders#/task/859)) — see [ADR 0042](adr/0042-builder-self-deploy-ci-auto-merge.md). **`laptop`** (legacy): `git push origin main` from the Mac → `ssh lars@REDACTED_IP ~/deploy.sh`. The droplet has a read-only deploy key at `~/.ssh/github_deploy` registered on the repo. `~/deploy.sh` does: `git fetch + reset --hard origin/main` → `npm ci --omit=dev` if `package-lock.json` changed → `./scripts/migrate.sh` → `sudo systemctl restart example` → `curl /healthz` smoke (**retried up to 15× @ 1s** — `systemctl` reports "active" before the Node process binds the port, so a single curl raced the bind and false-failed healthy deploys: [ADR 0056](adr/0056-prod-deploy-script-mirror-and-healthcheck-retry.md) / [#1026](https://example.com/builders#/task/1026)). Droplet checkout: `/home/lars/example/`. `~/deploy.sh` is hand-maintained on the droplet but now has a byte-faithful, reviewable repo mirror at `scripts/deploy/deploy-prod.sh` (instance-side) — **not** auto-installed (the ci deploy key is forced-command-locked, ADR 0042/0043; reinstall by hand on change: `scp scripts/deploy/deploy-prod.sh lars@…:deploy.sh`). **`ci`** (current, armed via [#679](https://example.com/builders#/task/679)): no builder box holds the droplet key — `ship.js` opens a PR + enables GitHub auto-merge, and `.github/workflows/deploy-prod.yml` (instance-side) runs the same `~/deploy.sh` from Actions on merge to `main`. Cutover preconditions (incl. a server-recorded **CI grade-gate**) are in ADR 0042.
69
70
  - **Post-merge branch cleanup (standard practice):** Every feature branch that lands on main via `--no-ff` merge gets deleted on origin once the deploy succeeds. The merge commit itself preserves the branch's history in main, so the named ref isn't carrying any signal — keeping it just clutters GitHub's branch list and tricks the UI into offering empty PRs against zero-diff branches. The auto-merge in [`scripts/gds/ship.js`](../scripts/gds/ship.js) does this automatically after `~/deploy.sh` returns 0; the manual [`/merge-mode`](../.claude/skills/merge-mode/SKILL.md) flow follows the same step 5b. Local refs and worktree directories stay — only the origin branch and the local tracking ref (cleaned on next `git fetch --prune`) go.
70
71
  - **Local dev machine:** Lars's MacBook Air (Apple Silicon, macOS Sequoia). Tooling installed via Homebrew at `/opt/homebrew/`. Node v26.0.0 locally; `package.json` declares `"engines": { "node": ">=22" }`. Single ed25519 SSH key (`~/.ssh/id_ed25519`) authenticates to GitHub and droplet.
71
72
  - **Smoke tests:** lightweight scripts in `/tmp/colyseus-*-smoketest.js` verify joinOrCreate, move protocol, interact, identity, queue. Run any after deploy with `node /tmp/colyseus-<name>-smoketest.js`.
@@ -229,7 +230,7 @@ Bongos views: `claimable_tasks` (rebuilt in 006 to use SELECT t.*; rebuilt again
229
230
  - Own-scoped session self-service ([ADR 0206](adr/0206-own-scoped-session-revocation-no-absolute-ceiling.md), task 1003341), in [`src/bongos/routes/my-sessions.js`](../src/bongos/routes/my-sessions.js): `GET /me/sessions` (every live session on the caller's own account — source, user agent, created/last-used/expires, a `current` flag; the token value is never selected), `POST /me/sessions/revoke` (`{session_id}` — one of your own; a miss answers `revoked: 0` so a stranger's id cannot be probed) and `POST /me/sessions/revoke-all` (sign out everywhere, the requesting session included). All three gate on `requireBuilder` alone and key every statement on `req.builder.id` — an account is never named in the query, body or path. They exist because a bearer refreshes to `now()+24h` on every call, so a leaked one never expires, and the cross-builder pair (`POST /auth/revoke`, `/auth/revoke-all`, both still gated on the admin `auth.session.revoke` atom) needed an Archon the victim might not have. Surfaced in the hall at Settings → Active sessions.
230
231
  - Authenticated CLI/web: `GET /me` (returns `rank`), `GET /versions[/progress]`, `GET /tasks[?version=&status=&kind=&discipline=]`, `GET /tasks/claimable[?version=&discipline=]`, `GET /tasks/:id`, `POST /tasks` (accepts `discipline` + `criterion_ids`; **metic+** — [ADR 0090](adr/0090-metic-task-authoring.md)), `PATCH /tasks/:id` (supports `parent_task_id`, `kind`, `discipline`, `goal_id` — (re)assign the task's goal; must be a goal in the task's own version, task 1763; **metic+**), `POST /tasks/:id/promote` (**metic+**), `POST /claims`, `POST /claims/:id/resolve`, `POST /cost`.
231
232
  - Criterion rollup + task↔criterion links ([ADR 0025](adr/0025-structured-criterion-task-link.md), [#435](https://example.com/builders#/task/435)/[#438](https://example.com/builders#/task/438)): `GET /versions/:id/progress` rolls up each done-when criterion → its gating tasks (via `task_criteria`) → live status counts + the not-yet-shipped `remaining[]` + `unattributed_tasks` (the read behind the `/status` skill, in `src/bongos/done-when.js criterionProgress`). The link CRUD mirrors the dependency endpoints: `GET /tasks/:id/criteria`, `POST /tasks/:id/criteria` (**metic+** — [ADR 0090](adr/0090-metic-task-authoring.md)) and `DELETE /tasks/:id/criteria/:criterionId` (**metic+**). A criterion ref is a numeric `done_when_criteria.id`, a positional `"Cn"` token, or a `criterion_id` slug, resolved against the task's version (`POST /tasks` links at create time so `/status` counts the task with no backfill).
232
- - Server-mediated branch publish (ADR 0055 / [#1025](https://example.com/builders#/task/1025) — lets a dev box with no GitHub push credential ship). Owner-gated like ship: `POST /tasks/:id/publish-branch` (`requireBuilder` + `gateTaskOwnership`, **NOT** `allowBoxScope` → a box-scoped session is `403 box_scope`, so the builder must `/builder-reauth` first; own 32 MB json parser for the base64 thin-bundle body, 20 MB decoded cap; the server pushes the branch + opens the PR + auto-merges with a server-side push credential — a **GitHub App** installation token (short-lived, repo-scoped; preferred, [ADR 0055](adr/0055-server-mediated-branch-publish.md) update / task 1028) or the `GITHUB_PUSH_TOKEN` PAT fallback; `503 push_unconfigured` when neither is set; `400 tip_mismatch` if the bundle tip ≠ the claimed `head_sha`) and `GET /tasks/:id/publish-status?branch=…` (polls PR + deploy-prod state derived live from GitHub). When the PR is still open it also carries `merge_driver`, whose `reason` says why it has not merged; on a red PR `failing_tests` names the failing unit tests (read from the `unit-report` commit status the `unit` workflow posts) and `checks_unreadable: true` says the check list is blind because the App lacks `Checks: read` — so an empty `checks[]` is never read as "nothing failed" (task 1003988, ADR 0301). Because the server's credential is the PR's AUTHOR, publish also **assigns the PR to the task's claim holder** and names them in the body (`modules/lifecycle/pr-assign.js`, task 1003991) — best-effort: the 201 carries `pr_assignee` (the login, or `null` when GitHub would not assign it) and a failed assignment never fails the publish. `ship.js` uses these in `ci` mode only when `pushVia()` resolves to server (a box, or `OTB_PUSH_VIA_SERVER=1`); a laptop with `gh` keeps the local push path unchanged. Implementation in `src/bongos/github-push.js`.
233
+ - Server-mediated branch publish (ADR 0055 / [#1025](https://example.com/builders#/task/1025) — lets a dev box with no GitHub push credential ship). Owner-gated like ship: `POST /tasks/:id/publish-branch` (`requireBuilder` + `gateTaskOwnership`, **NOT** `allowBoxScope` → a box-scoped session is `403 box_scope`, so the builder must `/builder-reauth` first; own 32 MB json parser for the base64 thin-bundle body, 20 MB decoded cap; the server pushes the branch + opens the PR + auto-merges with a server-side push credential — a **GitHub App** installation token (short-lived, repo-scoped; preferred, [ADR 0055](adr/0055-server-mediated-branch-publish.md) update / task 1028) or the `GITHUB_PUSH_TOKEN` PAT fallback; `503 push_unconfigured` when neither is set; `400 tip_mismatch` if the bundle tip ≠ the claimed `head_sha`) and `GET /tasks/:id/publish-status?branch=…` (polls PR + deploy-prod state derived live from GitHub). `branch` is optional: without it the server finds the task's own PR by its `task <id>: …` title, and the answer names the `branch` it used and its `branch_source` (`query` / `task_pr`, or `null` with a `branch_hint` when there is no such PR) — never a `400` (task 1003764). When the PR is still open it also carries `merge_driver`, whose `reason` says why it has not merged; on a red PR `failing_tests` names the failing unit tests (read from the `unit-report` commit status the `unit` workflow posts) and `checks_unreadable: true` says the check list is blind because the App lacks `Checks: read` — so an empty `checks[]` is never read as "nothing failed" (task 1003988, ADR 0301). Because the server's credential is the PR's AUTHOR, publish also **assigns the PR to the task's claim holder** and names them in the body (`modules/lifecycle/pr-assign.js`, task 1003991) — best-effort: the 201 carries `pr_assignee` (the login, or `null` when GitHub would not assign it) and a failed assignment never fails the publish. `ship.js` uses these in `ci` mode only when `pushVia()` resolves to server (a box, or `<PREFIX>_PUSH_VIA_SERVER=1`); a laptop with `gh` keeps the local push path unchanged. Implementation in `src/bongos/github-push.js`.
233
234
  - Archon monitoring reads backing the `/watch` page (ADR 0036): `GET /builders/roster`, `GET /grades/by-builder[?days=N]` (**archon-only**, [#726](https://example.com/builders#/task/726) — per-builder grade breakdown for the MARKS section; the project-wide aggregate stays public at `/public/grades`), `GET /audit-log`, `GET /override-requests`, `GET /access-requests`, `GET /security/reports`. Personal-prefs writes backing `/settings`: `GET/PATCH /me/skill-prefs`, `PATCH /me/disciplines`.
234
235
  - Per-builder "needs" + own Gemini key ([ADR 0073](adr/0073-builder-needs-signal-and-byok-gemini-key.md), [#1013](https://example.com/builders#/task/1013)): `GET /me` now also carries `needs` ({items, action_needed_count} — the consistent "the system needs an input from you" signal; `modules/builder-settings/builder-needs.js` is the SSOT — carved out in BV1.R80, resolved by `GET /me` via the `builder-settings` kernel port — rendered by the hall Standing card + the CLI `printNeedsNudge`). The own-key (pragmatic BYOK) endpoints, all own-scoped: `GET /me/art-key/own` (masked meta — last4 only), `PUT /me/art-key/own` (validate-on-save via a Google list-models call → encrypt with `src/bongos/secret-box.js` → store; `503 storage_not_configured` until `BUILDER_SECRET_KEY` is set, `422 invalid_key` on a bad key), `DELETE /me/art-key/own`. The existing `GET /me/art-key` (shared-key box-sync delivery) is extended to also deliver the decrypted own key, which `scripts/gds/fetch-art-key.js` syncs into the local `gemini_api_key` slot (own key wins in the `gen_api.py` cascade).
235
236
  - Builder memory (ADR 0024 cloneable memory + ADR 0026 BFG). Self-scoped (owner is always `req.builder.id`, never input): `POST /memory/sync` (push own memory; own 64 MB parser, vs the global 64 KB), `GET /memory/files`, `GET /memory/file`, `DELETE /memory/file` (the BFG delete affordance, 6C.2). Cross-builder (input-owner) endpoints — all privileged + audit-logged fail-closed: `GET /memory/builders/:id/files`+`/file` (**archon forensic** read), `GET /memory/bfg/builders/:id/files`+`/file` (**BFG-principal only**, 6B.1 read), and the one cross-builder WRITE `POST /memory/builders/:id/bfg-write` (**BFG-principal only**, kill-switched `BFG_WRITE_ENABLED` default-OFF, namespaced `bfg/`, attributed `author: BFG`, write+audit in one tx — dreams + transparent corrections, 6C.1/6C.2).
@@ -315,8 +315,8 @@ pre-merge gate misses, independent of the builder's cooperation:
315
315
  activated it; ADR 0043 §"G-2/G-17 resolution") blocks it. This hook is a CORE-repo control:
316
316
  scaffolded standalone instances are hookless by default — deliberate, not a gap
317
317
  ([ADR 0165](adr/0165-instances-hookless-by-default.md)); the graded
318
- pipeline pushes only via `scripts/gds/push-main.js` (which carries the `OTB_ALLOW_MAIN_PUSH`
319
- override). A raw push is caught and reverted by the **post-push main audit**
318
+ pipeline pushes only via `scripts/gds/push-main.js` (which carries the `<PREFIX>_ALLOW_MAIN_PUSH`
319
+ override — `BONGOS_ALLOW_MAIN_PUSH` on a vanilla instance). A raw push is caught and reverted by the **post-push main audit**
320
320
  (`scripts/gds/main-audit.js`) — nightly and as the `~/deploy.sh` deploy gate — which is the
321
321
  authoritative layer (it reads the real git history + real ranks, independent of the builder).
322
322
  - **The pre-push hook fails OPEN by contract, and the wrapper is what enforces that** (task 1002725).
@@ -4,13 +4,13 @@
4
4
  > Deterministic on a given tree — regenerate and commit rather than hand-editing.
5
5
  > Machine-readable twin: [`copy-registry.json`](copy-registry.json).
6
6
 
7
- **2048 strings** across 3 surfaces · 1750 distinct pieces of copy · 2048 certain, 0 heuristic · 211 shown in more than one place.
7
+ **2052 strings** across 3 surfaces · 1754 distinct pieces of copy · 2052 certain, 0 heuristic · 211 shown in more than one place.
8
8
 
9
9
  ## Surfaces
10
10
 
11
11
  | surface | lives at | files | strings |
12
12
  |---|---|---|---|
13
- | `builders-hall` | `modules/hall-ui/public` | 102 | 1547 |
13
+ | `builders-hall` | `modules/hall-ui/public` | 102 | 1551 |
14
14
  | `status-dashboard` | `modules/status-ui/public` | 4 | 100 |
15
15
  | `landing` | `modules/public-landing/public` | 5 | 401 |
16
16
 
@@ -78,7 +78,7 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
78
78
  | `7926e30955d2` | 3x | ← Back to goal | modules/hall-ui/public/goals.html:199, modules/hall-ui/public/goals.html:210, modules/hall-ui/public/goals.html:222 |
79
79
  | … | | _171 more in the JSON registry_ | |
80
80
 
81
- ## `builders-hall` — 1547 strings
81
+ ## `builders-hall` — 1551 strings
82
82
 
83
83
  | id | conf | text | where |
84
84
  |---|---|---|---|
@@ -89,7 +89,7 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
89
89
  | `66cea7cefa4e` | certain | '; for (const row of bodyRows) { html += ' | `modules/hall-ui/public/md-reader.js:220` |
90
90
  | `53e4ac514458` | certain | '; out.push(html); continue; } // Lists (unordered '- ' or ordered '1. '); consecutive items collapse. if (/^( | `modules/hall-ui/public/md-reader.js:224` |
91
91
  | `87fa099f5068` | certain | '; } html += ' | `modules/hall-ui/public/md-reader.js:224` |
92
- | `af615fa9f404` | certain | (checked {…}) | `modules/hall-ui/public/deploy.js:256` |
92
+ | `af615fa9f404` | certain | (checked {…}) | `modules/hall-ui/public/deploy.js:291` |
93
93
  | `544794f1ec8f` | certain | (later in | `modules/hall-ui/public/index.html:9` |
94
94
  | `3ac2eb36ba97` | certain | (no sections) | `modules/hall-ui/public/drachmae.js:260` |
95
95
  | `a4614c0b8eb5` | certain | (or use the Claude Code CLI) and open the project. | `modules/hall-ui/public/hall-render.js:864` |
@@ -245,10 +245,10 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
245
245
  | `55ad21bd03eb` | certain | Chart the routes | `modules/hall-ui/public/goal-map.html:97` |
246
246
  | `55ad21bd03eb` | certain | Chart the routes | `modules/hall-ui/public/thinking.html:96` |
247
247
  | `e6982a9ff948` | certain | Charter library | `modules/hall-ui/public/government.js:799` |
248
- | `f66f5cdaa732` | certain | Checked against {…} — nothing blocks this move.{…} | `modules/hall-ui/public/deploy.js:259` |
248
+ | `f66f5cdaa732` | certain | Checked against {…} — nothing blocks this move.{…} | `modules/hall-ui/public/deploy.js:294` |
249
249
  | `f8725cf3ba62` | certain | Checking dependency order… | `modules/hall-ui/public/work.js:865` |
250
250
  | `7a41b18c0de8` | certain | Checking for conflicts… | `modules/hall-ui/public/work.js:844` |
251
- | `ac7cf27bd7de` | certain | Checking what this would do, and what it would bring in. The answer comes from the machine itself, so it can t | `modules/hall-ui/public/deploy.js:248` |
251
+ | `ac7cf27bd7de` | certain | Checking what this would do, and what it would bring in. The answer comes from the machine itself, so it can t | `modules/hall-ui/public/deploy.js:283` |
252
252
  | `aa3ba7d28a76` | certain | Checking your key… | `modules/hall-ui/public/settings.js:1053` |
253
253
  | `834f8c6f3b72` | certain | Choose a builder… | `modules/hall-ui/public/goals-render.js:1246` |
254
254
  | `b3d0e2af5176` | certain | Choose a goal first. | `modules/hall-ui/public/task.js:938` |
@@ -337,8 +337,8 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
337
337
  | `2366356926b4` | certain | Could not mark the primer just now. Try again. | `modules/hall-ui/public/primer.js:259` |
338
338
  | `753987b5da13` | certain | Could not reach the submit endpoint. | `modules/hall-ui/public/modules.js:297` |
339
339
  | `6f500726f0ac` | certain | Could not read the report: {…} | `modules/hall-ui/public/watch.js:640` |
340
- | `21c2f33168a3` | certain | Could not read this project's deploy state: {…} | `modules/hall-ui/public/deploy.js:414` |
341
- | `21a782f1af26` | certain | Could not read what this would bring in: {…}. The check below still applies. | `modules/hall-ui/public/deploy.js:333` |
340
+ | `21c2f33168a3` | certain | Could not read this project's deploy state: {…} | `modules/hall-ui/public/deploy.js:449` |
341
+ | `21a782f1af26` | certain | Could not read what this would bring in: {…}. The check below still applies. | `modules/hall-ui/public/deploy.js:368` |
342
342
  | `8b470cebf53d` | certain | Could not remove your key. Try again. | `modules/hall-ui/public/settings.js:1133` |
343
343
  | `4cf6bc8b377b` | certain | Could not remove. Try again. | `modules/hall-ui/public/settings.js:1132` |
344
344
  | `7a778d188e87` | certain | Could not remove: {…} | `modules/hall-ui/public/government.js:369` |
@@ -388,7 +388,7 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
388
388
  | `a55e423263f0` | certain | Cross-project record | `modules/hall-ui/public/profile.html:94` |
389
389
  | `a55e423263f0` | certain | Cross-project record | `modules/hall-ui/public/settings.html:95` |
390
390
  | `24013a074724` | certain | Custom rank | `modules/hall-ui/public/government.html:113` |
391
- | `cf7d7d5d5e83` | certain | Database behind. | `modules/hall-ui/public/deploy.js:378` |
391
+ | `cf7d7d5d5e83` | certain | Database behind. | `modules/hall-ui/public/deploy.js:413` |
392
392
  | `6744aed3d15e` | certain | Dated exploit-detail engagement reports — kept out of the repo (threat-model §6.3) and served only to Archons. | `modules/hall-ui/public/watch.html:131` |
393
393
  | `d388906f550b` | certain | Declared files overlap: {…} (advisory) | `modules/hall-ui/public/task-lib.js:74` |
394
394
  | `7c6891813679` | certain | Default ({…}) | `modules/hall-ui/public/settings.js:63` |
@@ -567,6 +567,7 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
567
567
  | `ef224c9de7c8` | certain | Ideas — {{worldName}} | `modules/hall-ui/public/ideas.html:6` |
568
568
  | `9e9f8a44276b` | certain | Identity vouched | `modules/hall-ui/public/watch.js:373` |
569
569
  | `7d6a7de7a69e` | certain | If the {…} has invited you, sign in with GitHub and you're in. If not, ask them for an invite — this project d | `modules/hall-ui/public/hall-render.js:286` |
570
+ | `4ef9f2a4df3b` | certain | If you own this project, | `modules/hall-ui/public/deploy.js:250` |
570
571
  | `b6c47d4ee42c` | certain | Image key removed. | `modules/hall-ui/public/settings.js:1129` |
571
572
  | `783853467d52` | certain | Image-generation key | `modules/hall-ui/public/settings.html:184` |
572
573
  | `5c2e2bcbd5fb` | certain | In Progress | `modules/hall-ui/public/work.html:115` |
@@ -667,8 +668,9 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
667
668
  | `1ae18e58fead` | certain | Most recent first. Each load of this page is itself recorded in the audit log. | `modules/hall-ui/public/sessions.js:340` |
668
669
  | `f14a91b3f625` | certain | Most recent first. Each row is one recorded work session; every id on it opens its record. | `modules/hall-ui/public/sessions.html:56` |
669
670
  | `e52ae74f0052` | certain | Move to goal | `modules/hall-ui/public/task.js:581` |
670
- | `e77d5f3beaef` | certain | Move to {…} | `modules/hall-ui/public/deploy.js:360` |
671
- | `e77d5f3beaef` | certain | Move to {…} | `modules/hall-ui/public/deploy.js:472` |
671
+ | `e77d5f3beaef` | certain | Move to {…} | `modules/hall-ui/public/deploy.js:395` |
672
+ | `e77d5f3beaef` | certain | Move to {…} | `modules/hall-ui/public/deploy.js:507` |
673
+ | `a851e4dc141b` | certain | Moved {…}, and the box confirmed it. The project’s repository on GitHub still names the old core, so changes p | `modules/hall-ui/public/deploy.js:216` |
672
674
  | `393139f648b8` | certain | Moving to core | `modules/hall-ui/public/deploy.js:157` |
673
675
  | `ae84ebe1d735` | certain | Name cannot be blank. | `modules/hall-ui/public/settings.js:761` |
674
676
  | `31e91ee6ce03` | certain | Name must be {…} characters or fewer. | `modules/hall-ui/public/settings.js:766` |
@@ -707,10 +709,10 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
707
709
  | `1a46c31343cb` | certain | No projects are hosted here yet. | `modules/hall-ui/public/fleet-costs.js:68` |
708
710
  | `9f73b3f3dad0` | certain | No rank floor — any builder can claim this task | `modules/hall-ui/public/task-lib.js:82` |
709
711
  | `3fd0c6fcb92e` | certain | No request and no invite needed. Sign in with GitHub, and a step-by-step guide takes you the rest of the way. | `modules/hall-ui/public/hall-render.js:277` |
710
- | `2947c1ddea9a` | certain | No running box to deploy. | `modules/hall-ui/public/deploy.js:450` |
712
+ | `2947c1ddea9a` | certain | No running box to deploy. | `modules/hall-ui/public/deploy.js:485` |
711
713
  | `9fb9f766450d` | certain | No sections yet | `modules/hall-ui/public/primer.js:130` |
712
714
  | `bef9fe43ba84` | certain | No sessions recorded yet. They land here as builders ship and end sessions. | `modules/hall-ui/public/sessions.js:146` |
713
- | `084748fd85b4` | certain | No shipped work is recorded between core {…} and {…}. | `modules/hall-ui/public/deploy.js:340` |
715
+ | `084748fd85b4` | certain | No shipped work is recorded between core {…} and {…}. | `modules/hall-ui/public/deploy.js:375` |
714
716
  | `4485497d87bb` | certain | No specialities yet. Create one below — it takes a name and a craft, and you can train it afterwards. | `modules/hall-ui/public/settings-specialities.js:169` |
715
717
  | `545dc44ad427` | certain | No task in this goal depends on another task in this goal. | `modules/hall-ui/public/goal-forest-render.js:126` |
716
718
  | `712b64d8273f` | certain | No tasks match these filters. Try widening them. | `modules/hall-ui/public/work.js:423` |
@@ -722,7 +724,7 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
722
724
  | `c65c9f5c02e3` | certain | Nobody is waiting on you. Requests reach you by role — | `modules/hall-ui/public/collab.html:54` |
723
725
  | `91c409a4aea5` | certain | Nobody vouched for this name — anyone can file a request naming anyone. Confirm who is asking before you admit | `modules/hall-ui/public/watch.js:374` |
724
726
  | `4016b9cf8d57` | certain | None of your asks have been settled yet. | `modules/hall-ui/public/collab.html:134` |
725
- | `428a62539050` | certain | Not checked yet — the runner takes this reading on its own tick. | `modules/hall-ui/public/deploy.js:254` |
727
+ | `428a62539050` | certain | Not checked yet — the runner takes this reading on its own tick. | `modules/hall-ui/public/deploy.js:289` |
726
728
  | `c72e0bdb834a` | certain | Not declared in module.json — this is who ships the module. | `modules/hall-ui/public/modules.js:62` |
727
729
  | `361b353ded5e` | certain | Not enough shipped work yet to chart. | `modules/hall-ui/public/hall-widgets.js:184` |
728
730
  | `90230572d017` | certain | Not found | `modules/hall-ui/public/task.js:970` |
@@ -743,12 +745,13 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
743
745
  | `fec5d78497e8` | certain | Nothing in the backlog right now. | `modules/hall-ui/public/work.js:1087` |
744
746
  | `905e99f158c2` | certain | Nothing is discarded by omission: every task needs a decision before this can be submitted. Abandoning stamps | `modules/hall-ui/public/goals-render.js:1036` |
745
747
  | `2ec0fbb20a42` | certain | Nothing is waiting. A spark appears here when its author offers a quick idea up for development. | `modules/hall-ui/public/ideas.js:847` |
746
- | `9ac63d97239a` | certain | Nothing newer is published that this box can take. There is nothing to deploy. | `modules/hall-ui/public/deploy.js:395` |
748
+ | `9ac63d97239a` | certain | Nothing newer is published that this box can take. There is nothing to deploy. | `modules/hall-ui/public/deploy.js:430` |
747
749
  | `43626cff7071` | certain | Nothing of that kind in your sky. | `modules/hall-ui/public/sky-panel.js:122` |
748
750
  | `ad9a17a8a5eb` | certain | Nothing shipped yet. | `modules/hall-ui/public/profile.js:242` |
749
751
  | `f326632f2013` | certain | Nothing to submit — every module here ships with the core. | `modules/hall-ui/public/modules.js:258` |
750
752
  | `27c0d872db2d` | certain | Nothing you have typed above is lost by opening this. | `modules/hall-ui/public/ideas.html:155` |
751
- | `26a07b64f49d` | certain | Now running core {…} | `modules/hall-ui/public/deploy.js:211` |
753
+ | `26a07b64f49d` | certain | Now running core {…} | `modules/hall-ui/public/deploy.js:226` |
754
+ | `21cb60a8a96a` | certain | Now running core {…} — but GitHub was not updated. | `modules/hall-ui/public/deploy.js:216` |
752
755
  | `9d25ba1d2f17` | certain | Off voice — says it in the wrong register | `modules/hall-ui/public/copy-desk.html:89` |
753
756
  | `b89ad49770e7` | certain | On Windows, run | `modules/hall-ui/public/hall-render.js:890` |
754
757
  | `11a1905c76b2` | certain | On the board | `modules/hall-ui/public/hall-render.js:626` |
@@ -935,7 +938,7 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
935
938
  | `324af64c8b6e` | certain | See all {…} goals {…} | `modules/hall-ui/public/roadmap.js:207` |
936
939
  | `a9c398651862` | certain | See the cross-project record | `modules/hall-ui/public/profile-canonical.js:114` |
937
940
  | `17d5b5739f46` | certain | See the work board → | `modules/hall-ui/public/hall-render.js:1003` |
938
- | `55cde0774831` | certain | See what would change | `modules/hall-ui/public/deploy.js:221` |
941
+ | `55cde0774831` | certain | See what would change | `modules/hall-ui/public/deploy.js:256` |
939
942
  | `292761c89fae` | certain | See which goals wait on each other → | `modules/hall-ui/public/goals.html:47` |
940
943
  | `75dc5463facc` | certain | Select at least 2 waiting tasks to copy a parallel-session prompt. | `modules/hall-ui/public/work.js:829` |
941
944
  | `a98882faa482` | certain | Select at least 2 waiting tasks to copy a sequential prompt. | `modules/hall-ui/public/work.js:854` |
@@ -944,7 +947,7 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
944
947
  | `7e1d54119e08` | certain | Select task {…} for bulk release | `modules/hall-ui/public/work.js:242` |
945
948
  | `ae43a132699b` | certain | Selectable today | `modules/hall-ui/public/government.js:799` |
946
949
  | `53cc6d8dd23c` | certain | Send invitation | `modules/hall-ui/public/goals-render.js:1235` |
947
- | `a39b0f9d86e5` | certain | Serving {…} — read from the box itself, {…}. | `modules/hall-ui/public/deploy.js:398` |
950
+ | `a39b0f9d86e5` | certain | Serving {…} — read from the box itself, {…}. | `modules/hall-ui/public/deploy.js:433` |
948
951
  | `64a1f055129e` | certain | Session card richness | `modules/hall-ui/public/settings-render.js:83` |
949
952
  | `d14e8e9acaff` | certain | Session ended. | `modules/hall-ui/public/settings-sessions.js:81` |
950
953
  | `55e0a34bafed` | certain | Session log{…} | `modules/hall-ui/public/task.js:487` |
@@ -1005,7 +1008,7 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
1005
1008
  | `ec1c2dae4a90` | certain | Standing there | `modules/hall-ui/public/profile.js:314` |
1006
1009
  | `eaad12cacb9d` | certain | Start over | `modules/hall-ui/public/studio.js:235` |
1007
1010
  | `efe530c0e3a7` | certain | Still open | `modules/hall-ui/public/profile.js:494` |
1008
- | `490a3cbb8c1c` | certain | Still working on core {…}. It keeps going without this page — reload to see where it got to. | `modules/hall-ui/public/deploy.js:506` |
1011
+ | `490a3cbb8c1c` | certain | Still working on core {…}. It keeps going without this page — reload to see where it got to. | `modules/hall-ui/public/deploy.js:541` |
1009
1012
  | `9a4ced1afb6c` | certain | Stop waiting on task {…} | `modules/hall-ui/public/task.js:278` |
1010
1013
  | `b0861c874a2f` | certain | Stopped using it. | `modules/hall-ui/public/settings-specialities.js:200` |
1011
1014
  | `6c6544f5c011` | certain | Stored encrypted; never shown again after saving — only its last four digits. | `modules/hall-ui/public/settings.html:193` |
@@ -1111,7 +1114,7 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
1111
1114
  | `198ba9353bf6` | certain | The task feed did not answer. Nothing on the record has changed, only the read failed. Try again in a moment, | `modules/hall-ui/public/task.js:975` |
1112
1115
  | `34555793f33e` | certain | The task list could not be loaded right now. | `modules/hall-ui/public/work.js:1288` |
1113
1116
  | `aed969dd1e18` | certain | The unattended runner works only the goals listed here, and only while it is on. This is the switch — it lives | `modules/hall-ui/public/gate.html:54` |
1114
- | `8c991355687d` | certain | The upgrade checked {…} and refused:{…} | `modules/hall-ui/public/deploy.js:264` |
1117
+ | `8c991355687d` | certain | The upgrade checked {…} and refused:{…} | `modules/hall-ui/public/deploy.js:299` |
1115
1118
  | `a42a37c43bfb` | certain | The words this project shows people — what has been flagged, and what nobody has looked at. | `modules/hall-ui/public/copy-desk.js:328` |
1116
1119
  | `bcdbded93d4e` | certain | The work board failed to load. Reload to try again. | `modules/hall-ui/public/work.js:1492` |
1117
1120
  | `25794c439321` | certain | Then copy the project onto your machine and run the one-shot bootstrap (it checks your setup, installs depende | `modules/hall-ui/public/hall-render.js:890` |
@@ -1148,13 +1151,13 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
1148
1151
  | `9a685b01e2c6` | certain | This page opens at a higher rank. | `modules/hall-ui/public/government.html:37` |
1149
1152
  | `9a685b01e2c6` | certain | This page opens at a higher rank. | `modules/hall-ui/public/project-settings.html:36` |
1150
1153
  | `9a685b01e2c6` | certain | This page opens at a higher rank. | `modules/hall-ui/public/watch.html:40` |
1151
- | `3c8aaec39c40` | certain | This project's code expects {…} database change{…} that its database has not applied yet. Anything that relies | `modules/hall-ui/public/deploy.js:378` |
1152
- | `6e9dfe1fb903` | certain | This restarts {…} onto core | `modules/hall-ui/public/deploy.js:360` |
1154
+ | `3c8aaec39c40` | certain | This project's code expects {…} database change{…} that its database has not applied yet. Anything that relies | `modules/hall-ui/public/deploy.js:413` |
1155
+ | `6e9dfe1fb903` | certain | This restarts {…} onto core | `modules/hall-ui/public/deploy.js:395` |
1153
1156
  | `69e8beced2ff` | certain | This sends the idea back to its author. Say why, and which section. | `modules/hall-ui/public/board-room.js:363` |
1154
1157
  | `09256febc32d` | certain | This sentence has {…} {…} where a value is dropped in when it is shown. | `modules/hall-ui/public/copy-desk.js:422` |
1155
1158
  | `c9e50a67988a` | certain | This task has shipped and its credits have landed. Neither Ship it nor Confirm is available. | `modules/hall-ui/public/task.js:719` |
1156
1159
  | `62b0940efd7d` | certain | This task is already retired. Promote restores it to the backlog. | `modules/hall-ui/public/task.js:755` |
1157
- | `4301ecd67891` | certain | This would fail. | `modules/hall-ui/public/deploy.js:264` |
1160
+ | `4301ecd67891` | certain | This would fail. | `modules/hall-ui/public/deploy.js:299` |
1158
1161
  | `2ad5823d2cd7` | certain | Three dials, all settings rather than code: | `modules/hall-ui/public/government.html:55` |
1159
1162
  | `82367d2122af` | certain | To paste the sign-in code: | `modules/hall-ui/public/hall-render.js:825` |
1160
1163
  | `f158ed1c24a2` | certain | Toggle fullscreen | `modules/hall-ui/public/diagram-viewer.js:101` |
@@ -1202,7 +1205,7 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
1202
1205
  | `2dd116d2d817` | certain | What the current wording gets wrong, and what yours does about it. | `modules/hall-ui/public/copy-desk.html:166` |
1203
1206
  | `e179870922a3` | certain | What the session did, derived from its own transcript: whether it wrote files, used tools, and how many prompt | `modules/hall-ui/public/sessions.html:74` |
1204
1207
  | `515f3c6023a9` | certain | What the upgrade said | `modules/hall-ui/public/deploy.js:189` |
1205
- | `5a58392783fd` | certain | What this brings in | `modules/hall-ui/public/deploy.js:349` |
1208
+ | `5a58392783fd` | certain | What this brings in | `modules/hall-ui/public/deploy.js:384` |
1206
1209
  | `a444ad812e4f` | certain | What this builder has done, seen one role at a time. | `modules/hall-ui/public/profile.html:134` |
1207
1210
  | `32d675a2b022` | certain | What this rank is for (optional) | `modules/hall-ui/public/government.html:90` |
1208
1211
  | `04b3ff4c4f4c` | certain | What users can see | `modules/hall-ui/public/deploy.html:35` |
@@ -1242,7 +1245,7 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
1242
1245
  | `b6b0fcb2bcee` | certain | You already have a pending request or invitation for this goal. | `modules/hall-ui/public/goals-render.js:1389` |
1243
1246
  | `52e93bbc07a6` | certain | You are already a member of this goal. | `modules/hall-ui/public/goals-render.js:1390` |
1244
1247
  | `46b1265ef172` | certain | You are not a member of this goal. | `modules/hall-ui/public/goals-render.js:1346` |
1245
- | `921cb15a8188` | certain | You can still press Move — the runner will refuse it the same way, and the box is left where it is. | `modules/hall-ui/public/deploy.js:264` |
1248
+ | `921cb15a8188` | certain | You can still press Move — the runner will refuse it the same way, and the box is left where it is. | `modules/hall-ui/public/deploy.js:299` |
1246
1249
  | `b31fc908c962` | certain | You claimed #{…}. Open a terminal to start work. | `modules/hall-ui/public/goals-page.js:424` |
1247
1250
  | `b31fc908c962` | certain | You claimed #{…}. Open a terminal to start work. | `modules/hall-ui/public/goals-page.js:523` |
1248
1251
  | `b31fc908c962` | certain | You claimed #{…}. Open a terminal to start work. | `modules/hall-ui/public/work.js:916` |
@@ -1377,7 +1380,7 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
1377
1380
  | `77ad318bb546` | certain | invited — awaiting their response | `modules/hall-ui/public/goals-render.js:1424` |
1378
1381
  | `af0777cd098b` | certain | is hardcoded back inside this | `modules/hall-ui/public/index.html:56` |
1379
1382
  | `c767b3e07826` | certain | is only the screen; the | `modules/hall-ui/public/diagrams.html:74` |
1380
- | `d0e722302840` | certain | is published and this box is not on it yet. | `modules/hall-ui/public/deploy.js:221` |
1383
+ | `d0e722302840` | certain | is published and this box is not on it yet. | `modules/hall-ui/public/deploy.js:256` |
1381
1384
  | `37ac5d5b6779` | certain | is the BRAND (the h1 and the figures) and the lens and tools stay its siblings inside the same .top strip — th | `modules/hall-ui/public/goal-map.html:53` |
1382
1385
  | `aa530bd15088` | certain | itself). The registry stays the single source of truth for what the hall shows; a fitness check (scripts/gds/f | `modules/hall-ui/public/index.html:53` |
1383
1386
  | `6b530a7007bc` | certain | jump to a goal or a thought | `modules/hall-ui/public/goal-map.html:81` |
@@ -1432,7 +1435,8 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
1432
1435
  | `2fb1dad96280` | certain | pending, on the People tab | `modules/hall-ui/public/watch.html:46` |
1433
1436
  | `3b22c5af029b` | certain | rank or above, or that it is your own. | `modules/hall-ui/public/copy-desk.html:47` |
1434
1437
  | `80ddf28baee7` | certain | rank-key (kebab-case) | `modules/hall-ui/public/government.html:82` |
1435
- | `41a4b66c21e5` | certain | reads the control plane's own observation · ADR 0293 · every move is recorded with who asked | `modules/hall-ui/public/deploy.js:454` |
1438
+ | `41a4b66c21e5` | certain | reads the control plane's own observation · ADR 0293 · every move is recorded with who asked | `modules/hall-ui/public/deploy.js:489` |
1439
+ | `8d810f134b7b` | certain | reconnect GitHub with repository access | `modules/hall-ui/public/deploy.js:250` |
1436
1440
  | `f83f0a9d6b6a` | certain | recorded, on the Operations tab | `modules/hall-ui/public/watch.html:49` |
1437
1441
  | `26da1df6fd4a` | certain | reflects it. | `modules/hall-ui/public/settings.html:136` |
1438
1442
  | `9eca058c6ad2` | certain | release a thought — one line | `modules/hall-ui/public/goal-map.html:87` |
@@ -1592,7 +1596,7 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
1592
1596
  | `729d4ce22b99` | certain | — any — | `modules/hall-ui/public/hall-widgets.js:132` |
1593
1597
  | `13c0414d2a10` | certain | — attempted{…}. This project is still running core {…}. | `modules/hall-ui/public/deploy.js:203` |
1594
1598
  | `d2c30a1ee74e` | certain | — decide — | `modules/hall-ui/public/goals-render.js:1000` |
1595
- | `e31a588bb9e1` | certain | — moved {…}, and the box confirmed it. | `modules/hall-ui/public/deploy.js:211` |
1599
+ | `e31a588bb9e1` | certain | — moved {…}, and the box confirmed it. | `modules/hall-ui/public/deploy.js:226` |
1596
1600
  | `417adabd1a00` | certain | — no goal suggested — open the goal board and pick one — | `modules/hall-ui/public/task-detail.js:412` |
1597
1601
  | `da9962dc1729` | certain | — or open any diagram fullscreen. | `modules/hall-ui/public/diagrams.html:33` |
1598
1602
  | `e5c5e94152b3` | certain | — that's all the tooling you need up front. | `modules/hall-ui/public/hall-render.js:890` |
@@ -1602,11 +1606,11 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
1602
1606
  | `8f1d0e229725` | certain | — your thinking | `modules/hall-ui/public/thinking.html:57` |
1603
1607
  | `d3afa6d6dd9e` | certain | — your words, in your voice. Needed for a note or a follow-up. | `modules/hall-ui/public/studio.js:162` |
1604
1608
  | `68b547166d48` | certain | — {…} confirmed {…} can't land yet, so {…} reward is pending (it lands on ship). Rebase + re-ship or release { | `modules/hall-ui/public/hall-render.js:558` |
1605
- | `8f2eba6e0da8` | certain | — {…} {…} of work landed between core {…} and {…}{…}: | `modules/hall-ui/public/deploy.js:349` |
1609
+ | `8f2eba6e0da8` | certain | — {…} {…} of work landed between core {…} and {…}{…}: | `modules/hall-ui/public/deploy.js:384` |
1606
1610
  | `28fef677706c` | certain | — {…}. The project restarts as part of this, and puts itself back on {…} if the new core does not answer. This | `modules/hall-ui/public/deploy.js:157` |
1607
1611
  | `9a1cef2da08d` | certain | …and {…} more goals — | `modules/hall-ui/public/goal-inbox.js:127` |
1608
1612
  | `5b9fa7cb4fb0` | certain | …and {…} more waiting — | `modules/hall-ui/public/goal-inbox.js:158` |
1609
- | `b797996b2e4f` | certain | …and {…} more, not listed. | `modules/hall-ui/public/deploy.js:347` |
1613
+ | `b797996b2e4f` | certain | …and {…} more, not listed. | `modules/hall-ui/public/deploy.js:382` |
1610
1614
  | `b2a04abfead0` | certain | …{…} more awaiting a nod. | `modules/hall-ui/public/goal-inbox.js:316` |
1611
1615
  | `f16717b3e122` | certain | …{…} more awaiting an answer. | `modules/hall-ui/public/goal-inbox.js:396` |
1612
1616
  | `616fb9adf3cf` | certain | …{…} more going quiet. | `modules/hall-ui/public/goal-inbox.js:485` |