@bongos/core 1.19.45 → 1.19.46

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/.bongos-core.json CHANGED
@@ -2,11 +2,11 @@
2
2
  "artifact": "bongos-core",
3
3
  "manifest_schema": 1,
4
4
  "generator": "scripts/gds/package-core.js",
5
- "core_version": "1.19.45",
6
- "core_contract": "1.19.45",
7
- "source_commit": "290f271a1fb465184f1e30a82938dbb9fc0edd7f",
5
+ "core_version": "1.19.46",
6
+ "core_contract": "1.19.46",
7
+ "source_commit": "435360b40bbcf1f8b67e811825d20c78a80fd441",
8
8
  "source_ref": "HEAD",
9
- "built_at": "2026-08-11T17:49:40.375Z",
9
+ "built_at": "2026-08-11T18:01:18.461Z",
10
10
  "redaction": {
11
11
  "model": "docs-redacted+functional-verbatim",
12
12
  "docs_redacted": 290,
@@ -17,7 +17,7 @@
17
17
  "gate": "passed"
18
18
  },
19
19
  "file_count": 1525,
20
- "tree_sha256": "0722aab68f68291e412986ff75bc5c9e53914d42248afd4dd8f3fddef07c1d82",
20
+ "tree_sha256": "3a3587819ec4fe0e5609aee28a9d9b8bd3bc11af62addc3d85d760946f0882f0",
21
21
  "files": [
22
22
  {
23
23
  "path": ".claude/skills/blocker-review/SKILL.md",
@@ -2672,7 +2672,7 @@
2672
2672
  {
2673
2673
  "path": "modules/discord/ship-broadcast.js",
2674
2674
  "mode": "0000644",
2675
- "sha256": "5c1273de955d5559e549603d7c60a6987f88696631c7536c429c04d55c2fdf5c"
2675
+ "sha256": "a6250569de6838b1769768491ed2c9bc1da30cd8cd0ebda697ea142df7d902b8"
2676
2676
  },
2677
2677
  {
2678
2678
  "path": "modules/discord/webhook.js",
@@ -4032,12 +4032,12 @@
4032
4032
  {
4033
4033
  "path": "package-lock.json",
4034
4034
  "mode": "0000644",
4035
- "sha256": "b2fc08b1d386c093629982f52a456c2b79c9f3824a22a696ed6fdb37a9073def"
4035
+ "sha256": "aed2f26ebe4fe2b47756e44e59e7860370bc7915772c5cd8dcf409861e87f6c7"
4036
4036
  },
4037
4037
  {
4038
4038
  "path": "package.json",
4039
4039
  "mode": "0000644",
4040
- "sha256": "d955953100c62b9b03bec90b70122f0a35d18bed91e60af2ae78f0573509a852"
4040
+ "sha256": "615ec3ed94ced936891d834826b98bbfeae529dad7c1886d13c6230c6d63d88a"
4041
4041
  },
4042
4042
  {
4043
4043
  "path": "public-docs/index.html",
@@ -5657,7 +5657,7 @@
5657
5657
  {
5658
5658
  "path": "src/module-api.js",
5659
5659
  "mode": "0000644",
5660
- "sha256": "ef3fa14314f284d7e93062ddc0b9ee7a046885bb13b20e41f62c7ef66eb29a24"
5660
+ "sha256": "430e72a0dc3b4e87e8a1edee33314295aae624c736065d69f5c9ea5efbb7c41b"
5661
5661
  },
5662
5662
  {
5663
5663
  "path": "src/module-loader/loader.js",
@@ -7422,7 +7422,7 @@
7422
7422
  {
7423
7423
  "path": "tests/ship_broadcast_server.mjs",
7424
7424
  "mode": "0000644",
7425
- "sha256": "72507f8192bc95ac1c3a92714d2280a43ed588820ce409586a9dad88c5677b09"
7425
+ "sha256": "2bb81a2649402bc2c17b04d17a4d749ff674f1bf5ac101d168412e709bea8550"
7426
7426
  },
7427
7427
  {
7428
7428
  "path": "tests/ship_card.mjs",
@@ -87,9 +87,14 @@ async function postShipBroadcast(task, deps = {}) {
87
87
  // NOT start with `#<taskId>` — a LEADING task marker is what the applause bot maps
88
88
  // 👍 reactions onto (discord-reaction.parseShipMarker), and a strand is not
89
89
  // applaudable shipped work.
90
- function chooseStrandTargets({ securitySensitive, taskId, reason }) {
90
+ function chooseStrandTargets({ securitySensitive, taskId, title, reason }) {
91
91
  if (taskId == null) return [];
92
- const line = `⚠️ task ${taskId} stranded at 'confirmed' (${reason || 'unknown'}) — its builder must fix + re-land it, or release it.`;
92
+ // Title folds in so the notice is self-contained (task 1002638) — a builder
93
+ // shouldn't have to look the id up to know which work died. Degrades to the
94
+ // id-only line when the payload carries none. Titles are bounded (LIMITS.TITLE
95
+ // = 200) so the line stays well under Discord's message cap.
96
+ const what = title ? `task ${taskId} — "${title}"` : `task ${taskId}`;
97
+ const line = `⚠️ ${what} stranded at 'confirmed' (${reason || 'unknown'}) — its builder must fix + re-land it, or release it.`;
93
98
  if (securitySensitive) {
94
99
  return [{ channel: 'security_ship_feed', line }];
95
100
  }
@@ -110,7 +115,7 @@ async function postStrandNotice(info, deps = {}) {
110
115
 
111
116
  const postWebhook = deps.postWebhook || require('./webhook').postWebhook;
112
117
  const log = deps.log || console.log;
113
- const targets = chooseStrandTargets({ securitySensitive: sec, taskId: info.id, reason: info.reason });
118
+ const targets = chooseStrandTargets({ securitySensitive: sec, taskId: info.id, title: info.title, reason: info.reason });
114
119
  for (const { channel, line } of targets) {
115
120
  try {
116
121
  await postWebhook(channel, line);
package/package-lock.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@bongos/core",
3
- "version": "1.19.45",
3
+ "version": "1.19.46",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@bongos/core",
9
- "version": "1.19.45",
9
+ "version": "1.19.46",
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.45",
3
+ "version": "1.19.46",
4
4
  "description": "Cloud Bongos — the AI-first build platform core (GDS + platform surfaces + module system), installed as a versioned dependency (ADR 0108).",
5
5
  "license": "AGPL-3.0-or-later",
6
6
  "main": "src/platform-server.js",
package/src/module-api.js CHANGED
@@ -517,8 +517,10 @@ const { validateOrRespond, LIMITS, parseId, asyncHandler, corsPublicGet, parsePa
517
517
  // landed since 1.19.43 with no explicit bump. run 31518312009. (task 1002620)
518
518
  // 1.19.45 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
519
519
  // landed since 1.19.44 with no explicit bump. run 31519500533. (task 1002620)
520
+ // 1.19.46 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
521
+ // landed since 1.19.45 with no explicit bump. run 31520432748. (task 1002620)
520
522
  // ---------------------------------------------------------------------------
521
- const CORE_VERSION = '1.19.45'; // CI auto-patch carrier (ADR 0161); see changelog above
523
+ const CORE_VERSION = '1.19.46'; // CI auto-patch carrier (ADR 0161); see changelog above
522
524
 
523
525
  // A namespaced logger so a module's log lines are attributable + consistent.
524
526
  // Usage: const log = api.logger('dev-box'); log.info('mounted');
@@ -194,15 +194,36 @@ test('1002606 chooseStrandTargets: security strand → ONLY #security-ship-feed
194
194
  for (const { channel } of t) assert.ok(!PUBLIC_CHANNELS.has(channel));
195
195
  });
196
196
 
197
- await atest('1002606 postStrandNotice: posts to #ship-feed for a plain strand', async () => {
197
+ test('1002638 chooseStrandTargets: title folds into the line so the notice is self-contained', () => {
198
+ const t = shipBroadcast.chooseStrandTargets({
199
+ securitySensitive: false, taskId: 88, title: 'Fix the widget frobnicator', reason: 'strand:pr_closed_unmerged',
200
+ });
201
+ assert.equal(t.length, 1);
202
+ assert.match(t[0].line, /task 88/);
203
+ assert.match(t[0].line, /Fix the widget frobnicator/);
204
+ assert.match(t[0].line, /strand:pr_closed_unmerged/);
205
+ assert.ok(!/^\s*#\d/.test(t[0].line), 'strand line must not start with a #<id> ship marker');
206
+ });
207
+
208
+ test('1002638 chooseStrandTargets: missing title degrades to the id-only line (no "undefined")', () => {
209
+ for (const title of [undefined, null, '']) {
210
+ const t = shipBroadcast.chooseStrandTargets({ securitySensitive: false, taskId: 88, title, reason: 'strand:x' });
211
+ assert.equal(t.length, 1);
212
+ assert.match(t[0].line, /task 88/);
213
+ assert.ok(!/undefined|null/.test(t[0].line), `title=${String(title)} must not leak into the line`);
214
+ }
215
+ });
216
+
217
+ await atest('1002606 postStrandNotice: posts to #ship-feed for a plain strand (title carried through — 1002638)', async () => {
198
218
  const { fn, calls } = fakePoster();
199
219
  const res = await shipBroadcast.postStrandNotice(
200
- { id: 88, builder_id: 7, security_sensitive: false, reason: 'strand:pr_closed_unmerged' },
220
+ { id: 88, builder_id: 7, title: 'Fix the widget frobnicator', security_sensitive: false, reason: 'strand:pr_closed_unmerged' },
201
221
  { postWebhook: fn, log: quietLog }
202
222
  );
203
223
  assert.deepEqual(res.posted, ['ship_feed']);
204
224
  assert.equal(calls.length, 1);
205
225
  assert.match(calls[0].line, /task 88/);
226
+ assert.match(calls[0].line, /Fix the widget frobnicator/);
206
227
  });
207
228
 
208
229
  await atest('1002606 postStrandNotice: indeterminate security flag → FAIL CLOSED (no post)', async () => {