@bongos/core 1.19.800 → 1.19.802

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,22 +2,22 @@
2
2
  "artifact": "bongos-core",
3
3
  "manifest_schema": 1,
4
4
  "generator": "scripts/gds/package-core.js",
5
- "core_version": "1.19.800",
6
- "core_contract": "1.19.800",
7
- "source_commit": "61c8980e6b9f6fb0cbd611f41520cbcae4780f11",
5
+ "core_version": "1.19.802",
6
+ "core_contract": "1.19.802",
7
+ "source_commit": "45efc6ff51adfc6e4910c9a985eea7d6d03a55b5",
8
8
  "source_ref": "HEAD",
9
- "built_at": "2026-09-17T02:01:42.605Z",
9
+ "built_at": "2026-09-17T02:33:54.490Z",
10
10
  "redaction": {
11
11
  "model": "docs-redacted+functional-verbatim",
12
12
  "docs_redacted": 487,
13
13
  "agent_docs_stubbed": 25,
14
- "functional_verbatim": 2187,
14
+ "functional_verbatim": 2188,
15
15
  "rules": 3,
16
16
  "gate_literals": 3,
17
17
  "gate": "passed"
18
18
  },
19
- "file_count": 2699,
20
- "tree_sha256": "0d54a704f2ba5c26c517372981337570ff4a70da884edee06ef52c30e836fda3",
19
+ "file_count": 2700,
20
+ "tree_sha256": "4ee6d59590012d183002008d4e4cc2ebacb310dc098269f77c621e2d07a90df5",
21
21
  "files": [
22
22
  {
23
23
  "path": ".claude/skills/ask-for-help/SKILL.md",
@@ -1982,7 +1982,7 @@
1982
1982
  {
1983
1983
  "path": "docs/architecture.md",
1984
1984
  "mode": "0000644",
1985
- "sha256": "0946126f632fda787c80f6f7e2249dc5dd3eb28581c3a86022d0313ec5826fe3"
1985
+ "sha256": "d8a7777f2ebac97a6fe57324a31fe3747fc629feee725a7b3e27fe23e046d69a"
1986
1986
  },
1987
1987
  {
1988
1988
  "path": "docs/branding-contract.md",
@@ -2002,12 +2002,12 @@
2002
2002
  {
2003
2003
  "path": "docs/copy-inventory.md",
2004
2004
  "mode": "0000644",
2005
- "sha256": "ab5057dfc9880545e8d2ac6ac44eb86af18f13a7efe1a071c9a3b9910a2ec5b6"
2005
+ "sha256": "a9fadb69926ae276a4642f6d1ae19d714092109d326f5826ce828a4ef7015e8d"
2006
2006
  },
2007
2007
  {
2008
2008
  "path": "docs/copy-registry.json",
2009
2009
  "mode": "0000644",
2010
- "sha256": "8306b8b8748398081ddece28d92a5dd78b29facc39b55b394bb1b0877249264e"
2010
+ "sha256": "77327bd5ff618ff1a0cc2345e3bfe95a7f7acf8557c9dbbbb4f028737f966437"
2011
2011
  },
2012
2012
  {
2013
2013
  "path": "docs/design/apex-pass-2-direction.md",
@@ -2532,7 +2532,7 @@
2532
2532
  {
2533
2533
  "path": "docs/module-api-changelog.md",
2534
2534
  "mode": "0000644",
2535
- "sha256": "07a1c706c1ddc1d0c51da0737e861e8af59c0a50caa9119cfca43f1ad3fde6ba"
2535
+ "sha256": "6d176113a1a846ac31afbcab3dfcf8125ce4b90ce2f8308dd1d00b16da96490c"
2536
2536
  },
2537
2537
  {
2538
2538
  "path": "docs/modules-contract.md",
@@ -5317,7 +5317,7 @@
5317
5317
  {
5318
5318
  "path": "modules/hall-ui/public/task.js",
5319
5319
  "mode": "0000644",
5320
- "sha256": "015737c6c7e0da732ad5611d049aa3f09f4c868fbf2056d1495a991c5086a1dd"
5320
+ "sha256": "c61f2fb85a809557d6fcfebf90e02cadf01533125b40f86db46475c4970b6e87"
5321
5321
  },
5322
5322
  {
5323
5323
  "path": "modules/hall-ui/public/task.states.json",
@@ -5502,7 +5502,7 @@
5502
5502
  {
5503
5503
  "path": "modules/lifecycle/db-analytics.js",
5504
5504
  "mode": "0000644",
5505
- "sha256": "e7d1b7873795d869a0a22929f3658db593ede8533d641dd73baaa06ff6b48c9d"
5505
+ "sha256": "82bab8b382390313105ec87e6c7019671308c1353029f9ea40e2ef3819409e7e"
5506
5506
  },
5507
5507
  {
5508
5508
  "path": "modules/lifecycle/db-claim-reads.js",
@@ -5547,7 +5547,7 @@
5547
5547
  {
5548
5548
  "path": "modules/lifecycle/db-ship.js",
5549
5549
  "mode": "0000644",
5550
- "sha256": "a7a3f24e8cc01953e09c19c9dcb8f4a5a58bdd31fe8cf0076dd7cbb102491cf2"
5550
+ "sha256": "5b4e370fcaf6a5d23f2835833d4cd77eab67b9d509f78c24dd2650efa8e97fac"
5551
5551
  },
5552
5552
  {
5553
5553
  "path": "modules/lifecycle/db-tasks.js",
@@ -7712,12 +7712,12 @@
7712
7712
  {
7713
7713
  "path": "package-lock.json",
7714
7714
  "mode": "0000644",
7715
- "sha256": "2fa689bfe81f60fd4b8ca8e0304b2eac417c172af397d23c1de3427e0a6544a5"
7715
+ "sha256": "34cfc2b2ac517fd72eedb774df0e1f91e182f265bd29109af0a51a172fef6ca9"
7716
7716
  },
7717
7717
  {
7718
7718
  "path": "package.json",
7719
7719
  "mode": "0000644",
7720
- "sha256": "2e40419061babf39395a90a2b45c7c7409e1acce44e86984a3913dd6010a485a"
7720
+ "sha256": "ecd677de73f7be790d92bea1d0fc1d999d9ebfc43d6098810ce255eb9cb1d395"
7721
7721
  },
7722
7722
  {
7723
7723
  "path": "public-docs/index.html",
@@ -8977,7 +8977,7 @@
8977
8977
  {
8978
8978
  "path": "scripts/gds/ship-honesty.js",
8979
8979
  "mode": "0000644",
8980
- "sha256": "3ab4816fdd43d589cda73698a514f8e23103be166c1650fd24beeee9f529bb5b"
8980
+ "sha256": "f9cafe9726d6cedc398dc9898e33a9d2d5eca32354661b58d7f820e195d59137"
8981
8981
  },
8982
8982
  {
8983
8983
  "path": "scripts/gds/ship-io.js",
@@ -8997,7 +8997,7 @@
8997
8997
  {
8998
8998
  "path": "scripts/gds/ship-merge.js",
8999
8999
  "mode": "0000644",
9000
- "sha256": "b602b4cf8f0e66610991237e1cb7ade9cd5c14659b155ce3512268d40ae670eb"
9000
+ "sha256": "99401464922cc545681786e59ebdc5ad35ec5578f7562c7986e458af797e85ab"
9001
9001
  },
9002
9002
  {
9003
9003
  "path": "scripts/gds/ship-preflight-steps.js",
@@ -9602,7 +9602,7 @@
9602
9602
  {
9603
9603
  "path": "src/module-api.js",
9604
9604
  "mode": "0000644",
9605
- "sha256": "0a1e5d3b5db82b4a63d3936fd70ff4e079a1eef0b81b8d7041fcb3f1aaffc109"
9605
+ "sha256": "fdcbeb75b3f63bb495547ba048fdce05ff4956c1e1fce9a79376dcfc78109734"
9606
9606
  },
9607
9607
  {
9608
9608
  "path": "src/module-loader/catalog.js",
@@ -11362,7 +11362,7 @@
11362
11362
  {
11363
11363
  "path": "tests/hall_record_world.mjs",
11364
11364
  "mode": "0000644",
11365
- "sha256": "b8618fc69c3fde9b6987fea69839d74e843230a7d56e6e54a5170fce04548c20"
11365
+ "sha256": "af622fd6dac843070bf41077eccf15051a398006e35a25298595c87e129d377d"
11366
11366
  },
11367
11367
  {
11368
11368
  "path": "tests/hall_reference_world.mjs",
@@ -12579,6 +12579,11 @@
12579
12579
  "mode": "0000644",
12580
12580
  "sha256": "6dac9970bfdc8e5fd3940dc956b94963bc8ecdc345820de831078af614cf875f"
12581
12581
  },
12582
+ {
12583
+ "path": "tests/regrade_actual_minutes.mjs",
12584
+ "mode": "0000644",
12585
+ "sha256": "ad6d883fcb09f31dc7c06a2334ad807c15bd1effba43ef12b5fbdbf0ab141041"
12586
+ },
12582
12587
  {
12583
12588
  "path": "tests/regrade_eligibility.mjs",
12584
12589
  "mode": "0000644",
@@ -12927,7 +12932,7 @@
12927
12932
  {
12928
12933
  "path": "tests/ship_cannot_lie.mjs",
12929
12934
  "mode": "0000644",
12930
- "sha256": "55e94ed59bc1bd19e4a3dd0e9a9a415dde659c5d71af0dd827d1b288e66de3c7"
12935
+ "sha256": "55adaf198cd21d4f267f1f50c8e31e176d4b2f037a87abc5a7d10e5df0d123d2"
12931
12936
  },
12932
12937
  {
12933
12938
  "path": "tests/ship_card.mjs",
@@ -142,7 +142,9 @@ tasks + kind text NOT NULL DEFAULT 'unclassified' CHECK IN (feature|bug|infra|
142
142
  learning-capture|cleanup|decision|
143
143
  blocker-resolution|unclassified)
144
144
  + parent_task_id bigint REFERENCES tasks(id)
145
- + actual_minutes integer
145
+ + actual_minutes integer -- SUM of session_logs for the task, so
146
+ -- CLAIMED-session time only; a --regrade has no
147
+ -- claim and is deliberately not counted (task 1003964)
146
148
  + scoping_confidence integer CHECK (1..5)
147
149
  + discipline text NOT NULL DEFAULT 'unclassified' (mig 014; renamed mig 086)
148
150
  CHECK IN (engineer|artist|ideator|unclassified)
@@ -53,14 +53,14 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
53
53
  | `3eb67b892dea` | 4x | Percy Jackson | modules/public-landing/public/index.html:803, modules/public-landing/public/index.html:821, modules/public-landing/public/index.html:827 |
54
54
  | `e57ec24e13ef` | 4x | Sign in with GitHub | modules/hall-ui/public/hall-render.js:275, modules/hall-ui/public/hall-render.js:346, modules/hall-ui/public/hall-render.js:415 |
55
55
  | `2ae36be1c531` | 4x | Start a project | modules/public-landing/public/index.html:727, modules/public-landing/public/index.html:891, modules/public-landing/public/projects.html:509 |
56
- | `eff70e59d12e` | 4x | Task {…} | modules/hall-ui/public/task.js:451, modules/hall-ui/public/task.js:460, modules/hall-ui/public/task.js:688 |
56
+ | `eff70e59d12e` | 4x | Task {…} | modules/hall-ui/public/task.js:455, modules/hall-ui/public/task.js:464, modules/hall-ui/public/task.js:693 |
57
57
  | `b31fc908c962` | 4x | You claimed #{…}. Open a terminal to start work. | modules/hall-ui/public/goals-page.js:418, modules/hall-ui/public/goals-page.js:515, modules/hall-ui/public/work.js:904 |
58
58
  | `1de02052abf2` | 3x | Available from the {…} rank up. | modules/hall-ui/public/gate.js:222, modules/hall-ui/public/government.js:882, modules/hall-ui/public/harbor.js:340 |
59
59
  | `08afb1257b71` | 3x | Back to home | modules/hall-ui/public/drachmae.html:87, modules/hall-ui/public/primer.html:90, modules/hall-ui/public/primer.js:283 |
60
60
  | `118026595c16` | 3x | Board Room | modules/hall-ui/public/board-room.html:19, modules/hall-ui/public/board-room.html:19, modules/hall-ui/public/board-room.html:31 |
61
61
  | `a78477a24a48` | 3x | Builders' Hall | modules/hall-ui/public/index.html:12, modules/hall-ui/public/index.html:12, modules/hall-ui/public/index.html:45 |
62
62
  | `12ee050d0180` | 3x | Copy desk | modules/hall-ui/public/copy-desk.html:15, modules/hall-ui/public/copy-desk.html:15, modules/hall-ui/public/copy-desk.html:27 |
63
- | `a873e7c29d80` | 3x | Copy prompt | modules/hall-ui/public/task.js:614, modules/hall-ui/public/task.js:634, modules/hall-ui/public/work.js:599 |
63
+ | `a873e7c29d80` | 3x | Copy prompt | modules/hall-ui/public/task.js:619, modules/hall-ui/public/task.js:639, modules/hall-ui/public/work.js:599 |
64
64
  | `9c728558d6e7` | 3x | Drachmae & karma | modules/hall-ui/public/drachmae.html:22, modules/hall-ui/public/drachmae.html:22, modules/hall-ui/public/drachmae.html:37 |
65
65
  | `f6f68ba322be` | 3x | Open {…} | modules/hall-ui/public/goal-inbox.js:53, modules/hall-ui/public/goal-inbox.js:69, modules/hall-ui/public/goals.js:67 |
66
66
  | `e08628967f2f` | 3x | Project settings | modules/hall-ui/public/project-settings.html:15, modules/hall-ui/public/project-settings.html:15, modules/hall-ui/public/project-settings.html:26 |
@@ -180,7 +180,7 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
180
180
  | `1de02052abf2` | certain | Available from the {…} rank up. | `modules/hall-ui/public/gate.js:222` |
181
181
  | `1de02052abf2` | certain | Available from the {…} rank up. | `modules/hall-ui/public/government.js:882` |
182
182
  | `1de02052abf2` | certain | Available from the {…} rank up. | `modules/hall-ui/public/harbor.js:340` |
183
- | `bdbe9ff6a177` | certain | Awaiting the grader, or a confirmation, before it can ship. | `modules/hall-ui/public/task.js:604` |
183
+ | `bdbe9ff6a177` | certain | Awaiting the grader, or a confirmation, before it can ship. | `modules/hall-ui/public/task.js:609` |
184
184
  | `ecfbb10d4ca9` | certain | Awaiting the owner/manager's approval | `modules/hall-ui/public/goals-render.js:934` |
185
185
  | `08afb1257b71` | certain | Back to home | `modules/hall-ui/public/drachmae.html:87` |
186
186
  | `08afb1257b71` | certain | Back to home | `modules/hall-ui/public/primer.html:90` |
@@ -226,7 +226,7 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
226
226
  | `f8725cf3ba62` | certain | Checking dependency order… | `modules/hall-ui/public/work.js:853` |
227
227
  | `7a41b18c0de8` | certain | Checking for conflicts… | `modules/hall-ui/public/work.js:832` |
228
228
  | `aa3ba7d28a76` | certain | Checking your key… | `modules/hall-ui/public/settings.js:1073` |
229
- | `b3d0e2af5176` | certain | Choose a goal first. | `modules/hall-ui/public/task.js:663` |
229
+ | `b3d0e2af5176` | certain | Choose a goal first. | `modules/hall-ui/public/task.js:668` |
230
230
  | `1c6b0e3ffc0e` | certain | Choose a setup | `modules/hall-ui/public/hall-render.js:779` |
231
231
  | `6c88cdf417f1` | certain | Choose which sound plays for each build event — one when Claude waits for your input, another when a task ship | `modules/hall-ui/public/settings.html:350` |
232
232
  | `c10806b50c61` | certain | Claim task {…} | `modules/hall-ui/public/goals-render.js:345` |
@@ -260,7 +260,7 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
260
260
  | `c72c97dc33fe` | certain | Collab — {{worldName}} | `modules/hall-ui/public/collab.html:6` |
261
261
  | `c72c97dc33fe` | certain | Collab — {{worldName}} | `modules/hall-ui/public/collab.html:6` |
262
262
  | `cfc287c42263` | certain | Complete your profile | `modules/hall-ui/public/profile-nudge.js:62` |
263
- | `2867c85d196d` | certain | Confirm that verification for #{…} actually passed? | `modules/hall-ui/public/task.js:649` |
263
+ | `2867c85d196d` | certain | Confirm that verification for #{…} actually passed? | `modules/hall-ui/public/task.js:654` |
264
264
  | `9b16a22bf24c` | certain | Connect Discord & join the server | `modules/hall-ui/public/hall-render.js:983` |
265
265
  | `9b16a22bf24c` | certain | Connect Discord & join the server | `modules/hall-ui/public/settings.js:859` |
266
266
  | `9f8d8e07224f` | certain | Connect your Claude Desktop to your dev box with a one-time pairing code — the guided flow lives on its own pa | `modules/hall-ui/public/settings.html:243` |
@@ -275,8 +275,8 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
275
275
  | `30764a4f0e28` | certain | Copy for Session Start | `modules/hall-ui/public/collab.js:91` |
276
276
  | `7cabea700b57` | certain | Copy not supported here — select the value and copy by hand. | `modules/hall-ui/public/box-panel.js:415` |
277
277
  | `ebc8a6c16a22` | certain | Copy parallel prompt | `modules/hall-ui/public/work.html:146` |
278
- | `a873e7c29d80` | certain | Copy prompt | `modules/hall-ui/public/task.js:614` |
279
- | `a873e7c29d80` | certain | Copy prompt | `modules/hall-ui/public/task.js:634` |
278
+ | `a873e7c29d80` | certain | Copy prompt | `modules/hall-ui/public/task.js:619` |
279
+ | `a873e7c29d80` | certain | Copy prompt | `modules/hall-ui/public/task.js:639` |
280
280
  | `a873e7c29d80` | certain | Copy prompt | `modules/hall-ui/public/work.js:599` |
281
281
  | `8e2046777710` | certain | Copy prompt for task {…} | `modules/hall-ui/public/goals-render.js:346` |
282
282
  | `8e2046777710` | certain | Copy prompt for task {…} | `modules/hall-ui/public/work.js:467` |
@@ -302,7 +302,7 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
302
302
  | `01f0308c66e0` | certain | Could not invite that builder just now. | `modules/hall-ui/public/goals-render.js:1189` |
303
303
  | `71da00d47492` | certain | Could not invite: {…} | `modules/hall-ui/public/watch.js:321` |
304
304
  | `90691bceaf68` | certain | Could not load | `modules/hall-ui/public/project-settings.js:242` |
305
- | `90691bceaf68` | certain | Could not load | `modules/hall-ui/public/task.js:707` |
305
+ | `90691bceaf68` | certain | Could not load | `modules/hall-ui/public/task.js:712` |
306
306
  | `589a4cfc5442` | certain | Could not load idea {…}. | `modules/hall-ui/public/ideas.js:644` |
307
307
  | `192c893fc64e` | certain | Could not load modules. | `modules/hall-ui/public/modules.js:318` |
308
308
  | `8a4b590fa1a0` | certain | Could not load requests. | `modules/hall-ui/public/collab.js:458` |
@@ -318,7 +318,7 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
318
318
  | `2a9fb4046bc4` | certain | Could not load your rank. Return to the hall and try again. | `modules/hall-ui/public/ranks.js:196` |
319
319
  | `9d533e811dec` | certain | Could not load your sessions: {…} | `modules/hall-ui/public/settings-sessions.js:114` |
320
320
  | `64f9d51f0fa2` | certain | Could not load your settings. | `modules/hall-ui/public/settings.js:1335` |
321
- | `de244c45d916` | certain | Could not load {…} | `modules/hall-ui/public/task.js:700` |
321
+ | `de244c45d916` | certain | Could not load {…} | `modules/hall-ui/public/task.js:705` |
322
322
  | `2366356926b4` | certain | Could not mark the primer just now. Try again. | `modules/hall-ui/public/primer.js:260` |
323
323
  | `753987b5da13` | certain | Could not reach the submit endpoint. | `modules/hall-ui/public/modules.js:297` |
324
324
  | `6f500726f0ac` | certain | Could not read the report: {…} | `modules/hall-ui/public/watch.js:640` |
@@ -451,7 +451,7 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
451
451
  | `647bcfcfdb03` | certain | Fresh CLI token issued. Paste it in your terminal: | `modules/hall-ui/public/settings.js:932` |
452
452
  | `55c71d76a94c` | certain | From creation to production — and the exact step where {{currency}} are awarded (at | `modules/hall-ui/public/diagrams.html:52` |
453
453
  | `d32c5e058d1e` | certain | From the system | `modules/hall-ui/public/hall-render.js:658` |
454
- | `fc6fdfa639a7` | certain | Full log | `modules/hall-ui/public/task.js:440` |
454
+ | `fc6fdfa639a7` | certain | Full log | `modules/hall-ui/public/task.js:444` |
455
455
  | `ecae3916bf01` | certain | Gate — {{worldName}} | `modules/hall-ui/public/gate.html:6` |
456
456
  | `ecae3916bf01` | certain | Gate — {{worldName}} | `modules/hall-ui/public/gate.html:6` |
457
457
  | `c93912bbad76` | certain | Gathering the reviews and flagged copy that wait for you. | `modules/hall-ui/public/studio.html:46` |
@@ -553,7 +553,7 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
553
553
  | `35a15eb0a117` | certain | Last 30 days | `modules/hall-ui/public/hall-widgets.js:129` |
554
554
  | `9be8b839eff8` | certain | Last 7 days | `modules/hall-ui/public/hall-widgets.js:129` |
555
555
  | `59f0bc78a28f` | certain | Last 90 days | `modules/hall-ui/public/hall-widgets.js:130` |
556
- | `13bae4dfb28e` | certain | Last claimed by | `modules/hall-ui/public/task.js:546` |
556
+ | `13bae4dfb28e` | certain | Last claimed by | `modules/hall-ui/public/task.js:551` |
557
557
  | `1526a7ae8c85` | certain | Latest version: v{…}. | `modules/hall-ui/public/settings.js:1421` |
558
558
  | `7c9b7a89353b` | certain | Leave goal | `modules/hall-ui/public/goals-render.js:931` |
559
559
  | `f192ff6563f9` | certain | Leave your GitHub username and an Archon will let you in. No coding needed to start — once you're approved, si | `modules/hall-ui/public/hall-render.js:294` |
@@ -609,7 +609,7 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
609
609
  | `319e9db996ea` | certain | Modules — {{worldName}} | `modules/hall-ui/public/modules.html:6` |
610
610
  | `1ae18e58fead` | certain | Most recent first. Each load of this page is itself recorded in the audit log. | `modules/hall-ui/public/sessions.js:228` |
611
611
  | `f14a91b3f625` | certain | Most recent first. Each row is one recorded work session; every id on it opens its record. | `modules/hall-ui/public/sessions.html:56` |
612
- | `e52ae74f0052` | certain | Move to goal | `modules/hall-ui/public/task.js:507` |
612
+ | `e52ae74f0052` | certain | Move to goal | `modules/hall-ui/public/task.js:511` |
613
613
  | `e77d5f3beaef` | certain | Move to {…} | `modules/hall-ui/public/deploy.js:103` |
614
614
  | `e77d5f3beaef` | certain | Move to {…} | `modules/hall-ui/public/deploy.js:161` |
615
615
  | `ae84ebe1d735` | certain | Name cannot be blank. | `modules/hall-ui/public/settings.js:763` |
@@ -643,7 +643,7 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
643
643
  | `3b9823dd4579` | certain | No maintenance declared — nobody is on the hook for this module as the core advances. | `modules/hall-ui/public/modules.js:92` |
644
644
  | `64a4281934d1` | certain | No match. Try a page name, or an id like | `modules/hall-ui/public/palette.js:182` |
645
645
  | `4f89817b92e5` | certain | No onboarding steps recorded yet. | `modules/hall-ui/public/hall-render.js:911` |
646
- | `421ae031594e` | certain | No open goals in this version | `modules/hall-ui/public/task.js:506` |
646
+ | `421ae031594e` | certain | No open goals in this version | `modules/hall-ui/public/task.js:510` |
647
647
  | `2a6d7552e21f` | certain | No other sessions. | `modules/hall-ui/public/settings-sessions.js:64` |
648
648
  | `9f73b3f3dad0` | certain | No rank floor — any builder can claim this task | `modules/hall-ui/public/task-lib.js:62` |
649
649
  | `3fd0c6fcb92e` | certain | No request and no invite needed. Sign in with GitHub, and a step-by-step guide takes you the rest of the way. | `modules/hall-ui/public/hall-render.js:277` |
@@ -659,7 +659,7 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
659
659
  | `91c409a4aea5` | certain | Nobody vouched for this name — anyone can file a request naming anyone. Confirm who is asking before you admit | `modules/hall-ui/public/watch.js:374` |
660
660
  | `c72e0bdb834a` | certain | Not declared in module.json — this is who ships the module. | `modules/hall-ui/public/modules.js:62` |
661
661
  | `361b353ded5e` | certain | Not enough shipped work yet to chart. | `modules/hall-ui/public/hall-widgets.js:184` |
662
- | `90230572d017` | certain | Not found | `modules/hall-ui/public/task.js:695` |
662
+ | `90230572d017` | certain | Not found | `modules/hall-ui/public/task.js:700` |
663
663
  | `8226c979db4d` | certain | Not now | `modules/hall-ui/public/collab.js:365` |
664
664
  | `5ffcdc1a0176` | certain | Not scored — this builder’s own profile waived every signal, or the session predates this measure. | `modules/hall-ui/public/sessions.js:67` |
665
665
  | `61250b49a90b` | certain | Not scored. | `modules/hall-ui/public/idea.js:84` |
@@ -691,7 +691,7 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
691
691
  | `fa818ee444b4` | certain | Only this goal's owner or a manager (or an Archon) may do this. | `modules/hall-ui/public/goals-render.js:1233` |
692
692
  | `544011db314a` | certain | Only this goal's owner or a manager (or an Archon) may invite. | `modules/hall-ui/public/goals-render.js:1187` |
693
693
  | `261d123970e8` | certain | Open goal #{…} | `modules/hall-ui/public/roadmap.js:119` |
694
- | `5f3e0b179839` | certain | Open in Sessions | `modules/hall-ui/public/task.js:440` |
694
+ | `5f3e0b179839` | certain | Open in Sessions | `modules/hall-ui/public/task.js:444` |
695
695
  | `9f55e4674ebb` | certain | Open in the copy desk | `modules/hall-ui/public/studio.js:219` |
696
696
  | `3366b115217b` | certain | Open navigation | `modules/hall-ui/public/shell.js:452` |
697
697
  | `0f0b1e62148d` | certain | Open online environment | `modules/hall-ui/public/box-panel.js:421` |
@@ -767,7 +767,7 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
767
767
  | `b03e17693dcd` | certain | Read it as a table | `modules/hall-ui/public/watch.js:1167` |
768
768
  | `b6fcfdd652a7` | certain | Read it here | `modules/hall-ui/public/work.html:45` |
769
769
  | `053df132e22c` | certain | Read the full ask | `modules/hall-ui/public/collab.js:91` |
770
- | `c5f19a888a15` | certain | Read the handoff notes | `modules/hall-ui/public/task.js:438` |
770
+ | `c5f19a888a15` | certain | Read the handoff notes | `modules/hall-ui/public/task.js:442` |
771
771
  | `f9e998f4af3d` | certain | Read to the end and the button below unlocks. It is an honour system — nothing here checks your comprehension. | `modules/hall-ui/public/primer.html:100` |
772
772
  | `26e6c9879035` | certain | Reading the diagrams | `modules/hall-ui/public/diagrams.html:39` |
773
773
  | `81cd2cdf954d` | certain | Reading the request… | `modules/hall-ui/public/pair.html:28` |
@@ -851,7 +851,7 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
851
851
  | `fcd68c6a21fd` | certain | Serving now | `modules/hall-ui/public/deploy.js:115` |
852
852
  | `64a1f055129e` | certain | Session card richness | `modules/hall-ui/public/settings-render.js:83` |
853
853
  | `d14e8e9acaff` | certain | Session ended. | `modules/hall-ui/public/settings-sessions.js:81` |
854
- | `55e0a34bafed` | certain | Session log{…} | `modules/hall-ui/public/task.js:444` |
854
+ | `55e0a34bafed` | certain | Session log{…} | `modules/hall-ui/public/task.js:448` |
855
855
  | `cccb362bd6da` | certain | Sessions — {{worldName}} | `modules/hall-ui/public/sessions.html:6` |
856
856
  | `cccb362bd6da` | certain | Sessions — {{worldName}} | `modules/hall-ui/public/sessions.html:6` |
857
857
  | `b823d9a37a35` | certain | Set up key storage | `modules/hall-ui/public/settings.js:1024` |
@@ -862,9 +862,9 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
862
862
  | `62c3ea026095` | certain | Settings sections | `modules/hall-ui/public/settings.html:51` |
863
863
  | `2566a43904cb` | certain | Settings — {{worldName}} | `modules/hall-ui/public/settings.html:6` |
864
864
  | `2566a43904cb` | certain | Settings — {{worldName}} | `modules/hall-ui/public/settings.html:6` |
865
- | `ac44b08aec92` | certain | Ship it | `modules/hall-ui/public/task.js:600` |
865
+ | `ac44b08aec92` | certain | Ship it | `modules/hall-ui/public/task.js:605` |
866
866
  | `b94a6b5b3d8c` | certain | Shipped with the core | `modules/hall-ui/public/modules.html:56` |
867
- | `0c0a50ba1666` | certain | Shipped {…}{…}, {…}. | `modules/hall-ui/public/task.js:581` |
867
+ | `0c0a50ba1666` | certain | Shipped {…}{…}, {…}. | `modules/hall-ui/public/task.js:586` |
868
868
  | `6dde12eb0c78` | certain | Show all {…} | `modules/hall-ui/public/collab.js:245` |
869
869
  | `14d32a35c15f` | certain | Show my cross-project record | `modules/hall-ui/public/settings.js:516` |
870
870
  | `dc0f9fe50a65` | certain | Show the setup guide again | `modules/hall-ui/public/index.html:64` |
@@ -911,14 +911,14 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
911
911
  | `10cc12f37636` | certain | Task sections | `modules/hall-ui/public/work.html:53` |
912
912
  | `0e636ea41b29` | certain | Task status | `modules/hall-ui/public/goals-render.js:340` |
913
913
  | `af527fbc48e1` | certain | Task that carried the fix | `modules/hall-ui/public/copy-desk.html:127` |
914
- | `eff70e59d12e` | certain | Task {…} | `modules/hall-ui/public/task.js:451` |
915
- | `eff70e59d12e` | certain | Task {…} | `modules/hall-ui/public/task.js:460` |
916
- | `eff70e59d12e` | certain | Task {…} | `modules/hall-ui/public/task.js:688` |
917
- | `eff70e59d12e` | certain | Task {…} | `modules/hall-ui/public/task.js:700` |
914
+ | `eff70e59d12e` | certain | Task {…} | `modules/hall-ui/public/task.js:455` |
915
+ | `eff70e59d12e` | certain | Task {…} | `modules/hall-ui/public/task.js:464` |
916
+ | `eff70e59d12e` | certain | Task {…} | `modules/hall-ui/public/task.js:693` |
917
+ | `eff70e59d12e` | certain | Task {…} | `modules/hall-ui/public/task.js:705` |
918
918
  | `1d714be820d3` | certain | Task — {{worldName}} | `modules/hall-ui/public/task.html:6` |
919
919
  | `1d714be820d3` | certain | Task — {{worldName}} | `modules/hall-ui/public/task.html:6` |
920
920
  | `860fa4af9917` | certain | Tasks could not be loaded. | `modules/hall-ui/public/goals-render.js:1109` |
921
- | `0a471ed243db` | certain | Tasks in the ledger are numbered separately from GitHub pull requests, so this may be a PR number rather than | `modules/hall-ui/public/task.js:688` |
921
+ | `0a471ed243db` | certain | Tasks in the ledger are numbered separately from GitHub pull requests, so this may be a PR number rather than | `modules/hall-ui/public/task.js:693` |
922
922
  | `2fc66e722e33` | certain | Tasks open once you have read the builder primer. | `modules/hall-ui/public/work.html:43` |
923
923
  | `44579eef0c8d` | certain | Tasks — {{worldName}} | `modules/hall-ui/public/work.html:6` |
924
924
  | `44579eef0c8d` | certain | Tasks — {{worldName}} | `modules/hall-ui/public/work.html:6` |
@@ -931,7 +931,7 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
931
931
  | `50198c465225` | certain | The 16-value rank enum in three bands, which ranks are live, and the permissions each rank holds. | `modules/hall-ui/public/diagrams.html:59` |
932
932
  | `c5e6bdd32fe3` | certain | The Board Room is open to the builders this project’s constitution seats on its board. | `modules/hall-ui/public/board-room.js:436` |
933
933
  | `1569b8838862` | certain | The Dev Box app now acts as | `modules/hall-ui/public/pair.js:40` |
934
- | `6e93ef49d63f` | certain | The adversarial panel. Each worker reports pass, concerns or fail on its own; the gating workers must all pass | `modules/hall-ui/public/task.js:388` |
934
+ | `6e93ef49d63f` | certain | The adversarial panel. Each worker reports pass, concerns or fail on its own; the gating workers must all pass | `modules/hall-ui/public/task.js:392` |
935
935
  | `600b90074021` | certain | The art pipeline draws tiles and sprites with Google AI Studio (Gemini). Needed only if you generate art — you | `modules/hall-ui/public/settings.html:185` |
936
936
  | `4462dcaaaa7d` | certain | The artist reads this instead of guessing. A pointer with no judgement costs them a look and tells them nothin | `modules/hall-ui/public/copy-desk.html:103` |
937
937
  | `195b295d0bf3` | certain | The atlas regenerates itself on the server every time code ships; it has not been generated on this deploy yet | `modules/hall-ui/public/atlas.html:63` |
@@ -944,7 +944,7 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
944
944
  | `36ed1b04583e` | certain | The full queues | `modules/hall-ui/public/studio.html:56` |
945
945
  | `cb7c7879eeba` | certain | The fundamentals | `modules/hall-ui/public/project-settings.html:40` |
946
946
  | `4dd13bc5a35b` | certain | The goal's leads have paused applications; they can still invite you | `modules/hall-ui/public/goals-render.js:939` |
947
- | `19b23f2cc45b` | certain | The grading panel could not run when this task was shipped, so no quality signal was recorded — an outage, not | `modules/hall-ui/public/task.js:370` |
947
+ | `19b23f2cc45b` | certain | The grading panel could not run when this task was shipped, so no quality signal was recorded — an outage, not | `modules/hall-ui/public/task.js:374` |
948
948
  | `027e9420daa2` | certain | The headline lands, but the sub-line reads like a brochure. | `modules/hall-ui/public/studio.js:162` |
949
949
  | `797f02fa8295` | certain | The hosted machine your work runs on. Open it in your browser (the online terminal) or connect over SSH — whic | `modules/hall-ui/public/settings.html:204` |
950
950
  | `9f45c63c9697` | certain | The kinds of work you prefer. Task suggestions lean toward your choices — pick one, several, or none. | `modules/hall-ui/public/settings.html:127` |
@@ -980,7 +980,7 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
980
980
  | `6110f639b94d` | certain | The studio | `modules/hall-ui/public/studio.html:37` |
981
981
  | `7d016f4a65bf` | certain | The system is mid-build. These diagrams deliberately separate what stands today from what is yet planned, so t | `modules/hall-ui/public/diagrams.html:40` |
982
982
  | `599fd0e82d1c` | certain | The task board — all work | `modules/hall-ui/public/studio.html:58` |
983
- | `198ba9353bf6` | certain | The task feed did not answer. Nothing on the record has changed, only the read failed. Try again in a moment, | `modules/hall-ui/public/task.js:700` |
983
+ | `198ba9353bf6` | certain | The task feed did not answer. Nothing on the record has changed, only the read failed. Try again in a moment, | `modules/hall-ui/public/task.js:705` |
984
984
  | `34555793f33e` | certain | The task list could not be loaded right now. | `modules/hall-ui/public/work.js:1301` |
985
985
  | `a42a37c43bfb` | certain | The words this project shows people — what has been flagged, and what nobody has looked at. | `modules/hall-ui/public/copy-desk.js:328` |
986
986
  | `bcdbded93d4e` | certain | The work board failed to load. Reload to try again. | `modules/hall-ui/public/work.js:1496` |
@@ -1014,7 +1014,7 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
1014
1014
  | `77e3b8f5318b` | certain | This restarts the platform onto core | `modules/hall-ui/public/deploy.js:103` |
1015
1015
  | `69e8beced2ff` | certain | This sends the idea back to its author. Say why, and which section. | `modules/hall-ui/public/board-room.js:276` |
1016
1016
  | `09256febc32d` | certain | This sentence has {…} {…} where a value is dropped in when it is shown. | `modules/hall-ui/public/copy-desk.js:422` |
1017
- | `c9e50a67988a` | certain | This task has shipped and its credits have landed. Neither Ship it nor Confirm is available. | `modules/hall-ui/public/task.js:609` |
1017
+ | `c9e50a67988a` | certain | This task has shipped and its credits have landed. Neither Ship it nor Confirm is available. | `modules/hall-ui/public/task.js:614` |
1018
1018
  | `7217c4f1769d` | certain | This will {…} | `modules/hall-ui/public/harbor.js:125` |
1019
1019
  | `2ad5823d2cd7` | certain | Three dials, all settings rather than code: | `modules/hall-ui/public/government.html:55` |
1020
1020
  | `82367d2122af` | certain | To paste the sign-in code: | `modules/hall-ui/public/hall-render.js:779` |
@@ -1276,7 +1276,7 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
1276
1276
  | `1b88ce51fd84` | certain | to tend now · {…} | `modules/hall-ui/public/studio.js:219` |
1277
1277
  | `edd5e9f56c25` | certain | unanimous agreement | `modules/hall-ui/public/government.js:587` |
1278
1278
  | `f98966dc7cac` | certain | upkeep undeclared | `modules/hall-ui/public/modules.js:92` |
1279
- | `4de556377db2` | certain | verdict {…} | `modules/hall-ui/public/task.js:392` |
1279
+ | `4de556377db2` | certain | verdict {…} | `modules/hall-ui/public/task.js:396` |
1280
1280
  | `969577b937d6` | certain | versions in flight | `modules/hall-ui/public/roadmap.js:305` |
1281
1281
  | `8cd3cc4005fc` | certain | via goal | `modules/hall-ui/public/dom-utils.js:364` |
1282
1282
  | `007b28a56031` | certain | view diff | `modules/hall-ui/public/gate.js:145` |
@@ -1303,7 +1303,7 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
1303
1303
  | `98b1c674fc37` | certain | {…} and up | `modules/hall-ui/public/sessions.js:149` |
1304
1304
  | `111b71a9acaf` | certain | {…} and up. | `modules/hall-ui/public/sessions.js:147` |
1305
1305
  | `0da0e247ff0f` | certain | {…} asking to connect | `modules/hall-ui/public/profile-connections.js:136` |
1306
- | `788ff11f1135` | certain | {…} awarded | `modules/hall-ui/public/task.js:435` |
1306
+ | `788ff11f1135` | certain | {…} awarded | `modules/hall-ui/public/task.js:439` |
1307
1307
  | `9d160147b34a` | certain | {…} criteria · since {…} | `modules/hall-ui/public/roadmap.js:160` |
1308
1308
  | `9d160147b34a` | certain | {…} criteria · since {…} | `modules/hall-ui/public/roadmap.js:183` |
1309
1309
  | `78ba2bd4bc44` | certain | {…} criteria · started {…} | `modules/hall-ui/public/roadmap.js:243` |
@@ -1320,7 +1320,7 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
1320
1320
  | `154bc518bab4` | certain | {…} proposed | `modules/hall-ui/public/government.js:695` |
1321
1321
  | `275f3565c78b` | certain | {…} reset to its default {…} permissions. | `modules/hall-ui/public/government.js:297` |
1322
1322
  | `33afba17ee0f` | certain | {…} seeded | `modules/hall-ui/public/roadmap.js:214` |
1323
- | `732b4c935e36` | certain | {…} sessions | `modules/hall-ui/public/task.js:443` |
1323
+ | `732b4c935e36` | certain | {…} sessions | `modules/hall-ui/public/task.js:447` |
1324
1324
  | `3d76dce19c4a` | certain | {…} session{…} across {…} builder{…}. | `modules/hall-ui/public/sessions.js:226` |
1325
1325
  | `e08fa22622f0` | certain | {…} shipped, {…} confirmed, {…} completed, {…} remaining of {…} | `modules/hall-ui/public/roadmap.js:74` |
1326
1326
  | `e08fa22622f0` | certain | {…} shipped, {…} confirmed, {…} completed, {…} remaining of {…} | `modules/hall-ui/public/roadmap.js:305` |
@@ -1345,12 +1345,12 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
1345
1345
  | `b814cb35ce2f` | certain | {…} — the box this platform runs on | `modules/hall-ui/public/deploy.js:168` |
1346
1346
  | `f75ee96a7511` | certain | {…} — total payout from shipped work. | `modules/hall-ui/public/profile.js:94` |
1347
1347
  | `2a2728a4ec4f` | certain | {…}% of tasks complete | `modules/hall-ui/public/roadmap.js:70` |
1348
- | `15e545eb3ce2` | certain | {…}, no such task | `modules/hall-ui/public/task.js:688` |
1348
+ | `15e545eb3ce2` | certain | {…}, no such task | `modules/hall-ui/public/task.js:693` |
1349
1349
  | `c43050b62297` | certain | {…}/100 complete | `modules/hall-ui/public/idea.js:87` |
1350
1350
  | `8e8c7da4f7f5` | certain | {…}criteria met · awaiting review | `modules/hall-ui/public/goals-render.js:155` |
1351
1351
  | `1e275ee0299c` | certain | {…}s only | `modules/hall-ui/public/government.js:896` |
1352
1352
  | `499916045b19` | certain | {…}{…} asks to join | `modules/hall-ui/public/goal-inbox.js:69` |
1353
- | `3d74668f69e5` | certain | {…}{…} · {…} | `modules/hall-ui/public/task.js:543` |
1353
+ | `3d74668f69e5` | certain | {…}{…} · {…} | `modules/hall-ui/public/task.js:548` |
1354
1354
  | `9588652a7aff` | certain | · follows your profile setting | `modules/hall-ui/public/settings.js:568` |
1355
1355
  | `4a5ff4f662df` | certain | — ${…} of ${…} this month ({…}%). {…} | `modules/hall-ui/public/hall-render.js:471` |
1356
1356
  | `a6ae9cbdee30` | certain | — all builders — | `modules/hall-ui/public/builders.js:675` |
@@ -269,10 +269,10 @@
269
269
  "text": "Task {…}",
270
270
  "occurrences": 4,
271
271
  "at": [
272
- "modules/hall-ui/public/task.js:451",
273
- "modules/hall-ui/public/task.js:460",
274
- "modules/hall-ui/public/task.js:688",
275
- "modules/hall-ui/public/task.js:700"
272
+ "modules/hall-ui/public/task.js:455",
273
+ "modules/hall-ui/public/task.js:464",
274
+ "modules/hall-ui/public/task.js:693",
275
+ "modules/hall-ui/public/task.js:705"
276
276
  ]
277
277
  },
278
278
  {
@@ -348,8 +348,8 @@
348
348
  "text": "Copy prompt",
349
349
  "occurrences": 3,
350
350
  "at": [
351
- "modules/hall-ui/public/task.js:614",
352
- "modules/hall-ui/public/task.js:634",
351
+ "modules/hall-ui/public/task.js:619",
352
+ "modules/hall-ui/public/task.js:639",
353
353
  "modules/hall-ui/public/work.js:599"
354
354
  ]
355
355
  },
@@ -700,7 +700,7 @@
700
700
  "occurrences": 2,
701
701
  "at": [
702
702
  "modules/hall-ui/public/project-settings.js:242",
703
- "modules/hall-ui/public/task.js:707"
703
+ "modules/hall-ui/public/task.js:712"
704
704
  ]
705
705
  },
706
706
  {
@@ -2692,7 +2692,7 @@
2692
2692
  "surface": "builders-hall",
2693
2693
  "text": "Awaiting the grader, or a confirmation, before it can ship.",
2694
2694
  "file": "modules/hall-ui/public/task.js",
2695
- "line": 604,
2695
+ "line": 609,
2696
2696
  "origin": "js-markup",
2697
2697
  "confidence": "certain"
2698
2698
  },
@@ -3106,7 +3106,7 @@
3106
3106
  "surface": "builders-hall",
3107
3107
  "text": "Choose a goal first.",
3108
3108
  "file": "modules/hall-ui/public/task.js",
3109
- "line": 663,
3109
+ "line": 668,
3110
3110
  "origin": "js-notice",
3111
3111
  "confidence": "certain"
3112
3112
  },
@@ -3412,7 +3412,7 @@
3412
3412
  "surface": "builders-hall",
3413
3413
  "text": "Confirm that verification for #{…} actually passed?",
3414
3414
  "file": "modules/hall-ui/public/task.js",
3415
- "line": 649,
3415
+ "line": 654,
3416
3416
  "origin": "js-notice",
3417
3417
  "confidence": "certain"
3418
3418
  },
@@ -3547,7 +3547,7 @@
3547
3547
  "surface": "builders-hall",
3548
3548
  "text": "Copy prompt",
3549
3549
  "file": "modules/hall-ui/public/task.js",
3550
- "line": 614,
3550
+ "line": 619,
3551
3551
  "origin": "js-markup",
3552
3552
  "confidence": "certain"
3553
3553
  },
@@ -3556,7 +3556,7 @@
3556
3556
  "surface": "builders-hall",
3557
3557
  "text": "Copy prompt",
3558
3558
  "file": "modules/hall-ui/public/task.js",
3559
- "line": 634,
3559
+ "line": 639,
3560
3560
  "origin": "js-text-assign",
3561
3561
  "confidence": "certain"
3562
3562
  },
@@ -3790,7 +3790,7 @@
3790
3790
  "surface": "builders-hall",
3791
3791
  "text": "Could not load",
3792
3792
  "file": "modules/hall-ui/public/task.js",
3793
- "line": 707,
3793
+ "line": 712,
3794
3794
  "origin": "js-text-assign",
3795
3795
  "confidence": "certain"
3796
3796
  },
@@ -3934,7 +3934,7 @@
3934
3934
  "surface": "builders-hall",
3935
3935
  "text": "Could not load {…}",
3936
3936
  "file": "modules/hall-ui/public/task.js",
3937
- "line": 700,
3937
+ "line": 705,
3938
3938
  "origin": "js-markup",
3939
3939
  "confidence": "certain"
3940
3940
  },
@@ -5131,7 +5131,7 @@
5131
5131
  "surface": "builders-hall",
5132
5132
  "text": "Full log",
5133
5133
  "file": "modules/hall-ui/public/task.js",
5134
- "line": 440,
5134
+ "line": 444,
5135
5135
  "origin": "js-markup",
5136
5136
  "confidence": "certain"
5137
5137
  },
@@ -6049,7 +6049,7 @@
6049
6049
  "surface": "builders-hall",
6050
6050
  "text": "Last claimed by",
6051
6051
  "file": "modules/hall-ui/public/task.js",
6052
- "line": 546,
6052
+ "line": 551,
6053
6053
  "origin": "js-markup",
6054
6054
  "confidence": "certain"
6055
6055
  },
@@ -6553,7 +6553,7 @@
6553
6553
  "surface": "builders-hall",
6554
6554
  "text": "Move to goal",
6555
6555
  "file": "modules/hall-ui/public/task.js",
6556
- "line": 507,
6556
+ "line": 511,
6557
6557
  "origin": "js-markup",
6558
6558
  "confidence": "certain"
6559
6559
  },
@@ -6859,7 +6859,7 @@
6859
6859
  "surface": "builders-hall",
6860
6860
  "text": "No open goals in this version",
6861
6861
  "file": "modules/hall-ui/public/task.js",
6862
- "line": 506,
6862
+ "line": 510,
6863
6863
  "origin": "js-markup",
6864
6864
  "confidence": "certain"
6865
6865
  },
@@ -7003,7 +7003,7 @@
7003
7003
  "surface": "builders-hall",
7004
7004
  "text": "Not found",
7005
7005
  "file": "modules/hall-ui/public/task.js",
7006
- "line": 695,
7006
+ "line": 700,
7007
7007
  "origin": "js-text-assign",
7008
7008
  "confidence": "certain"
7009
7009
  },
@@ -7291,7 +7291,7 @@
7291
7291
  "surface": "builders-hall",
7292
7292
  "text": "Open in Sessions",
7293
7293
  "file": "modules/hall-ui/public/task.js",
7294
- "line": 440,
7294
+ "line": 444,
7295
7295
  "origin": "js-markup",
7296
7296
  "confidence": "certain"
7297
7297
  },
@@ -7975,7 +7975,7 @@
7975
7975
  "surface": "builders-hall",
7976
7976
  "text": "Read the handoff notes",
7977
7977
  "file": "modules/hall-ui/public/task.js",
7978
- "line": 438,
7978
+ "line": 442,
7979
7979
  "origin": "js-markup",
7980
7980
  "confidence": "certain"
7981
7981
  },
@@ -8731,7 +8731,7 @@
8731
8731
  "surface": "builders-hall",
8732
8732
  "text": "Session log{…}",
8733
8733
  "file": "modules/hall-ui/public/task.js",
8734
- "line": 444,
8734
+ "line": 448,
8735
8735
  "origin": "js-markup",
8736
8736
  "confidence": "certain"
8737
8737
  },
@@ -8830,7 +8830,7 @@
8830
8830
  "surface": "builders-hall",
8831
8831
  "text": "Ship it",
8832
8832
  "file": "modules/hall-ui/public/task.js",
8833
- "line": 600,
8833
+ "line": 605,
8834
8834
  "origin": "js-markup",
8835
8835
  "confidence": "certain"
8836
8836
  },
@@ -8848,7 +8848,7 @@
8848
8848
  "surface": "builders-hall",
8849
8849
  "text": "Shipped {…}{…}, {…}.",
8850
8850
  "file": "modules/hall-ui/public/task.js",
8851
- "line": 581,
8851
+ "line": 586,
8852
8852
  "origin": "js-markup",
8853
8853
  "confidence": "certain"
8854
8854
  },
@@ -9271,7 +9271,7 @@
9271
9271
  "surface": "builders-hall",
9272
9272
  "text": "Task {…}",
9273
9273
  "file": "modules/hall-ui/public/task.js",
9274
- "line": 451,
9274
+ "line": 455,
9275
9275
  "origin": "js-text-assign",
9276
9276
  "confidence": "certain"
9277
9277
  },
@@ -9280,7 +9280,7 @@
9280
9280
  "surface": "builders-hall",
9281
9281
  "text": "Task {…}",
9282
9282
  "file": "modules/hall-ui/public/task.js",
9283
- "line": 460,
9283
+ "line": 464,
9284
9284
  "origin": "js-markup",
9285
9285
  "confidence": "certain"
9286
9286
  },
@@ -9289,7 +9289,7 @@
9289
9289
  "surface": "builders-hall",
9290
9290
  "text": "Task {…}",
9291
9291
  "file": "modules/hall-ui/public/task.js",
9292
- "line": 688,
9292
+ "line": 693,
9293
9293
  "origin": "js-markup",
9294
9294
  "confidence": "certain"
9295
9295
  },
@@ -9298,7 +9298,7 @@
9298
9298
  "surface": "builders-hall",
9299
9299
  "text": "Task {…}",
9300
9300
  "file": "modules/hall-ui/public/task.js",
9301
- "line": 700,
9301
+ "line": 705,
9302
9302
  "origin": "js-markup",
9303
9303
  "confidence": "certain"
9304
9304
  },
@@ -9334,7 +9334,7 @@
9334
9334
  "surface": "builders-hall",
9335
9335
  "text": "Tasks in the ledger are numbered separately from GitHub pull requests, so this may be a PR number rather than a task. The work board lists everything that does exist.",
9336
9336
  "file": "modules/hall-ui/public/task.js",
9337
- "line": 688,
9337
+ "line": 693,
9338
9338
  "origin": "js-markup",
9339
9339
  "confidence": "certain"
9340
9340
  },
@@ -9451,7 +9451,7 @@
9451
9451
  "surface": "builders-hall",
9452
9452
  "text": "The adversarial panel. Each worker reports pass, concerns or fail on its own; the gating workers must all pass before confirmed becomes {…}, and one concerns falls the task through to the manual confirm path.",
9453
9453
  "file": "modules/hall-ui/public/task.js",
9454
- "line": 388,
9454
+ "line": 392,
9455
9455
  "origin": "js-markup",
9456
9456
  "confidence": "certain"
9457
9457
  },
@@ -9568,7 +9568,7 @@
9568
9568
  "surface": "builders-hall",
9569
9569
  "text": "The grading panel could not run when this task was shipped, so no quality signal was recorded — an outage, not a verdict.",
9570
9570
  "file": "modules/hall-ui/public/task.js",
9571
- "line": 370,
9571
+ "line": 374,
9572
9572
  "origin": "js-markup",
9573
9573
  "confidence": "certain"
9574
9574
  },
@@ -9892,7 +9892,7 @@
9892
9892
  "surface": "builders-hall",
9893
9893
  "text": "The task feed did not answer. Nothing on the record has changed, only the read failed. Try again in a moment, or go back.",
9894
9894
  "file": "modules/hall-ui/public/task.js",
9895
- "line": 700,
9895
+ "line": 705,
9896
9896
  "origin": "js-markup",
9897
9897
  "confidence": "certain"
9898
9898
  },
@@ -10198,7 +10198,7 @@
10198
10198
  "surface": "builders-hall",
10199
10199
  "text": "This task has shipped and its credits have landed. Neither Ship it nor Confirm is available.",
10200
10200
  "file": "modules/hall-ui/public/task.js",
10201
- "line": 609,
10201
+ "line": 614,
10202
10202
  "origin": "js-markup",
10203
10203
  "confidence": "certain"
10204
10204
  },
@@ -12556,7 +12556,7 @@
12556
12556
  "surface": "builders-hall",
12557
12557
  "text": "verdict {…}",
12558
12558
  "file": "modules/hall-ui/public/task.js",
12559
- "line": 392,
12559
+ "line": 396,
12560
12560
  "origin": "js-markup",
12561
12561
  "confidence": "certain"
12562
12562
  },
@@ -12799,7 +12799,7 @@
12799
12799
  "surface": "builders-hall",
12800
12800
  "text": "{…} awarded",
12801
12801
  "file": "modules/hall-ui/public/task.js",
12802
- "line": 435,
12802
+ "line": 439,
12803
12803
  "origin": "js-markup",
12804
12804
  "confidence": "certain"
12805
12805
  },
@@ -12952,7 +12952,7 @@
12952
12952
  "surface": "builders-hall",
12953
12953
  "text": "{…} sessions",
12954
12954
  "file": "modules/hall-ui/public/task.js",
12955
- "line": 443,
12955
+ "line": 447,
12956
12956
  "origin": "js-markup",
12957
12957
  "confidence": "certain"
12958
12958
  },
@@ -13177,7 +13177,7 @@
13177
13177
  "surface": "builders-hall",
13178
13178
  "text": "{…}, no such task",
13179
13179
  "file": "modules/hall-ui/public/task.js",
13180
- "line": 688,
13180
+ "line": 693,
13181
13181
  "origin": "js-markup",
13182
13182
  "confidence": "certain"
13183
13183
  },
@@ -13222,7 +13222,7 @@
13222
13222
  "surface": "builders-hall",
13223
13223
  "text": "{…}{…} · {…}",
13224
13224
  "file": "modules/hall-ui/public/task.js",
13225
- "line": 543,
13225
+ "line": 548,
13226
13226
  "origin": "js-markup",
13227
13227
  "confidence": "certain"
13228
13228
  },
@@ -2074,5 +2074,9 @@ is load-bearing: the script throws rather than guess if it is missing, and
2074
2074
  landed since 1.19.798 with no explicit bump. run 35170980369. (task 1002620)
2075
2075
  1.19.800 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
2076
2076
  landed since 1.19.799 with no explicit bump. run 35172784518. (task 1002620)
2077
+ 1.19.801 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
2078
+ landed since 1.19.800 with no explicit bump. run 35173442594. (task 1002620)
2079
+ 1.19.802 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
2080
+ landed since 1.19.801 with no explicit bump. run 35174865190. (task 1002620)
2077
2081
  ---------------------------------------------------------------------------
2078
2082
  ```
@@ -275,11 +275,15 @@
275
275
  // hall renders. Only figures the record actually CARRIES are drawn: most tasks
276
276
  // have no recorded actual, and a band of dashes reads as a broken record
277
277
  // rather than an honest one. Under two figures there is no band at all.
278
+ // A fourth element is an optional `title` for the cell — for a figure whose
279
+ // label is shorter than what the number actually counts. 'Actual' is the case
280
+ // it exists for (task 1003964): it is claimed-session time, so a re-graded
281
+ // task's recovery session is not in it, and the bare word promises otherwise.
278
282
  function figureBand(figs) {
279
283
  const present = figs.filter((f) => f && f[1] != null && f[1] !== '');
280
284
  if (present.length < 2) return '';
281
- const cells = present.map(([label, value, unit]) =>
282
- `<div class="rec-fig"><span class="rec-fig__l">${escapeHtml(label)}</span>` +
285
+ const cells = present.map(([label, value, unit, title]) =>
286
+ `<div class="rec-fig"${title ? ` title="${escapeHtml(title)}"` : ''}><span class="rec-fig__l">${escapeHtml(label)}</span>` +
283
287
  `<span class="rec-fig__v">${escapeHtml(String(value))}` +
284
288
  `${unit ? `<u class="rec-fig__u">${escapeHtml(unit)}</u>` : ''}</span></div>`).join('');
285
289
  return `<div class="rec-figs">${cells}</div>`;
@@ -520,7 +524,8 @@
520
524
  parts.push(figureBand([
521
525
  [window.OTBBranding?.taskCreditLabel?.(t) ?? curLabel(), creditVal],
522
526
  ['Estimated', t.est_minutes, 'm'],
523
- ['Actual', t.actual_minutes, 'm'],
527
+ ['Actual', t.actual_minutes, 'm',
528
+ 'Time measured across this task\u2019s claimed sessions. A re-grade has no claim, so a re-graded task\u2019s recovery session is not counted here.'],
524
529
  ['Priority', t.priority == null ? null : 'P' + t.priority],
525
530
  ]));
526
531
  parts.push(lifecycleRail(t, creditVal));
@@ -60,6 +60,13 @@ async function recentShippedTasks(limit = 30, { days = null } = {}) {
60
60
 
61
61
  // Rolling median of actual/est ratio for a builder's last N shipped tasks.
62
62
  // Returns null if there is insufficient data.
63
+ //
64
+ // actual_minutes is CLAIMED-session time (see the note at the recompute in
65
+ // db-ship.js, task 1003964). A task that was re-graded carries only its first
66
+ // attempt's figure, so its ratio understates the work — deliberately, because no
67
+ // defensible clock exists for a claimless window. It is noise in a median, not a
68
+ // bias worth correcting for: every re-grade pulls the same direction, and the
69
+ // sample is dominated by tasks that were never re-graded.
63
70
 
64
71
  async function getEstVsActualRatio(builderId, limit = 10) {
65
72
  const { rows } = await pool.query(
@@ -221,9 +221,30 @@ async function resolveClaim({ claimId, builderId, outcome, notesMd, valueSummary
221
221
  );
222
222
  }
223
223
 
224
- // Write the session_logs entry + recompute actual_minutes FIRST, so the
225
- // grader (below) can see a fresh actual_minutes value when scoring the
226
- // est/actual ratio criterion.
224
+ // WHAT actual_minutes MEANS, and what it deliberately does not (task 1003964).
225
+ //
226
+ // It is the SUM of every session_logs row for the task, and session_logs rows
227
+ // are sealed per CLAIM — so the field measures CLAIMED session time, nothing
228
+ // else. A --regrade has no claim (that is the defining property of the
229
+ // #678 path): it never reaches resolveClaim, seals no row, and does not
230
+ // recompute. The recovery session's time is therefore NOT counted, and a
231
+ // re-graded task keeps the figure its first attempt measured.
232
+ //
233
+ // That is a DECISION, not an oversight. A claimless window has no defensible
234
+ // start: the prior grade's timestamp puts the whole gap between attempts in
235
+ // the sum (task 1002343 would have recorded ~3 days instead of 19 minutes —
236
+ // worse than stale, and calibration reads this field), and the ship's own
237
+ // session digest measures a Claude Code session, which routinely spans
238
+ // several tasks and is absent entirely outside an interactive session.
239
+ //
240
+ // The ordering below is NOT for the grader, whatever this comment used to
241
+ // say. V3.R18 (#209) moved the grader out of resolveClaim — see the block
242
+ // after this one — and the live panel never receives actual_minutes at all
243
+ // (modules/grading/grader-prompt.js buildPrompt prints est_minutes only;
244
+ // scoreEstActualBand lives in gradeDeterministic, whose one non-test caller
245
+ // is the retroactive audit in scripts/gds/audit-ships.js). The seal must
246
+ // still precede the recompute, because the recompute SUMs the row it writes.
247
+ // tests/regrade_actual_minutes.mjs pins the panel half of that.
227
248
  await sealSessionLog(client, {
228
249
  builderId, taskId: claim.task_id, claimId, startedAt: claim.claimed_at,
229
250
  outcome, notesMd: notesMd ?? null,
package/package-lock.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@bongos/core",
3
- "version": "1.19.800",
3
+ "version": "1.19.802",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@bongos/core",
9
- "version": "1.19.800",
9
+ "version": "1.19.802",
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.800",
3
+ "version": "1.19.802",
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",
@@ -249,9 +249,66 @@ function staleSummaryNotice(taskId, storedSummary) {
249
249
  ];
250
250
  }
251
251
 
252
+ // ---- a --db-only that cannot apply must SAY so (task 1003959) ---------------
253
+ //
254
+ // THE FIFTH SILENCE, and the only one that is not about prose: a flag the
255
+ // operator typed, dropped without a word. zeroCommitVerdict(commitsAhead, dbOnly)
256
+ // consults dbOnly ONLY at zero commits ahead — with commits ahead the verdict is
257
+ // 'has-commits' and the run falls through to the ordinary merge/PR path, which
258
+ // never receives dbOnly at all.
259
+ //
260
+ // The BEHAVIOUR is right and stays: a branch carrying real commits must be
261
+ // merged, not waved through as an empty ship. What was missing is the sentence
262
+ // saying so, and its absence is expensive out of proportion to its size — task
263
+ // 1003229 was filed against --db-only and survived for days on the strength of
264
+ // it. The reporter's flag was dropped here, their PR then failed to land for an
265
+ // unrelated reason (the reconciler, task 1002723), and with nothing in the
266
+ // output distinguishing an honoured flag from an ignored one, every visible sign
267
+ // pointed at --db-only.
268
+ //
269
+ // So: a notice, not a refusal and not a behaviour change — the same posture as
270
+ // staleSummaryNotice above, and testable for the same reason. It names the path
271
+ // actually being taken, because "your flag was ignored" without "and here is
272
+ // what is happening instead" only moves the confusion.
273
+ //
274
+ // Returns [] when the flag was HONOURED (zero commits ahead) or never passed —
275
+ // a notice that fires on the happy path is noise.
276
+ function dbOnlyIgnoredNotice(taskId, { dbOnly = false, commitsAhead = '0', branch = '', deployMode = 'laptop' } = {}) {
277
+ if (!dbOnly) return [];
278
+ // The one case the flag really covers. gitOk returns null when the count could
279
+ // not be read, which zeroCommitVerdict already treats as 'has-commits' — keep
280
+ // that reading rather than inventing a second opinion about the same branch.
281
+ if (String(commitsAhead) === '0') return [];
282
+
283
+ // Branch names and a git count both reach a TERMINAL here. git forbids control
284
+ // characters in a refname, so this strips nothing in practice — but the notice
285
+ // exists to be believed, and one that could be repainted from below by its own
286
+ // subject would be the wrong thing to have built.
287
+ const clean = (s) => String(s == null ? '' : s).replace(/[\u0000-\u001f\u007f-\u009f]/g, ' ').replace(/\s+/g, ' ').trim();
288
+ const head = clean(branch) || 'this branch';
289
+ const n = Number(clean(commitsAhead));
290
+ const ahead = Number.isInteger(n) && n > 0
291
+ ? `${n} commit${n === 1 ? '' : 's'} ahead of origin/main`
292
+ : 'ahead of origin/main';
293
+ // Name the real path, not a generic one — 'ci' lands by PR and never touches
294
+ // the operator's main worktree; 'laptop' merges and deploys from this machine.
295
+ const instead = deployMode === 'ci'
296
+ ? `pushing ${head} and landing it by PR, with CI deploying`
297
+ : `pushing ${head}, merging it into main here and deploying`;
298
+
299
+ return [
300
+ `⚠ --db-only was passed, but ${head} is ${ahead} — the flag does not apply and is being IGNORED.`,
301
+ ` Shipping the normal way instead: ${instead}. Nothing is skipped and nothing is stranded.`,
302
+ ' --db-only only covers a ship with NOTHING to merge — work written straight to the prod DB.',
303
+ ' If you expected a zero-commit ship, this is the branch disagreeing; see what is on it:',
304
+ ' git log --oneline origin/main..HEAD',
305
+ ` Then re-ship when the branch is what you meant: node scripts/gds/ship.js ${taskId}`,
306
+ ];
307
+ }
308
+
252
309
  module.exports = {
253
310
  resolveProse, markShipProgress, fatalRecoveryLines, smokeGateMessages,
254
- proseFlagPresent, regradeNotesRefusal, staleSummaryNotice,
311
+ proseFlagPresent, regradeNotesRefusal, staleSummaryNotice, dbOnlyIgnoredNotice,
255
312
  _resetForTest: () => { shipProgress = { stage: 'preflight', taskId: null }; },
256
313
  _peekForTest: () => shipProgress,
257
314
  };
@@ -26,9 +26,15 @@ const {
26
26
  landed,
27
27
  } = require('./ship-land.js');
28
28
  const { runSmoke } = require('./ship-grade.js');
29
+ const { dbOnlyIgnoredNotice } = require('./ship-honesty.js');
29
30
  const { currentBranch, mainWorktreeBusy, regenerateApiClient, regenerateApiDocs, regenerateDiagrams, regenerateFileMap, regenerateRepoMap, regenerateSessionIndex } = require('./ship-regen.js');
30
31
  const { REPO_ROOT } = require('./ship-state.js');
31
32
 
33
+ // zeroCommitVerdict — dbOnly is deliberately consulted ONLY at zero commits
34
+ // ahead: a branch carrying real commits must be merged, whatever flag was typed.
35
+ // That asymmetry is correct and is not a bug — but it means an explicitly-passed
36
+ // --db-only can be DROPPED, so mergeLocally pairs this with dbOnlyIgnoredNotice
37
+ // (task 1003959) rather than letting the drop happen in silence.
32
38
  function zeroCommitVerdict(commitsAhead, dbOnly) {
33
39
  if (commitsAhead !== '0') return 'has-commits';
34
40
  return dbOnly ? 'db-only' : 'refuse';
@@ -141,6 +147,11 @@ async function mergeLocally(taskId, valueSummary, { dbOnly = false } = {}) {
141
147
  }
142
148
  const commitsAhead = gitOk('git rev-list origin/main..HEAD --count');
143
149
  const verdict = zeroCommitVerdict(commitsAhead, dbOnly);
150
+ // task 1003959: the verdict above drops an explicitly-passed --db-only when the
151
+ // branch has commits. Say so HERE — before the push, the merge and the deploy —
152
+ // so the operator learns their flag did not apply while the run can still be
153
+ // stopped, not from a PR that landed differently than they expected.
154
+ for (const line of dbOnlyIgnoredNotice(taskId, { dbOnly, commitsAhead, branch, deployMode })) console.log(line);
144
155
  if (verdict === 'refuse') {
145
156
  // task 391 (idea #37): the old code short-circuited ANY zero-commit branch
146
157
  // straight to shipped — silently advancing a claim with empty/wrong touches[]
package/src/module-api.js CHANGED
@@ -71,7 +71,7 @@ const { responsibilityFor, ROLE_RESPONSIBILITIES } = require('./role-responsibil
71
71
  // there. scripts/gds/bump-version.js still rewrites the literal below; it appends
72
72
  // the entry to that file. Look for a version's history there, not here.
73
73
  // ---------------------------------------------------------------------------
74
- const CORE_VERSION = '1.19.800'; // CI auto-patch carrier (ADR 0161); changelog: docs/module-api-changelog.md
74
+ const CORE_VERSION = '1.19.802'; // CI auto-patch carrier (ADR 0161); changelog: docs/module-api-changelog.md
75
75
 
76
76
  // A namespaced logger so a module's log lines are attributable + consistent.
77
77
  // Usage: const log = api.logger('dev-box'); log.info('mounted');
@@ -412,6 +412,25 @@ test('the figure band drops absent figures rather than drawing a dash', async ()
412
412
  assert.deepEqual(labels, ['credits', 'Estimated', 'Priority'], 'the figures it DOES carry are all drawn, in order');
413
413
  });
414
414
 
415
+ // task 1003964 — 'Actual' is claimed-session time, and the bare label promises
416
+ // more than that: a re-graded task's recovery session is not in the number,
417
+ // because a re-grade has no claim to seal a session_logs row against. The
418
+ // decision is fine; the word alone hiding it is not. Rendered, not grepped —
419
+ // a title that never survives figureBand looks identical in the source.
420
+ test('the Actual figure says what it counts, and only that figure carries a title', async () => {
421
+ const r = renderTask({ ...BASE_TASK });
422
+ await r.boot(); await settle();
423
+ const cells = [...r.html().matchAll(/<div class="rec-fig"([^>]*)>[\s\S]*?<span class="rec-fig__l">([^<]+)</g)]
424
+ .map((m) => ({ attrs: m[1], label: m[2] }));
425
+ const actual = cells.find((c) => c.label === 'Actual');
426
+ assert.ok(actual, 'the figure is drawn at all');
427
+ assert.match(actual.attrs, /title="[^"]*claimed sessions[^"]*"/, 'it names what it measures');
428
+ assert.match(actual.attrs, /re-grade/, 'and what it deliberately leaves out');
429
+ for (const c of cells.filter((x) => x.label !== 'Actual')) {
430
+ assert.equal(c.attrs.trim(), '', `${c.label} carries no stray title`);
431
+ }
432
+ });
433
+
415
434
  test('under two figures there is no band at all — one figure is not a row', async () => {
416
435
  const r = renderTask({ ...BASE_TASK, credits_reward: null, est_minutes: null, actual_minutes: null });
417
436
  await r.boot(); await settle();
@@ -0,0 +1,100 @@
1
+ // tests/regrade_actual_minutes.mjs — a re-grade does not re-measure, and the
2
+ // panel is not fed the figure it would misread (task 1003964, goal 1000118).
3
+ //
4
+ // THE MECHANISM. actual_minutes is recomputed in exactly one place — resolveClaim
5
+ // (modules/lifecycle/db-ship.js) — as the SUM of every session_logs row for the
6
+ // task, and session_logs rows are sealed per CLAIM. A --regrade has no claim,
7
+ // which is the defining property of that path (#678): it never reaches
8
+ // resolveClaim, seals no row, and does not recompute. A re-graded task therefore
9
+ // keeps the figure its FIRST, grade-failed attempt measured (observed on task
10
+ // 1002343: actual_minutes=19 from 2026-09-04, shipped on the 2026-09-07 redo).
11
+ //
12
+ // THE POSTURE, and why it is a decision rather than a patch. A claimless window
13
+ // has no defensible start time. The prior grade's timestamp puts the entire gap
14
+ // between attempts into the sum — for task 1002343 that is ~3 days, roughly
15
+ // 4300 minutes in place of 19, which is worse than stale and poisons the same
16
+ // calibration the fix was meant to protect. The ship's own session digest
17
+ // (scripts/gds/session-digest-build.js) measures a Claude Code SESSION, which
18
+ // routinely spans several tasks and is absent outside an interactive one. An
19
+ // opt-in --minutes flag would be omitted by default, which is the present
20
+ // silence with a flag beside it. So: actual_minutes means CLAIMED-session time,
21
+ // stated at the recompute, in the schema map, in the calibration reader, and on
22
+ // the hall figure — the four places someone meets the number.
23
+ // The hall half is pinned in tests/hall_record_world.mjs, which owns the render
24
+ // harness that proves the title survives figureBand rather than merely existing.
25
+ //
26
+ // WHAT THIS FILE PINS is the half that can silently become untrue. The bug row
27
+ // was filed believing the grader scores an est/actual ratio against the stale
28
+ // figure; on current main it cannot, because the live panel never receives
29
+ // actual_minutes at all. That is the whole reason the posture is safe, so it is
30
+ // the thing that needs a tripwire: wire actual_minutes into the panel prompt and
31
+ // this file reds, and the decision has to be made again with the risk real.
32
+ import { strict as assert } from 'node:assert';
33
+ import { test } from 'node:test';
34
+ import { createRequire } from 'node:module';
35
+ import { readFileSync } from 'node:fs';
36
+
37
+ const require = createRequire(import.meta.url);
38
+ const { buildPrompt } = require('../modules/grading/grader-prompt.js');
39
+
40
+ // A task carrying an unmistakable actual_minutes — a value that cannot appear by
41
+ // coincidence in a prompt full of ids, line counts and minute figures.
42
+ const TASK = {
43
+ id: 1003964,
44
+ title: 'A re-graded task keeps the first attempt figure',
45
+ kind: 'bug',
46
+ discipline: 'engineer',
47
+ est_minutes: 60,
48
+ actual_minutes: 31337,
49
+ scoping_confidence: 4,
50
+ description: 'the description',
51
+ };
52
+
53
+ const BUNDLE = {
54
+ task: TASK,
55
+ valueSummary: 'a value summary',
56
+ diff: 'diff --git a/x.js b/x.js\n+one line\n',
57
+ changedFiles: ['x.js'],
58
+ diffStats: { files: 1, insertions: 1, deletions: 0 },
59
+ };
60
+
61
+ test('the panel prompt does not carry actual_minutes — the tripwire', () => {
62
+ // THE reason a stale figure is harmless today. If this ever starts failing,
63
+ // the panel is scoring a number that on a re-grade comes from a superseded
64
+ // attempt, and "documented as excluded" stops being a sufficient answer.
65
+ const prompt = buildPrompt(BUNDLE);
66
+ assert.ok(!prompt.includes('31337'), 'the stored figure never reaches the panel');
67
+ assert.doesNotMatch(prompt, /actual[_ ]minutes/i, 'nor the field by name');
68
+ // And the assertion is not vacuous: the prompt DOES carry the estimate, which
69
+ // is the neighbouring field and the one the panel is meant to weigh.
70
+ assert.match(prompt, /60 min/, 'est_minutes is what the panel is given instead');
71
+ });
72
+
73
+ test('a task with no actual_minutes at all builds the same prompt', () => {
74
+ // The inverse of the tripwire: if the two prompts ever differ, the field is
75
+ // reaching the panel through some path this file is not watching.
76
+ const withFigure = buildPrompt(BUNDLE);
77
+ const without = buildPrompt({ ...BUNDLE, task: { ...TASK, actual_minutes: null } });
78
+ assert.equal(withFigure, without, 'actual_minutes changes nothing about what the panel reads');
79
+ });
80
+
81
+ test('scoreEstActualBand is reachable only from the retroactive audit', () => {
82
+ // The one scorer that DOES read the figure. It lives in gradeDeterministic,
83
+ // which the grader module's own comment calls the legacy v1 entry — its single
84
+ // non-test caller is scripts/gds/audit-ships.js, a process audit run by hand
85
+ // over already-shipped tasks, not a gate anything passes through. A new caller
86
+ // is the same risk as wiring the figure into the prompt.
87
+ const grader = require('../modules/grading/grader.js');
88
+ assert.equal(typeof grader.gradeDeterministic, 'function', 'the legacy entry still exists');
89
+ assert.equal(grader.gradeSubagent.length > 0, true, 'and the live entry is a different function');
90
+
91
+ // gradeSubagent / gradeSubagentV3MultiShot take a single options object, so the
92
+ // guard that matters is which KEYS they destructure. Neither may take minutes.
93
+ const src = readFileSync(new URL('../modules/grading/grader.js', import.meta.url), 'utf8');
94
+ for (const fn of ['async function gradeSubagent(', 'async function gradeSubagentV3MultiShot(']) {
95
+ const at = src.indexOf(fn);
96
+ assert.ok(at !== -1, `${fn} is still the entry point this pins`);
97
+ const sig = src.slice(at, src.indexOf(')', at));
98
+ assert.ok(!/actualMinutes/.test(sig), `${fn} does not accept actualMinutes`);
99
+ }
100
+ });
@@ -21,6 +21,10 @@
21
21
  // (4) --regrade must not silently REUSE the failed attempt's summary. The same
22
22
  // silence as (3) from the other side: prose the builder never handed over,
23
23
  // published as though they had (task 1003693).
24
+ //
25
+ // (5) An explicitly-passed --db-only that cannot apply must say so. The same
26
+ // silence again, and the first one that is not about prose: a flag the
27
+ // operator typed, dropped by the merge leg without a word (task 1003959).
24
28
  import { strict as assert } from 'node:assert';
25
29
  import { test } from 'node:test';
26
30
  import { createRequire } from 'node:module';
@@ -30,7 +34,7 @@ const require = createRequire(import.meta.url);
30
34
  const { argText } = require('../scripts/gds/cli-lib.js');
31
35
  const {
32
36
  fatalRecoveryLines, markShipProgress, _peekForTest,
33
- proseFlagPresent, regradeNotesRefusal, staleSummaryNotice,
37
+ proseFlagPresent, regradeNotesRefusal, staleSummaryNotice, dbOnlyIgnoredNotice,
34
38
  } = require('../scripts/gds/ship-honesty.js');
35
39
 
36
40
  // Injected IO so no case touches the filesystem.
@@ -371,3 +375,88 @@ test('the notice is wired into the regrade path, before any grade spend', () =>
371
375
  const preflight = code.indexOf('preflight(claimLike');
372
376
  assert.ok(preflight !== -1 && call < preflight, 'and prints before the preflight and the panel');
373
377
  });
378
+ // ── (5) a --db-only that cannot apply says so (task 1003959) ─────────────────
379
+ //
380
+ // The same silence as (3) and (4) from a third side, and the only one that is
381
+ // not about prose: a flag the operator TYPED, dropped without a word.
382
+ // zeroCommitVerdict consults dbOnly only at zero commits ahead, so with commits
383
+ // ahead the ordinary merge/PR path runs and never sees the flag. That path is
384
+ // correct; the silence is what let task 1003229 sit open against --db-only while
385
+ // the real stall was elsewhere (task 1002723).
386
+
387
+ test('the dropped --db-only notice names the flag, the branch and the path taken instead', () => {
388
+ const lines = dbOnlyIgnoredNotice(1003959, {
389
+ dbOnly: true, commitsAhead: '3', branch: 'task-1003959', deployMode: 'ci',
390
+ });
391
+ const text = lines.join('\n');
392
+ // The whole deliverable: the operator must be able to tell an honoured flag
393
+ // from an ignored one by reading the output.
394
+ assert.match(text, /--db-only/, 'names the flag that was dropped');
395
+ assert.match(text, /IGNORED/, 'and says plainly that it was');
396
+ assert.match(text, /3 commits ahead of origin\/main/, 'names why it does not apply');
397
+ assert.match(text, /task-1003959/, 'and which branch disagreed');
398
+ // "your flag was ignored" without "and here is what happens instead" only
399
+ // moves the confusion one step.
400
+ assert.match(text, /landing it by PR/, 'names the path actually being taken');
401
+ assert.match(text, /nothing is stranded/i, 'and says the ship is not in danger');
402
+ // A notice that names no next step is noise with a warning sign on it.
403
+ assert.match(text, /git log --oneline origin\/main\.\.HEAD/, 'names a runnable way to check the branch');
404
+ assert.match(text, /ship\.js 1003959/, 'and the re-ship with the real task id');
405
+ });
406
+
407
+ test('the notice names the LAPTOP path when that is the one being taken', () => {
408
+ // Naming a PR land on a box that is about to merge and deploy locally would be
409
+ // a second untruth told while correcting the first.
410
+ const laptop = dbOnlyIgnoredNotice(7, { dbOnly: true, commitsAhead: '1', branch: 'task-7', deployMode: 'laptop' }).join('\n');
411
+ assert.match(laptop, /merging it into main here and deploying/, 'the local merge chain');
412
+ assert.ok(!/by PR/.test(laptop), 'and not the PR path it is not taking');
413
+ assert.match(laptop, /1 commit ahead/, 'singular reads as English');
414
+ });
415
+
416
+ test('the notice is silent when the flag was honoured, or never passed', () => {
417
+ // Zero commits ahead IS the case --db-only covers: the flag applied, nothing
418
+ // was dropped, and warning there would train the builder to skip the notice.
419
+ assert.deepEqual(dbOnlyIgnoredNotice(1, { dbOnly: true, commitsAhead: '0', branch: 'task-1' }), []);
420
+ for (const ahead of ['0', '4', null, undefined]) {
421
+ assert.deepEqual(dbOnlyIgnoredNotice(1, { dbOnly: false, commitsAhead: ahead }), [], 'no flag, no notice');
422
+ }
423
+ assert.deepEqual(dbOnlyIgnoredNotice(1), [], 'and a bare call cannot fire it');
424
+ });
425
+
426
+ test('an unreadable commit count still produces a truthful notice', () => {
427
+ // gitOk returns null when the count cannot be read, and zeroCommitVerdict
428
+ // already reads that as 'has-commits'. The notice must not invent "null
429
+ // commits ahead" — it drops the number and keeps the claim.
430
+ const lines = dbOnlyIgnoredNotice(9, { dbOnly: true, commitsAhead: null, branch: null });
431
+ const text = lines.join('\n');
432
+ assert.ok(lines.length > 0, 'an unreadable count is still an ignored flag');
433
+ assert.ok(!/null|NaN|undefined/.test(text), 'and never says so out loud');
434
+ assert.match(text, /this branch is ahead of origin\/main/, 'falls back to the claim without a count');
435
+
436
+ // The one place a branch name reaches a TERMINAL. git forbids control
437
+ // characters in a refname, so this strips nothing in practice — but a notice
438
+ // that could be repainted by its own subject is the wrong thing to have built.
439
+ const esc = dbOnlyIgnoredNotice(11, { dbOnly: true, commitsAhead: '2', branch: 'task\u001b[31m-11\u0007' }).join(' ');
440
+ assert.ok(!/[\u0000-\u001f\u007f-\u009f]/.test(esc), 'terminal control characters are stripped before display');
441
+ });
442
+
443
+ test('the notice is wired into the merge leg, before the push', () => {
444
+ // The (1) lesson again: a helper nothing calls is not a fix. And the ORDER is
445
+ // load-bearing for the same reason the --notes refusal's is — a warning read
446
+ // after the branch has already been pushed and merged cannot stop that run.
447
+ const src = readFileSync(new URL('../scripts/gds/ship-merge.js', import.meta.url), 'utf8');
448
+ assert.match(src, /require\('\.\/ship-honesty\.js'\)/, 'ship-merge imports the notice');
449
+ const merge = src.slice(src.indexOf('async function mergeLocally'));
450
+ const code = merge.replace(/\/\/[^\n]*/g, ''); // comments describe, they do not print
451
+
452
+ const call = code.indexOf('dbOnlyIgnoredNotice(taskId,');
453
+ assert.ok(call !== -1, 'mergeLocally emits the notice');
454
+ // It must be fed the real values, not a re-derived opinion about the branch.
455
+ assert.match(code.slice(call, call + 200), /dbOnly, commitsAhead, branch, deployMode/,
456
+ 'from the same values the verdict was computed from');
457
+ // Every path out of the verdict is downstream of it: the refusal, the empty
458
+ // ship, the ci land and the laptop push.
459
+ for (const after of ["=== 'refuse'", "=== 'ci'", "gitArgvOk(['push'"]) {
460
+ assert.ok(call < code.indexOf(after), `prints before ${after}`);
461
+ }
462
+ });