@bongos/core 1.21.6 → 1.21.8

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.
@@ -4873,10 +4873,45 @@ summary{min-height:24px;padding:3px 0;}
4873
4873
  show(2, true);
4874
4874
  });
4875
4875
  /* the done panel's invite step names the demo's teammates (task 1004420): the hub
4876
- holds no invite of its own, so the founder sends each from the project's own box */
4876
+ holds no invite of its own, so the founder sends each from the project's own box.
4877
+ The names ride the created record too, so a reload before the hall is up keeps them
4878
+ (task 1004503). */
4879
+ function demoTeam() {
4880
+ if (state.demo && state.demo.invites && state.demo.invites.length) return state.demo.invites;
4881
+ var created = createdRecord();
4882
+ return created && Array.isArray(created.demo_invites) ? created.demo_invites : [];
4883
+ }
4884
+ /* The invite step (tasks 1002346 and 1004503). A second account cannot join until the
4885
+ project's hall is up, so the box opens only on the done panel's own verified Live
4886
+ (last_verified_up), never while the project is being set up. Before that, one plain
4887
+ line says when inviting opens, naming a demo's teammates so they are not lost. The
4888
+ CREATED RECORD is the proof the widget needs: no signed-in identity, no filed instance
4889
+ or no slug means nothing to invite to. Opening loads the suggestions once; a later
4890
+ tick does not ask again. */
4891
+ var invitesOpen = false;
4892
+ function paintInviteGate(live) {
4893
+ var created = createdRecord();
4894
+ var canInvite = !!(me && created && created.id && created.slug);
4895
+ if (live && canInvite) {
4896
+ if (invitesOpen) return;
4897
+ invitesOpen = true;
4898
+ setInviteSlug('wizInvite', created.slug);
4899
+ paintDemoTeam();
4900
+ loadInviteSuggestions('wizInvite', created.id);
4901
+ $('wizInviteLater').innerHTML = 'You can invite builders any time from ' + projectPageLink('the project’s own page') + '.';
4902
+ return;
4903
+ }
4904
+ invitesOpen = false;
4905
+ setInviteSlug('wizInvite', '');
4906
+ $('wizDemoTeam').hidden = true;
4907
+ var team = demoTeam();
4908
+ $('wizInviteLater').textContent = team.length
4909
+ ? 'You can invite ' + team.map(function (h) { return '@' + h; }).join(', ') + ' once its hall is up.'
4910
+ : 'You can invite builders once its hall is up.';
4911
+ }
4877
4912
  function paintDemoTeam() {
4878
4913
  var line = $('wizDemoTeam');
4879
- var who = state.demo && state.demo.invites && state.demo.invites.length ? state.demo.invites : [];
4914
+ var who = demoTeam();
4880
4915
  line.hidden = !who.length;
4881
4916
  line.textContent = who.length ? 'Your demo teammates: ' + who.map(function (h) { return '@' + h; }).join(', ') + '. Invite each one here.' : '';
4882
4917
  if (who.length && !$('wizInviteWho').value) $('wizInviteWho').value = who[0];
@@ -6399,7 +6434,9 @@ summary{min-height:24px;padding:3px 0;}
6399
6434
  sessionStorage.setItem(CREATED_KEY, JSON.stringify({
6400
6435
  id: data.instance && data.instance.id, slug: state.slug, domain: madeDomain,
6401
6436
  noaddr: !madeDomain,
6402
- mode: state.mode, name: state.name, at: Date.now()
6437
+ mode: state.mode, name: state.name, at: Date.now(),
6438
+ /* a demo's teammates, offered once the hall is up (task 1004503) */
6439
+ demo_invites: state.demo && state.demo.invites && state.demo.invites.length ? state.demo.invites.slice() : undefined
6403
6440
  }));
6404
6441
  sessionStorage.removeItem(DRAFT_KEY);
6405
6442
  } catch (e) {}
@@ -6650,16 +6687,8 @@ summary{min-height:24px;padding:3px 0;}
6650
6687
  skippable, so this panel names where it lives afterwards rather than
6651
6688
  leaving an owner to go looking for it. */
6652
6689
  $('doneModules').innerHTML = 'Add or remove modules later in ' + projectPageLink('the project’s settings') + '.';
6653
- /* the invite step (task 1002346, BV1.R27). The CREATED RECORD is the proof
6654
- the widget needs and the only one this panel has: no signed-in identity,
6655
- no filed instance or no slug ⇒ nothing to invite to, and the step stays
6656
- hidden. It is deliberately NOT keyed on instanceId, which startProgress
6657
- sets only AFTER this runs. */
6658
- var created = createdRecord();
6659
- setInviteSlug('wizInvite', (me && created && created.id && created.slug) ? created.slug : '');
6660
- paintDemoTeam();
6661
- loadInviteSuggestions('wizInvite', (me && created && created.slug) ? created.id : '');
6662
- $('wizInviteLater').innerHTML = 'You can invite builders any time from ' + projectPageLink('the project’s own page') + '.';
6690
+ /* the invite step waits for the hall (task 1004503): until it answers, one line */
6691
+ paintInviteGate(false);
6663
6692
  renderSteps();
6664
6693
  }
6665
6694
 
@@ -6912,6 +6941,7 @@ summary{min-height:24px;padding:3px 0;}
6912
6941
  if (inst.last_verified_up) {
6913
6942
  /* the alive moment (task 1004504): said only once the project has answered */
6914
6943
  $('done-h').textContent = (state.name || state.slug || 'Your project') + ' is alive.';
6944
+ paintInviteGate(true); /* the hall answers, so others can join now */
6915
6945
  setProgress(progressMarkup(-1, 3,
6916
6946
  'Your project is answering at ' + link + '. Finish the steps below and the hall is yours.', 'isLive', flow));
6917
6947
  return true;
@@ -56,7 +56,7 @@
56
56
  "in-new-review-run": {"auth":true,"url":"/projects?view=new","actions":[["wait",600],["click","#termsAck"],["wait",100],["click","#wizStart"],["wait",400],["fill","#newName","Mercury"],["click","#typeCards .tpill[data-type=\"game\"]"],["fill","#f-desc","A co-op farming game where the seasons never repeat."],["click","#panel-what button[type=submit]"],["wait",400],["select","#physCountry","US"],["wait",100],["click","[data-phys=\"builder_geography\"][data-val=\"global\"]"],["click","[data-phys=\"minors_on_board\"][data-val=\"false\"]"],["click","[data-phys=\"entity\"][data-val=\"intent-solo\"]"],["click","#physNext"],["wait",700],["click","#reviewRows .setRow[data-row=\"run\"] [data-row-chg]"],["wait",300],["click","[data-phys=\"framing\"][data-val=\"hybrid\"]"],["wait",600]],"expect":{"visible":["#physSuite"]}},
57
57
  "in-new-review-confirmed": {"auth":true,"url":"/projects?view=new","actions":[["wait",600],["click","#termsAck"],["wait",100],["click","#wizStart"],["wait",400],["fill","#newName","Mercury"],["click","#typeCards .tpill[data-type=\"game\"]"],["fill","#f-desc","A co-op farming game where the seasons never repeat."],["click","#panel-what button[type=submit]"],["wait",400],["select","#physCountry","US"],["wait",100],["click","[data-phys=\"builder_geography\"][data-val=\"global\"]"],["click","[data-phys=\"minors_on_board\"][data-val=\"false\"]"],["click","[data-phys=\"entity\"][data-val=\"intent-solo\"]"],["click","#physNext"],["wait",700],["click","#reviewRows .setRow[data-row=\"code\"] [data-row-ok]"],["wait",200],["click","#reviewRows .setRow[data-row=\"address\"] [data-row-chg]"],["wait",200],["fill","#f-slug","mercury"],["wait",900],["fill","#f-domain","mercury.example.com"],["wait",200],["click","#reviewRows .setRow[data-row=\"address\"] [data-row-use]"],["wait",200],["click","#reviewRows .setRow[data-row=\"app\"] [data-row-ok]"],["wait",150],["click","#reviewRows .setRow[data-row=\"extras\"] [data-row-ok]"],["wait",150],["click","#reviewRows .setRow[data-row=\"team\"] [data-row-ok]"],["wait",150],["click","#reviewRows .setRow[data-row=\"run\"] [data-row-ok]"],["wait",200]],"expect":{"visible":["#reviewGo","#reviewRows .setRow.done"],"text":[["#reviewGo","Continue"]]}},
58
58
  "in-new-look": {"auth":true,"url":"/projects?view=new","actions":[["wait",600],["click","#termsAck"],["wait",100],["click","#wizStart"],["wait",400],["fill","#newName","Mercury"],["click","#typeCards .tpill[data-type=\"game\"]"],["fill","#f-desc","A co-op farming game where the seasons never repeat."],["click","#panel-what button[type=submit]"],["wait",400],["select","#physCountry","US"],["wait",100],["click","[data-phys=\"builder_geography\"][data-val=\"global\"]"],["click","[data-phys=\"minors_on_board\"][data-val=\"false\"]"],["click","[data-phys=\"entity\"][data-val=\"intent-solo\"]"],["click","#physNext"],["wait",700],["click","#reviewRows .setRow[data-row=\"code\"] [data-row-ok]"],["wait",200],["click","#reviewRows .setRow[data-row=\"address\"] [data-row-chg]"],["wait",200],["fill","#f-slug","mercury"],["wait",900],["fill","#f-domain","mercury.example.com"],["wait",200],["click","#reviewRows .setRow[data-row=\"address\"] [data-row-use]"],["wait",200],["click","#reviewRows .setRow[data-row=\"app\"] [data-row-ok]"],["wait",150],["click","#reviewRows .setRow[data-row=\"extras\"] [data-row-ok]"],["wait",150],["click","#reviewRows .setRow[data-row=\"team\"] [data-row-ok]"],["wait",150],["click","#reviewRows .setRow[data-row=\"run\"] [data-row-ok]"],["wait",200],["click","#reviewGo"],["wait",500]],"expect":{"visible":["#panel-look","#wizLook","#wizRecap","#doCreate"],"hidden":["#panel-review"],"attr":[["#wizRoom","data-screen","look"]]}},
59
- "in-new-done": {"auth":true,"url":"/projects?view=new","actions":[["wait",600],["click","#termsAck"],["wait",100],["click","#wizStart"],["wait",400],["fill","#newName","Mercury"],["click","#typeCards .tpill[data-type=\"game\"]"],["fill","#f-desc","A co-op farming game where the seasons never repeat."],["click","#panel-what button[type=submit]"],["wait",400],["select","#physCountry","US"],["wait",100],["click","[data-phys=\"builder_geography\"][data-val=\"global\"]"],["click","[data-phys=\"minors_on_board\"][data-val=\"false\"]"],["click","[data-phys=\"entity\"][data-val=\"intent-solo\"]"],["click","#physNext"],["wait",700],["click","#reviewRows .setRow[data-row=\"code\"] [data-row-ok]"],["wait",200],["click","#reviewRows .setRow[data-row=\"address\"] [data-row-chg]"],["wait",200],["fill","#f-slug","mercury"],["wait",900],["fill","#f-domain","mercury.example.com"],["wait",200],["click","#reviewRows .setRow[data-row=\"address\"] [data-row-use]"],["wait",200],["click","#reviewRows .setRow[data-row=\"app\"] [data-row-ok]"],["wait",150],["click","#reviewRows .setRow[data-row=\"extras\"] [data-row-ok]"],["wait",150],["click","#reviewRows .setRow[data-row=\"team\"] [data-row-ok]"],["wait",150],["click","#reviewRows .setRow[data-row=\"run\"] [data-row-ok]"],["wait",200],["click","#reviewGo"],["wait",500],["click","#doCreate"],["wait",1500]],"expect":{"visible":["#panel-done","#liveProgress .prog","#humanSteps li"],"hidden":["#panel-look","#qWrap","#wizBack"]}},
59
+ "in-new-done": {"auth":true,"url":"/projects?view=new","actions":[["wait",600],["click","#termsAck"],["wait",100],["click","#wizStart"],["wait",400],["fill","#newName","Mercury"],["click","#typeCards .tpill[data-type=\"game\"]"],["fill","#f-desc","A co-op farming game where the seasons never repeat."],["click","#panel-what button[type=submit]"],["wait",400],["select","#physCountry","US"],["wait",100],["click","[data-phys=\"builder_geography\"][data-val=\"global\"]"],["click","[data-phys=\"minors_on_board\"][data-val=\"false\"]"],["click","[data-phys=\"entity\"][data-val=\"intent-solo\"]"],["click","#physNext"],["wait",700],["click","#reviewRows .setRow[data-row=\"code\"] [data-row-ok]"],["wait",200],["click","#reviewRows .setRow[data-row=\"address\"] [data-row-chg]"],["wait",200],["fill","#f-slug","mercury"],["wait",900],["fill","#f-domain","mercury.example.com"],["wait",200],["click","#reviewRows .setRow[data-row=\"address\"] [data-row-use]"],["wait",200],["click","#reviewRows .setRow[data-row=\"app\"] [data-row-ok]"],["wait",150],["click","#reviewRows .setRow[data-row=\"extras\"] [data-row-ok]"],["wait",150],["click","#reviewRows .setRow[data-row=\"team\"] [data-row-ok]"],["wait",150],["click","#reviewRows .setRow[data-row=\"run\"] [data-row-ok]"],["wait",200],["click","#reviewGo"],["wait",500],["click","#doCreate"],["wait",1500]],"expect":{"visible":["#panel-done","#liveProgress .prog","#humanSteps li","#wizInviteLater"],"hidden":["#panel-look","#qWrap","#wizBack","#wizInvite"]}},
60
60
  "in-new-resume-offer": {"auth":true,"url":"/projects?view=new","actions":[["wait",600],["click","#termsAck"],["wait",100],["click","#wizStart"],["wait",400],["fill","#newName","Mercury"],["click","#typeCards .tpill[data-type=\"game\"]"],["fill","#f-desc","A co-op farming game where the seasons never repeat."],["click","#panel-what button[type=submit]"],["wait",400],["select","#physCountry","US"],["wait",100],["click","[data-phys=\"builder_geography\"][data-val=\"global\"]"],["click","[data-phys=\"minors_on_board\"][data-val=\"false\"]"],["click","[data-phys=\"entity\"][data-val=\"intent-solo\"]"],["click","#physNext"],["wait",700],["click","#reviewRows .setRow[data-row=\"code\"] [data-row-ok]"],["wait",200],["click","#reviewRows .setRow[data-row=\"address\"] [data-row-chg]"],["wait",200],["fill","#f-slug","mercury"],["wait",900],["fill","#f-domain","mercury.example.com"],["wait",200],["click","#reviewRows .setRow[data-row=\"address\"] [data-row-use]"],["wait",200],["click","#reviewRows .setRow[data-row=\"app\"] [data-row-ok]"],["wait",150],["click","#reviewRows .setRow[data-row=\"extras\"] [data-row-ok]"],["wait",150],["click","#reviewRows .setRow[data-row=\"team\"] [data-row-ok]"],["wait",150],["click","#reviewRows .setRow[data-row=\"run\"] [data-row-ok]"],["wait",200],["click","#reviewGo"],["wait",500],["click","#doCreate"],["wait",1500],["click","#projTrig"],["wait",350],["click","#menuProjects [data-nav=\"new\"]"],["wait",500]],"expect":{"visible":["#panel-fork","#wizResume","#wizResumeGo"],"hidden":["#panel-done"],"text":[["#wizResumeName","Mercury"]]}},
61
61
  "in-new-look-custom": {"auth":true,"url":"/projects?view=new","actions":[["wait",600],["click","#termsAck"],["wait",100],["click","#wizStart"],["wait",400],["fill","#newName","Mercury"],["click","#typeCards .tpill[data-type=\"game\"]"],["fill","#f-desc","A co-op farming game where the seasons never repeat."],["click","#panel-what button[type=submit]"],["wait",400],["select","#physCountry","US"],["wait",100],["click","[data-phys=\"builder_geography\"][data-val=\"global\"]"],["click","[data-phys=\"minors_on_board\"][data-val=\"false\"]"],["click","[data-phys=\"entity\"][data-val=\"intent-solo\"]"],["click","#physNext"],["wait",700],["click","#reviewRows .setRow[data-row=\"code\"] [data-row-ok]"],["wait",200],["click","#reviewRows .setRow[data-row=\"address\"] [data-row-chg]"],["wait",200],["fill","#f-slug","mercury"],["wait",900],["fill","#f-domain","mercury.example.com"],["wait",200],["click","#reviewRows .setRow[data-row=\"address\"] [data-row-use]"],["wait",200],["click","#reviewRows .setRow[data-row=\"app\"] [data-row-ok]"],["wait",150],["click","#reviewRows .setRow[data-row=\"extras\"] [data-row-ok]"],["wait",150],["click","#reviewRows .setRow[data-row=\"team\"] [data-row-ok]"],["wait",150],["click","#reviewRows .setRow[data-row=\"run\"] [data-row-ok]"],["wait",200],["click","#reviewGo"],["wait",500],["click","#wizLook-custom"],["wait",200]],"expect":{"visible":["#panel-look","#wizAccent","#wizAccentNote"],"hidden":["#panel-review"]}},
62
62
  "out-new": {"auth":false,"url":"/projects?view=new","expect":{"visible":["#panel-gate","#wizSignin"],"hidden":["#qWrap","#panel-fork"]}},
@@ -0,0 +1,106 @@
1
+ {
2
+ "_": "The owner's projects for the kit (task 1003345): four states the mine list and the manage page render — live, standing up, snagged, torn down. Timestamps written \"$now-3m\" / \"$now-1d\" are resolved by the stub at request time so \"checked 3m ago\" stays true. Mooring (task 1003345, the grade's finding): live but unreachable since its last probe, so the restart door renders and the restart probe has a row to drive.",
3
+ "instances": [
4
+ {
5
+ "id": 101,
6
+ "slug": "demo",
7
+ "status": "active",
8
+ "domain": "demo.cloudbongos.com",
9
+ "target_ref": "builder/demo",
10
+ "hosting_shape": "co-tenant",
11
+ "onboard_mode": "scaffold",
12
+ "created_at": "2026-08-01T10:00:00.000Z",
13
+ "provisioned_at": "2026-08-01T10:20:00.000Z",
14
+ "updated_at": "$now-3m",
15
+ "last_verified_at": "$now-3m",
16
+ "last_verified_up": true,
17
+ "error_note": null,
18
+ "dns_note": null,
19
+ "dns_resolves": true,
20
+ "torn_down_at": null,
21
+ "open_intent": null
22
+ },
23
+ {
24
+ "id": 102,
25
+ "slug": "mercury",
26
+ "status": "active",
27
+ "planet_template": "blob-frost-tint",
28
+ "planet_accent": "sun-lit",
29
+ "domain": "mercury.cloudbongos.com",
30
+ "target_ref": "builder/mercury",
31
+ "hosting_shape": "cloud-host",
32
+ "owner_monthly_usd": null,
33
+ "onboard_mode": "scaffold",
34
+ "created_at": "$now-6m",
35
+ "provisioned_at": "$now-1m",
36
+ "updated_at": "$now-2m",
37
+ "last_verified_at": "$now-1m",
38
+ "last_verified_up": true,
39
+ "error_note": null,
40
+ "dns_note": null,
41
+ "torn_down_at": null,
42
+ "open_intent": {
43
+ "action": "standup",
44
+ "state": "running",
45
+ "created_at": "$now-6m"
46
+ },
47
+ "dns_resolves": true
48
+ },
49
+ {
50
+ "id": 103,
51
+ "slug": "tidepool",
52
+ "status": "error",
53
+ "domain": "tidepool.cloudbongos.com",
54
+ "target_ref": "builder/tidepool",
55
+ "hosting_shape": "co-tenant",
56
+ "onboard_mode": "adopt",
57
+ "created_at": "2026-08-20T09:00:00.000Z",
58
+ "provisioned_at": null,
59
+ "updated_at": "$now-1d",
60
+ "last_verified_at": null,
61
+ "last_verified_up": null,
62
+ "error_note": "The deploy could not read the repository: it is private, and the deploy key only reads public ones.",
63
+ "dns_note": null,
64
+ "torn_down_at": null,
65
+ "open_intent": null
66
+ },
67
+ {
68
+ "id": 104,
69
+ "slug": "old-lantern",
70
+ "status": "torn_down",
71
+ "domain": "old-lantern.cloudbongos.com",
72
+ "target_ref": "builder/old-lantern",
73
+ "hosting_shape": "co-tenant",
74
+ "onboard_mode": "scaffold",
75
+ "created_at": "2026-07-02T09:00:00.000Z",
76
+ "provisioned_at": "2026-07-02T09:30:00.000Z",
77
+ "updated_at": "2026-08-15T12:00:00.000Z",
78
+ "last_verified_at": "2026-08-15T11:50:00.000Z",
79
+ "last_verified_up": true,
80
+ "error_note": null,
81
+ "dns_note": null,
82
+ "dns_resolves": true,
83
+ "torn_down_at": "2026-08-15T12:00:00.000Z",
84
+ "open_intent": null
85
+ },
86
+ {
87
+ "id": 105,
88
+ "slug": "mooring",
89
+ "status": "active",
90
+ "domain": "mooring.cloudbongos.com",
91
+ "target_ref": "builder/mooring",
92
+ "hosting_shape": "co-tenant",
93
+ "onboard_mode": "scaffold",
94
+ "created_at": "2026-08-10T09:00:00.000Z",
95
+ "provisioned_at": "2026-08-10T09:20:00.000Z",
96
+ "updated_at": "$now-20m",
97
+ "last_verified_at": "$now-20m",
98
+ "last_verified_up": false,
99
+ "error_note": null,
100
+ "dns_note": null,
101
+ "dns_resolves": true,
102
+ "torn_down_at": null,
103
+ "open_intent": null
104
+ }
105
+ ]
106
+ }
package/package-lock.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@bongos/core",
3
- "version": "1.21.6",
3
+ "version": "1.21.8",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@bongos/core",
9
- "version": "1.21.6",
9
+ "version": "1.21.8",
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.21.6",
3
+ "version": "1.21.8",
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",
@@ -8788,5 +8788,21 @@
8788
8788
  "id": "1004440",
8789
8789
  "text": "A builder's profile on the Cloud Bongos hub now shows each craft's own work. An artist sees their approved pages, an ideator sees their filed, Full and board-ratified ideas, and the roles shown come from the work someone has a"
8790
8790
  }
8791
+ ],
8792
+ "1.21.7": [
8793
+ {
8794
+ "id": "1004503",
8795
+ "text": "When you start a project, the invite box now waits until your project is actually up, because nobody can join before then. Until it is, one line says when you can invite, and a demo's teammates are kept ready for that moment."
8796
+ }
8797
+ ],
8798
+ "1.21.8": [
8799
+ {
8800
+ "id": "1004525",
8801
+ "text": "The city's start governing button now opens the governor's street. Every part of the project's government stands as a building in one row, in the order work moves, with a building for each open goal. A pin with its label stand"
8802
+ },
8803
+ {
8804
+ "id": "1004441",
8805
+ "text": "Checked and signed off on the live site: artists and ideators now read as their own craft on profiles, the builders list and the status page. Their earnings charts show, and builders can choose their main role in Settings."
8806
+ }
8791
8807
  ]
8792
8808
  }
@@ -951,6 +951,14 @@ function mountInternalSurfaces(app) {
951
951
  // NB as at PROJECT_SETTINGS_PAGE_RE: nothing between the `=` and the literal
952
952
  // (tests/hall_page_gate_map.mjs parses this file statically). Prose goes above.
953
953
  const CITY_PAGE_RE = /^\/builders\/city(?:\.html)?\/?$/;
954
+ // /street — the Governor City's street (task 1004525), the city's one door.
955
+ // The same atom for the same reason: its governed read is the same docket.
956
+ // Its other reads (goals, rollups, the viewer's own earnings) are
957
+ // requireBuilder, a wider floor.
958
+ //
959
+ // NB as at PROJECT_SETTINGS_PAGE_RE: nothing between the `=` and the literal
960
+ // (tests/hall_page_gate_map.mjs parses this file statically). Prose goes above.
961
+ const STREET_PAGE_RE = /^\/builders\/street(?:\.html)?\/?$/;
954
962
  // /deploy — the owner's deploy door (task 1003159, ADR 0293). Gated on the
955
963
  // `core.pin.move` atom, the same key its preview and its move both check, so the
956
964
  // shell's reach equals the right to press the button. Archon-floor and system:true,
@@ -1037,6 +1045,10 @@ function mountInternalSurfaces(app) {
1037
1045
  if (CITY_PAGE_RE.test(norm)) {
1038
1046
  return gdsAuth.requireBoardVotePage(req, res, next);
1039
1047
  }
1048
+ // task 1004525: the street, on the same atom (see STREET_PAGE_RE).
1049
+ if (STREET_PAGE_RE.test(norm)) {
1050
+ return gdsAuth.requireBoardVotePage(req, res, next);
1051
+ }
1040
1052
  // ADR 0293: the deploy door, on the same atom its two routes check.
1041
1053
  if (DEPLOY_PAGE_RE.test(norm)) {
1042
1054
  return gdsAuth.requireCorePinPage(req, res, next);
package/src/module-api.js CHANGED
@@ -75,7 +75,7 @@ const { responsibilityFor, ROLE_RESPONSIBILITIES } = require('./role-responsibil
75
75
  // MAJOR (see allowBoxScope below): passes the request through untouched.
76
76
  function deprecatedNoopMiddleware(_req, _res, next) { next(); }
77
77
 
78
- const CORE_VERSION = '1.21.6'; // CI auto-patch carrier (ADR 0161); changelog: docs/module-api-changelog.md
78
+ const CORE_VERSION = '1.21.8'; // CI auto-patch carrier (ADR 0161); changelog: docs/module-api-changelog.md
79
79
 
80
80
  // A namespaced logger so a module's log lines are attributable + consistent.
81
81
  // Usage: const log = api.logger('discord'); log.info('mounted');
@@ -378,7 +378,15 @@ test('the module doc still records where the 2179 density pass landed', () => {
378
378
  // the hall's own 'hall-theme' preference. Whether it should join the chrome
379
379
  // behind the full-screen switch, as the sky did in task 1004327, is the
380
380
  // owner's call, named in that task's ship notes.
381
- const STANDALONE_EXEMPT = { 'city.html': 'the governor city home: nothing on the page but the prototype home (task 1004524)' };
381
+ // THE STREET (task 1004525) follows the city, for the same reason: the
382
+ // reference design's street view shows nothing on the page but its own header
383
+ // (the wordmark back to the city, needs you, moving, your share, the switch),
384
+ // the street and the six readings. Same terms as the city: style.css and the
385
+ // hall's tokens, the hall's own 'hall-theme' preference, no private palette.
386
+ const STANDALONE_EXEMPT = {
387
+ 'city.html': 'the governor city home: nothing on the page but the prototype home (task 1004524)',
388
+ 'street.html': 'the governor street: nothing on the page but the prototype street view (task 1004525)',
389
+ };
382
390
 
383
391
  test('every hall page loads style.css and shell.js', () => {
384
392
  const missing = [];
@@ -144,6 +144,9 @@ const ORACLE = {
144
144
  // governed read, GET /government/docket, checks board.vote.cast, so the page's
145
145
  // reach equals the right to read the docket it draws.
146
146
  '/builders/city': 'requireBoardVotePage',
147
+ // task 1004525: the street, the city's one door, on the same atom for the
148
+ // same reason (its governed read is the same docket).
149
+ '/builders/street': 'requireBoardVotePage',
147
150
 
148
151
  // Deliberately UNGATED — the landing card, the rank ladder, the reward
149
152
  // schedule and a builder's public portfolio all render for a stranger.