@bongos/core 1.19.329 → 1.19.330

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.329",
6
- "core_contract": "1.19.329",
7
- "source_commit": "ed313bf56c84b4802561c1a22a7b1f13552d3297",
5
+ "core_version": "1.19.330",
6
+ "core_contract": "1.19.330",
7
+ "source_commit": "acf9d9dd29679f6c527824b2803950999664958e",
8
8
  "source_ref": "HEAD",
9
- "built_at": "2026-08-24T23:19:59.592Z",
9
+ "built_at": "2026-08-24T23:30:13.047Z",
10
10
  "redaction": {
11
11
  "model": "docs-redacted+functional-verbatim",
12
12
  "docs_redacted": 324,
@@ -17,7 +17,7 @@
17
17
  "gate": "passed"
18
18
  },
19
19
  "file_count": 1811,
20
- "tree_sha256": "2e52a9d82898b6470557b59fc6ca710346a09b410a7f47f88fc037ad493df397",
20
+ "tree_sha256": "40c5457e809c4588d34d3be61fccf5c49606fc002cbf64170aaf50c56ffa7652",
21
21
  "files": [
22
22
  {
23
23
  "path": ".claude/skills/blocker-review/SKILL.md",
@@ -1452,12 +1452,12 @@
1452
1452
  {
1453
1453
  "path": "docs/copy-inventory.md",
1454
1454
  "mode": "0000644",
1455
- "sha256": "c8ac603ee95d84be92bda48042d937a62bfedb22bdc7a5c4362955db71a6ca8c"
1455
+ "sha256": "04addfdc7fb7e9b59968d9d8daacd44d24280405868a705a65a3e4fd6166ec90"
1456
1456
  },
1457
1457
  {
1458
1458
  "path": "docs/copy-registry.json",
1459
1459
  "mode": "0000644",
1460
- "sha256": "b764712ca31d56511fed2e7d439b7230ab3539519aa337bc1c57360412cf3b13"
1460
+ "sha256": "a7516b85bec7090bf2ea753246e03c0d3cd3505c54ea5de68987cf4b2543001c"
1461
1461
  },
1462
1462
  {
1463
1463
  "path": "docs/design-contract.md",
@@ -4667,12 +4667,12 @@
4667
4667
  {
4668
4668
  "path": "package-lock.json",
4669
4669
  "mode": "0000644",
4670
- "sha256": "454fbe2af15bdbe1cdd60d5eb558c601062ee8efb13b21805f0644e07a125984"
4670
+ "sha256": "9bb6d40a874f3fa2ac02ff97883933dd86765c7c0d0f12aee6914961584b9702"
4671
4671
  },
4672
4672
  {
4673
4673
  "path": "package.json",
4674
4674
  "mode": "0000644",
4675
- "sha256": "40a3c39811c23c665f9710599982e4964d6f58d405c6e2fcf24b96e4aab36820"
4675
+ "sha256": "2b5ad8d6ae7d079ecc2d53f39c32f076521b843514fe80b71851f80440463ab6"
4676
4676
  },
4677
4677
  {
4678
4678
  "path": "public-docs/index.html",
@@ -4912,7 +4912,7 @@
4912
4912
  {
4913
4913
  "path": "public-landing/assets/cosmos.css",
4914
4914
  "mode": "0000644",
4915
- "sha256": "d39de81b2de333eb82eb5486bf975b56a99d24cf56bc84815fdf4bb96ae9fa0e"
4915
+ "sha256": "a7f21729b00719b22cfd13c14b33d87f4fdd8aaa2890a174bfc36d1b53c1e5e4"
4916
4916
  },
4917
4917
  {
4918
4918
  "path": "public-landing/assets/verro-medallion.png",
@@ -4927,12 +4927,12 @@
4927
4927
  {
4928
4928
  "path": "public-landing/index.html",
4929
4929
  "mode": "0000644",
4930
- "sha256": "ab299596b6c514ac044b2471330026e1516f6878e02b9045afae0ddc1f5fbfd9"
4930
+ "sha256": "db0d924005e8806d9e64c5c12b31c91957f1f625da972cafd5745c2cbdbf6dd9"
4931
4931
  },
4932
4932
  {
4933
4933
  "path": "public-landing/projects.html",
4934
4934
  "mode": "0000644",
4935
- "sha256": "98e234b47865c9f84650d2b1a9408610965ef780492fcc9b70d74adee57ad039"
4935
+ "sha256": "203b726527c02ed0383945c431df062ae6f02ed64cadc7942f9fef3e587a9da6"
4936
4936
  },
4937
4937
  {
4938
4938
  "path": "public-landing/world/assets/clouds/cloud-island-large.png",
@@ -6452,7 +6452,7 @@
6452
6452
  {
6453
6453
  "path": "src/module-api.js",
6454
6454
  "mode": "0000644",
6455
- "sha256": "a06153efe33e5d5729c4c6a86e1889441808217fa7fe6c9b07bd6b5ebe86114c"
6455
+ "sha256": "da4209544a6cd0b389cccc563cd45f6c04fc22816f7b132772024f77fa2900f8"
6456
6456
  },
6457
6457
  {
6458
6458
  "path": "src/module-loader/catalog.js",
@@ -8332,7 +8332,7 @@
8332
8332
  {
8333
8333
  "path": "tests/projects_hub_pre_uat.mjs",
8334
8334
  "mode": "0000644",
8335
- "sha256": "566428702a778df50caf55d7050adbe18d3005eecf8f63aa6a758437ab2934a7"
8335
+ "sha256": "a3cea371bb80b2dc05762a11bc43de84667f06db8723e384b34073e48fdfda6a"
8336
8336
  },
8337
8337
  {
8338
8338
  "path": "tests/promote_goal_id.mjs",
@@ -4,7 +4,7 @@
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
- **1381 strings** across 3 surfaces · 1225 distinct pieces of copy · 1381 certain, 0 heuristic · 126 shown in more than one place.
7
+ **1383 strings** across 3 surfaces · 1226 distinct pieces of copy · 1383 certain, 0 heuristic · 127 shown in more than one place.
8
8
 
9
9
  ## Surfaces
10
10
 
@@ -12,7 +12,7 @@
12
12
  |---|---|---|---|
13
13
  | `builders-hall` | `modules/hall-ui/public` | 65 | 1096 |
14
14
  | `status-dashboard` | `modules/status-ui/public` | 4 | 98 |
15
- | `landing` | `public-landing` | 2 | 187 |
15
+ | `landing` | `public-landing` | 2 | 189 |
16
16
 
17
17
  ## Confidence, and why it is on every row
18
18
 
@@ -76,7 +76,7 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
76
76
  | `3837f6d586a3` | 2x | Copy the task prompt to your clipboard | modules/hall-ui/public/goals-page.js:552, modules/hall-ui/public/work.js:356 |
77
77
  | `e3fd1febf63d` | 2x | Could not copy to the clipboard. Try again. | modules/hall-ui/public/goals-page.js:515, modules/hall-ui/public/work.js:461 |
78
78
  | `7775fec0fa85` | 2x | Could not load sessions. | modules/hall-ui/public/sessions.js:168, modules/hall-ui/public/sessions.js:207 |
79
- | … | | _86 more in the JSON registry_ | |
79
+ | … | | _87 more in the JSON registry_ | |
80
80
 
81
81
  ## `builders-hall` — 1096 strings
82
82
 
@@ -1282,7 +1282,7 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
1282
1282
  | `7667eb552781` | certain | {…}: {…}% ({…}/{…} checks) | `modules/status-ui/public/status.js:468` |
1283
1283
  | `6d0d64f10bd9` | certain | ‹ earlier page | `modules/status-ui/public/index.html:321` |
1284
1284
 
1285
- ## `landing` — 187 strings
1285
+ ## `landing` — 189 strings
1286
1286
 
1287
1287
  | id | conf | text | where |
1288
1288
  |---|---|---|---|
@@ -1328,7 +1328,6 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
1328
1328
  | `c01533093b42` | certain | Create your first project | `public-landing/projects.html:560` |
1329
1329
  | `b07e75a05f48` | certain | Creating the repo yourself on GitHub? Public or private is your choice there — both work here, and we never ch | `public-landing/projects.html:829` |
1330
1330
  | `3aeefb044b9f` | certain | Creation steps | `public-landing/projects.html:685` |
1331
- | `b228633307df` | certain | Delete the project | `public-landing/projects.html:660` |
1332
1331
  | `47d1558b17a3` | certain | Domain you own | `public-landing/projects.html:862` |
1333
1332
  | `d919980d2ca5` | certain | Download our core code and protocols, and build instantly with your team. | `public-landing/index.html:499` |
1334
1333
  | `af5ca714d375` | certain | Equity issuance, business filing, and builder compensation. | `public-landing/index.html:509` |
@@ -1362,11 +1361,13 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
1362
1361
  | `837fdaa0936a` | certain | Nothing matches that. | `public-landing/projects.html:556` |
1363
1362
  | `8329bb1a3693` | certain | One tap files the request and the platform starts standing your project up — server, database, address. Here's | `public-landing/projects.html:882` |
1364
1363
  | `86cde1930d84` | certain | Only mine | `public-landing/projects.html:394` |
1364
+ | `cbfdd6ac4ec8` | certain | Open source (AGPL-3.0) | `public-landing/index.html:546` |
1365
+ | `cbfdd6ac4ec8` | certain | Open source (AGPL-3.0) | `public-landing/projects.html:980` |
1365
1366
  | `275ca0d5ce65` | certain | Open source. | `public-landing/index.html:499` |
1366
1367
  | `94c67d09c97c` | certain | Open the map → | `public-landing/index.html:476` |
1367
1368
  | `b4a3643706ac` | certain | Open → | `public-landing/projects.html:466` |
1368
1369
  | `d4e9bf625ab3` | certain | Pick one of your repositories | `public-landing/projects.html:803` |
1369
- | `8addc4b11b13` | certain | Pick the shape that fits best — it labels the project on the map. Not sure is a fine answer. | `public-landing/projects.html:749` |
1370
+ | `65635b58dfab` | certain | Pick the shape that fits best — it’s how the project is listed on the map, and it stays as you pick it for now | `public-landing/projects.html:749` |
1370
1371
  | `92c7055aa799` | certain | Project handle | `public-landing/projects.html:852` |
1371
1372
  | `8b4663ad561c` | certain | Project hub | `public-landing/projects.html:357` |
1372
1373
  | `edab0ed81a40` | certain | Project name | `public-landing/projects.html:728` |
@@ -1400,6 +1401,7 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
1400
1401
  | `0b1330bed905` | certain | Starting point | `public-landing/projects.html:775` |
1401
1402
  | `decfc9512772` | certain | Switch light / dark | `public-landing/projects.html:371` |
1402
1403
  | `25bdf1bf7113` | certain | Switch light or dark mode | `public-landing/projects.html:371` |
1404
+ | `d75633cc707d` | certain | Take it offline | `public-landing/projects.html:660` |
1403
1405
  | `d3ce1efd0e67` | certain | Tearing down stops the project’s server and its nightly backups. It does | `public-landing/projects.html:668` |
1404
1406
  | `f6584b0a728b` | certain | The Verro Labs mark: a galaxy and constellation above a river valley threaded with circuitry | `public-landing/index.html:426` |
1405
1407
  | `72e85e8b6f47` | certain | The drums are rolling | `public-landing/projects.html:896` |
@@ -3,11 +3,11 @@
3
3
  "generator": "scripts/gds/copy-inventory.js",
4
4
  "goal": 1000074,
5
5
  "counts": {
6
- "strings": 1381,
7
- "unique_ids": 1225,
8
- "certain": 1381,
6
+ "strings": 1383,
7
+ "unique_ids": 1226,
8
+ "certain": 1383,
9
9
  "heuristic": 0,
10
- "duplicate_ids": 126
10
+ "duplicate_ids": 127
11
11
  },
12
12
  "surfaces": {
13
13
  "builders-hall": {
@@ -23,7 +23,7 @@
23
23
  "landing": {
24
24
  "at": "public-landing",
25
25
  "files": 2,
26
- "strings": 187
26
+ "strings": 189
27
27
  }
28
28
  },
29
29
  "blind_spots": [
@@ -818,6 +818,16 @@
818
818
  "modules/hall-ui/public/work.js:341"
819
819
  ]
820
820
  },
821
+ {
822
+ "id": "cbfdd6ac4ec8",
823
+ "surface": "landing",
824
+ "text": "Open source (AGPL-3.0)",
825
+ "occurrences": 2,
826
+ "at": [
827
+ "public-landing/index.html:546",
828
+ "public-landing/projects.html:980"
829
+ ]
830
+ },
821
831
  {
822
832
  "id": "855277dff074",
823
833
  "surface": "builders-hall",
@@ -11572,15 +11582,6 @@
11572
11582
  "origin": "html-attr:aria-label",
11573
11583
  "confidence": "certain"
11574
11584
  },
11575
- {
11576
- "id": "b228633307df",
11577
- "surface": "landing",
11578
- "text": "Delete the project",
11579
- "file": "public-landing/projects.html",
11580
- "line": 660,
11581
- "origin": "html-text",
11582
- "confidence": "certain"
11583
- },
11584
11585
  {
11585
11586
  "id": "47d1558b17a3",
11586
11587
  "surface": "landing",
@@ -11878,6 +11879,24 @@
11878
11879
  "origin": "html-text",
11879
11880
  "confidence": "certain"
11880
11881
  },
11882
+ {
11883
+ "id": "cbfdd6ac4ec8",
11884
+ "surface": "landing",
11885
+ "text": "Open source (AGPL-3.0)",
11886
+ "file": "public-landing/index.html",
11887
+ "line": 546,
11888
+ "origin": "html-text",
11889
+ "confidence": "certain"
11890
+ },
11891
+ {
11892
+ "id": "cbfdd6ac4ec8",
11893
+ "surface": "landing",
11894
+ "text": "Open source (AGPL-3.0)",
11895
+ "file": "public-landing/projects.html",
11896
+ "line": 980,
11897
+ "origin": "html-text",
11898
+ "confidence": "certain"
11899
+ },
11881
11900
  {
11882
11901
  "id": "275ca0d5ce65",
11883
11902
  "surface": "landing",
@@ -11915,9 +11934,9 @@
11915
11934
  "confidence": "certain"
11916
11935
  },
11917
11936
  {
11918
- "id": "8addc4b11b13",
11937
+ "id": "65635b58dfab",
11919
11938
  "surface": "landing",
11920
- "text": "Pick the shape that fits best — it labels the project on the map. Not sure is a fine answer.",
11939
+ "text": "Pick the shape that fits best — it’s how the project is listed on the map, and it stays as you pick it for now. Not sure is a fine answer.",
11921
11940
  "file": "public-landing/projects.html",
11922
11941
  "line": 749,
11923
11942
  "origin": "html-text",
@@ -12220,6 +12239,15 @@
12220
12239
  "origin": "html-attr:aria-label",
12221
12240
  "confidence": "certain"
12222
12241
  },
12242
+ {
12243
+ "id": "d75633cc707d",
12244
+ "surface": "landing",
12245
+ "text": "Take it offline",
12246
+ "file": "public-landing/projects.html",
12247
+ "line": 660,
12248
+ "origin": "html-text",
12249
+ "confidence": "certain"
12250
+ },
12223
12251
  {
12224
12252
  "id": "d3ce1efd0e67",
12225
12253
  "surface": "landing",
package/package-lock.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@bongos/core",
3
- "version": "1.19.329",
3
+ "version": "1.19.330",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@bongos/core",
9
- "version": "1.19.329",
9
+ "version": "1.19.330",
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.329",
3
+ "version": "1.19.330",
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",
@@ -348,6 +348,10 @@ h1{font-family:var(--font-display);font-weight:700;font-size:clamp(24px,3.4vw,32
348
348
  the browser's default blue, the one colour in the page that is not ours */
349
349
  .finePrint a{color:var(--link-ink);font-weight:700;text-decoration:none;}
350
350
  .finePrint a:hover{text-decoration:underline;}
351
+ /* the footer's licence link (owner decision 10, 2026-08-24) — the same link
352
+ ink as fine print, so it never falls back to the browser's blue */
353
+ .foot a{color:var(--link-ink);font-weight:700;text-decoration:none;}
354
+ .foot a:hover{text-decoration:underline;}
351
355
 
352
356
  /* ── progress strips: one visual, per-flow vocabularies (direction §4).
353
357
  Default = the sea-blue "working" look; .isLive = verified-landed green;
@@ -543,7 +543,7 @@ h1.big{font-family:var(--font-display);font-weight:700;font-size:clamp(33px,5.4v
543
543
  <!-- The footer line SPLITS. Its first half is a claim about the platform itself
544
544
  and is untrue of a project built on it, so only the attribution half travels.
545
545
  (Today's page ships the whole line to every instance — this is that fix.) -->
546
- <div class="foot"><!--apex-only:start--><span>A non-profit, capture-resistant commons. </span><!--apex-only:end-->Built by agents, on Cloud&nbsp;Bongos.</div>
546
+ <div class="foot"><!--apex-only:start--><span>A non-profit, capture-resistant commons. </span><!--apex-only:end-->Built by agents, on Cloud&nbsp;Bongos. <a href="https://www.gnu.org/licenses/agpl-3.0.html" target="_blank" rel="noopener">Open source (AGPL-3.0)</a>.</div>
547
547
 
548
548
  <script>
549
549
  (function () {
@@ -78,7 +78,7 @@ try{var _m=localStorage.getItem('cb-color-mode');if(_m==='light'||_m==='dark')do
78
78
  @keyframes fadeStep{from{opacity:0;transform:translateX(10px)}to{opacity:1;transform:none}}
79
79
  /* show() moves focus to each panel's h1 for keyboard/SR context — keep the
80
80
  focus, lose the ring (a black rectangle around a heading; owner walk) */
81
- h1[tabindex="-1"]:focus{outline:none;}
81
+ h1[tabindex="-1"]:focus:not(:focus-visible){outline:none;}
82
82
  /* the done step needs the full card width — the split collapses and the
83
83
  bongo pair steps aside for the checklist */
84
84
  .createSplit.wizDone{display:block;}
@@ -657,7 +657,7 @@ h1[tabindex="-1"]:focus{outline:none;}
657
657
  name typed back: it is the only control on this page that ends
658
658
  something, and the card's one-click confirm is too light for it. -->
659
659
  <div class="card" id="mDelete">
660
- <h2 style="font-family:var(--font-display);font-size:19px;margin-bottom:12px;">Delete the project</h2>
660
+ <h2 style="font-family:var(--font-display);font-size:19px;margin-bottom:12px;">Take it offline</h2>
661
661
  <div id="mDel"><p class="finePrint">Reading the project…</p></div>
662
662
  <!-- the teardown-vs-delete distinction, stated once as a SIBLING of the
663
663
  volatile slot (the #mRepoVisWhy shape) so no re-render can drop it.
@@ -746,7 +746,7 @@ h1[tabindex="-1"]:focus{outline:none;}
746
746
  forced into a wrong answer, and it can change later. -->
747
747
  <section class="panel" id="panel-type" aria-labelledby="type-h">
748
748
  <h1 id="type-h">What kind of project is it?</h1>
749
- <p class="lede">Pick the shape that fits best — it labels the project on the map. Not sure is a fine answer.</p>
749
+ <p class="lede">Pick the shape that fits best — it’s how the project is listed on the map, and it stays as you pick it for now. Not sure is a fine answer.</p>
750
750
  <form data-next="3">
751
751
  <div class="typeCards" id="typeCards" role="group" aria-label="Project type">
752
752
  <button type="button" class="tpill" data-type="game" aria-pressed="false">Game</button>
@@ -977,7 +977,7 @@ h1[tabindex="-1"]:focus{outline:none;}
977
977
  </div>
978
978
  </section>
979
979
 
980
- <div class="foot"><!--apex-only:start--><span>A non-profit, capture-resistant commons. </span><!--apex-only:end-->Built by agents, on <span data-brand-product-inline>Cloud&nbsp;Bongos</span>.</div>
980
+ <div class="foot"><!--apex-only:start--><span>A non-profit, capture-resistant commons. </span><!--apex-only:end-->Built by agents, on <span data-brand-product-inline>Cloud&nbsp;Bongos</span>. <a href="https://www.gnu.org/licenses/agpl-3.0.html" target="_blank" rel="noopener">Open source (AGPL-3.0)</a>.</div>
981
981
 
982
982
  <script>
983
983
  /* Brand-pack fill (R57): the server injects window.__BRANDING__ ahead of this
@@ -3505,6 +3505,10 @@ h1[tabindex="-1"]:focus{outline:none;}
3505
3505
  };
3506
3506
  function groupFor(inst) {
3507
3507
  if (inst.status === 'active' && inst.last_verified_up === false) return 'attention';
3508
+ /* the card shows its red error paragraph under exactly this condition
3509
+ (renderCard) — a project the owner is being told about cannot sit under
3510
+ Live. The intent-vs-status contract is deliberately left alone. */
3511
+ if (inst.error_note && !inst.open_intent) return 'attention';
3508
3512
  return STATE_GROUP[inst.status] || 'all';
3509
3513
  }
3510
3514
  function findText(inst) {
@@ -3779,8 +3783,8 @@ h1[tabindex="-1"]:focus{outline:none;}
3779
3783
  both the honest word and the accurate one, since a revive re-uses exactly
3780
3784
  this hostname. */
3781
3785
  return inst && inst.hosting_shape === 'dedicated'
3782
- ? 'This project has a machine to itself, so the machine goes away and its database goes with it. Your repository is untouched. Its web address stays reserved for this project and shows an error page until you bring it back.'
3783
- : 'The server goes away. Your repository is untouched. The database is kept, so bringing it back later restores its memory. Its web address stays reserved for this project and shows an error page until you bring it back.';
3786
+ ? 'This project has a machine to itself, so the machine goes away and its database goes with it. Your repository is untouched. Its web address stays reserved for this project and shows an error page until you bring it back. Nothing here erases a project.'
3787
+ : 'The server goes away. Your repository is untouched. The database is kept, so bringing it back later restores its memory. Its web address stays reserved for this project and shows an error page until you bring it back. Nothing here erases a project.';
3784
3788
  }
3785
3789
 
3786
3790
  function addressRow(inst) {
package/src/module-api.js CHANGED
@@ -1085,8 +1085,10 @@ const { validateOrRespond, LIMITS, parseId, asyncHandler, corsPublicGet, parsePa
1085
1085
  // landed since 1.19.327 with no explicit bump. run 32786284063. (task 1002620)
1086
1086
  // 1.19.329 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
1087
1087
  // landed since 1.19.328 with no explicit bump. run 32788827293. (task 1002620)
1088
+ // 1.19.330 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
1089
+ // landed since 1.19.329 with no explicit bump. run 32789596635. (task 1002620)
1088
1090
  // ---------------------------------------------------------------------------
1089
- const CORE_VERSION = '1.19.329'; // CI auto-patch carrier (ADR 0161); see changelog above
1091
+ const CORE_VERSION = '1.19.330'; // CI auto-patch carrier (ADR 0161); see changelog above
1090
1092
 
1091
1093
  // A namespaced logger so a module's log lines are attributable + consistent.
1092
1094
  // Usage: const log = api.logger('dev-box'); log.info('mounted');
@@ -15,6 +15,7 @@ const ROOT = path.join(path.dirname(fileURLToPath(import.meta.url)), '..');
15
15
  // anchored regexes below reason about line ends
16
16
  const HUB = fs.readFileSync(path.join(ROOT, 'public-landing', 'projects.html'), 'utf8').replace(/\r\n/g, '\n');
17
17
  const COSMOS = fs.readFileSync(path.join(ROOT, 'public-landing', 'assets', 'cosmos.css'), 'utf8').replace(/\r\n/g, '\n');
18
+ const INDEX = fs.readFileSync(path.join(ROOT, 'public-landing', 'index.html'), 'utf8').replace(/\r\n/g, '\n');
18
19
  const SCRIPT = HUB.slice(HUB.lastIndexOf('<script>'), HUB.lastIndexOf('</script>'));
19
20
 
20
21
  // a function's text runs from its declaration to the next declaration in the
@@ -264,3 +265,47 @@ test('a heartbeat re-render keeps an open fold open and a half-typed domain type
264
265
  const set = card.indexOf('li.innerHTML = orbFor(inst)');
265
266
  assert.ok(card.indexOf('var keepOpen') < set && card.indexOf('if (fold && keepOpen) fold.open = true;') > set, 'read before the swap, restore after it');
266
267
  });
268
+
269
+ /* ── the owner's five calls of 2026-08-24 (task 1003250) ── */
270
+ test('decision 6 — the manage section is "Take it offline", and the teardown truth ends by saying nothing erases', () => {
271
+ const del = (HUB.match(/<div class="card" id="mDelete">[\s\S]*?<\/details>\s*<\/div>/) || [''])[0];
272
+ assert.ok(del, '#mDelete exists');
273
+ assert.match(del, /<h2[^>]*>Take it offline<\/h2>/, 'the heading says what the control does');
274
+ assert.doesNotMatch(HUB, /Delete the project/, 'the word "Delete" no longer promises an erase anywhere on the page');
275
+ const truth = fn('teardownTruth');
276
+ assert.equal((truth.match(/until you bring it back\. Nothing here erases a project\.'/g) || []).length, 2, 'both hosting shapes end on the same sentence');
277
+ });
278
+
279
+ test('decision 5 — the Type step says the type is fixed for now', () => {
280
+ const type = (HUB.match(/<section class="panel" id="panel-type"[\s\S]*?<\/section>/) || [''])[0];
281
+ assert.ok(type, '#panel-type exists');
282
+ assert.match(type, /<p class="lede">Pick the shape that fits best — it’s how the project is listed on the map, and it stays as you pick it for now\. Not sure is a fine answer\.<\/p>/);
283
+ });
284
+
285
+ test('decision 8 — a card carrying a red error paragraph never tallies under Live', () => {
286
+ const g = fn('groupFor');
287
+ const down = g.indexOf("if (inst.status === 'active' && inst.last_verified_up === false) return 'attention';");
288
+ const err = g.indexOf("if (inst.error_note && !inst.open_intent) return 'attention';");
289
+ const table = g.indexOf('return STATE_GROUP[inst.status]');
290
+ assert.ok(down >= 0 && err > down && err < table, 'the rule sits after the down-probe override and before the status table');
291
+ // the same predicate renderCard uses to show the paragraph — the two cannot drift apart
292
+ assert.match(fn('renderCard'), /if \(\(inst\.status === 'error' \|\| inst\.error_note\) && !inst\.open_intent\) \{/);
293
+ assert.doesNotMatch(g, /open_intent\.action/, 'the intent-vs-status contract is left alone');
294
+ });
295
+
296
+ test('decision 9 — only mouse-driven focus on a wizard heading goes ringless', () => {
297
+ assert.match(HUB, /h1\[tabindex="-1"\]:focus:not\(:focus-visible\)\{outline:none;\}/);
298
+ assert.doesNotMatch(HUB, /h1\[tabindex="-1"\]:focus\{outline:none;\}/, 'the blanket suppression is gone');
299
+ });
300
+
301
+ test('decision 10 — both footers carry the open-source (AGPL-3.0) link, in link ink', () => {
302
+ const AGPL = /<a href="https:\/\/www\.gnu\.org\/licenses\/agpl-3\.0\.html" target="_blank" rel="noopener">Open source \(AGPL-3\.0\)<\/a>\./;
303
+ const hubFoot = (HUB.match(/<div class="foot">[\s\S]*?<\/div>/) || [''])[0];
304
+ const indexFoot = (INDEX.match(/<div class="foot">[\s\S]*?<\/div>/) || [''])[0];
305
+ assert.match(hubFoot, AGPL, 'projects.html');
306
+ assert.match(indexFoot, AGPL, 'index.html');
307
+ // the link sits OUTSIDE the apex-only span, so a child instance keeps it too
308
+ assert.ok(hubFoot.indexOf('<!--apex-only:end-->') < hubFoot.search(AGPL), 'projects.html: after the apex-only block');
309
+ assert.ok(indexFoot.indexOf('<!--apex-only:end-->') < indexFoot.search(AGPL), 'index.html: after the apex-only block');
310
+ assert.match(COSMOS, /\.foot a\{color:var\(--link-ink\);font-weight:700;text-decoration:none;\}/, 'never the browser’s blue');
311
+ });