@bongos/core 1.19.306 → 1.19.308

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 CHANGED
@@ -2,22 +2,22 @@
2
2
  "artifact": "bongos-core",
3
3
  "manifest_schema": 1,
4
4
  "generator": "scripts/gds/package-core.js",
5
- "core_version": "1.19.306",
6
- "core_contract": "1.19.306",
7
- "source_commit": "bfb69ddea49ebcce6d1d0608dd8e1fc50cc755e2",
5
+ "core_version": "1.19.308",
6
+ "core_contract": "1.19.308",
7
+ "source_commit": "73400ffdb3672b797a1dda57f589d9cc43da2ed1",
8
8
  "source_ref": "HEAD",
9
- "built_at": "2026-08-23T19:41:29.546Z",
9
+ "built_at": "2026-08-23T20:30:08.216Z",
10
10
  "redaction": {
11
11
  "model": "docs-redacted+functional-verbatim",
12
12
  "docs_redacted": 322,
13
13
  "agent_docs_stubbed": 22,
14
- "functional_verbatim": 1416,
14
+ "functional_verbatim": 1420,
15
15
  "rules": 3,
16
16
  "gate_literals": 3,
17
17
  "gate": "passed"
18
18
  },
19
- "file_count": 1760,
20
- "tree_sha256": "a2c3f65e69e891c0076d0b10268d3549cfddf8d76d1f320274e86fd833d56013",
19
+ "file_count": 1764,
20
+ "tree_sha256": "bfea309c25b9ba974096b8f0572e268ea80238aaf00e23d700adeb9e58458d49",
21
21
  "files": [
22
22
  {
23
23
  "path": ".claude/skills/blocker-review/SKILL.md",
@@ -97,7 +97,7 @@
97
97
  {
98
98
  "path": ".claude/skills/builder-ship/SKILL.md",
99
99
  "mode": "0000644",
100
- "sha256": "bb9075e768b4cbc6142e2b4b24a57f92e9a4ae75d76f6849566082e0c5495d13"
100
+ "sha256": "78fcb68ce3ff4b1028904acb9d4d0a37dadd8377108fefef248feef010e4c8b1"
101
101
  },
102
102
  {
103
103
  "path": ".claude/skills/builder-stage/SKILL.md",
@@ -142,7 +142,7 @@
142
142
  {
143
143
  "path": ".claude/skills/fix-task/SKILL.md",
144
144
  "mode": "0000644",
145
- "sha256": "2ccc2a59ce44ba21c18db999c86768252b2fa6c8be6fa81f2b00a71eb727e664"
145
+ "sha256": "59b29fcdf54fe51e85191d1a66be237ef35432b76b26a10ec67e46bf08b4d1d3"
146
146
  },
147
147
  {
148
148
  "path": ".claude/skills/goal-create/SKILL.md",
@@ -1662,12 +1662,12 @@
1662
1662
  {
1663
1663
  "path": "docs/recipes/claude-design-loop.md",
1664
1664
  "mode": "0000644",
1665
- "sha256": "4f2e7cc445ae05968ba65fcb0c995cb358f144344dcb498047ec753a5a229a39"
1665
+ "sha256": "389dbbbfb7c941315731d533e300b5d43f40a8aac866c5a1c74c32d5be212a22"
1666
1666
  },
1667
1667
  {
1668
1668
  "path": "docs/recipes/core-release-pipeline.md",
1669
1669
  "mode": "0000644",
1670
- "sha256": "100a1bd6bde327c60f37727ce85f75cf5539b007473359692de7ab87876c936b"
1670
+ "sha256": "b42d8b4620355bef0e27480b2ddfaa07140e322de988839f0e102f1a1545ac47"
1671
1671
  },
1672
1672
  {
1673
1673
  "path": "docs/recipes/devbox-app-release.md",
@@ -1687,7 +1687,7 @@
1687
1687
  {
1688
1688
  "path": "docs/recipes/figma-design-loop.md",
1689
1689
  "mode": "0000644",
1690
- "sha256": "0c2c462d59634b9ec0e777d713cbc0bdc5af06408aa8b3717d2afac09c0070f0"
1690
+ "sha256": "6bfee82bddc07a5743316e310dda1e6cb7266fa7805fc1eed67bc8cc17980b46"
1691
1691
  },
1692
1692
  {
1693
1693
  "path": "docs/recipes/gds-db-backup.md",
@@ -4577,12 +4577,12 @@
4577
4577
  {
4578
4578
  "path": "package-lock.json",
4579
4579
  "mode": "0000644",
4580
- "sha256": "ab53e6d02f437a24895dd3d04b3e8ef39ddf4257b8c4b2e784a84dd10820adc4"
4580
+ "sha256": "4293f77940579b7c64fa5bc09f5a132c27efb5e4d21ee37a29ee3cf08d60ad88"
4581
4581
  },
4582
4582
  {
4583
4583
  "path": "package.json",
4584
4584
  "mode": "0000644",
4585
- "sha256": "c98acd264e43f570b82f0c7c72efb952d6e68758794f4c49a78db06cf44a867f"
4585
+ "sha256": "254eba7acbbc7ba707abfe41dd50f8e83880cf8f93cbe5daff2c88cf02dd46f1"
4586
4586
  },
4587
4587
  {
4588
4588
  "path": "public-docs/index.html",
@@ -5082,7 +5082,7 @@
5082
5082
  {
5083
5083
  "path": "scripts/gds/cli-lib.js",
5084
5084
  "mode": "0000644",
5085
- "sha256": "95574e210b1fd215b10c7664da109b0698b18aa7724daa736bade6d752318f63"
5085
+ "sha256": "5aa658b099b2acda06cdb3aecfe905da7de79f2b12c844faca091ff061454017"
5086
5086
  },
5087
5087
  {
5088
5088
  "path": "scripts/gds/code.js",
@@ -5309,6 +5309,11 @@
5309
5309
  "mode": "0000644",
5310
5310
  "sha256": "75130de4a880fc7d76f5a8d79ed65750238df94847c1ccfdc974188f9300a1e6"
5311
5311
  },
5312
+ {
5313
+ "path": "scripts/gds/go-live.js",
5314
+ "mode": "0000644",
5315
+ "sha256": "05734e21763cc0b0614275efa76b7b68afabee8be93f3f2d797400d6a97e86c1"
5316
+ },
5312
5317
  {
5313
5318
  "path": "scripts/gds/goal.js",
5314
5319
  "mode": "0000644",
@@ -5784,10 +5789,15 @@
5784
5789
  "mode": "0000644",
5785
5790
  "sha256": "087def1396283b19cb8a6deea4cc7f362d7a2f164d496a587220f0a48568aae6"
5786
5791
  },
5792
+ {
5793
+ "path": "scripts/gds/ship-honesty.js",
5794
+ "mode": "0000644",
5795
+ "sha256": "32827178a46cc01c36c422e1adef433be99492e8444a8affbe51e5e8c1e8ce9f"
5796
+ },
5787
5797
  {
5788
5798
  "path": "scripts/gds/ship.js",
5789
5799
  "mode": "0000644",
5790
- "sha256": "73c2e91340171d6a9112e869552be17e0f82aeb80a5c680205ac452d34c3ddc4"
5800
+ "sha256": "f3005175abc0ba20e958381df6aee02402267e9956da466386656dd4e86ad8cf"
5791
5801
  },
5792
5802
  {
5793
5803
  "path": "scripts/gds/smoke-batch-claim.sh",
@@ -6242,7 +6252,7 @@
6242
6252
  {
6243
6253
  "path": "src/module-api.js",
6244
6254
  "mode": "0000644",
6245
- "sha256": "31f8e9579aa3e015fc2c1f819d5d84076db27e831bfb3419ca48141cbcd84038"
6255
+ "sha256": "87cec9eba20525297a298914c20d89882db138f0cdbc5c1ae4a5ce3d285147db"
6246
6256
  },
6247
6257
  {
6248
6258
  "path": "src/module-loader/catalog.js",
@@ -7159,6 +7169,11 @@
7159
7169
  "mode": "0000644",
7160
7170
  "sha256": "d0d10628a17717fdef505dcf501915ecfcc31a0c99d9e5d4cf6dc06b47d8c883"
7161
7171
  },
7172
+ {
7173
+ "path": "tests/go_live.mjs",
7174
+ "mode": "0000644",
7175
+ "sha256": "90c8cbfd8bf0b446261f9fd837b9b08b1035210f1cbf1f7ff81998ec535c32f1"
7176
+ },
7162
7177
  {
7163
7178
  "path": "tests/goal_abuse_matrix.mjs",
7164
7179
  "mode": "0000644",
@@ -8282,7 +8297,7 @@
8282
8297
  {
8283
8298
  "path": "tests/route_rank_check.mjs",
8284
8299
  "mode": "0000644",
8285
- "sha256": "1cb0af04d3f0f837ab19c5c821e91ca7a183f2744608d7ee3b79b4886fbbd4ed"
8300
+ "sha256": "bdc58224050392ece492ae8e8f12f62a8934d86e3993e0df5b8cb0aac80602e8"
8286
8301
  },
8287
8302
  {
8288
8303
  "path": "tests/route_validation.mjs",
@@ -8504,6 +8519,11 @@
8504
8519
  "mode": "0000644",
8505
8520
  "sha256": "afdb09a3ee072fea82390a187c12c42d8249fce0ce84644a4b8dff6a643dd009"
8506
8521
  },
8522
+ {
8523
+ "path": "tests/ship_cannot_lie.mjs",
8524
+ "mode": "0000644",
8525
+ "sha256": "82f6f951cc50c34860545be0f309e18a796ebb5baa712ccb341e1fd0dd72a233"
8526
+ },
8507
8527
  {
8508
8528
  "path": "tests/ship_card.mjs",
8509
8529
  "mode": "0000644",
@@ -8552,7 +8572,7 @@
8552
8572
  {
8553
8573
  "path": "tests/ship_smoke_gate.mjs",
8554
8574
  "mode": "0000644",
8555
- "sha256": "43e2f109ce85e99e71daa4573a6ec4fc591b167fe81ee02f2f73ea1ce84d465c"
8575
+ "sha256": "6ce7bd5d2a8910e201a9869c8a3f22ef210fd4400fbd14777d8d15d13252a97e"
8556
8576
  },
8557
8577
  {
8558
8578
  "path": "tests/ship_upload_skip.mjs",
@@ -7,7 +7,7 @@ You are shipping a task on behalf of the current builder. Shipping is the moment
7
7
 
8
8
  ## What this skill does
9
9
 
10
- Runs `node scripts/gds/ship.js <task-id> --notes "..." --summary "..."`.
10
+ Runs `node scripts/gds/ship.js <task-id> --notes-file notes.md --summary-file summary.txt`.
11
11
 
12
12
  The CLI drives a **three-state lifecycle** with a subagent grader between states (Phase 5, 2026-05-10):
13
13
 
@@ -34,7 +34,7 @@ The CLI drives a **three-state lifecycle** with a subagent grader between states
34
34
 
35
35
  **When you see that block, position the sandbox link prominently for the builder.** `ship.js` also emits the deterministic lifecycle card for the `review` stage (an `[otb-card-html] <path>` marker) — if an in-feed visualization tool is available, render that card (its primary action is **Open in sandbox ↗**, the URL); it's the cleanest way to make the link impossible to miss. Either way, surface the URL as its own standalone, clickable line in chat — a clear callout, NOT buried inside a paragraph of command output — and say in one line what to look at. This is the moment the change is ready to review; the link must be impossible to miss. Let the builder open it, review, and suggest changes; iterate if needed. **Only once the builder explicitly approves, re-run with `node scripts/gds/ship.js <id> --approved`** — that records their sign-off as a durable `sandbox_review` fact on the task (who, when, and the content stamp of exactly what was reviewed). Never pass `--approved` yourself without a real human go; the pause + sign-off IS the feature. `--skip-stage` is the escape hatch (use sparingly — the gate exists so unreviewed game changes don't ride straight to prod). Laptop sessions and non-game diffs are unaffected.
36
36
 
37
- 2. **Compose the handoff notes (`--notes`)** following the structure in `docs/handoff-template.md`:
37
+ 2. **Compose the handoff notes (`--notes-file`)** following the structure in `docs/handoff-template.md`:
38
38
  - What shipped (with confidence tags: verified-prod | verified-smoke | implemented-not-verified)
39
39
  - What's broken or unverified
40
40
  - Manual checks the next session should run first
@@ -52,16 +52,28 @@ The CLI drives a **three-state lifecycle** with a subagent grader between states
52
52
  - "Sessions can claim work atomically; merge conflicts can't happen across worktrees."
53
53
  No jargon, no file paths, no commit hashes.
54
54
 
55
- 4. **Run**:
55
+ 4. **Run** — write the prose to files and pass the file (task 1003168):
56
56
  ```bash
57
- node scripts/gds/ship.js <task-id> \
58
- --notes "$(cat <<'EOF'
59
- ...handoff markdown...
60
- EOF
61
- )" \
62
- --summary "the one-liner"
57
+ # write notes.md and summary.txt with your editor/Write tool first
58
+ node scripts/gds/ship.js <task-id> --notes-file notes.md --summary-file summary.txt
63
59
  ```
64
60
 
61
+ **Use the `-file` forms.** Handoff notes are technical prose, so they contain
62
+ backticks — and a backtick in an inline `--notes "..."` is command-substituted
63
+ by the shell *before* node runs: the span executes, its output replaces it, and
64
+ the rest of the argument list is truncated. That is not hypothetical; it shipped
65
+ a task with **empty notes and no summary**, so the ledger held nothing about a
66
+ session that had happened (learning 1000197). A file argument is the one form
67
+ the shell cannot rewrite. `-` reads stdin if you'd rather pipe.
68
+
69
+ Inline `--notes "..."` / `--summary "..."` still work for short prose with no
70
+ backticks, `$`, or newlines. The older documented form —
71
+ `--notes "$(cat <<'EOF' … EOF)"` — is *also* shell-safe, because the quoted
72
+ heredoc delimiter suppresses expansion; it is simply easy to get subtly wrong,
73
+ and when you do the failure is silent. Passing both `--notes` and
74
+ `--notes-file` is refused rather than resolved by precedence, so nothing you
75
+ wrote is dropped without a word.
76
+
65
77
  **Never merge a task branch to main before running `ship.js`.** `ship.js` diffs the claim branch against `main`; an already-merged branch yields an empty diff, and the only exits are `--allow-empty` (dead-ends the task at `completed`, requiring an Archon-only confirm) or reverting the merge. Ship from the branch, then let `ship.js` land it. (This trap was hit on tasks 1002417 and 1002419, producing blockers 1000081/1000082 and an ~8.5-hour stall.)
66
78
 
67
79
  5. **Render the completion card — it IS the summary; do NOT write a prose recap (task 1270).**
@@ -39,7 +39,7 @@ Runs the recurring "claim, fix, and ship task NNNN" macro end to end. Its own va
39
39
 
40
40
  6. **Ship from the claim branch** — see `/builder-ship` for handoff notes, the value summary, and the completion-card rendering contract. In short:
41
41
  ```
42
- node scripts/gds/ship.js <id> --notes "..." --summary "..."
42
+ node scripts/gds/ship.js <id> --notes-file notes.md --summary-file summary.txt
43
43
  ```
44
44
  **Never merge the claim branch into `main` before running `ship.js`.** `ship.js` diffs the branch against `main`; a pre-merged branch yields an empty diff, and the only way out is `--allow-empty` (dead-ends the task at `completed`, needing an Archon-only confirm) or reverting the merge. Ship from the branch and let `ship.js` land it — the same trap `/builder-ship` calls out.
45
45
 
@@ -113,7 +113,7 @@ The adapter writes files to `src/ui/<surfaceId>/` and updates `config/design-sou
113
113
  ```bash
114
114
  git add src/ui/hall-ui/ config/design-sources.json
115
115
  git commit -m "ui(hall-ui): Claude Design export (task 1234)"
116
- node scripts/gds/ship.js 1234 --notes "..." --summary "..."
116
+ node scripts/gds/ship.js 1234 --notes-file notes.md --summary-file summary.txt
117
117
  ```
118
118
 
119
119
  ---
@@ -136,6 +136,38 @@ The generic mechanics are [upgrading-the-core](upgrading-the-core.md); this is t
136
136
 
137
137
  **Cadence: bump once, at session end.** One upgrade covers every release the session landed (publish-on-merge cuts one per merge — you don't chase each). Don't bump per-ship.
138
138
 
139
+ ### Step 0 — try the one command first (task 1003189)
140
+
141
+ The whole sequence below is deterministic, so it is also a script. `go-live.js` composes the
142
+ same parts this runbook narrates — `deploy-divergence.js` for the gap, the registry for proof a
143
+ release exists, and `bongos upgrade --registry --commit-pin` for the bump itself — and reports
144
+ once instead of forty times:
145
+
146
+ ```bash
147
+ node scripts/gds/go-live.js
148
+ ```
149
+
150
+ That is **plan-only and read-only**: it prints live-vs-target, checks the registry actually
151
+ carries the target, and names every halt condition it found. Add `--apply` to move the pin.
152
+
153
+ It **halts rather than guessing** on exactly the things that need judgement — unreleased commits
154
+ on `main`, a registry missing the target, a dirty tree on either end, a failed health check, an
155
+ uncommitted pin. When it halts, fall through to the manual steps below and use your own head;
156
+ that is what the rest of this section is for.
157
+
158
+ Two flags worth knowing:
159
+
160
+ - `--verify-marker <path>=<needle>` refuses a target that does not actually contain your change.
161
+ This is the guard for the trap in Step 1: the carrier sitting on `main` when your fix merged
162
+ was usually cut *before* it, so deploying "the version main was on" is a textbook-clean go-live
163
+ that changes nothing — and every downstream check agrees it worked.
164
+ - `--allow-unreleased` downgrades the UNRELEASED halt to a warning. Reach for it only when you
165
+ have already confirmed *why* main is ahead of its last release.
166
+
167
+ Host topology (ssh alias, box paths, service names, health URL) lives in a host-owned
168
+ `config/go-live.json`, never in the core — run `node scripts/gds/go-live.js --help` for the
169
+ schema. A core that named one instance's box would not be a core.
170
+
139
171
  ### Step 1 — pick the version (your machine, main checkout)
140
172
 
141
173
  ```bash
@@ -98,7 +98,7 @@ The adapter translates frames/text/solid-fill rectangles into `.js` + `.css` fil
98
98
  ```bash
99
99
  git add src/ui/hall-ui/ config/design-sources.json
100
100
  git commit -m "ui(hall-ui): Figma export (task 1234)"
101
- node scripts/gds/ship.js 1234 --notes "..." --summary "..."
101
+ node scripts/gds/ship.js 1234 --notes-file notes.md --summary-file summary.txt
102
102
  ```
103
103
 
104
104
  ---
package/package-lock.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@bongos/core",
3
- "version": "1.19.306",
3
+ "version": "1.19.308",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@bongos/core",
9
- "version": "1.19.306",
9
+ "version": "1.19.308",
10
10
  "license": "AGPL-3.0-or-later",
11
11
  "dependencies": {
12
12
  "express": "^4.21.2",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bongos/core",
3
- "version": "1.19.306",
3
+ "version": "1.19.308",
4
4
  "description": "Cloud Bongos — the AI-first build platform core (GDS + platform surfaces + module system), installed as a versioned dependency (ADR 0108).",
5
5
  "license": "AGPL-3.0-or-later",
6
6
  "main": "src/platform-server.js",
@@ -266,6 +266,58 @@ function stripBom(s) {
266
266
  return s.charCodeAt(0) === 0xfeff ? s.slice(1) : s;
267
267
  }
268
268
 
269
+ // argText(name, args, io) — resolve prose passed EITHER inline (`--notes "..."`)
270
+ // or from a file (`--notes-file path`, or `-` for stdin). Returns
271
+ // { value, source, error }: `value` is a string ('' when neither flag is
272
+ // present), `source` is 'inline' | 'file' | 'stdin' | 'none', and `error` is a
273
+ // caller-printable string when the request was refused or unreadable.
274
+ //
275
+ // WHY THIS EXISTS (learning 1000197). Prose handed to a CLI inline goes through
276
+ // the SHELL first. A handoff note containing backticks — which technical prose
277
+ // constantly does — is command-substituted by bash before node ever runs: the
278
+ // backticked span executes, its output replaces it, and the rest of the argument
279
+ // list is truncated. That is not a theoretical hazard; it silently shipped a task
280
+ // with EMPTY notes and no summary, so the ledger recorded nothing about a session
281
+ // that had happened. A file argument is the only form the shell cannot rewrite.
282
+ //
283
+ // BOTH-GIVEN IS AN ERROR, never a silent precedence. Picking one would mean the
284
+ // caller's other input vanished without a word — the same class of quiet loss
285
+ // this helper exists to end (the capture.js --spark/--full refusal precedent).
286
+ function argText(name, args = process.argv.slice(2), io = {}) {
287
+ const readFile = io.readFile || ((f) => require('fs').readFileSync(f, 'utf8'));
288
+ const readStdin = io.readStdin || (() => require('fs').readFileSync(0, 'utf8'));
289
+ const fileFlag = `${name}-file`;
290
+ const inline = arg(name, args);
291
+ // arg() returns undefined (not null) for a flag present as the LAST token, so
292
+ // presence must be tested separately — otherwise `--notes-file` with no path
293
+ // slips past the null check and resolves to an empty string, which is the very
294
+ // silent-empty outcome this helper exists to prevent.
295
+ const filePresent = args.includes(fileFlag) || args.some((a) => a.startsWith(`${fileFlag}=`));
296
+ const file = filePresent ? arg(fileFlag, args) : null;
297
+
298
+ if (inline != null && filePresent) {
299
+ return {
300
+ value: '', source: 'none',
301
+ error: `${name} and ${fileFlag} were both given. Pass one — ${fileFlag} is the safe form for prose `
302
+ + '(a shell rewrites backticks in an inline value before node sees it). Refusing rather than '
303
+ + 'silently picking one, so nothing you wrote is dropped without a word.',
304
+ };
305
+ }
306
+ if (filePresent) {
307
+ if (file == null || file === '' || file.startsWith('--')) {
308
+ return { value: '', source: 'none', error: `${fileFlag} needs a path (or - for stdin).` };
309
+ }
310
+ try {
311
+ const raw = file === '-' ? readStdin() : readFile(file);
312
+ return { value: stripBom(String(raw)), source: file === '-' ? 'stdin' : 'file', error: null };
313
+ } catch (err) {
314
+ return { value: '', source: 'none', error: `could not read ${fileFlag} ${file}: ${err.message}` };
315
+ }
316
+ }
317
+ if (inline != null) return { value: inline, source: 'inline', error: null };
318
+ return { value: '', source: 'none', error: null };
319
+ }
320
+
269
321
  // resolveQuiet(args, env) — true when api.js's stderr status banner should be
270
322
  // suppressed: the --quiet flag or the GDS_QUIET env var. Both default to the
271
323
  // live process, matching hasFlag()'s own default-args contract. Default OFF —
@@ -853,6 +905,7 @@ module.exports = {
853
905
  loadSessionSync,
854
906
  saveSession,
855
907
  arg,
908
+ argText,
856
909
  hasFlag,
857
910
  stripBom,
858
911
  repairMsysMangledPath,