@bongos/core 1.19.308 → 1.19.310
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 +16 -16
- package/docs/api/openapi.json +5 -5
- package/docs/api-reference.md +3 -3
- package/modules/ideas/routes/blockers.js +3 -3
- package/modules/lifecycle/routes/done-when.js +3 -3
- package/package-lock.json +2 -2
- package/package.json +1 -1
- package/scripts/gds/claude-materialize.js +16 -0
- package/src/bongos/routes/healthz.js +1 -1
- package/src/bongos/routes/public.js +2 -2
- package/src/module-api.js +5 -1
- package/tests/claude_materialize.mjs +19 -0
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.
|
|
6
|
-
"core_contract": "1.19.
|
|
7
|
-
"source_commit": "
|
|
5
|
+
"core_version": "1.19.310",
|
|
6
|
+
"core_contract": "1.19.310",
|
|
7
|
+
"source_commit": "5b818fdd0299678fb8ba3d222dd9f916281057ea",
|
|
8
8
|
"source_ref": "HEAD",
|
|
9
|
-
"built_at": "2026-08-23T20:
|
|
9
|
+
"built_at": "2026-08-23T20:40:41.952Z",
|
|
10
10
|
"redaction": {
|
|
11
11
|
"model": "docs-redacted+functional-verbatim",
|
|
12
12
|
"docs_redacted": 322,
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"gate": "passed"
|
|
18
18
|
},
|
|
19
19
|
"file_count": 1764,
|
|
20
|
-
"tree_sha256": "
|
|
20
|
+
"tree_sha256": "a15e680234e3ff733027b28fadc46849add8160eec5afcf7b7c3d5dc2509a9fb",
|
|
21
21
|
"files": [
|
|
22
22
|
{
|
|
23
23
|
"path": ".claude/skills/blocker-review/SKILL.md",
|
|
@@ -1417,12 +1417,12 @@
|
|
|
1417
1417
|
{
|
|
1418
1418
|
"path": "docs/api-reference.md",
|
|
1419
1419
|
"mode": "0000644",
|
|
1420
|
-
"sha256": "
|
|
1420
|
+
"sha256": "a654d9def4780d3210c66031193198f58fd0d7d84f5088c4ce7e6d0a58682193"
|
|
1421
1421
|
},
|
|
1422
1422
|
{
|
|
1423
1423
|
"path": "docs/api/openapi.json",
|
|
1424
1424
|
"mode": "0000644",
|
|
1425
|
-
"sha256": "
|
|
1425
|
+
"sha256": "e0b531f19187a3c00a54917bff4e2827a75b250f1aaa761229660a974a4f6217"
|
|
1426
1426
|
},
|
|
1427
1427
|
{
|
|
1428
1428
|
"path": "docs/architecture.md",
|
|
@@ -3777,7 +3777,7 @@
|
|
|
3777
3777
|
{
|
|
3778
3778
|
"path": "modules/ideas/routes/blockers.js",
|
|
3779
3779
|
"mode": "0000644",
|
|
3780
|
-
"sha256": "
|
|
3780
|
+
"sha256": "2247bb4499e6296fca8ccde3614b6726a50435786fc3cf634eaacd35982ef3f4"
|
|
3781
3781
|
},
|
|
3782
3782
|
{
|
|
3783
3783
|
"path": "modules/ideas/routes/inbox.js",
|
|
@@ -3927,7 +3927,7 @@
|
|
|
3927
3927
|
{
|
|
3928
3928
|
"path": "modules/lifecycle/routes/done-when.js",
|
|
3929
3929
|
"mode": "0000644",
|
|
3930
|
-
"sha256": "
|
|
3930
|
+
"sha256": "73dee3ef1546bf873a27bac8a160c8de64a6dbb5d0da6f3b68648d3a90e07d21"
|
|
3931
3931
|
},
|
|
3932
3932
|
{
|
|
3933
3933
|
"path": "modules/lifecycle/routes/gate-approvals.js",
|
|
@@ -4577,12 +4577,12 @@
|
|
|
4577
4577
|
{
|
|
4578
4578
|
"path": "package-lock.json",
|
|
4579
4579
|
"mode": "0000644",
|
|
4580
|
-
"sha256": "
|
|
4580
|
+
"sha256": "0d120722614fdddf98aa543303d1c1fada639e93da07d75b87fdf257e59ae098"
|
|
4581
4581
|
},
|
|
4582
4582
|
{
|
|
4583
4583
|
"path": "package.json",
|
|
4584
4584
|
"mode": "0000644",
|
|
4585
|
-
"sha256": "
|
|
4585
|
+
"sha256": "8c05cbebb968c9d858ee8ca77cb58282f6a64c876096a11cc772aa08f330d2a6"
|
|
4586
4586
|
},
|
|
4587
4587
|
{
|
|
4588
4588
|
"path": "public-docs/index.html",
|
|
@@ -5067,7 +5067,7 @@
|
|
|
5067
5067
|
{
|
|
5068
5068
|
"path": "scripts/gds/claude-materialize.js",
|
|
5069
5069
|
"mode": "0000644",
|
|
5070
|
-
"sha256": "
|
|
5070
|
+
"sha256": "a044b7ea705a87e569f903eb4fb19c941a1fbfd11b069563a2bc767be339d184"
|
|
5071
5071
|
},
|
|
5072
5072
|
{
|
|
5073
5073
|
"path": "scripts/gds/claude-md-template.js",
|
|
@@ -6162,7 +6162,7 @@
|
|
|
6162
6162
|
{
|
|
6163
6163
|
"path": "src/bongos/routes/healthz.js",
|
|
6164
6164
|
"mode": "0000644",
|
|
6165
|
-
"sha256": "
|
|
6165
|
+
"sha256": "26f4992c484d2fc5882131c695c4173db950e4c815424fad68385bfa64fa7ab8"
|
|
6166
6166
|
},
|
|
6167
6167
|
{
|
|
6168
6168
|
"path": "src/bongos/routes/instance.js",
|
|
@@ -6197,7 +6197,7 @@
|
|
|
6197
6197
|
{
|
|
6198
6198
|
"path": "src/bongos/routes/public.js",
|
|
6199
6199
|
"mode": "0000644",
|
|
6200
|
-
"sha256": "
|
|
6200
|
+
"sha256": "295b4bafc8a7bf832ed33fb0d35f4487a788caaff994383cda451cc24de2c6c7"
|
|
6201
6201
|
},
|
|
6202
6202
|
{
|
|
6203
6203
|
"path": "src/bongos/routes/security.js",
|
|
@@ -6252,7 +6252,7 @@
|
|
|
6252
6252
|
{
|
|
6253
6253
|
"path": "src/module-api.js",
|
|
6254
6254
|
"mode": "0000644",
|
|
6255
|
-
"sha256": "
|
|
6255
|
+
"sha256": "6d3b31b887cd58a7f28d9050d4f31da50bc0b82146921a175665397a6f36cc7f"
|
|
6256
6256
|
},
|
|
6257
6257
|
{
|
|
6258
6258
|
"path": "src/module-loader/catalog.js",
|
|
@@ -6727,7 +6727,7 @@
|
|
|
6727
6727
|
{
|
|
6728
6728
|
"path": "tests/claude_materialize.mjs",
|
|
6729
6729
|
"mode": "0000644",
|
|
6730
|
-
"sha256": "
|
|
6730
|
+
"sha256": "5ca8997f238d8395663992c9ce9ccef08ea2b09fbee6735c44f119050ef9455b"
|
|
6731
6731
|
},
|
|
6732
6732
|
{
|
|
6733
6733
|
"path": "tests/clawback_confirmed_backlog.mjs",
|
package/docs/api/openapi.json
CHANGED
|
@@ -1269,7 +1269,7 @@
|
|
|
1269
1269
|
"blockers"
|
|
1270
1270
|
],
|
|
1271
1271
|
"summary": "GET /blockers",
|
|
1272
|
-
"description": "List currently-open blockers + the tasks each is blocking. Public: anyone landing on /builders or status
|
|
1272
|
+
"description": "List currently-open blockers + the tasks each is blocking. Public: anyone landing on /builders or the status dashboard (status.<apex>) can see what's stuck on the owner. rank: public — open blocker list; documented \"Public: anyone landing on /builders or the status dashboard can see what's stuck on the owner\" in the handler comment above.\n\n**Rank:** `public` — No authentication — any caller.",
|
|
1273
1273
|
"x-rank": "public",
|
|
1274
1274
|
"x-source": "modules/ideas/routes/blockers.js",
|
|
1275
1275
|
"responses": {
|
|
@@ -6167,7 +6167,7 @@
|
|
|
6167
6167
|
"healthz"
|
|
6168
6168
|
],
|
|
6169
6169
|
"summary": "GET /healthz",
|
|
6170
|
-
"description": "liveness probe; status
|
|
6170
|
+
"description": "liveness probe; the status dashboard (status.<apex>) hits this anonymously.\n\n**Rank:** `public` — No authentication — any caller.",
|
|
6171
6171
|
"x-rank": "public",
|
|
6172
6172
|
"x-source": "src/bongos/routes/healthz.js",
|
|
6173
6173
|
"responses": {
|
|
@@ -10623,7 +10623,7 @@
|
|
|
10623
10623
|
"public"
|
|
10624
10624
|
],
|
|
10625
10625
|
"summary": "GET /public/tasks/:id",
|
|
10626
|
-
"description": "Single-task resolver for \"#NNN\" deep links. Our docs reference GDS task IDs as bare \"#NNN\"; read on github.com those collide with GitHub's own PR/issue autolinker (a separate number space) and mis-link, so they are rewritten to status-dashboard permalinks (status
|
|
10626
|
+
"description": "Single-task resolver for \"#NNN\" deep links. Our docs reference GDS task IDs as bare \"#NNN\"; read on github.com those collide with GitHub's own PR/issue autolinker (a separate number space) and mis-link, so they are rewritten to status-dashboard permalinks (status.<apex>/#/task/N) that resolve here. Privacy gate: a full title/summary is exposed ONLY for already-public work (status shipped|confirmed — same surface as /public/recent-shipped). In-flight tasks return status + version with the title WITHHELD, so unshipped or security-sensitive task names never leak to the open web. `kind`/`priority` are non-sensitive and always returned. rank: public — single-task resolver for doc deep links (title gated to shipped/confirmed).\n\n**Rank:** `public` — No authentication — any caller.",
|
|
10627
10627
|
"x-rank": "public",
|
|
10628
10628
|
"x-source": "src/bongos/routes/public.js",
|
|
10629
10629
|
"parameters": [
|
|
@@ -10693,7 +10693,7 @@
|
|
|
10693
10693
|
"public"
|
|
10694
10694
|
],
|
|
10695
10695
|
"summary": "GET /public/versions",
|
|
10696
|
-
"description": "read-only surface for status
|
|
10696
|
+
"description": "read-only surface for the status dashboard (status.<apex>).\n\n**Rank:** `public` — No authentication — any caller.",
|
|
10697
10697
|
"x-rank": "public",
|
|
10698
10698
|
"x-source": "src/bongos/routes/public.js",
|
|
10699
10699
|
"responses": {
|
|
@@ -13471,7 +13471,7 @@
|
|
|
13471
13471
|
"versions"
|
|
13472
13472
|
],
|
|
13473
13473
|
"summary": "GET /versions/:id/done-when",
|
|
13474
|
-
"description": "Public: status
|
|
13474
|
+
"description": "Public: the status dashboard (status.<apex>) fetches this every 60s alongside other public/* surfaces. No auth, same Cache-Control posture as the other status feeds. rank: public — the status dashboard (status.<apex>) fetches every 60s anonymously.\n\n**Rank:** `public` — No authentication — any caller.",
|
|
13475
13475
|
"x-rank": "public",
|
|
13476
13476
|
"x-source": "modules/lifecycle/routes/done-when.js",
|
|
13477
13477
|
"parameters": [
|
package/docs/api-reference.md
CHANGED
|
@@ -256,7 +256,7 @@ Base path: `/api/bongos`. Ranks (enforced server-side, [ADR 0016](adr/<redacted>
|
|
|
256
256
|
|
|
257
257
|
| Method | Path | Rank | Body | Description |
|
|
258
258
|
|---|---|---|---|---|
|
|
259
|
-
| GET | `/api/bongos/healthz` | `public` | — | liveness probe; status
|
|
259
|
+
| GET | `/api/bongos/healthz` | `public` | — | liveness probe; the status dashboard (status.<apex>) hits this anonymously. |
|
|
260
260
|
|
|
261
261
|
## `inbox` (14)
|
|
262
262
|
|
|
@@ -439,7 +439,7 @@ Base path: `/api/bongos`. Ranks (enforced server-side, [ADR 0016](adr/<redacted>
|
|
|
439
439
|
| GET | `/api/bongos/public/repo-info` | `public` | — | GitHub URL bases for the deployed checkout (V3.R13-followup-2 task 411). |
|
|
440
440
|
| GET | `/api/bongos/public/tasks/:id` | `public` | — | Single-task resolver for "#NNN" deep links. |
|
|
441
441
|
| GET | `/api/bongos/public/uptime` | `public` | — | Uptime: current status + 90-day history bucketed by hour. |
|
|
442
|
-
| GET | `/api/bongos/public/versions` | `public` | — | read-only surface for status.
|
|
442
|
+
| GET | `/api/bongos/public/versions` | `public` | — | read-only surface for the status dashboard (status.<apex>). |
|
|
443
443
|
|
|
444
444
|
## `scouting` (1)
|
|
445
445
|
|
|
@@ -536,7 +536,7 @@ Base path: `/api/bongos`. Ranks (enforced server-side, [ADR 0016](adr/<redacted>
|
|
|
536
536
|
|---|---|---|---|---|
|
|
537
537
|
| GET | `/api/bongos/versions` | `public` | — | read-only version list; mirrors /public/versions. |
|
|
538
538
|
| POST | `/api/bongos/versions` | `metic+archon` | `id`, `name`, `status`, `track`, `done_when`, `scope_doc_path`, `criteria` | POST /versions — create a version + its done-when criteria in one call. |
|
|
539
|
-
| GET | `/api/bongos/versions/:id/done-when` | `public` | — | Public: status
|
|
539
|
+
| GET | `/api/bongos/versions/:id/done-when` | `public` | — | Public: the status dashboard (status.<apex>) fetches this every 60s alongside other public/* surfaces. |
|
|
540
540
|
| POST | `/api/bongos/versions/:id/done-when` | `metic+archon` | `criterion_id`, `criterion_md`, `goal_id`, `sort_order` | Auth (Metic+, then the goal's own authority): create a done-when criterion at RUNTIME. |
|
|
541
541
|
| GET | `/api/bongos/versions/:id/progress` | `public` | — | Per-criterion progress rollup: each done-when criterion → the tasks that gate it (task_criteria, migration 055) → live statuses → what re… |
|
|
542
542
|
| GET | `/api/bongos/versions/close-suggestions` | `public` | — | Close-flow gate suggestions for every version still 'building'. |
|
|
@@ -10,10 +10,10 @@ module.exports = function buildBlockersRouter() {
|
|
|
10
10
|
const router = express.Router();
|
|
11
11
|
|
|
12
12
|
// List currently-open blockers + the tasks each is blocking.
|
|
13
|
-
// Public: anyone landing on /builders or status
|
|
14
|
-
// what's stuck on
|
|
13
|
+
// Public: anyone landing on /builders or the status dashboard (status.<apex>)
|
|
14
|
+
// can see what's stuck on the owner.
|
|
15
15
|
// rank: public — open blocker list; documented "Public: anyone landing on /builders
|
|
16
|
-
// or status
|
|
16
|
+
// or the status dashboard can see what's stuck on the owner" in the handler comment above.
|
|
17
17
|
router.get('/blockers', async (req, res) => {
|
|
18
18
|
try {
|
|
19
19
|
// R14 (#2001 / ADR 0119): the open-blocker list is public + grows with the
|
|
@@ -80,10 +80,10 @@ function authorizeCriterionCreate({ goal, version, actorId, actorRank, actorMemb
|
|
|
80
80
|
module.exports = function buildDoneWhenRouter() {
|
|
81
81
|
const router = express.Router();
|
|
82
82
|
|
|
83
|
-
// Public: status
|
|
84
|
-
// public/* surfaces. No auth, same Cache-Control posture as the other
|
|
83
|
+
// Public: the status dashboard (status.<apex>) fetches this every 60s alongside
|
|
84
|
+
// other public/* surfaces. No auth, same Cache-Control posture as the other
|
|
85
85
|
// status feeds.
|
|
86
|
-
// rank: public — status
|
|
86
|
+
// rank: public — the status dashboard (status.<apex>) fetches every 60s anonymously.
|
|
87
87
|
router.get('/versions/:id/done-when', asyncHandler('GET /versions/:id/done-when', async (req, res) => {
|
|
88
88
|
const versionId = String(req.params.id || '').trim();
|
|
89
89
|
if (!versionId) return res.fail('version_id_required', 400);
|
package/package-lock.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bongos/core",
|
|
3
|
-
"version": "1.19.
|
|
3
|
+
"version": "1.19.310",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@bongos/core",
|
|
9
|
-
"version": "1.19.
|
|
9
|
+
"version": "1.19.310",
|
|
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.
|
|
3
|
+
"version": "1.19.310",
|
|
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",
|
|
@@ -82,6 +82,13 @@ function hostOf(origin) { try { return new URL(String(origin)).host || null; } c
|
|
|
82
82
|
// instance-config uses, so nothing here is ever a founder literal (R76-safe).
|
|
83
83
|
function effConfigDir(b) { return (b && b.configDir) || ic.FALLBACK_DIR; }
|
|
84
84
|
function effEnvPrefix(b) { return (b && b.envPrefix) || ic.FALLBACK_ENV_PREFIX; }
|
|
85
|
+
// The brand token outbound User-Agents are built from, mirroring src/branding.js
|
|
86
|
+
// userAgent(): repo name, else env prefix, lowercased. Kept in sync by the
|
|
87
|
+
// tests/claude_materialize.mjs UA-rule case + tests/hook_user_agents.mjs.
|
|
88
|
+
function effUaBase(b) {
|
|
89
|
+
const base = (b && b.repo && b.repo.name) || (b && b.envPrefix) || '';
|
|
90
|
+
return String(base).toLowerCase();
|
|
91
|
+
}
|
|
85
92
|
|
|
86
93
|
// Ordered source→target rebrand rules from two branding objects. PURE + exported.
|
|
87
94
|
function buildRebrandRules(from = {}, to = {}) {
|
|
@@ -109,6 +116,15 @@ function buildRebrandRules(from = {}, to = {}) {
|
|
|
109
116
|
add(`[${fc}]`, `[${tc}]`);
|
|
110
117
|
// The instance env-var prefix (e.g. OTB_ → CLOUDBONGOS_), bounded by its underscore.
|
|
111
118
|
add(`${effEnvPrefix(from)}_`, `${effEnvPrefix(to)}_`);
|
|
119
|
+
// task 1002672: the bare User-Agent brand token (e.g. `amazonprimea-gds-cli/1.0`
|
|
120
|
+
// in a hook's outbound fetch). It carries no TLD, so none of the HOST rules above
|
|
121
|
+
// ever matched it and a founder-branded UA leaked into every materialized
|
|
122
|
+
// instance verbatim. Bounded by the `-gds` suffix (the userAgent() convention)
|
|
123
|
+
// so a bare founder word in prose is NOT rewritten — only the UA token shape.
|
|
124
|
+
// Both bases must resolve: an empty side would degenerate into a bare `-gds`
|
|
125
|
+
// rule that rewrites every occurrence of the suffix itself.
|
|
126
|
+
const fromUa = effUaBase(from), toUa = effUaBase(to);
|
|
127
|
+
if (fromUa && toUa) add(`${fromUa}-gds`, `${toUa}-gds`);
|
|
112
128
|
// Longest literal first so a full host is replaced before any bare token inside it.
|
|
113
129
|
rules.sort((x, y) => y.pattern.source.length - x.pattern.source.length);
|
|
114
130
|
return rules;
|
|
@@ -4,7 +4,7 @@ const auth = require('../auth');
|
|
|
4
4
|
module.exports = function buildHealthzRouter() {
|
|
5
5
|
const router = express.Router();
|
|
6
6
|
|
|
7
|
-
// rank: public — liveness probe; status
|
|
7
|
+
// rank: public — liveness probe; the status dashboard (status.<apex>) hits this anonymously.
|
|
8
8
|
router.get('/healthz', async (_req, res) => {
|
|
9
9
|
res.json({
|
|
10
10
|
ok: true,
|
|
@@ -140,7 +140,7 @@ module.exports = function buildPublicRouter() {
|
|
|
140
140
|
res.json(clientModules());
|
|
141
141
|
});
|
|
142
142
|
|
|
143
|
-
// rank: public — read-only surface for status.
|
|
143
|
+
// rank: public — read-only surface for the status dashboard (status.<apex>).
|
|
144
144
|
router.get('/public/versions', async (req, res) => {
|
|
145
145
|
// R14 (#2001 / ADR 0119): adopt the shared pagination contract (was unbounded).
|
|
146
146
|
// Small list → fetch + slice; `page` is additive (readers of .versions unchanged).
|
|
@@ -378,7 +378,7 @@ module.exports = function buildPublicRouter() {
|
|
|
378
378
|
// Single-task resolver for "#NNN" deep links. Our docs reference GDS task IDs
|
|
379
379
|
// as bare "#NNN"; read on github.com those collide with GitHub's own PR/issue
|
|
380
380
|
// autolinker (a separate number space) and mis-link, so they are rewritten to
|
|
381
|
-
// status-dashboard permalinks (status
|
|
381
|
+
// status-dashboard permalinks (status.<apex>/#/task/N) that resolve
|
|
382
382
|
// here. Privacy gate: a full title/summary is exposed ONLY for
|
|
383
383
|
// already-public work (status shipped|confirmed — same surface as
|
|
384
384
|
// /public/recent-shipped). In-flight tasks return status + version with the
|
package/src/module-api.js
CHANGED
|
@@ -1043,8 +1043,12 @@ const { validateOrRespond, LIMITS, parseId, asyncHandler, corsPublicGet, parsePa
|
|
|
1043
1043
|
// landed since 1.19.306 with no explicit bump. run 32663876767. (task 1002620)
|
|
1044
1044
|
// 1.19.308 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
|
|
1045
1045
|
// landed since 1.19.307 with no explicit bump. run 32664559221. (task 1002620)
|
|
1046
|
+
// 1.19.309 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
|
|
1047
|
+
// landed since 1.19.308 with no explicit bump. run 32664868080. (task 1002620)
|
|
1048
|
+
// 1.19.310 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
|
|
1049
|
+
// landed since 1.19.309 with no explicit bump. run 32665109518. (task 1002620)
|
|
1046
1050
|
// ---------------------------------------------------------------------------
|
|
1047
|
-
const CORE_VERSION = '1.19.
|
|
1051
|
+
const CORE_VERSION = '1.19.310'; // CI auto-patch carrier (ADR 0161); see changelog above
|
|
1048
1052
|
|
|
1049
1053
|
// A namespaced logger so a module's log lines are attributable + consistent.
|
|
1050
1054
|
// Usage: const log = api.logger('dev-box'); log.info('mounted');
|
|
@@ -200,6 +200,25 @@ t('buildRebrandRules: partial target (only publicOrigin) → subdomains fall bac
|
|
|
200
200
|
assert.equal(out, 'acme.example.org', 'no builders.acme.example.org mangling');
|
|
201
201
|
});
|
|
202
202
|
|
|
203
|
+
// task 1002672: the bare UA brand token (no TLD — none of the host rules match it).
|
|
204
|
+
// A founder-branded hook UA like `amazonprimea-gds-cli/1.0` must neutralize on
|
|
205
|
+
// materialize; a bare founder word in prose (no `-gds` suffix) must NOT be touched.
|
|
206
|
+
t('buildRebrandRules: User-Agent brand token rewritten; bare brand word in prose untouched', () => {
|
|
207
|
+
const from = { ...OTB, repo: { name: 'amazonprimea' } };
|
|
208
|
+
const to = { domains: { publicOrigin: 'https://acme.example.org' }, envPrefix: 'ACME', repo: { name: 'acme-city' } };
|
|
209
|
+
const rules = m.buildRebrandRules(from, to);
|
|
210
|
+
assert.equal(m.rebrandText(`'User-Agent': 'amazonprimea-gds-cli/1.0'`, rules), `'User-Agent': 'acme-city-gds-cli/1.0'`);
|
|
211
|
+
assert.equal(m.rebrandText('amazonprimea-gds/1.0', rules), 'acme-city-gds/1.0');
|
|
212
|
+
assert.equal(m.rebrandText('the amazonprimea style guide', rules), 'the amazonprimea style guide', 'prose token without -gds suffix stays');
|
|
213
|
+
// envPrefix fallback when repo.name is absent on either side.
|
|
214
|
+
const rules2 = m.buildRebrandRules(OTB, { domains: { publicOrigin: 'https://acme.example.org' }, envPrefix: 'ACME' });
|
|
215
|
+
assert.equal(m.rebrandText('otb-gds-cli/1.0', rules2), 'acme-gds-cli/1.0');
|
|
216
|
+
// No degenerate bare `-gds` rule when a side resolves to nothing.
|
|
217
|
+
const rules3 = m.buildRebrandRules({ domains: {} }, { domains: { publicOrigin: 'https://acme.example.org' }, envPrefix: 'ACME' });
|
|
218
|
+
assert.ok(!rules3.some((r) => r.pattern.source === '-gds'), 'no bare -gds rule');
|
|
219
|
+
assert.equal(m.rebrandText('plain-gds/1.0 text', m.buildRebrandRules({}, {})), 'plain-gds/1.0 text');
|
|
220
|
+
});
|
|
221
|
+
|
|
203
222
|
t('buildRebrandRules: source === target is an empty ruleset → rebrandText is a no-op', () => {
|
|
204
223
|
assert.equal(m.buildRebrandRules(OTB, OTB).length, 0);
|
|
205
224
|
const s = 'https://amazonprimea.com ~/.config/otb';
|