@bongos/core 1.21.132 → 1.21.134

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.
@@ -5,7 +5,7 @@
5
5
  "adr": "0341 D3",
6
6
  "reread": "node scripts/gds/page-reader.js --stale",
7
7
  "how": ["Generated by node scripts/gds/page-reader.js (BV2.TW04, task 1004315; ADR 0341 D3). Do not hand-edit.","One entry per page of docs/page-inventory.json. Lines are in page order: the default state first, and a line only another state shows sits where that state shows it, with its state named.","placement: placed = a docs/copy-registry.json row renders it (file, line, string_id); shared = shell text every page of the surface carries (top bar, sidebar, footer), with its row when the registry has one; unplaced = the registry cannot place it (a rewrite becomes an engineer task, ADR 0341 D4).","text keeps {…} where the registry row has a hole, or where a value the page read from its API was filled in. A string that is only such data is counted under omitted.data, not listed.","reading_hash is over the non-shared lines (key, section, text); files_hash is over the page's inventory files. --check compares files_hash only and never opens a browser.","Rendered through the hall-preview harness (hall) and the ui-design kit stub (landing, status), at 1280x800 with the clock pinned, so a reading is the fixture world's page."],
8
- "counts": {"pages":46,"lines":5545,"placed":1695,"shared":398,"unplaced":3452,"omitted_data":3574},
8
+ "counts": {"pages":46,"lines":5546,"placed":1696,"shared":398,"unplaced":3452,"omitted_data":3574},
9
9
  "pages": [
10
10
  {
11
11
  "id": "builders:atlas",
@@ -1200,12 +1200,12 @@
1200
1200
  "id": "builders:goals",
1201
1201
  "surface": "builders",
1202
1202
  "title": "Goals",
1203
- "states_read": ["list","filters","cards","detail","dependencies","out","uat","uat-panel"],
1204
- "files_hash": "21afef3818c14ce5",
1205
- "reading_hash": "3f72f589e565cc1a",
1206
- "counts": {"lines":155,"placed":51,"shared":8,"unplaced":96},
1203
+ "states_read": ["list","filters","cards","detail","dependencies","out","uat","uat-panel","author"],
1204
+ "files_hash": "f7f8e781b83d7c32",
1205
+ "reading_hash": "7aa1a6e1946dc077",
1206
+ "counts": {"lines":156,"placed":52,"shared":8,"unplaced":96},
1207
1207
  "omitted": {"data":268},
1208
- "notes": ["filters: an action failed (page.click: Timeout 6000ms exceeded.); read as it stood","cards: an action failed (page.click: Timeout 6000ms exceeded.); read as it stood","uat-panel: an action failed (page.click: Timeout 6000ms exceeded.); read as it stood"],
1208
+ "notes": ["filters: an action failed (page.click: Timeout 6000ms exceeded.); read as it stood","cards: an action failed (page.click: Timeout 6000ms exceeded.); read as it stood","uat-panel: an action failed (page.click: Timeout 6000ms exceeded.); read as it stood","author: an action failed (page.click: Timeout 6000ms exceeded.); read as it stood"],
1209
1209
  "lines": [
1210
1210
  {"key":"L0001","section":"skip link","text":"Skip to content","placement":"shared","file":"modules/hall-ui/public/shell.js","line":860,"string_id":"87cee78ca134"},
1211
1211
  {"key":"L0002","section":"top bar","text":"Goals","placement":"shared"},
@@ -1219,149 +1219,150 @@
1219
1219
  {"key":"L0010","section":"Goals","text":"{…} file{…}","placement":"placed","file":"modules/hall-ui/public/gate.js","line":151,"string_id":"3efa67dc6e07","state":"dependencies"},
1220
1220
  {"key":"L0011","section":"Goals","text":"{…} and {…}","placement":"placed","file":"modules/hall-ui/public/profile-nudge.js","line":77,"string_id":"56b00d773232","occurrences":6},
1221
1221
  {"key":"L0012","section":"Goals","text":"See which goals wait on each other →","placement":"placed","file":"modules/hall-ui/public/goals.html","line":39,"string_id":"292761c89fae"},
1222
- {"key":"L0013","section":"Goals","text":"← Back to goal","placement":"placed","file":"modules/hall-ui/public/goals.html","line":187,"string_id":"7926e30955d2","state":"dependencies"},
1223
- {"key":"L0014","section":"Completion","text":"Completion","placement":"unplaced","state":"uat"},
1224
- {"key":"L0015","section":"Completion","text":"Every done-when criterion for this goal, with its full detail.","placement":"placed","file":"modules/hall-ui/public/goals.html","line":218,"string_id":"2ae1eb35611e","state":"uat"},
1225
- {"key":"L0016","section":"Completion","text":"{…} of {…} criteria satisfied","placement":"placed","file":"modules/hall-ui/public/goals-lib.js","line":32,"string_id":"cc5106af4b35","state":"uat"},
1226
- {"key":"L0017","section":"Completion","text":"{…} and {…}","placement":"placed","file":"modules/hall-ui/public/profile-nudge.js","line":77,"string_id":"56b00d773232","state":"uat","occurrences":2},
1227
- {"key":"L0018","section":"Completion","text":"{…} project{…}","placement":"placed","file":"modules/hall-ui/public/fleet.js","line":39,"string_id":"771bef3d31b5","state":"uat","occurrences":2},
1228
- {"key":"L0019","section":"Completion","text":"Awaiting UAT","placement":"placed","file":"modules/hall-ui/public/criterion-uat-ui.js","line":77,"string_id":"c78685da0e42","state":"uat","occurrences":2},
1229
- {"key":"L0020","section":"Completion","text":"on the live site","placement":"unplaced","state":"uat"},
1230
- {"key":"L0021","section":"Completion","text":"Test and sign off","placement":"placed","file":"modules/hall-ui/public/criterion-uat-ui.js","line":76,"string_id":"8584832c348f","state":"uat","occurrences":2},
1231
- {"key":"L0022","section":"Completion","text":"Backend-only","placement":"unplaced","state":"uat"},
1232
- {"key":"L0023","section":"Completion","text":"Mark backend-only","placement":"placed","file":"modules/hall-ui/public/criterion-uat-ui.js","line":85,"string_id":"525e085a6770","state":"uat"},
1233
- {"key":"L0024","section":"Completion","text":"Metic-and-above builders vote on Full Ideas in the Board Room","placement":"unplaced","state":"uat"},
1234
- {"key":"L0025","section":"Completion","text":"Satisfied (UAT)","placement":"unplaced","state":"uat"},
1235
- {"key":"L0026","section":"Completion","text":"See the UAT","placement":"placed","file":"modules/hall-ui/public/criterion-uat-ui.js","line":80,"string_id":"00473a773fd7","state":"uat"},
1236
- {"key":"L0027","section":"Completion","text":"The constitution in force always matches the last ratified amendment","placement":"unplaced","state":"uat"},
1237
- {"key":"L0028","section":"Completion","text":"Closed before UAT","placement":"unplaced","state":"uat"},
1238
- {"key":"L0029","section":"footer","text":"Sign out","placement":"shared","file":"modules/hall-ui/public/shell.js","line":520,"string_id":"1883ad7f07fc","state":"uat","occurrences":4},
1239
- {"key":"L0030","section":"Completion","text":"Builders hall · this session","placement":"placed","file":"modules/hall-ui/public/craft-mode.js","line":810,"string_id":"fd1903586e8e","state":"uat"},
1240
- {"key":"L0031","section":"Task {…}","text":"Task dependencies","placement":"placed","file":"modules/hall-ui/public/goals.html","line":189,"string_id":"a0f384b022fd","state":"dependencies"},
1241
- {"key":"L0032","section":"Task {…}","text":"{…} and {…}","placement":"placed","file":"modules/hall-ui/public/profile-nudge.js","line":77,"string_id":"56b00d773232","state":"dependencies"},
1242
- {"key":"L0033","section":"Task {…}","text":"#1165 Blocker-solve","placement":"unplaced","state":"dependencies"},
1243
- {"key":"L0034","section":"Task {…}","text":"{…}: /{…}-s…","placement":"unplaced","state":"dependencies"},
1244
- {"key":"L0035","section":"Task {…}","text":"P2 · {…}","placement":"unplaced","state":"dependencies","occurrences":4},
1245
- {"key":"L0036","section":"Task {…}","text":"#2170 Work {…}","placement":"unplaced","state":"dependencies"},
1246
- {"key":"L0037","section":"Task {…}","text":"redesign: tabs, filter…","placement":"unplaced","state":"dependencies"},
1247
- {"key":"L0038","section":"Task {…}","text":"#594 V4.R29 — Status","placement":"unplaced","state":"dependencies"},
1248
- {"key":"L0039","section":"Task {…}","text":"surface v2: {…} re…","placement":"unplaced","state":"dependencies"},
1249
- {"key":"L0040","section":"Task {…}","text":"P3 · {…}","placement":"unplaced","state":"dependencies"},
1250
- {"key":"L0041","section":"Task {…}","text":"#2171 Goals page:","placement":"unplaced","state":"dependencies"},
1251
- {"key":"L0042","section":"Task {…}","text":"converge onto the kit…","placement":"unplaced","state":"dependencies"},
1252
- {"key":"L0043","section":"Task {…}","text":"#2172 Settings","placement":"unplaced","state":"dependencies"},
1253
- {"key":"L0044","section":"Task {…}","text":"regroup: 6 groups, st…","placement":"unplaced","state":"dependencies"},
1254
- {"key":"L0045","section":"Task {…}","text":"Task","placement":"placed","file":"modules/hall-ui/public/task.js","line":475,"string_id":"eff70e59d12e","state":"dependencies"},
1255
- {"key":"L0046","section":"Task {…}","text":"Status","placement":"unplaced","state":"dependencies"},
1256
- {"key":"L0047","section":"Task {…}","text":"Priority","placement":"unplaced","state":"dependencies"},
1257
- {"key":"L0048","section":"Task {…}","text":"Waits on","placement":"placed","file":"modules/hall-ui/public/goal-forest-render.js","line":186,"string_id":"8e4f0179e1d3","state":"dependencies"},
1258
- {"key":"L0049","section":"Task {…}","text":"Needed by","placement":"placed","file":"modules/hall-ui/public/goal-forest-render.js","line":186,"string_id":"83197947ee8d","state":"dependencies"},
1259
- {"key":"L0050","section":"Task {…}","text":"Chain","placement":"unplaced","state":"dependencies"},
1260
- {"key":"L0051","section":"Task {…}","text":"P2","placement":"unplaced","state":"dependencies","occurrences":4},
1261
- {"key":"L0052","section":"Task {…}","text":"Chain 1 · 3 tasks","placement":"unplaced","state":"dependencies","occurrences":3},
1262
- {"key":"L0053","section":"Task {…}","text":"P3","placement":"unplaced","state":"dependencies"},
1263
- {"key":"L0054","section":"Task {…}","text":"Chain 2 · 2 tasks","placement":"unplaced","state":"dependencies","occurrences":2},
1264
- {"key":"L0055","section":"Conflicts12","text":"Conflicts","placement":"unplaced","state":"dependencies"},
1265
- {"key":"L0056","section":"Conflicts12","text":"Open tasks whose declared files overlap — sequence these before two builders collide.","placement":"placed","file":"modules/hall-ui/public/goals.html","line":195,"string_id":"99c630009152","state":"dependencies"},
1266
- {"key":"L0057","section":"Conflicts12","text":"Builders hall · this session","placement":"placed","file":"modules/hall-ui/public/craft-mode.js","line":810,"string_id":"fd1903586e8e","state":"dependencies"},
1267
- {"key":"L0058","section":"Goals","text":"← All goals","placement":"placed","file":"modules/hall-ui/public/goals.html","line":75,"string_id":"d4b84b7fbdeb","state":"detail"},
1268
- {"key":"L0059","section":"#1000081 {…}","text":"Claude's notes on this goal","placement":"placed","file":"modules/hall-ui/public/goals.html","line":86,"string_id":"5b3b75ee0596","state":"detail"},
1269
- {"key":"L0060","section":"Completion3","text":"Completion","placement":"unplaced","state":"detail"},
1270
- {"key":"L0061","section":"Completion3","text":"{…} of {…} criteria satisfied","placement":"placed","file":"modules/hall-ui/public/goals-lib.js","line":32,"string_id":"cc5106af4b35","state":"detail"},
1271
- {"key":"L0062","section":"Completion3","text":"Goal {…}","placement":"placed","file":"modules/hall-ui/public/gate.js","line":360,"string_id":"ec88b946ad16","state":"detail"},
1272
- {"key":"L0063","section":"Completion3","text":"{…} — harness fixture {…}","placement":"unplaced","state":"detail","occurrences":3},
1273
- {"key":"L0064","section":"Members0","text":"Members","placement":"unplaced","state":"detail"},
1274
- {"key":"L0065","section":"Members0","text":"No {…} assigned yet — an Archon can appoint one.","placement":"unplaced","state":"detail"},
1275
- {"key":"L0066","section":"Members0","text":"No members yet — be the first to join.","placement":"unplaced","state":"detail"},
1276
- {"key":"L0067","section":"Dependencies5","text":"Dependencies","placement":"unplaced","state":"detail"},
1277
- {"key":"L0068","section":"Dependencies5","text":"5 tasks linked by dependencies, in 2 chains.","placement":"unplaced","state":"detail"},
1278
- {"key":"L0069","section":"Dependencies5","text":"Ship these first","placement":"placed","file":"modules/hall-ui/public/goal-forest-render.js","line":125,"string_id":"48a40cce6763","state":"detail"},
1279
- {"key":"L0070","section":"Dependencies5","text":"unblocks 2","placement":"unplaced","state":"detail"},
1280
- {"key":"L0071","section":"Dependencies5","text":"unblocks 1","placement":"unplaced","state":"detail"},
1281
- {"key":"L0072","section":"Dependencies5","text":"{…} file{…}","placement":"placed","file":"modules/hall-ui/public/gate.js","line":151,"string_id":"3efa67dc6e07","state":"detail"},
1282
- {"key":"L0073","section":"Dependencies5","text":"See the full picture →","placement":"placed","file":"modules/hall-ui/public/goal-forest-render.js","line":138,"string_id":"9276193a0e41","state":"detail"},
1283
- {"key":"L0074","section":"Tasks","text":"Tasks","placement":"unplaced","state":"detail"},
1284
- {"key":"L0075","section":"Tasks","text":"To do","placement":"unplaced","state":"detail"},
1285
- {"key":"L0076","section":"Tasks","text":"Completed","placement":"unplaced","state":"detail"},
1286
- {"key":"L0077","section":"Tasks","text":"Search","placement":"unplaced","state":"detail"},
1287
- {"key":"L0078","section":"Tasks","text":"task #{…}","placement":"placed","file":"modules/hall-ui/public/copy-desk.js","line":105,"string_id":"a6e803a31a4d","attr":"placeholder","state":"detail"},
1288
- {"key":"L0079","section":"Tasks","text":"Sort","placement":"unplaced","state":"detail"},
1289
- {"key":"L0080","section":"Tasks","text":"{…} / minute (high → low)","placement":"unplaced","state":"detail"},
1290
- {"key":"L0081","section":"Tasks","text":"{…} (high → low)","placement":"unplaced","state":"detail"},
1291
- {"key":"L0082","section":"Tasks","text":"minutes (low → high)","placement":"unplaced","state":"detail"},
1292
- {"key":"L0083","section":"Tasks","text":"priority (P0 first)","placement":"unplaced","state":"detail"},
1293
- {"key":"L0084","section":"Tasks","text":"task {…}","placement":"placed","file":"modules/hall-ui/public/gate.js","line":157,"string_id":"4d8ee7d68974","state":"detail"},
1294
- {"key":"L0085","section":"Tasks","text":"status","placement":"unplaced","state":"detail"},
1295
- {"key":"L0086","section":"Tasks","text":"Filters","placement":"unplaced","state":"detail"},
1296
- {"key":"L0087","section":"Tasks","text":"{…} of {…}","placement":"placed","file":"modules/hall-ui/public/sky-panel.js","line":120,"string_id":"73c1372b43d9","state":"detail","occurrences":3},
1297
- {"key":"L0088","section":"Tasks","text":"Archon","placement":"unplaced","state":"detail"},
1298
- {"key":"L0089","section":"Tasks","text":"30m","placement":"unplaced","state":"detail"},
1299
- {"key":"L0090","section":"Tasks","text":"1.00 {…}/min","placement":"unplaced","state":"detail","occurrences":9},
1300
- {"key":"L0091","section":"Tasks","text":"11d","placement":"unplaced","state":"detail"},
1301
- {"key":"L0092","section":"Tasks","text":"{…} Est.","placement":"unplaced","state":"detail","occurrences":25},
1302
- {"key":"L0093","section":"Tasks","text":"Claim","placement":"unplaced","state":"detail","occurrences":25},
1303
- {"key":"L0094","section":"Tasks","text":"Metic+","placement":"unplaced","state":"detail","occurrences":6},
1304
- {"key":"L0095","section":"Tasks","text":"60m","placement":"unplaced","state":"detail","occurrences":17},
1305
- {"key":"L0096","section":"Tasks","text":"Any rank","placement":"placed","file":"modules/hall-ui/public/task-lib.js","line":82,"string_id":"52ed0e2e3470","state":"detail","occurrences":18},
1306
- {"key":"L0097","section":"Tasks","text":"45m","placement":"unplaced","state":"detail","occurrences":2},
1307
- {"key":"L0098","section":"Tasks","text":"4w","placement":"unplaced","state":"detail","occurrences":21},
1308
- {"key":"L0099","section":"Tasks","text":"0.85 {…}/min","placement":"unplaced","state":"detail","occurrences":11},
1309
- {"key":"L0100","section":"Tasks","text":"40m","placement":"unplaced","state":"detail"},
1310
- {"key":"L0101","section":"Tasks","text":"0.75 {…}/min","placement":"unplaced","state":"detail"},
1311
- {"key":"L0102","section":"Tasks","text":"2w","placement":"unplaced","state":"detail"},
1312
- {"key":"L0103","section":"Tasks","text":"90m","placement":"unplaced","state":"detail"},
1313
- {"key":"L0104","section":"Tasks","text":"0.67 {…}/min","placement":"unplaced","state":"detail"},
1314
- {"key":"L0105","section":"Tasks","text":"120m","placement":"unplaced","state":"detail","occurrences":3},
1315
- {"key":"L0106","section":"Tasks","text":"0.58 {…}/min","placement":"unplaced","state":"detail"},
1316
- {"key":"L0107","section":"Tasks","text":"8w","placement":"unplaced","state":"detail"},
1317
- {"key":"L0108","section":"Tasks","text":"0.50 {…}/min","placement":"unplaced","state":"detail","occurrences":2},
1318
- {"key":"L0109","section":"Tasks","text":"Per page","placement":"placed","file":"modules/hall-ui/public/hall-kit.js","line":74,"string_id":"4a46b478edaf","state":"detail"},
1319
- {"key":"L0110","section":"Tasks","text":"‹ Prev","placement":"placed","file":"modules/hall-ui/public/hall-kit.js","line":74,"string_id":"de8fa5223aee","state":"detail"},
1320
- {"key":"L0111","section":"Tasks","text":"Page {…} of {…}","placement":"placed","file":"modules/hall-ui/public/hall-kit.js","line":112,"string_id":"15a49bf15007","state":"detail"},
1321
- {"key":"L0112","section":"Tasks","text":"Next ›","placement":"placed","file":"modules/hall-ui/public/hall-kit.js","line":74,"string_id":"f52ba261d930","state":"detail"},
1322
- {"key":"L0113","section":"Tasks","text":"Builders hall · this session","placement":"placed","file":"modules/hall-ui/public/craft-mode.js","line":810,"string_id":"fd1903586e8e","state":"detail"},
1323
- {"key":"L0114","section":"Goals","text":"Search","placement":"unplaced"},
1324
- {"key":"L0115","section":"Goals","text":"goal # or name…","placement":"unplaced","attr":"placeholder"},
1325
- {"key":"L0116","section":"Goals","text":"Version","placement":"unplaced"},
1326
- {"key":"L0117","section":"Goals","text":"— any —","placement":"placed","file":"modules/hall-ui/public/hall-widgets.js","line":163,"string_id":"729d4ce22b99","occurrences":2},
1327
- {"key":"L0118","section":"Goals","text":"Status","placement":"unplaced"},
1328
- {"key":"L0119","section":"Goals","text":"open","placement":"placed","file":"modules/hall-ui/public/approval-queue.js","line":163,"string_id":"9a803563c948","occurrences":16},
1329
- {"key":"L0120","section":"Goals","text":"Sort","placement":"unplaced"},
1330
- {"key":"L0121","section":"Goals","text":"priority (version order)","placement":"unplaced"},
1331
- {"key":"L0122","section":"Goals","text":"newest first","placement":"unplaced"},
1332
- {"key":"L0123","section":"Goals","text":"oldest first","placement":"placed","file":"modules/hall-ui/public/hall-widgets.js","line":165,"string_id":"759c12b5f983"},
1333
- {"key":"L0124","section":"Goals","text":"recently {…}","placement":"unplaced"},
1334
- {"key":"L0125","section":"Goals","text":"stalest first","placement":"unplaced"},
1335
- {"key":"L0126","section":"Goals","text":"Filters","placement":"unplaced"},
1336
- {"key":"L0127","section":"Goals","text":"Views","placement":"unplaced"},
1337
- {"key":"L0128","section":"Goals","text":"rows","placement":"unplaced"},
1338
- {"key":"L0129","section":"Goals","text":"cards","placement":"unplaced"},
1339
- {"key":"L0130","section":"Goals","text":"Ready to claim","placement":"unplaced"},
1340
- {"key":"L0131","section":"Goals","text":"across 15 {…} {…}","placement":"unplaced"},
1341
- {"key":"L0132","section":"Goals","text":"In progress","placement":"unplaced"},
1342
- {"key":"L0133","section":"Goals","text":"claimed right now","placement":"unplaced"},
1343
- {"key":"L0134","section":"Goals","text":"Blocked","placement":"unplaced"},
1344
- {"key":"L0135","section":"Goals","text":"waiting on upstream tasks","placement":"unplaced"},
1345
- {"key":"L0136","section":"Goals","text":"Criteria met","placement":"unplaced"},
1346
- {"key":"L0137","section":"Goals","text":"on 15 {…} {…}","placement":"unplaced"},
1347
- {"key":"L0138","section":"Goals","text":"Active","placement":"unplaced"},
1348
- {"key":"L0139","section":"Goals","text":"{…} project{…}","placement":"placed","file":"modules/hall-ui/public/fleet.js","line":39,"string_id":"771bef3d31b5","occurrences":7},
1349
- {"key":"L0140","section":"Goals","text":"claim next","placement":"placed","file":"modules/hall-ui/public/goals-render.js","line":169,"string_id":"9203a7283960","occurrences":15},
1350
- {"key":"L0141","section":"Goals","text":"in progress","placement":"placed","file":"modules/hall-ui/public/roadmap.js","line":120,"string_id":"b2b399fdd6a4","occurrences":4},
1351
- {"key":"L0142","section":"Goals","text":"blocked","placement":"unplaced","occurrences":8},
1352
- {"key":"L0143","section":"Goals","text":"backlog","placement":"unplaced","occurrences":4},
1353
- {"key":"L0144","section":"Goals","text":"{…} of {…}","placement":"placed","file":"modules/hall-ui/public/sky-panel.js","line":120,"string_id":"73c1372b43d9"},
1354
- {"key":"L0145","section":"Goals","text":"⚖ admitted","placement":"placed","file":"modules/hall-ui/public/goals-render.js","line":194,"string_id":"5d6f38a02386","occurrences":3},
1355
- {"key":"L0146","section":"Goals","text":"sessions","placement":"placed","file":"modules/hall-ui/public/task.js","line":467,"string_id":"732b4c935e36"},
1356
- {"key":"L0147","section":"Goals","text":"Builders hall · this session","placement":"placed","file":"modules/hall-ui/public/craft-mode.js","line":810,"string_id":"fd1903586e8e"},
1357
- {"key":"L0148","section":"What are you doing now?","text":"What are you doing now?","placement":"placed","file":"modules/hall-ui/public/craft-mode.js","line":811,"string_id":"60853319f290"},
1358
- {"key":"L0149","section":"What are you doing now?","text":"Pick one. You can switch any time from the top bar.","placement":"placed","file":"modules/hall-ui/public/craft-mode.js","line":812,"string_id":"4f87d5b17b54"},
1359
- {"key":"L0150","section":"What are you doing now?","text":"Building","placement":"unplaced"},
1360
- {"key":"L0151","section":"What are you doing now?","text":"{…} and {…}","placement":"placed","file":"modules/hall-ui/public/profile-nudge.js","line":77,"string_id":"56b00d773232","occurrences":3},
1361
- {"key":"L0152","section":"What are you doing now?","text":"Artistry","placement":"unplaced"},
1362
- {"key":"L0153","section":"What are you doing now?","text":"Ideating","placement":"unplaced"},
1363
- {"key":"L0154","section":"What are you doing now?","text":"Turn thoughts into {…}.","placement":"unplaced"},
1364
- {"key":"L0155","section":"What are you doing now?","text":"Ask me again next session","placement":"placed","file":"modules/hall-ui/public/craft-mode.js","line":815,"string_id":"fa86bf403775"}
1222
+ {"key":"L0013","section":"Goals","text":"New goal","placement":"placed","file":"modules/hall-ui/public/goal-author.js","line":38,"string_id":"38e215b464a4"},
1223
+ {"key":"L0014","section":"Goals","text":"← Back to goal","placement":"placed","file":"modules/hall-ui/public/goals.html","line":189,"string_id":"7926e30955d2","state":"dependencies"},
1224
+ {"key":"L0015","section":"Completion","text":"Completion","placement":"unplaced","state":"uat"},
1225
+ {"key":"L0016","section":"Completion","text":"Every done-when criterion for this goal, with its full detail.","placement":"placed","file":"modules/hall-ui/public/goals.html","line":220,"string_id":"2ae1eb35611e","state":"uat"},
1226
+ {"key":"L0017","section":"Completion","text":"{…} of {…} criteria satisfied","placement":"placed","file":"modules/hall-ui/public/goals-lib.js","line":32,"string_id":"cc5106af4b35","state":"uat"},
1227
+ {"key":"L0018","section":"Completion","text":"{…} and {…}","placement":"placed","file":"modules/hall-ui/public/profile-nudge.js","line":77,"string_id":"56b00d773232","state":"uat","occurrences":2},
1228
+ {"key":"L0019","section":"Completion","text":"{…} project{…}","placement":"placed","file":"modules/hall-ui/public/fleet.js","line":39,"string_id":"771bef3d31b5","state":"uat","occurrences":2},
1229
+ {"key":"L0020","section":"Completion","text":"Awaiting UAT","placement":"placed","file":"modules/hall-ui/public/criterion-uat-ui.js","line":77,"string_id":"c78685da0e42","state":"uat","occurrences":2},
1230
+ {"key":"L0021","section":"Completion","text":"on the live site","placement":"unplaced","state":"uat"},
1231
+ {"key":"L0022","section":"Completion","text":"Test and sign off","placement":"placed","file":"modules/hall-ui/public/criterion-uat-ui.js","line":76,"string_id":"8584832c348f","state":"uat","occurrences":2},
1232
+ {"key":"L0023","section":"Completion","text":"Backend-only","placement":"unplaced","state":"uat"},
1233
+ {"key":"L0024","section":"Completion","text":"Mark backend-only","placement":"placed","file":"modules/hall-ui/public/criterion-uat-ui.js","line":85,"string_id":"525e085a6770","state":"uat"},
1234
+ {"key":"L0025","section":"Completion","text":"Metic-and-above builders vote on Full Ideas in the Board Room","placement":"unplaced","state":"uat"},
1235
+ {"key":"L0026","section":"Completion","text":"Satisfied (UAT)","placement":"unplaced","state":"uat"},
1236
+ {"key":"L0027","section":"Completion","text":"See the UAT","placement":"placed","file":"modules/hall-ui/public/criterion-uat-ui.js","line":80,"string_id":"00473a773fd7","state":"uat"},
1237
+ {"key":"L0028","section":"Completion","text":"The constitution in force always matches the last ratified amendment","placement":"unplaced","state":"uat"},
1238
+ {"key":"L0029","section":"Completion","text":"Closed before UAT","placement":"unplaced","state":"uat"},
1239
+ {"key":"L0030","section":"footer","text":"Sign out","placement":"shared","file":"modules/hall-ui/public/shell.js","line":520,"string_id":"1883ad7f07fc","state":"uat","occurrences":4},
1240
+ {"key":"L0031","section":"Completion","text":"Builders hall · this session","placement":"placed","file":"modules/hall-ui/public/craft-mode.js","line":810,"string_id":"fd1903586e8e","state":"uat"},
1241
+ {"key":"L0032","section":"Task {…}","text":"Task dependencies","placement":"placed","file":"modules/hall-ui/public/goals.html","line":191,"string_id":"a0f384b022fd","state":"dependencies"},
1242
+ {"key":"L0033","section":"Task {…}","text":"{…} and {…}","placement":"placed","file":"modules/hall-ui/public/profile-nudge.js","line":77,"string_id":"56b00d773232","state":"dependencies"},
1243
+ {"key":"L0034","section":"Task {…}","text":"#1165 Blocker-solve","placement":"unplaced","state":"dependencies"},
1244
+ {"key":"L0035","section":"Task {…}","text":"{…}: /{…}-s…","placement":"unplaced","state":"dependencies"},
1245
+ {"key":"L0036","section":"Task {…}","text":"P2 · {…}","placement":"unplaced","state":"dependencies","occurrences":4},
1246
+ {"key":"L0037","section":"Task {…}","text":"#2170 Work {…}","placement":"unplaced","state":"dependencies"},
1247
+ {"key":"L0038","section":"Task {…}","text":"redesign: tabs, filter…","placement":"unplaced","state":"dependencies"},
1248
+ {"key":"L0039","section":"Task {…}","text":"#594 V4.R29 — Status","placement":"unplaced","state":"dependencies"},
1249
+ {"key":"L0040","section":"Task {…}","text":"surface v2: {…} re…","placement":"unplaced","state":"dependencies"},
1250
+ {"key":"L0041","section":"Task {…}","text":"P3 · {…}","placement":"unplaced","state":"dependencies"},
1251
+ {"key":"L0042","section":"Task {…}","text":"#2171 Goals page:","placement":"unplaced","state":"dependencies"},
1252
+ {"key":"L0043","section":"Task {…}","text":"converge onto the kit…","placement":"unplaced","state":"dependencies"},
1253
+ {"key":"L0044","section":"Task {…}","text":"#2172 Settings","placement":"unplaced","state":"dependencies"},
1254
+ {"key":"L0045","section":"Task {…}","text":"regroup: 6 groups, st…","placement":"unplaced","state":"dependencies"},
1255
+ {"key":"L0046","section":"Task {…}","text":"Task","placement":"placed","file":"modules/hall-ui/public/task.js","line":475,"string_id":"eff70e59d12e","state":"dependencies"},
1256
+ {"key":"L0047","section":"Task {…}","text":"Status","placement":"unplaced","state":"dependencies"},
1257
+ {"key":"L0048","section":"Task {…}","text":"Priority","placement":"unplaced","state":"dependencies"},
1258
+ {"key":"L0049","section":"Task {…}","text":"Waits on","placement":"placed","file":"modules/hall-ui/public/goal-forest-render.js","line":186,"string_id":"8e4f0179e1d3","state":"dependencies"},
1259
+ {"key":"L0050","section":"Task {…}","text":"Needed by","placement":"placed","file":"modules/hall-ui/public/goal-forest-render.js","line":186,"string_id":"83197947ee8d","state":"dependencies"},
1260
+ {"key":"L0051","section":"Task {…}","text":"Chain","placement":"unplaced","state":"dependencies"},
1261
+ {"key":"L0052","section":"Task {…}","text":"P2","placement":"unplaced","state":"dependencies","occurrences":4},
1262
+ {"key":"L0053","section":"Task {…}","text":"Chain 1 · 3 tasks","placement":"unplaced","state":"dependencies","occurrences":3},
1263
+ {"key":"L0054","section":"Task {…}","text":"P3","placement":"unplaced","state":"dependencies"},
1264
+ {"key":"L0055","section":"Task {…}","text":"Chain 2 · 2 tasks","placement":"unplaced","state":"dependencies","occurrences":2},
1265
+ {"key":"L0056","section":"Conflicts12","text":"Conflicts","placement":"unplaced","state":"dependencies"},
1266
+ {"key":"L0057","section":"Conflicts12","text":"Open tasks whose declared files overlap — sequence these before two builders collide.","placement":"placed","file":"modules/hall-ui/public/goals.html","line":197,"string_id":"99c630009152","state":"dependencies"},
1267
+ {"key":"L0058","section":"Conflicts12","text":"Builders hall · this session","placement":"placed","file":"modules/hall-ui/public/craft-mode.js","line":810,"string_id":"fd1903586e8e","state":"dependencies"},
1268
+ {"key":"L0059","section":"Goals","text":"← All goals","placement":"placed","file":"modules/hall-ui/public/goals.html","line":77,"string_id":"d4b84b7fbdeb","state":"detail"},
1269
+ {"key":"L0060","section":"#1000081 {…}","text":"Claude's notes on this goal","placement":"placed","file":"modules/hall-ui/public/goals.html","line":88,"string_id":"5b3b75ee0596","state":"detail"},
1270
+ {"key":"L0061","section":"Completion3","text":"Completion","placement":"unplaced","state":"detail"},
1271
+ {"key":"L0062","section":"Completion3","text":"{…} of {…} criteria satisfied","placement":"placed","file":"modules/hall-ui/public/goals-lib.js","line":32,"string_id":"cc5106af4b35","state":"detail"},
1272
+ {"key":"L0063","section":"Completion3","text":"Goal {…}","placement":"placed","file":"modules/hall-ui/public/gate.js","line":360,"string_id":"ec88b946ad16","state":"detail"},
1273
+ {"key":"L0064","section":"Completion3","text":"{…} — harness fixture {…}","placement":"unplaced","state":"detail","occurrences":3},
1274
+ {"key":"L0065","section":"Members0","text":"Members","placement":"unplaced","state":"detail"},
1275
+ {"key":"L0066","section":"Members0","text":"No {…} assigned yet — an Archon can appoint one.","placement":"unplaced","state":"detail"},
1276
+ {"key":"L0067","section":"Members0","text":"No members yet — be the first to join.","placement":"unplaced","state":"detail"},
1277
+ {"key":"L0068","section":"Dependencies5","text":"Dependencies","placement":"unplaced","state":"detail"},
1278
+ {"key":"L0069","section":"Dependencies5","text":"5 tasks linked by dependencies, in 2 chains.","placement":"unplaced","state":"detail"},
1279
+ {"key":"L0070","section":"Dependencies5","text":"Ship these first","placement":"placed","file":"modules/hall-ui/public/goal-forest-render.js","line":125,"string_id":"48a40cce6763","state":"detail"},
1280
+ {"key":"L0071","section":"Dependencies5","text":"unblocks 2","placement":"unplaced","state":"detail"},
1281
+ {"key":"L0072","section":"Dependencies5","text":"unblocks 1","placement":"unplaced","state":"detail"},
1282
+ {"key":"L0073","section":"Dependencies5","text":"{…} file{…}","placement":"placed","file":"modules/hall-ui/public/gate.js","line":151,"string_id":"3efa67dc6e07","state":"detail"},
1283
+ {"key":"L0074","section":"Dependencies5","text":"See the full picture →","placement":"placed","file":"modules/hall-ui/public/goal-forest-render.js","line":138,"string_id":"9276193a0e41","state":"detail"},
1284
+ {"key":"L0075","section":"Tasks","text":"Tasks","placement":"unplaced","state":"detail"},
1285
+ {"key":"L0076","section":"Tasks","text":"To do","placement":"unplaced","state":"detail"},
1286
+ {"key":"L0077","section":"Tasks","text":"Completed","placement":"unplaced","state":"detail"},
1287
+ {"key":"L0078","section":"Tasks","text":"Search","placement":"unplaced","state":"detail"},
1288
+ {"key":"L0079","section":"Tasks","text":"task #{…}","placement":"placed","file":"modules/hall-ui/public/copy-desk.js","line":105,"string_id":"a6e803a31a4d","attr":"placeholder","state":"detail"},
1289
+ {"key":"L0080","section":"Tasks","text":"Sort","placement":"unplaced","state":"detail"},
1290
+ {"key":"L0081","section":"Tasks","text":"{…} / minute (high → low)","placement":"unplaced","state":"detail"},
1291
+ {"key":"L0082","section":"Tasks","text":"{…} (high → low)","placement":"unplaced","state":"detail"},
1292
+ {"key":"L0083","section":"Tasks","text":"minutes (low → high)","placement":"unplaced","state":"detail"},
1293
+ {"key":"L0084","section":"Tasks","text":"priority (P0 first)","placement":"unplaced","state":"detail"},
1294
+ {"key":"L0085","section":"Tasks","text":"task {…}","placement":"placed","file":"modules/hall-ui/public/gate.js","line":157,"string_id":"4d8ee7d68974","state":"detail"},
1295
+ {"key":"L0086","section":"Tasks","text":"status","placement":"unplaced","state":"detail"},
1296
+ {"key":"L0087","section":"Tasks","text":"Filters","placement":"unplaced","state":"detail"},
1297
+ {"key":"L0088","section":"Tasks","text":"{…} of {…}","placement":"placed","file":"modules/hall-ui/public/sky-panel.js","line":120,"string_id":"73c1372b43d9","state":"detail","occurrences":3},
1298
+ {"key":"L0089","section":"Tasks","text":"Archon","placement":"unplaced","state":"detail"},
1299
+ {"key":"L0090","section":"Tasks","text":"30m","placement":"unplaced","state":"detail"},
1300
+ {"key":"L0091","section":"Tasks","text":"1.00 {…}/min","placement":"unplaced","state":"detail","occurrences":9},
1301
+ {"key":"L0092","section":"Tasks","text":"11d","placement":"unplaced","state":"detail"},
1302
+ {"key":"L0093","section":"Tasks","text":"{…} Est.","placement":"unplaced","state":"detail","occurrences":25},
1303
+ {"key":"L0094","section":"Tasks","text":"Claim","placement":"unplaced","state":"detail","occurrences":25},
1304
+ {"key":"L0095","section":"Tasks","text":"Metic+","placement":"unplaced","state":"detail","occurrences":6},
1305
+ {"key":"L0096","section":"Tasks","text":"60m","placement":"unplaced","state":"detail","occurrences":17},
1306
+ {"key":"L0097","section":"Tasks","text":"Any rank","placement":"placed","file":"modules/hall-ui/public/task-lib.js","line":82,"string_id":"52ed0e2e3470","state":"detail","occurrences":18},
1307
+ {"key":"L0098","section":"Tasks","text":"45m","placement":"unplaced","state":"detail","occurrences":2},
1308
+ {"key":"L0099","section":"Tasks","text":"4w","placement":"unplaced","state":"detail","occurrences":21},
1309
+ {"key":"L0100","section":"Tasks","text":"0.85 {…}/min","placement":"unplaced","state":"detail","occurrences":11},
1310
+ {"key":"L0101","section":"Tasks","text":"40m","placement":"unplaced","state":"detail"},
1311
+ {"key":"L0102","section":"Tasks","text":"0.75 {…}/min","placement":"unplaced","state":"detail"},
1312
+ {"key":"L0103","section":"Tasks","text":"2w","placement":"unplaced","state":"detail"},
1313
+ {"key":"L0104","section":"Tasks","text":"90m","placement":"unplaced","state":"detail"},
1314
+ {"key":"L0105","section":"Tasks","text":"0.67 {…}/min","placement":"unplaced","state":"detail"},
1315
+ {"key":"L0106","section":"Tasks","text":"120m","placement":"unplaced","state":"detail","occurrences":3},
1316
+ {"key":"L0107","section":"Tasks","text":"0.58 {…}/min","placement":"unplaced","state":"detail"},
1317
+ {"key":"L0108","section":"Tasks","text":"8w","placement":"unplaced","state":"detail"},
1318
+ {"key":"L0109","section":"Tasks","text":"0.50 {…}/min","placement":"unplaced","state":"detail","occurrences":2},
1319
+ {"key":"L0110","section":"Tasks","text":"Per page","placement":"placed","file":"modules/hall-ui/public/hall-kit.js","line":74,"string_id":"4a46b478edaf","state":"detail"},
1320
+ {"key":"L0111","section":"Tasks","text":"‹ Prev","placement":"placed","file":"modules/hall-ui/public/hall-kit.js","line":74,"string_id":"de8fa5223aee","state":"detail"},
1321
+ {"key":"L0112","section":"Tasks","text":"Page {…} of {…}","placement":"placed","file":"modules/hall-ui/public/hall-kit.js","line":112,"string_id":"15a49bf15007","state":"detail"},
1322
+ {"key":"L0113","section":"Tasks","text":"Next ›","placement":"placed","file":"modules/hall-ui/public/hall-kit.js","line":74,"string_id":"f52ba261d930","state":"detail"},
1323
+ {"key":"L0114","section":"Tasks","text":"Builders hall · this session","placement":"placed","file":"modules/hall-ui/public/craft-mode.js","line":810,"string_id":"fd1903586e8e","state":"detail"},
1324
+ {"key":"L0115","section":"Goals","text":"Search","placement":"unplaced"},
1325
+ {"key":"L0116","section":"Goals","text":"goal # or name…","placement":"unplaced","attr":"placeholder"},
1326
+ {"key":"L0117","section":"Goals","text":"Version","placement":"unplaced"},
1327
+ {"key":"L0118","section":"Goals","text":"— any —","placement":"placed","file":"modules/hall-ui/public/hall-widgets.js","line":163,"string_id":"729d4ce22b99","occurrences":2},
1328
+ {"key":"L0119","section":"Goals","text":"Status","placement":"unplaced"},
1329
+ {"key":"L0120","section":"Goals","text":"open","placement":"placed","file":"modules/hall-ui/public/approval-queue.js","line":163,"string_id":"9a803563c948","occurrences":16},
1330
+ {"key":"L0121","section":"Goals","text":"Sort","placement":"unplaced"},
1331
+ {"key":"L0122","section":"Goals","text":"priority (version order)","placement":"unplaced"},
1332
+ {"key":"L0123","section":"Goals","text":"newest first","placement":"unplaced"},
1333
+ {"key":"L0124","section":"Goals","text":"oldest first","placement":"placed","file":"modules/hall-ui/public/hall-widgets.js","line":165,"string_id":"759c12b5f983"},
1334
+ {"key":"L0125","section":"Goals","text":"recently {…}","placement":"unplaced"},
1335
+ {"key":"L0126","section":"Goals","text":"stalest first","placement":"unplaced"},
1336
+ {"key":"L0127","section":"Goals","text":"Filters","placement":"unplaced"},
1337
+ {"key":"L0128","section":"Goals","text":"Views","placement":"unplaced"},
1338
+ {"key":"L0129","section":"Goals","text":"rows","placement":"unplaced"},
1339
+ {"key":"L0130","section":"Goals","text":"cards","placement":"unplaced"},
1340
+ {"key":"L0131","section":"Goals","text":"Ready to claim","placement":"unplaced"},
1341
+ {"key":"L0132","section":"Goals","text":"across 15 {…} {…}","placement":"unplaced"},
1342
+ {"key":"L0133","section":"Goals","text":"In progress","placement":"unplaced"},
1343
+ {"key":"L0134","section":"Goals","text":"claimed right now","placement":"unplaced"},
1344
+ {"key":"L0135","section":"Goals","text":"Blocked","placement":"unplaced"},
1345
+ {"key":"L0136","section":"Goals","text":"waiting on upstream tasks","placement":"unplaced"},
1346
+ {"key":"L0137","section":"Goals","text":"Criteria met","placement":"unplaced"},
1347
+ {"key":"L0138","section":"Goals","text":"on 15 {…} {…}","placement":"unplaced"},
1348
+ {"key":"L0139","section":"Goals","text":"Active","placement":"unplaced"},
1349
+ {"key":"L0140","section":"Goals","text":"{…} project{…}","placement":"placed","file":"modules/hall-ui/public/fleet.js","line":39,"string_id":"771bef3d31b5","occurrences":7},
1350
+ {"key":"L0141","section":"Goals","text":"claim next","placement":"placed","file":"modules/hall-ui/public/goals-render.js","line":169,"string_id":"9203a7283960","occurrences":15},
1351
+ {"key":"L0142","section":"Goals","text":"in progress","placement":"placed","file":"modules/hall-ui/public/roadmap.js","line":120,"string_id":"b2b399fdd6a4","occurrences":4},
1352
+ {"key":"L0143","section":"Goals","text":"blocked","placement":"unplaced","occurrences":8},
1353
+ {"key":"L0144","section":"Goals","text":"backlog","placement":"unplaced","occurrences":4},
1354
+ {"key":"L0145","section":"Goals","text":"{…} of {…}","placement":"placed","file":"modules/hall-ui/public/sky-panel.js","line":120,"string_id":"73c1372b43d9"},
1355
+ {"key":"L0146","section":"Goals","text":"⚖ admitted","placement":"placed","file":"modules/hall-ui/public/goals-render.js","line":194,"string_id":"5d6f38a02386","occurrences":3},
1356
+ {"key":"L0147","section":"Goals","text":"sessions","placement":"placed","file":"modules/hall-ui/public/task.js","line":467,"string_id":"732b4c935e36"},
1357
+ {"key":"L0148","section":"Goals","text":"Builders hall · this session","placement":"placed","file":"modules/hall-ui/public/craft-mode.js","line":810,"string_id":"fd1903586e8e"},
1358
+ {"key":"L0149","section":"What are you doing now?","text":"What are you doing now?","placement":"placed","file":"modules/hall-ui/public/craft-mode.js","line":811,"string_id":"60853319f290"},
1359
+ {"key":"L0150","section":"What are you doing now?","text":"Pick one. You can switch any time from the top bar.","placement":"placed","file":"modules/hall-ui/public/craft-mode.js","line":812,"string_id":"4f87d5b17b54"},
1360
+ {"key":"L0151","section":"What are you doing now?","text":"Building","placement":"unplaced"},
1361
+ {"key":"L0152","section":"What are you doing now?","text":"{…} and {…}","placement":"placed","file":"modules/hall-ui/public/profile-nudge.js","line":77,"string_id":"56b00d773232","occurrences":3},
1362
+ {"key":"L0153","section":"What are you doing now?","text":"Artistry","placement":"unplaced"},
1363
+ {"key":"L0154","section":"What are you doing now?","text":"Ideating","placement":"unplaced"},
1364
+ {"key":"L0155","section":"What are you doing now?","text":"Turn thoughts into {…}.","placement":"unplaced"},
1365
+ {"key":"L0156","section":"What are you doing now?","text":"Ask me again next session","placement":"placed","file":"modules/hall-ui/public/craft-mode.js","line":815,"string_id":"fa86bf403775"}
1365
1366
  ]
1366
1367
  },
1367
1368
  {
@@ -0,0 +1,129 @@
1
+ // goal-author-lib.js — the PURE half of authoring a goal and a done-when
2
+ // criterion from the hall (task 1003463), exposed as window.OTBGoalAuthor.
3
+ // Everything here is a function over its arguments — no DOM, no fetch — so the
4
+ // request bodies the form sends are pinned by tests/goal_author_ui.mjs. The DOM
5
+ // half is goal-author.js.
6
+ //
7
+ // What this file deliberately does NOT do (ADR 0366 D2 — interview-shaped steps
8
+ // are absent, not half-built): it picks no version, infers no scope, drafts no
9
+ // criteria or seed tasks, and judges no reuse. It also does NOT pre-filter the
10
+ // two authority walls — a Metic's protected-scope goal and a non-member's
11
+ // criterion are refused BY THE SERVER, and `refusalText` only renders that
12
+ // refusal in words (ADR 0086, ADR 0154).
13
+ (function () {
14
+ 'use strict';
15
+
16
+ // The server's own bounds (LIMITS.TITLE in _helpers.js). A longer name is
17
+ // refused there with a 400; the form stops at the same number so the box and
18
+ // the wall agree.
19
+ const TITLE_MAX = 200;
20
+ const SLUG_MAX = 48;
21
+
22
+ // The slug a criterion is filed under, derived from its outcome text. The
23
+ // server refuses a slug shaped like a positional ref (C1, C2, …) because the
24
+ // positional reading wins and the slug would be unreachable by its own name.
25
+ function criterionSlug(text) {
26
+ const words = String(text == null ? '' : text)
27
+ .toLowerCase()
28
+ .normalize('NFKD').replace(/[̀-ͯ]/g, '')
29
+ .replace(/[^a-z0-9]+/g, '-')
30
+ .replace(/^-+|-+$/g, '');
31
+ let slug = words.slice(0, SLUG_MAX).replace(/-+$/g, '');
32
+ if (!slug) return '';
33
+ if (/^c\d+$/.test(slug)) slug = `criterion-${slug}`;
34
+ return slug;
35
+ }
36
+
37
+ const clean = (s) => String(s == null ? '' : s).trim();
38
+
39
+ // POST /goals body. `spec_task: true` is ADR 0366 D3: the goal arrives with a
40
+ // "Spec goal N" task that gates its other work, and the scope is set when that
41
+ // task is done — so there is NO scope_modules field on this form, and the body
42
+ // never carries one. `succeeds_goal_id` and `admit_reason` are likewise absent
43
+ // (carry-forward is interview-shaped; admission is an Archon decision made
44
+ // elsewhere).
45
+ function buildGoalBody(f) {
46
+ const body = {
47
+ version_id: clean(f.version_id),
48
+ title: clean(f.title),
49
+ spec_task: true,
50
+ };
51
+ const subtitle = clean(f.subtitle);
52
+ const description = clean(f.description);
53
+ if (subtitle) body.subtitle = subtitle;
54
+ if (description) body.description = description;
55
+ const cat = Number(f.category_id);
56
+ if (Number.isInteger(cat) && cat > 0) body.category_id = cat;
57
+ return body;
58
+ }
59
+
60
+ // Why the goal form cannot be sent yet — null when it can. Mirrors only the
61
+ // shape the server checks first (required + length), never an authority rule.
62
+ function goalFormProblem(f) {
63
+ if (!clean(f.version_id)) return 'Pick the version this goal belongs to.';
64
+ const t = clean(f.title);
65
+ if (!t) return 'Give the goal a name.';
66
+ if (t.length > TITLE_MAX) return `Keep the name under ${TITLE_MAX} characters.`;
67
+ return null;
68
+ }
69
+
70
+ // The criterion form: the outcome text and the goal it belongs to. The version
71
+ // is the goal's own (the server refuses a goal on another version as a bad
72
+ // reference), so the page passes it from the goal row rather than asking.
73
+ function buildCriterionRequest(f) {
74
+ const text = clean(f.outcome);
75
+ return {
76
+ path: `/versions/${encodeURIComponent(clean(f.version_id))}/done-when`,
77
+ body: {
78
+ criterion_id: clean(f.slug) || criterionSlug(text),
79
+ criterion_md: text,
80
+ goal_id: Number(f.goal_id),
81
+ },
82
+ };
83
+ }
84
+
85
+ function criterionFormProblem(f) {
86
+ if (!(Number(f.goal_id) > 0)) return 'Pick the goal this criterion belongs to.';
87
+ if (!clean(f.outcome)) return 'Say what will be true when this goal is done.';
88
+ if (!criterionSlug(f.outcome)) return 'Use a few words with letters or numbers in them.';
89
+ return null;
90
+ }
91
+
92
+ // The refusal, in words. The server's envelope is { error: { code, message } };
93
+ // an older route may send { error: 'code' } or { message }. A refusal the server
94
+ // phrased keeps its own sentence — this only supplies one where the server sent
95
+ // a bare code, and says "who can do this" rather than hiding the wall.
96
+ const FALLBACK = {
97
+ archon_required_for_protected_scope: 'A goal scoped to a protected module can only be created by an Archon.',
98
+ archon_required_for_admission: 'Only an Archon may admit a goal into a version that is already building.',
99
+ criterion_exists: 'A criterion with that name already exists on this version. Reword the outcome slightly.',
100
+ reserved_criterion_slug: 'That name looks like a position (C1, C2…). Reword the outcome.',
101
+ bad_goal_id: 'That goal is not on this version.',
102
+ goal_not_yours: 'Only a goal’s owner or manager (or an Archon) can add criteria to it.',
103
+ version_not_found: 'That version no longer exists.',
104
+ };
105
+ function refusalText(status, data) {
106
+ const err = data && data.error;
107
+ const code = (err && typeof err === 'object' ? err.code : err) || (data && data.code) || '';
108
+ const msg = (err && typeof err === 'object' ? err.message : null) || (data && data.message) || '';
109
+ if (msg && msg !== code) return msg;
110
+ if (FALLBACK[code]) return FALLBACK[code];
111
+ if (status === 401) return 'Sign in again to do this.';
112
+ if (status === 403) return 'You do not have permission to do this. Ask the goal’s owner or an Archon.';
113
+ return 'That did not go through. Try again, or ask the project owner if it keeps happening.';
114
+ }
115
+
116
+ // Versions the form offers: every one still open to goals. The server decides
117
+ // who may add to which (a building version needs an Archon's admission), so the
118
+ // status rides on the label instead of the list being pre-filtered by rank.
119
+ function openVersions(list) {
120
+ return (Array.isArray(list) ? list : [])
121
+ .filter((v) => v && v.id != null && ['planning', 'building'].includes(String(v.status)))
122
+ .map((v) => ({ id: String(v.id), status: String(v.status), label: `${v.id} (${String(v.status) === 'planning' ? 'being planned' : 'being built'})` }));
123
+ }
124
+
125
+ window.OTBGoalAuthor = {
126
+ TITLE_MAX, criterionSlug, buildGoalBody, goalFormProblem,
127
+ buildCriterionRequest, criterionFormProblem, refusalText, openVersions,
128
+ };
129
+ })();