@bongos/core 1.24.3 → 1.24.5

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.
Files changed (76) hide show
  1. package/.bongos-core.json +142 -67
  2. package/clients/bongos-client/README.md +1 -1
  3. package/clients/bongos-client/bongos-client.global.js +6 -0
  4. package/clients/bongos-client/index.cjs +6 -0
  5. package/clients/bongos-client/index.d.ts +8 -0
  6. package/clients/bongos-client/index.mjs +6 -0
  7. package/config/branding.neutral.json +0 -1
  8. package/docs/adr/0396-google-sign-in-a-stand-in-login-and-a-browser-approved-cli-sign-in.md +11 -0
  9. package/docs/api/openapi.json +121 -4
  10. package/docs/api-reference.md +8 -1
  11. package/docs/branding-contract.md +1 -1
  12. package/docs/copy-inventory.md +11 -11
  13. package/docs/copy-registry.json +12 -12
  14. package/docs/file-map.md +3 -2
  15. package/docs/module-api-changelog.md +2 -2
  16. package/docs/page-readings.json +1 -1
  17. package/modules/copy-desk/auto-close.js +46 -8
  18. package/modules/copy-desk/page-status.js +11 -2
  19. package/modules/copy-desk/tests/copy_no_cms.mjs +8 -1
  20. package/modules/copy-desk/tests/copy_page_auto_close.mjs +64 -2
  21. package/modules/copy-desk/tests/copy_page_status.mjs +5 -1
  22. package/modules/discord/ship-broadcast.js +7 -0
  23. package/modules/economy/credit-wording.js +93 -0
  24. package/modules/economy/credits.js +26 -12
  25. package/modules/economy/reward-policy.js +49 -3
  26. package/modules/economy/reward.js +5 -0
  27. package/modules/government/routes/government.js +7 -0
  28. package/modules/hall-ui/public/tweak-editor.js +2 -1
  29. package/modules/ideas/routes/inbox.js +6 -0
  30. package/modules/lifecycle/db-claims.js +2 -2
  31. package/modules/lifecycle/db-ship.js +2 -2
  32. package/modules/lifecycle/routes/project-settings.js +6 -4
  33. package/modules/market-watch/ask.js +425 -0
  34. package/modules/market-watch/migrations/market_watch_003_ask_pool.sql +21 -0
  35. package/modules/market-watch/module.json +10 -3
  36. package/modules/market-watch/pollers/weekly-ask.js +89 -0
  37. package/modules/market-watch/public/hall-widget.js +271 -0
  38. package/modules/market-watch/public/weekly-ask.css +39 -0
  39. package/modules/market-watch/routes/ask.js +95 -0
  40. package/modules/onboarding/routes/access-requests.js +38 -10
  41. package/modules/platform-identity/account-logins.js +13 -0
  42. package/modules/platform-identity/routes/my-projects.js +10 -7
  43. package/modules/platform-identity/routes/sso.js +11 -6
  44. package/package-lock.json +2 -2
  45. package/package.json +1 -1
  46. package/release-notes.json +37 -1
  47. package/scripts/bongos/backfill-subagent-rewards.js +7 -7
  48. package/scripts/bongos/codemod-rename-scripts-gds.js +1 -3
  49. package/scripts/bongos/dev-box-guard.js +0 -1
  50. package/scripts/bongos/publish-manifest.js +1 -1
  51. package/scripts/bongos/run-unit-tests.js +4 -0
  52. package/scripts/hall-preview/server.js +13 -0
  53. package/src/bongos/agent-standing-rules.js +44 -0
  54. package/src/bongos/auth-idp.js +17 -5
  55. package/src/bongos/db-kernel.js +14 -1
  56. package/src/bongos/module-scope-map.js +4 -2
  57. package/src/bongos/routes/me.js +4 -1
  58. package/src/module-api.js +1 -1
  59. package/tests/account_logins.mjs +6 -4
  60. package/tests/agent_standing_rules.mjs +142 -0
  61. package/tests/backfill_subagent_rewards.mjs +7 -7
  62. package/tests/claims_batch_routes.mjs +36 -13
  63. package/tests/copy_stuck_page_tweaks.mjs +3 -1
  64. package/tests/credit_grant.mjs +7 -7
  65. package/tests/credit_wording.mjs +154 -0
  66. package/tests/google_halls.mjs +211 -0
  67. package/tests/government_laws_session.mjs +2 -1
  68. package/tests/hall_tweak_editor.mjs +11 -0
  69. package/tests/host_topology_skips.mjs +2 -0
  70. package/tests/market_watch_ask.mjs +369 -0
  71. package/tests/market_watch_ask_db.mjs +122 -0
  72. package/tests/market_watch_data_db.mjs +4 -0
  73. package/tests/market_watch_module.mjs +9 -5
  74. package/tests/project_settings_page.mjs +1 -1
  75. package/tests/reward_cost_scale.mjs +200 -0
  76. package/tests/run_node_reroute.mjs +136 -0
@@ -5,7 +5,7 @@ A **generated**, zero-dependency typed client for the Bongos API — produced fr
5
5
  by hand; it regenerates when the spec changes, so it can never drift from the routes.
6
6
 
7
7
  - API version: **v1** (served at `/api/bongos/v1`)
8
- - 634 operations across 79 resource groups
8
+ - 636 operations across 80 resource groups
9
9
 
10
10
  ## Use it from your project
11
11
 
@@ -754,6 +754,12 @@ function createClient(opts = {}) {
754
754
  // POST /llm-cache/store — rank: metic+archon — POST /llm-cache/store
755
755
  postLlmCacheStore: (args) => request("POST", "/llm-cache/store", { hasBody: true }, args),
756
756
  },
757
+ "marketWatch": {
758
+ // GET /market-watch/ask — rank: any-builder — GET /market-watch/ask
759
+ getMarketWatchAsk: (args) => request("GET", "/market-watch/ask", { hasBody: false }, args),
760
+ // POST /market-watch/ask/answer — rank: any-builder — POST /market-watch/ask/answer
761
+ postMarketWatchAskAnswer: (args) => request("POST", "/market-watch/ask/answer", { hasBody: true }, args),
762
+ },
757
763
  "me": {
758
764
  // GET /me — rank: any-builder — GET /me
759
765
  getMe: (args) => request("GET", "/me", { hasBody: false }, args),
@@ -753,6 +753,12 @@ function createClient(opts = {}) {
753
753
  // POST /llm-cache/store — rank: metic+archon — POST /llm-cache/store
754
754
  postLlmCacheStore: (args) => request("POST", "/llm-cache/store", { hasBody: true }, args),
755
755
  },
756
+ "marketWatch": {
757
+ // GET /market-watch/ask — rank: any-builder — GET /market-watch/ask
758
+ getMarketWatchAsk: (args) => request("GET", "/market-watch/ask", { hasBody: false }, args),
759
+ // POST /market-watch/ask/answer — rank: any-builder — POST /market-watch/ask/answer
760
+ postMarketWatchAskAnswer: (args) => request("POST", "/market-watch/ask/answer", { hasBody: true }, args),
761
+ },
756
762
  "me": {
757
763
  // GET /me — rank: any-builder — GET /me
758
764
  getMe: (args) => request("GET", "/me", { hasBody: false }, args),
@@ -107,6 +107,7 @@ export interface GetInboxTemplateResponse { template: unknown }
107
107
  export interface GetInboxVotesResponse { votes: unknown }
108
108
  export interface GetLeaderboardResponse { leaderboard: unknown; page: unknown }
109
109
  export interface GetLearningsResponse { learnings: unknown }
110
+ export interface GetMarketWatchAskResponse { card: unknown }
110
111
  export interface GetMeAchievementsResponse { unlocked: unknown }
111
112
  export interface GetMeCrossProjectResponse { hide_stats: boolean; profile_state: unknown; handle: unknown; display_name: unknown; bio: unknown; links: unknown; cross_project: unknown; account_visibility: unknown; recruiter_discoverable: unknown; recruiter_discoverable_effective: unknown }
112
113
  export interface GetMeDisplayNameResponse { display_name: unknown; max_length: unknown }
@@ -461,6 +462,7 @@ export interface PostLlmCacheLookupRequest { cache_key?: unknown; tokens_saved_e
461
462
  export interface PostLlmCacheLookupResponse { hit: boolean; result: unknown }
462
463
  export interface PostLlmCacheStoreRequest { spec?: unknown; result_stdout?: unknown; result_cost_usd?: unknown }
463
464
  export interface PostLlmCacheStoreResponse { stored: boolean; result_cost_usd?: unknown }
465
+ export interface PostMarketWatchAskAnswerRequest { week_of?: string; picks?: unknown[]; names?: unknown[]; nothing?: boolean; builder_id?: number }
464
466
  export interface PostMeAnthropicLinkRequest { anthropic_email: string; anthropic_user_id: string }
465
467
  export interface PostMeAnthropicLinkResponse { linked: unknown }
466
468
  export interface PostMeFilterViewsRequest { page: string; name: string; values: Record<string, unknown>; is_default?: boolean }
@@ -1371,6 +1373,12 @@ export interface BongosClient {
1371
1373
  /** POST /llm-cache/store — rank: metic+archon */
1372
1374
  postLlmCacheStore(args?: RequestArgs & { body?: PostLlmCacheStoreRequest }): Promise<PostLlmCacheStoreResponse>;
1373
1375
  };
1376
+ "marketWatch": {
1377
+ /** GET /market-watch/ask — rank: any-builder */
1378
+ getMarketWatchAsk(args?: RequestArgs): Promise<GetMarketWatchAskResponse>;
1379
+ /** POST /market-watch/ask/answer — rank: any-builder */
1380
+ postMarketWatchAskAnswer(args?: RequestArgs & { body?: PostMarketWatchAskAnswerRequest }): Promise<ApiResponse>;
1381
+ };
1374
1382
  "me": {
1375
1383
  /** GET /me — rank: any-builder */
1376
1384
  getMe(args?: RequestArgs): Promise<ApiResponse>;
@@ -750,6 +750,12 @@ export function createClient(opts = {}) {
750
750
  // POST /llm-cache/store — rank: metic+archon — POST /llm-cache/store
751
751
  postLlmCacheStore: (args) => request("POST", "/llm-cache/store", { hasBody: true }, args),
752
752
  },
753
+ "marketWatch": {
754
+ // GET /market-watch/ask — rank: any-builder — GET /market-watch/ask
755
+ getMarketWatchAsk: (args) => request("GET", "/market-watch/ask", { hasBody: false }, args),
756
+ // POST /market-watch/ask/answer — rank: any-builder — POST /market-watch/ask/answer
757
+ postMarketWatchAskAnswer: (args) => request("POST", "/market-watch/ask/answer", { hasBody: true }, args),
758
+ },
753
759
  "me": {
754
760
  // GET /me — rank: any-builder — GET /me
755
761
  getMe: (args) => request("GET", "/me", { hasBody: false }, args),
@@ -48,7 +48,6 @@
48
48
  },
49
49
  "reward": {
50
50
  "marginPct": 20,
51
- "usdPeg": 1,
52
51
  "mode": "cost-plus-and-estimate"
53
52
  },
54
53
  "models": {
@@ -39,3 +39,14 @@ Three things stood in the way:
39
39
  ## What this does not do
40
40
 
41
41
  It adds no other provider, no email codes and no passwords. It does not link accounts, show a Link GitHub chip, or guide anyone to GitHub (tasks 1004995–1004997).
42
+
43
+ ## Amendment — project halls take a Google-only person (task 1004994)
44
+
45
+ Decision 8's two refusals are lifted, without ever sending a minted key to a core that cannot take one:
46
+
47
+ - **A hall says it can.** Core's `idpAuthorizeUrl` adds `person_keys=1` to the hub authorize link. The hub's `/sso/authorize` hands a minted key only to a link that carries it (`hallTakesPersonKey`); an older hall's link does not, and the person reads a plain page saying the project needs an update. GitHub people are unchanged on every hall.
48
+ - **Joining is relayed by the stand-in.** `POST /my-projects/join` sends `~<handle>` with the application vouch for the person key. The hall's public `POST /access-requests` accepts a stand-in **only** with that vouch (a stand-in is not an identity anyone may type), and an older hall's `bad_github_login` refusal is said as "this project needs an update" (`needs_update`).
49
+ - **The approval is matched on the key, never the handle.** A handle can be renamed and later taken by someone else, so `hasInvitedAccessRequest(login, githubId)` matches a minted key on `applicant_github_id` alone; both hub sign-ins on a hall pass it. A vouch is accepted only when a negative key and a stand-in login come together.
50
+ - **People read the handle.** The hall's admission queue shows `ana`, not `~ana`.
51
+
52
+ Credits, ranks and community pages needed no change: the hub's check-in and rollup already take a negative key. Still open: a hall's command-line sign-in (`/sso/device/*`) is GitHub's device flow, so a Google-only person signs in to a hall in the browser; engineering work still needs GitHub (task 1004997).
@@ -197,6 +197,10 @@
197
197
  "name": "llm-cache",
198
198
  "description": "Endpoints under `/api/bongos/llm-cache`."
199
199
  },
200
+ {
201
+ "name": "market-watch",
202
+ "description": "Endpoints under `/api/bongos/market-watch`."
203
+ },
200
204
  {
201
205
  "name": "me",
202
206
  "description": "Endpoints under `/api/bongos/me`."
@@ -13952,6 +13956,86 @@
13952
13956
  ]
13953
13957
  }
13954
13958
  },
13959
+ "/market-watch/ask": {
13960
+ "get": {
13961
+ "operationId": "get_market_watch_ask",
13962
+ "tags": [
13963
+ "market-watch"
13964
+ ],
13965
+ "summary": "GET /market-watch/ask",
13966
+ "description": "every member reads their own card; nobody else's (isMember in gate()).\n\n**Rank:** `any-builder` — Any authenticated builder (row-level ownership enforced in-handler).",
13967
+ "x-rank": "any-builder",
13968
+ "x-source": "modules/market-watch/routes/ask.js",
13969
+ "responses": {
13970
+ "200": {
13971
+ "description": "Success.",
13972
+ "content": {
13973
+ "application/json": {
13974
+ "schema": {
13975
+ "$ref": "#/components/schemas/GetMarketWatchAskResponse"
13976
+ }
13977
+ }
13978
+ }
13979
+ },
13980
+ "400": {
13981
+ "$ref": "#/components/responses/BadRequest"
13982
+ },
13983
+ "401": {
13984
+ "$ref": "#/components/responses/Unauthorized"
13985
+ },
13986
+ "403": {
13987
+ "$ref": "#/components/responses/Forbidden"
13988
+ }
13989
+ },
13990
+ "security": [
13991
+ {
13992
+ "builderSession": []
13993
+ }
13994
+ ]
13995
+ }
13996
+ },
13997
+ "/market-watch/ask/answer": {
13998
+ "post": {
13999
+ "operationId": "post_market_watch_ask_answer",
14000
+ "tags": [
14001
+ "market-watch"
14002
+ ],
14003
+ "summary": "POST /market-watch/ask/answer",
14004
+ "description": "a member answers for themselves only (isMember in gate()).\n\n**Rank:** `any-builder` — Any authenticated builder (row-level ownership enforced in-handler).",
14005
+ "x-rank": "any-builder",
14006
+ "x-source": "modules/market-watch/routes/ask.js",
14007
+ "requestBody": {
14008
+ "required": false,
14009
+ "content": {
14010
+ "application/json": {
14011
+ "schema": {
14012
+ "$ref": "#/components/schemas/PostMarketWatchAskAnswerRequest"
14013
+ }
14014
+ }
14015
+ },
14016
+ "x-validated": true
14017
+ },
14018
+ "responses": {
14019
+ "200": {
14020
+ "description": "Success."
14021
+ },
14022
+ "400": {
14023
+ "$ref": "#/components/responses/ValidationFailed"
14024
+ },
14025
+ "401": {
14026
+ "$ref": "#/components/responses/Unauthorized"
14027
+ },
14028
+ "403": {
14029
+ "$ref": "#/components/responses/Forbidden"
14030
+ }
14031
+ },
14032
+ "security": [
14033
+ {
14034
+ "builderSession": []
14035
+ }
14036
+ ]
14037
+ }
14038
+ },
13955
14039
  "/me": {
13956
14040
  "get": {
13957
14041
  "operationId": "get_me",
@@ -19493,7 +19577,7 @@
19493
19577
  "project-settings"
19494
19578
  ],
19495
19579
  "summary": "GET /project-settings",
19496
- "description": "GET /project-settings — all five rows in ONE read. rank: project.settings.manage (metic+, government_010), the SAME floor as the page it serves (requireGovernmentPage). The first cut gated this any-builder on the reasoning that it is \"the project's own published terms\" — but the payload also carries reward-policy internals (marginPct, usdPeg, mode), a raw rejected project_settings value, and internal file/migration paths, and a xenos who cannot even load the page could still curl those. Matching the read floor to the page's (task 1003280 grade, hacker lens) closes that asymmetry; the two WRITES already gate on this same atom, so the whole surface is now one floor. One read, not five: the page draws five rows, so it asks for five rows. Fetching per-row would put the hall's own settings page in the shape goal 1000072's criterion names (hall-ui/CLAUDE.md, \"a card asks the server for the rows it draws\").\n\n**Rank:** `metic+archon` — Metic or Archon rank (review/triage powers).\n\n**Permissions:** `project.settings.manage` (all required).",
19580
+ "description": "GET /project-settings — all five rows in ONE read. rank: project.settings.manage (metic+, government_010), the SAME floor as the page it serves (requireGovernmentPage). The first cut gated this any-builder on the reasoning that it is \"the project's own published terms\" — but the payload also carries reward-policy internals (marginPct, costScale, mode), a raw rejected project_settings value, and internal file/migration paths, and a xenos who cannot even load the page could still curl those. Matching the read floor to the page's (task 1003280 grade, hacker lens) closes that asymmetry; the two WRITES already gate on this same atom, so the whole surface is now one floor. One read, not five: the page draws five rows, so it asks for five rows. Fetching per-row would put the hall's own settings page in the shape goal 1000072's criterion names (hall-ui/CLAUDE.md, \"a card asks the server for the rows it draws\").\n\n**Rank:** `metic+archon` — Metic or Archon rank (review/triage powers).\n\n**Permissions:** `project.settings.manage` (all required).",
19497
19581
  "x-rank": "metic+archon",
19498
19582
  "x-source": "modules/lifecycle/routes/project-settings.js",
19499
19583
  "x-permissions": [
@@ -31051,6 +31135,15 @@
31051
31135
  "learnings"
31052
31136
  ]
31053
31137
  },
31138
+ "GetMarketWatchAskResponse": {
31139
+ "type": "object",
31140
+ "properties": {
31141
+ "card": {}
31142
+ },
31143
+ "required": [
31144
+ "card"
31145
+ ]
31146
+ },
31054
31147
  "GetMeAchievementsResponse": {
31055
31148
  "type": "object",
31056
31149
  "properties": {
@@ -36533,6 +36626,30 @@
36533
36626
  "stored"
36534
36627
  ]
36535
36628
  },
36629
+ "PostMarketWatchAskAnswerRequest": {
36630
+ "type": "object",
36631
+ "properties": {
36632
+ "week_of": {
36633
+ "type": "string",
36634
+ "maxLength": 10
36635
+ },
36636
+ "picks": {
36637
+ "type": "array",
36638
+ "maxItems": 20
36639
+ },
36640
+ "names": {
36641
+ "type": "array",
36642
+ "maxItems": 6
36643
+ },
36644
+ "nothing": {
36645
+ "type": "boolean"
36646
+ },
36647
+ "builder_id": {
36648
+ "type": "integer"
36649
+ }
36650
+ },
36651
+ "additionalProperties": false
36652
+ },
36536
36653
  "PostMeAnthropicLinkRequest": {
36537
36654
  "type": "object",
36538
36655
  "properties": {
@@ -40319,9 +40436,9 @@
40319
40436
  "description": "A required dependency/feature is not configured or is temporarily down."
40320
40437
  }
40321
40438
  },
40322
- "x-endpoint-count": 634,
40323
- "x-schema-count": 684,
40439
+ "x-endpoint-count": 636,
40440
+ "x-schema-count": 686,
40324
40441
  "x-undocumented-bodies": 12,
40325
- "x-response-schemas": 440,
40442
+ "x-response-schemas": 441,
40326
40443
  "x-generated-by": "scripts/bongos/gen-api-docs.js"
40327
40444
  }
@@ -2,7 +2,7 @@
2
2
 
3
3
  # Bongos API reference
4
4
 
5
- > **Generated from the live route files** — the route file is authoritative. 634 endpoints across 104 route files.
5
+ > **Generated from the live route files** — the route file is authoritative. 636 endpoints across 105 route files.
6
6
  > Machine-readable spec: [`docs/api/openapi.json`](api/openapi.json) (OpenAPI 3.1). Rendered docs site: **`/docs`** (e.g. `cloudbongos.com/docs`).
7
7
 
8
8
  Base path: `/api/bongos`. Ranks (enforced server-side, [ADR 0016](adr/0016-trust-boundary-server-enforced-permissions.md)): `public` < `any-builder` < `metic+archon` < `archon`.
@@ -518,6 +518,13 @@ Base path: `/api/bongos`. Ranks (enforced server-side, [ADR 0016](adr/0016-trust
518
518
  | POST | `/api/bongos/llm-cache/lookup` | `metic+archon` | `cache_key`, `tokens_saved_est` | POST /llm-cache/lookup — hit/miss + atomic hit_count bump. |
519
519
  | POST | `/api/bongos/llm-cache/store` | `metic+archon` | `spec`, `result_stdout`, `result_cost_usd` | POST /llm-cache/store — upsert a freshly-produced result. |
520
520
 
521
+ ## `market-watch` (2)
522
+
523
+ | Method | Path | Rank | Body | Description |
524
+ |---|---|---|---|---|
525
+ | GET | `/api/bongos/market-watch/ask` | `any-builder` | — | every member reads their own card; nobody else's (isMember in gate()). |
526
+ | POST | `/api/bongos/market-watch/ask/answer` | `any-builder` | `week_of`, `picks`, `names`, `nothing`, `builder_id` | a member answers for themselves only (isMember in gate()). |
527
+
521
528
  ## `me` (54)
522
529
 
523
530
  | Method | Path | Rank | Body | Description |
@@ -33,7 +33,7 @@ env override → instance config (config/branding.json) → neutral star
33
33
  | `repo` | `{ owner, name }` GitHub binding. |
34
34
  | `db.database` | DB name Bongos pool connects to when neither `DATABASE_URL` nor `PGHOST`/`PGDATABASE` is set (`src/bongos/pool.js`, ADR 0062 §5). `null` in the neutral starter = **fail loud** rather than silently target a host DB. |
35
35
  | `currency` | `{ label, symbol }` — the reward unit label (e.g. "example"). Display only. |
36
- | `reward` | `{ marginPct, usdPeg, mode }` — the per-instance reward POLICY the economy module reads ([ADR 0054](adr/0054-session-token-reward-cost-plus.md) + ADR 0146, tasks 2009/1002270): the cost-plus margin percent (default `20`), the example-per-USD peg (default `1`), and `mode` — `"cost-plus-and-estimate"` (default; pay both the per-task author estimate AND the cost-plus session reward) or `"cost-plus-only"` (suppress the per-task estimate payout; the cost-plus session reward is the sole equity reward). Two per-craft lanes sit beside `mode` and are not derived from it: `ideatorCredit` ([ADR 0172](adr/0172-per-craft-compensation-ideator-credit-lane.md)) and `artistCredit` ([ADR 0341](adr/0341-the-page-is-the-unit-of-tweak-mode.md) D10, an approved page tweak pays its artist), each default on and withheld only by an explicit `false`. A committed, code-reviewed change — not a live UI knob. Omit ⇒ code defaults (20% margin, 1:1 peg, pay both streams, both lanes on). |
36
+ | `reward` | `{ marginPct, costScale, mode }` — the per-instance reward POLICY the economy module reads ([ADR 0054](adr/0054-session-token-reward-cost-plus.md) + ADR 0146, tasks 2009/1002270): the cost-plus margin percent (default `20`), the sizing factor `costScale` (default `1`; it sizes credits from cost and is not an exchange rate — a credit has no price, [ADR 0387](adr/0387-two-ledgers-credits-measure-work-money-stays-with-the-processor.md)), and `mode` — `"cost-plus-and-estimate"` (default; pay both the per-task author estimate AND the cost-plus session reward) or `"cost-plus-only"` (suppress the per-task estimate payout; the cost-plus session reward is the sole equity reward). Two per-craft lanes sit beside `mode` and are not derived from it: `ideatorCredit` ([ADR 0172](adr/0172-per-craft-compensation-ideator-credit-lane.md)) and `artistCredit` ([ADR 0341](adr/0341-the-page-is-the-unit-of-tweak-mode.md) D10, an approved page tweak pays its artist), each default on and withheld only by an explicit `false`. A committed, code-reviewed change — not a live UI knob. Omit ⇒ code defaults (20% margin, scale 1, pay both streams, both lanes on). **`usdPeg` is the deprecated old name of `costScale`** (task 1004968): it is still read, with a one-line deprecation note in the server log, so no host pack breaks; when both are set `costScale` wins. The neutral pack sets neither key (the default `1` lives in code), so a host pack's old `usdPeg` is never shadowed by the deep-merge. Rename it at your next pack edit — support for the old key goes in a later release. |
37
37
  | `models` | `{ main, subagentDefault, subagentRoutine }` — the per-instance subagent model-allocation DEFAULT the builder-settings module reads (task 2011): the tier for the main session, subagent-default work, and routine plumbing (tiers: `haiku`/`sonnet`/`opus`/`fable`). A per-builder override resolves over this. Omit ⇒ code defaults (`opus`/`opus`/`haiku`). |
38
38
  | `tracks` | The configurable version-track set (replaces the hardcoded `product\|internal`). |
39
39
  | `theme` | `{ palette, mode, ui }` — palette file ref + theme mode, plus `ui`, the WEB look `themeMarkup()` splices into every served page as a plain `:root` after the page's stylesheet: `colors` (the thirteen contract tokens — **light-mode values**; each stylesheet derives its own dark tier from them at `:root[data-mode="dark"]` + its `prefers-color-scheme` twin, which outrank the pack), `fonts` (`display`, `body`, `links`), `favicon`, and `backdrop` — a `body{background:…}` rule that outranks every sheet in **both** modes, so a dual-mode world sets it to `var(--bg)` (the neutral pack does since [task 1003298](https://cloudbongos.com/builders#/task/1003298), ADR 0196) rather than a literal. The neutral values are the chrome world's; `config/design-tokens.neutral.json` must mirror `colors` + `fonts` key for key (`tests/design_tokens_sync.mjs`), and the world's derived recipes are recorded in `DESIGN.md`. The ui-design module's **style library** (`modules/ui-design/styles/`, [ADR 0219](adr/0219-a-look-is-a-branding-pack-the-style-library.md)) ships ready-made `theme.ui` blocks (looks) an instance copies into this field; every served sheet reads only these fifteen, so a look re-themes every surface with no page edit. |
@@ -848,7 +848,7 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
848
848
  | `4f89817b92e5` | certain | No onboarding steps recorded yet. | `modules/hall-ui/public/hall-render.js:893` |
849
849
  | `421ae031594e` | certain | No open goals in this version | `modules/hall-ui/public/task.js:577` |
850
850
  | `2a6d7552e21f` | certain | No other sessions. | `modules/hall-ui/public/settings-sessions.js:64` |
851
- | `90623fec4cfa` | certain | No page is open. | `modules/hall-ui/public/tweak-editor.js:574` |
851
+ | `90623fec4cfa` | certain | No page is open. | `modules/hall-ui/public/tweak-editor.js:575` |
852
852
  | `1a46c31343cb` | certain | No projects are hosted here yet. | `modules/hall-ui/public/fleet-costs.js:69` |
853
853
  | `9f73b3f3dad0` | certain | No rank floor — any builder can claim this task | `modules/hall-ui/public/task-lib.js:77` |
854
854
  | `4ffd939755e0` | certain | No real-world data yet, so it is listed but not ranked. | `modules/hall-ui/public/modules.js:343` |
@@ -874,7 +874,7 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
874
874
  | `730a248e7888` | certain | No {…} {…} render; showing {…} {…}. | `modules/hall-ui/public/approval-queue.js:141` |
875
875
  | `1967d2176f2e` | certain | Nobody has an open ask right now. | `modules/hall-ui/public/collab.html:95` |
876
876
  | `c65c9f5c02e3` | certain | Nobody is waiting on you. Requests reach you by role — | `modules/hall-ui/public/collab.html:54` |
877
- | `d5cf262e671d` | certain | Nobody is writing this page. Take it, and every line here is yours to type over. | `modules/hall-ui/public/tweak-editor.js:323` |
877
+ | `d5cf262e671d` | certain | Nobody is writing this page. Take it, and every line here is yours to type over. | `modules/hall-ui/public/tweak-editor.js:324` |
878
878
  | `380b924cd4a0` | certain | Nobody recorded — it falls to the owner | `modules/hall-ui/public/government-access.js:35` |
879
879
  | `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:397` |
880
880
  | `4016b9cf8d57` | certain | None of your asks have been settled yet. | `modules/hall-ui/public/collab.html:145` |
@@ -1299,7 +1299,7 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
1299
1299
  | `59fcf7f5ac27` | certain | Switch to light mode | `modules/hall-ui/public/street.html:95` |
1300
1300
  | `93fa2e97dd35` | certain | System default for this skill | `modules/hall-ui/public/settings.js:72` |
1301
1301
  | `da9da6e866bd` | certain | Take it offline | `modules/hall-ui/public/project-settings.html:59` |
1302
- | `aa8da34fe237` | certain | Take the next page, or pick one from the studio. | `modules/hall-ui/public/tweak-editor.js:575` |
1302
+ | `aa8da34fe237` | certain | Take the next page, or pick one from the studio. | `modules/hall-ui/public/tweak-editor.js:576` |
1303
1303
  | `fc53e250e86f` | certain | Take this page | `modules/hall-ui/public/paintbrush.js:116` |
1304
1304
  | `8b3cdb88b0f4` | certain | Taken out of the store. Your copy keeps working, but it will get no more updates. | `modules/hall-ui/public/modules.js:134` |
1305
1305
  | `e604fc3ace79` | certain | Task # | `modules/hall-ui/public/blockers.js:138` |
@@ -1353,7 +1353,7 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
1353
1353
  | `51633ea53205` | certain | The doc is now this page's reference. Every idea links back to it. | `modules/hall-ui/public/page-notes.js:195` |
1354
1354
  | `239d641c20fa` | certain | The document | `modules/hall-ui/public/settings-specialities.js:354` |
1355
1355
  | `784618f83a42` | certain | The earlier ideas could not be loaded. Reload the page to try again. | `modules/hall-ui/public/lightbulb.js:118` |
1356
- | `ffaa4df90f66` | certain | The editor could not load. | `modules/hall-ui/public/tweak-editor.js:723` |
1356
+ | `ffaa4df90f66` | certain | The editor could not load. | `modules/hall-ui/public/tweak-editor.js:724` |
1357
1357
  | `6e2554615883` | certain | The event sounds could not be loaded. Reload the page to try again. | `modules/hall-ui/public/settings.js:391` |
1358
1358
  | `6a208d46dd0f` | certain | The founding mark is numbered in the order people joined while the project was founded. It is kept for good an | `modules/hall-ui/public/ranks.html:41` |
1359
1359
  | `7e77b1ed9c86` | certain | The founding wall | `modules/hall-ui/public/hall-widgets.js:133` |
@@ -1380,7 +1380,7 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
1380
1380
  | `27037792dd7d` | certain | The mobile layout can wait until the desktop one ships. | `modules/hall-ui/public/notes-panel.js:68` |
1381
1381
  | `381f29be7497` | certain | The most recently shipped tasks. | `modules/hall-ui/public/work.html:140` |
1382
1382
  | `82479c539fca` | certain | The name shown beside your work — in the roster, the leaderboard, and the work feed. Your sign-in and the cred | `modules/hall-ui/public/settings.html:78` |
1383
- | `4b20ecf5528b` | certain | The next page could not be read. | `modules/hall-ui/public/tweak-editor.js:586` |
1383
+ | `4b20ecf5528b` | certain | The next page could not be read. | `modules/hall-ui/public/tweak-editor.js:587` |
1384
1384
  | `b88dd8b96b72` | certain | The next person to notice this sentence reads your note instead of re-litigating it. | `modules/hall-ui/public/copy-desk.html:135` |
1385
1385
  | `329a1d350f07` | certain | The page changed after your draft was saved, so the draft is not shown over its new words. Rewrite the lines a | `modules/hall-ui/public/tweak-editor.js:319` |
1386
1386
  | `aa716f3dd551` | certain | The page could not be loaded. Try again. | `modules/hall-ui/public/builders.js:1409` |
@@ -1456,7 +1456,7 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
1456
1456
  | `c7d2bc751184` | certain | This goal was added to {…} after it had already started building — an Archon override of the scope gate | `modules/hall-ui/public/goals-render.js:895` |
1457
1457
  | `23f531302e9e` | certain | This is you — | `modules/hall-ui/public/profile.js:363` |
1458
1458
  | `d313d3dfe438` | certain | This move is decided by the project’s government, not by one person here. | `modules/hall-ui/public/deploy.js:583` |
1459
- | `f303bd107422` | certain | This page has been submitted and is on its way to the site. Its words are frozen until it ships or is sent bac | `modules/hall-ui/public/tweak-editor.js:331` |
1459
+ | `f303bd107422` | certain | This page has been submitted and is on its way to the site. Its words are frozen until it ships or is sent bac | `modules/hall-ui/public/tweak-editor.js:332` |
1460
1460
  | `e54578188187` | certain | This page is for members of the board. | `modules/hall-ui/public/board-room.html:43` |
1461
1461
  | `9a685b01e2c6` | certain | This page opens at a higher rank. | `modules/hall-ui/public/deploy.html:33` |
1462
1462
  | `9a685b01e2c6` | certain | This page opens at a higher rank. | `modules/hall-ui/public/fleet.html:32` |
@@ -1740,7 +1740,7 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
1740
1740
  | `a3fd52d9513b` | certain | document{…} you added · learned | `modules/hall-ui/public/settings-specialities.js:322` |
1741
1741
  | `fcec9cad1c69` | certain | download .docx | `modules/hall-ui/public/tweak-editor.html:65` |
1742
1742
  | `7c1f761ff7c0` | certain | download this page again | `modules/hall-ui/public/tweak-editor.html:131` |
1743
- | `87129aa3ab0a` | certain | downloaded .docx | `modules/hall-ui/public/tweak-editor.js:481` |
1743
+ | `87129aa3ab0a` | certain | downloaded .docx | `modules/hall-ui/public/tweak-editor.js:482` |
1744
1744
  | `16d18b40bd23` | certain | drag to pan · ⌘/ctrl + scroll to zoom · ⤢ fullscreen | `modules/hall-ui/public/diagram-viewer.js:125` |
1745
1745
  | `91a14a57b576` | certain | e.g. My open goals | `modules/hall-ui/public/hall-kit.js:409` |
1746
1746
  | `77b0b2b446a1` | certain | e.g. octocat | `modules/hall-ui/public/hall-render.js:300` |
@@ -1890,7 +1890,7 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
1890
1890
  | `70bbd20d223f` | certain | take it | `modules/hall-ui/public/studio.js:743` |
1891
1891
  | `d4f99c118825` | certain | take next | `modules/hall-ui/public/tweak-editor.html:106` |
1892
1892
  | `357cc737dd98` | certain | take the studio page | `modules/hall-ui/public/studio.html:109` |
1893
- | `24fc2b94ea7d` | certain | take this page | `modules/hall-ui/public/tweak-editor.js:324` |
1893
+ | `24fc2b94ea7d` | certain | take this page | `modules/hall-ui/public/tweak-editor.js:325` |
1894
1894
  | `a6e803a31a4d` | certain | task #{…} | `modules/hall-ui/public/copy-desk.js:105` |
1895
1895
  | `eb808f2daba3` | certain | task dependenc{…} · click to chart it · double-click to chart every route from here | `modules/hall-ui/public/sky-interaction.js:37` |
1896
1896
  | `3906fbc07bbe` | certain | task id | `modules/hall-ui/public/task.js:608` |
@@ -1941,7 +1941,7 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
1941
1941
  | `73e8a560927b` | certain | up for a vote | `modules/hall-ui/public/my-agents.js:424` |
1942
1942
  | `f98966dc7cac` | certain | upkeep undeclared | `modules/hall-ui/public/modules.js:104` |
1943
1943
  | `432def6844b7` | certain | upload .docx | `modules/hall-ui/public/tweak-editor.html:66` |
1944
- | `432def6844b7` | certain | upload .docx | `modules/hall-ui/public/tweak-editor.js:506` |
1944
+ | `432def6844b7` | certain | upload .docx | `modules/hall-ui/public/tweak-editor.js:507` |
1945
1945
  | `f26117caa2f1` | certain | usually done in about a minute | `modules/hall-ui/public/ai-studio.js:377` |
1946
1946
  | `4de556377db2` | certain | verdict {…} | `modules/hall-ui/public/task.js:432` |
1947
1947
  | `f20985df3729` | certain | version · {…} | `modules/hall-ui/public/sky-interaction.js:38` |
@@ -1994,8 +1994,8 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
1994
1994
  | `78ba2bd4bc44` | certain | {…} criteria · started {…} | `modules/hall-ui/public/roadmap.js:259` |
1995
1995
  | `5ccebd39118e` | certain | {…} deleted. | `modules/hall-ui/public/government.js:324` |
1996
1996
  | `cf89ac85440d` | certain | {…} earned | `modules/hall-ui/public/goals-render.js:821` |
1997
- | `55b949873848` | certain | {…} is in. | `modules/hall-ui/public/tweak-editor.js:577` |
1998
- | `80b4aa799a4b` | certain | {…} is writing this page now. You can read it, download it, or take another page from the studio. | `modules/hall-ui/public/tweak-editor.js:328` |
1997
+ | `55b949873848` | certain | {…} is in. | `modules/hall-ui/public/tweak-editor.js:578` |
1998
+ | `80b4aa799a4b` | certain | {…} is writing this page now. You can read it, download it, or take another page from the studio. | `modules/hall-ui/public/tweak-editor.js:329` |
1999
1999
  | `c80c3434ae36` | certain | {…} key ending {…} | `modules/hall-ui/public/ai-studio.js:272` |
2000
2000
  | `5ad81ff61920` | certain | {…} lands in your balance; your card is charged {…}. | `modules/hall-ui/public/ai-studio.js:517` |
2001
2001
  | `830d2be6f859` | certain | {…} line | `modules/hall-ui/public/tweak-editor.js:235` |
@@ -2845,7 +2845,7 @@
2845
2845
  "occurrences": 2,
2846
2846
  "at": [
2847
2847
  "modules/hall-ui/public/tweak-editor.html:66",
2848
- "modules/hall-ui/public/tweak-editor.js:506"
2848
+ "modules/hall-ui/public/tweak-editor.js:507"
2849
2849
  ]
2850
2850
  },
2851
2851
  {
@@ -9949,7 +9949,7 @@
9949
9949
  "surface": "builders-hall",
9950
9950
  "text": "No page is open.",
9951
9951
  "file": "modules/hall-ui/public/tweak-editor.js",
9952
- "line": 574,
9952
+ "line": 575,
9953
9953
  "origin": "js-text-assign",
9954
9954
  "confidence": "certain"
9955
9955
  },
@@ -10183,7 +10183,7 @@
10183
10183
  "surface": "builders-hall",
10184
10184
  "text": "Nobody is writing this page. Take it, and every line here is yours to type over.",
10185
10185
  "file": "modules/hall-ui/public/tweak-editor.js",
10186
- "line": 323,
10186
+ "line": 324,
10187
10187
  "origin": "js-markup",
10188
10188
  "confidence": "certain"
10189
10189
  },
@@ -14008,7 +14008,7 @@
14008
14008
  "surface": "builders-hall",
14009
14009
  "text": "Take the next page, or pick one from the studio.",
14010
14010
  "file": "modules/hall-ui/public/tweak-editor.js",
14011
- "line": 575,
14011
+ "line": 576,
14012
14012
  "origin": "js-text-assign",
14013
14013
  "confidence": "certain"
14014
14014
  },
@@ -14494,7 +14494,7 @@
14494
14494
  "surface": "builders-hall",
14495
14495
  "text": "The editor could not load.",
14496
14496
  "file": "modules/hall-ui/public/tweak-editor.js",
14497
- "line": 723,
14497
+ "line": 724,
14498
14498
  "origin": "js-notice",
14499
14499
  "confidence": "certain"
14500
14500
  },
@@ -14737,7 +14737,7 @@
14737
14737
  "surface": "builders-hall",
14738
14738
  "text": "The next page could not be read.",
14739
14739
  "file": "modules/hall-ui/public/tweak-editor.js",
14740
- "line": 586,
14740
+ "line": 587,
14741
14741
  "origin": "js-text-assign",
14742
14742
  "confidence": "certain"
14743
14743
  },
@@ -15421,7 +15421,7 @@
15421
15421
  "surface": "builders-hall",
15422
15422
  "text": "This page has been submitted and is on its way to the site. Its words are frozen until it ships or is sent back.",
15423
15423
  "file": "modules/hall-ui/public/tweak-editor.js",
15424
- "line": 331,
15424
+ "line": 332,
15425
15425
  "origin": "js-markup",
15426
15426
  "confidence": "certain"
15427
15427
  },
@@ -17977,7 +17977,7 @@
17977
17977
  "surface": "builders-hall",
17978
17978
  "text": "downloaded .docx",
17979
17979
  "file": "modules/hall-ui/public/tweak-editor.js",
17980
- "line": 481,
17980
+ "line": 482,
17981
17981
  "origin": "js-text-assign",
17982
17982
  "confidence": "certain"
17983
17983
  },
@@ -19327,7 +19327,7 @@
19327
19327
  "surface": "builders-hall",
19328
19328
  "text": "take this page",
19329
19329
  "file": "modules/hall-ui/public/tweak-editor.js",
19330
- "line": 324,
19330
+ "line": 325,
19331
19331
  "origin": "js-markup",
19332
19332
  "confidence": "certain"
19333
19333
  },
@@ -19786,7 +19786,7 @@
19786
19786
  "surface": "builders-hall",
19787
19787
  "text": "upload .docx",
19788
19788
  "file": "modules/hall-ui/public/tweak-editor.js",
19789
- "line": 506,
19789
+ "line": 507,
19790
19790
  "origin": "js-text-assign",
19791
19791
  "confidence": "certain"
19792
19792
  },
@@ -20263,7 +20263,7 @@
20263
20263
  "surface": "builders-hall",
20264
20264
  "text": "{…} is in.",
20265
20265
  "file": "modules/hall-ui/public/tweak-editor.js",
20266
- "line": 577,
20266
+ "line": 578,
20267
20267
  "origin": "js-text-assign",
20268
20268
  "confidence": "certain"
20269
20269
  },
@@ -20272,7 +20272,7 @@
20272
20272
  "surface": "builders-hall",
20273
20273
  "text": "{…} is writing this page now. You can read it, download it, or take another page from the studio.",
20274
20274
  "file": "modules/hall-ui/public/tweak-editor.js",
20275
- "line": 328,
20275
+ "line": 329,
20276
20276
  "origin": "js-markup",
20277
20277
  "confidence": "certain"
20278
20278
  },
package/docs/file-map.md CHANGED
@@ -461,7 +461,7 @@ To install on a new machine, symlink each routine's directory under `~/.claude/s
461
461
  ```
462
462
  .claude/hooks/
463
463
  ├── secret-gate.js ← PreToolUse (Edit|Write|MultiEdit|NotebookEdit|Bash|PowerShell): cooperative, fail-OPEN block of secret-shaped content before it reaches the tree or a shell (task 1003125, ADR 0022)
464
- ├── run-node.sh ← the node resolver every hook command runs through (task 1003548): $OTB_NODE_BIN → PATH → known install dirs → nvm; one actionable line + exit 1 when none is found. 1,055 hook runs had died silently with `node: command not found`
464
+ ├── run-node.sh ← the node resolver every hook command runs through (task 1003548): $OTB_NODE_BIN → PATH → known install dirs → nvm; one actionable line + exit 1 when none is found. 1,055 hook runs had died silently with `node: command not found`. Also runs the SESSION's checkout's copy of a hook when the session sits in a worktree, since Claude Code points $CLAUDE_PROJECT_DIR at the main checkout (task 1005015; off-switch OTB_HOOKS_FROM_PROJECT_DIR=1)
465
465
  ├── edit-hints.js ← PostToolUse (Edit|Write|MultiEdit): lints a saved SKILL.md's frontmatter (scripts/bongos/skill-lint.js) and names the generator an edited path makes stale (copy-registry, repo-map blocks, file-map, openapi, §13 snippet) with its command (task 1003548)
466
466
  ├── git-guard.js ← PreToolUse (Bash|PowerShell): same contract as secret-gate — blocks `git stash` (repo-global stack, learning 1000215), raw `git worktree remove` (follows the node_modules junction, task 1002809), `git push origin main` (PR-only) and `git branch -D`, each with its remedy; kill-switch BONGOS_GIT_GUARD_OFF=1 (task 1003365)
467
467
  ├── allow-rule-guard.js ← PreToolUse (PowerShell): a command that names something the project's allow-list pre-approves ASKS unless it is PLAIN — command names, bare-word arguments, `$name` reads, literal strings, `; | && ||`, `2>&1` / `> $null`, and nothing else. An allowlist of shape, not a denylist of tricks (the denylist cut was evaded eleven ways in review). Never blocks, fails open, silent for commands nobody pre-allowed. Exists because the client ordering that already does this for PowerShell is undocumented (ADR 0304 amendment, task 1004014); kill-switch BONGOS_ALLOW_RULE_GUARD_OFF=1
@@ -483,7 +483,8 @@ To install on a new machine, symlink each routine's directory under `~/.claude/s
483
483
  ├── stuck-strikes.js ← shared helper, not a hook: the per-session strike counter (hashed signatures in os.tmpdir()) + the static instruction text; stuck-detector.js, git-guard.js and worktree-guard.js all count through it (task 1003990)
484
484
  ├── pre-compact.js ← PreCompact: thin reader around eviction-policy.js — emits an eviction directive (blocks to drop + one-line recovery stubs) at the compaction seam (task 1349)
485
485
  ├── eviction-policy.js ← pure deterministic in-session compaction classifier (transcript turns → eviction set + replacement stubs); no I/O, unit-tested in tests/eviction_policy.mjs; consumed by pre-compact.js (task 1348)
486
- └── stop-refcheck.js ← Stop: deterministic backstop that catches a bare `#NNN` Bongos ref in live session text (autolinks to a 404 GitHub issue) and asks for the clickable form (follow-on to task 929)
486
+ ├── stop-refcheck.js ← Stop: deterministic backstop that catches a bare `#NNN` Bongos ref in live session text (autolinks to a 404 GitHub issue) and asks for the clickable form (follow-on to task 929)
487
+ └── stop-slopcheck.js ← Stop: when the agent's last message reverses an earlier belief ("turns out", "I was wrong"), asks once whether a doc/hook/output misled it — the Slop Bongo rule; words from src/bongos/agent-standing-rules.js, with a local copy held equal by tests for a checkout whose core cannot load; reads only the transcript tail (task 1005015)
487
488
  ```
488
489
 
489
490
  > Restored in task 1003365 from the box's pre-re-seed checkout: the tree was lost when core was re-seeded to 1.18.0 (task 1003272 found the sound half; this brought back the rest). `stop-sound.js` was NOT restored — `scripts/bongos/turn-end-sound.js` superseded it. Every hook above is wired in `.claude/settings.json`, which is the authority on what actually runs.
@@ -3266,7 +3266,7 @@ is load-bearing: the script throws rather than guess if it is missing, and
3266
3266
  landed since 1.24.0 with no explicit bump. run 40985289858. (task 1002620)
3267
3267
  1.24.2 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
3268
3268
  landed since 1.24.1 with no explicit bump. run 41000649913. (task 1002620)
3269
- 1.24.3 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
3270
- landed since 1.24.2 with no explicit bump. run 41001671514. (task 1002620)
3269
+ 1.24.5 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
3270
+ landed since 1.24.2 with no explicit bump. run 41006914357. (task 1002620)
3271
3271
  ---------------------------------------------------------------------------
3272
3272
  ```
@@ -4300,7 +4300,7 @@
4300
4300
  "surface": "builders",
4301
4301
  "title": "Tweak a page",
4302
4302
  "states_read": ["doc","typed","chrome","submitted","picking","out"],
4303
- "files_hash": "a2b68a2fa0504a35",
4303
+ "files_hash": "6ea8b7ad13d0121d",
4304
4304
  "reading_hash": "711c540ebc7ef977",
4305
4305
  "counts": {"lines":23,"placed":15,"shared":1,"unplaced":7},
4306
4306
  "omitted": {"data":35},