@bongos/core 1.17.1 → 1.17.2

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 (164) hide show
  1. package/.bongos-core.json +244 -264
  2. package/.claude/skills/blocker-review/SKILL.md +1 -1
  3. package/.claude/skills/builder-claim/SKILL.md +2 -0
  4. package/.claude/skills/builder-exit/SKILL.md +2 -2
  5. package/.claude/skills/builder-redteam/SKILL.md +3 -3
  6. package/.claude/skills/builder-setup/SKILL.md +2 -2
  7. package/.claude/skills/builder-start/SKILL.md +1 -1
  8. package/.claude/skills/dev/SKILL.md +1 -1
  9. package/.claude/skills/idea-triage/SKILL.md +2 -2
  10. package/.claude/skills/ideate/SKILL.md +1 -1
  11. package/.claude/skills/merge-mode/SKILL.md +1 -1
  12. package/.claude/skills/new-project/SKILL.md +3 -0
  13. package/.claude/skills/paint/SKILL.md +1 -1
  14. package/GOVERNANCE.md +1 -1
  15. package/README.md +1 -1
  16. package/docs/adr/0001-stack-choice-single-vps.md +1 -1
  17. package/docs/adr/0008-google-chat-oauth-user-auth.md +1 -1
  18. package/docs/adr/0019-red-team-bounty-payout-table.md +3 -3
  19. package/docs/adr/0020-security-model-public-stub.md +1 -1
  20. package/docs/adr/0023-kind-multipliers-and-idea-bonus.md +1 -1
  21. package/docs/adr/0024-cloneable-repo-local-first-memory.md +1 -1
  22. package/docs/adr/0026-bfg-memory-hygiene-and-cross-builder-learning.md +4 -4
  23. package/docs/adr/0027-bfg-session-inefficiency-evaluator.md +3 -3
  24. package/docs/adr/0030-builders-hall-live-updates.md +1 -1
  25. package/docs/adr/0031-cloud-dev-environments-for-builders.md +4 -4
  26. package/docs/adr/0032-discord-mirror-of-gds.md +2 -2
  27. package/docs/adr/0034-thetes-graduated-newcomer-rank.md +1 -1
  28. package/docs/adr/0044-mediterranean-palette-replacement.md +1 -1
  29. package/docs/adr/0044-per-box-live-game-preview.md +1 -1
  30. package/docs/adr/0054-session-token-reward-cost-plus.md +10 -10
  31. package/docs/adr/0057-container-cost-ledger.md +3 -3
  32. package/docs/adr/0062-medusa-instance-model-decoupling.md +4 -4
  33. package/docs/adr/0065-agpl-nonprofit-ai-first-governance.md +2 -2
  34. package/docs/adr/0085-remove-default-per-builder-spend-cap.md +1 -1
  35. package/docs/adr/0086-goal-scoped-work-hierarchy.md +1 -1
  36. package/docs/adr/0096-require-reward-before-workable.md +9 -9
  37. package/docs/adr/0097-retroactive-reward-backfill.md +3 -3
  38. package/docs/adr/0100-two-repo-instance-model.md +1 -1
  39. package/docs/adr/0101-goal-hierarchy-phase-5-judge-membership-reward.md +3 -3
  40. package/docs/adr/0103-core-first-extraction-cloud-bongos-trunk.md +3 -3
  41. package/docs/adr/0107-module-upstreaming-contribution-to-core-catalog.md +1 -1
  42. package/docs/adr/0120-pay-on-land-and-builder-owned-rebase-gate.md +6 -6
  43. package/docs/adr/0136-update-channel-subscription-policy.md +51 -0
  44. package/docs/adr/0137-upstream-publish-policy-manual-owner-gated.md +40 -0
  45. package/docs/adr/0138-bundled-module-deps-declared-per-module.md +45 -0
  46. package/docs/adr/README.md +9 -6
  47. package/docs/architecture.md +2 -2
  48. package/docs/branding-contract.md +5 -4
  49. package/docs/canonical-permissions.md +1 -1
  50. package/docs/design/vanilla-hall-ui-redesign-scope.md +1 -1
  51. package/docs/file-map.md +18 -17
  52. package/docs/handoff-template.md +2 -2
  53. package/docs/modules-contract.md +6 -1
  54. package/docs/onboarding/diagrams/README.md +7 -7
  55. package/docs/onboarding/drachmae-and-karma.md +18 -18
  56. package/docs/onboarding/primer.md +9 -9
  57. package/docs/recipes/audit-replay.md +2 -2
  58. package/docs/recipes/builder-box-lifecycle.md +2 -2
  59. package/docs/recipes/claude-design-loop.md +1 -1
  60. package/docs/recipes/ops-gotchas.md +1 -1
  61. package/docs/recipes/private-npm-distribution.md +17 -0
  62. package/docs/recipes/staging-environment.md +1 -1
  63. package/docs/recipes/upgrading-the-core.md +55 -0
  64. package/docs/research/cursor-competitive-analysis.md +1 -1
  65. package/docs/research/llm-model-agnostic-and-cheaper-grader.md +1 -1
  66. package/modules/discord/module.json +2 -1
  67. package/modules/economy/achievements.js +9 -1
  68. package/modules/economy/credits.js +10 -1
  69. package/modules/hall-ui/public/builders.js +71 -4
  70. package/modules/hall-ui/public/goal-inbox.js +191 -0
  71. package/modules/hall-ui/public/hall-widgets.js +14 -1
  72. package/modules/hall-ui/public/index.html +3 -0
  73. package/modules/hall-ui/public/new-project-wizard.js +1 -0
  74. package/modules/hall-ui/public/style.css +43 -0
  75. package/modules/provisioning/CLAUDE.md +15 -0
  76. package/modules/provisioning/migrations/provisioning_001_tables.sql +160 -0
  77. package/modules/provisioning/migrations/provisioning_002_standalone_shape.sql +11 -0
  78. package/modules/provisioning/migrations/provisioning_003_github_app_manifest.sql +95 -0
  79. package/modules/provisioning/module.json +17 -0
  80. package/modules/provisioning/onboard-plan.js +37 -0
  81. package/modules/provisioning/provisioning.js +539 -0
  82. package/modules/provisioning/rate-limit.js +35 -0
  83. package/modules/provisioning/routes/provisioning.js +607 -0
  84. package/modules/provisioning/tests/provisioning.mjs +232 -0
  85. package/modules/provisioning/ui/.gitkeep +0 -0
  86. package/modules/security/secret-scrub.js +10 -0
  87. package/package-lock.json +2 -2
  88. package/package.json +7 -2
  89. package/scripts/discord/README.md +1 -1
  90. package/scripts/gds/claim.js +98 -48
  91. package/scripts/gds/claude-materialize.js +30 -9
  92. package/scripts/gds/cutover-codemod.js +241 -0
  93. package/scripts/gds/fitness.js +54 -0
  94. package/scripts/gds/init.js +59 -3
  95. package/scripts/gds/lint-infra-exec.js +70 -0
  96. package/scripts/gds/lint-workflow-exec.js +63 -0
  97. package/scripts/gds/mirror-lineage-check.js +14 -5
  98. package/scripts/gds/mirror-redact.js +8 -0
  99. package/scripts/gds/onboard.js +4 -0
  100. package/scripts/gds/package-core.js +18 -3
  101. package/scripts/gds/publish-manifest.js +60 -2
  102. package/scripts/gds/run-routine.js +51 -13
  103. package/scripts/gds/run-unit-tests.js +4 -0
  104. package/scripts/gds/update-channel.js +186 -0
  105. package/scripts/gds/upgrade.js +116 -9
  106. package/src/bongos/auth.js +14 -1
  107. package/src/bongos/serve-internal.js +10 -1
  108. package/src/branding.js +1 -0
  109. package/src/module-api.js +12 -1
  110. package/src/module-loader/loader.js +36 -4
  111. package/src/module-loader/manifest-schema.js +16 -1
  112. package/tests/branding.mjs +11 -0
  113. package/tests/claim_error_surface.mjs +107 -0
  114. package/tests/claude_materialize.mjs +20 -0
  115. package/tests/consumer_layout_boot.mjs +302 -0
  116. package/tests/cutover_codemod.mjs +184 -0
  117. package/tests/device_flow_start.mjs +25 -2
  118. package/tests/hook_core_resolve.mjs +125 -0
  119. package/tests/infra_exec_paths.mjs +104 -0
  120. package/tests/init.mjs +47 -0
  121. package/tests/mirror_lineage_proof.mjs +14 -0
  122. package/tests/module_loader.mjs +42 -0
  123. package/tests/module_manifest.mjs +19 -0
  124. package/tests/onboard.mjs +13 -0
  125. package/tests/package_core.mjs +8 -0
  126. package/tests/provisioning_github_app_routes.mjs +15 -0
  127. package/tests/publish_manifest.mjs +52 -1
  128. package/tests/run_routine.mjs +26 -1
  129. package/tests/run_routine_two_root.mjs +77 -0
  130. package/tests/scrubber_corpus.mjs +17 -0
  131. package/tests/update_channel.mjs +186 -0
  132. package/tests/upgrade.mjs +131 -0
  133. package/tests/workflow_exec_paths.mjs +98 -0
  134. package/docs/design/container-exterior-tiles.md +0 -49
  135. package/docs/design/container-exterior.md +0 -81
  136. package/docs/design/container-interior.md +0 -77
  137. package/docs/design/world-map-scroll.md +0 -41
  138. package/docs/recipes/claude-gemini-bongos-doors.md +0 -155
  139. package/docs/recipes/cloudbongos-staging-gate.md +0 -139
  140. package/docs/recipes/cloudbongos-standup.md +0 -111
  141. package/docs/recipes/parallel-load-results-2026-05-30.md +0 -63
  142. package/docs/recipes/parallel-load-test.md +0 -32
  143. package/docs/recipes/pixel-art-pipeline.md +0 -411
  144. package/docs/recipes/staging-data.md +0 -50
  145. package/migrations/instance/018_pms_v3_planning_seed.sql +0 -131
  146. package/migrations/instance/080_gds_v4_planning_seed.sql +0 -75
  147. package/migrations/instance/110_medusa_planning_seed.sql +0 -70
  148. package/migrations/instance/120_bongos_v1_planning_seed.sql +0 -69
  149. package/migrations/instance/144_bongos_v1_module_system_criterion.sql +0 -26
  150. package/migrations/instance/159_bongos_v1_goal_hierarchy_criterion.sql +0 -29
  151. package/migrations/instance/172_v2_world_planning_seed.sql +0 -163
  152. package/migrations/instance/173_bongos_v1_c7_core_modularized.sql +0 -33
  153. package/migrations/instance/182_gdsv4_bongos_consolidation.sql +0 -132
  154. package/migrations/instance/183_gdsv4_carryover_themed_goals.sql +0 -116
  155. package/migrations/instance/186_bongos_v1_governance_planning_seed.sql +0 -69
  156. package/scripts/gds/art-stage.js +0 -152
  157. package/server.js +0 -212
  158. package/tests/art_key.mjs +0 -121
  159. package/tests/day_cycle.mjs +0 -197
  160. package/tests/snapshot_picker.mjs +0 -233
  161. package/tests/sprite_facing.mjs +0 -35
  162. package/tests/terrain_picker.mjs +0 -298
  163. package/tests/turn_in_place.mjs +0 -280
  164. package/tests/walkability.mjs +0 -188
@@ -3,7 +3,7 @@ name: blocker-review
3
3
  description: Daily review of open GDS blockers — surface each, prompt the user to resolve, escalate, or note continued blockage. Resolving a blocker auto-promotes any linked tasks from blocked → ready (DB trigger). Triggers when the user says "/blocker-review", "review blockers", "what's stuck on me", "what's stuck on Lars", "check blockers", or runs as a scheduled daily task. Metic+ rank only (Metic and Archon; not Xenos).
4
4
  ---
5
5
 
6
- You are running the daily blocker-review session for Off the Boats. Open blockers in the GDS `blockers` table get surfaced one-at-a-time, with prompts for the user to take action — resolve, escalate, or confirm still-blocked.
6
+ You are running the daily blocker-review session for Example. Open blockers in the GDS `blockers` table get surfaced one-at-a-time, with prompts for the user to take action — resolve, escalate, or confirm still-blocked.
7
7
 
8
8
  This is the structural cure for the old "task #3 sat in `blocked` for days because nobody flipped it after the blocker was resolved" pattern. Phase 2a's BEFORE-UPDATE trigger auto-promotes linked tasks the moment a blocker is marked resolved. This skill is what makes sure resolutions actually get marked.
9
9
 
@@ -25,6 +25,8 @@ A CLI session may hold **at most one active claim at a time**, and that claim sh
25
25
 
26
26
  The server now **enforces** the one-claim half (task 1642): `POST /api/gds/claims` refuses a second claim when the **same session** already holds an active one, returning `409 session_already_has_active_claim` (the body names the in-flight task id + title). This is session-scoped (a builder may still run several sessions in parallel, each with its own worktree and its own single claim) and fail-closed. So the **default claim flow must put the task in a fresh worktree** — never reuse a worktree that already owns a claim.
27
27
 
28
+ **One-claim-per-session is NOT "only one task at a time."** To work several tasks in parallel you have two supported paths, and the CLI refusal now names both (task 1476): (a) open a **separate worktree/session per task** — each holds its own single claim and ships its own clean branch; or (b) use the **hall work board's multi-select bulk-claim** to claim a set at once. Over-claiming is still discouraged — a pile of slow, unfinished claims blocks others and the stale-claim sweep auto-releases idle ones — but the limit is one claim *per session*, not one task *per builder*.
29
+
28
30
  **Default flow — claim into a dedicated worktree:**
29
31
 
30
32
  1. **Ensure a dedicated worktree for this task** before claiming. If the harness exposes a worktree primitive (e.g. `EnterWorktree` named `task-N`), enter a worktree named for the task id so this claim gets its own branch and never reuses a busy worktree. If you are already in a clean, claim-free worktree dedicated to this task, stay in it. If the current worktree already holds another active claim, do **not** claim here — open a new worktree/session first (the server will refuse otherwise).
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: builder-exit
3
- description: Gracefully offboard (or reactivate) a builder. Deactivating releases their active claims, seals each with a final session log, drops their rank to the sandboxed Xenos tier, blocks them from claiming new work, and archives their local memory — all while preserving their drachmae, credit history, and shipped-task attribution indefinitely. Triggers when the user says "/builder-exit N", "offboard builder N", "builder X is leaving", "deactivate builder", or "reactivate builder N". Archon-only — the offboard endpoint is Archon-gated. If a non-Archon, or anyone who just wants to end their own session, invokes it, redirect them to /builder-end (the session close-out) instead of dead-ending on a 403.
3
+ description: Gracefully offboard (or reactivate) a builder. Deactivating releases their active claims, seals each with a final session log, drops their rank to the sandboxed Xenos tier, blocks them from claiming new work, and archives their local memory — all while preserving their example, credit history, and shipped-task attribution indefinitely. Triggers when the user says "/builder-exit N", "offboard builder N", "builder X is leaving", "deactivate builder", or "reactivate builder N". Archon-only — the offboard endpoint is Archon-gated. If a non-Archon, or anyone who just wants to end their own session, invokes it, redirect them to /builder-end (the session close-out) instead of dead-ending on a 403.
4
4
  ---
5
5
 
6
6
  **Script skill (authoritative).** The core action is the `PATCH /api/gds/builders/:id/status` API call via `cli-lib.js`. Once intent is confirmed, run it and print the response verbatim — do not summarize or editorialize the claims-released list.
@@ -24,7 +24,7 @@ Deactivating a builder via `PATCH /api/gds/builders/:id/status { status: 'inacti
24
24
  1. **Releases every active claim** they hold (`released_at = now`, outcome `abandoned`) and bounces each in-flight task back to `ready` so the work isn't stranded.
25
25
  2. **Seals an outstanding session log** for each released claim (a closing `abandoned`-on-exit row — the audit trail shows the work was handed back, not silently dropped).
26
26
  3. **Drops their rank to `xenos`** (the sandboxed tier) and sets `status = 'inactive'`, which **blocks them from claiming any new task** (the claim path refuses with `BUILDER_INACTIVE`).
27
- 4. **Preserves everything else**: drachmae (`total_credits`), the full `credit_log`, their shipped tasks, and historical session logs all stay, attributed to them, indefinitely.
27
+ 4. **Preserves everything else**: example (`total_credits`), the full `credit_log`, their shipped tasks, and historical session logs all stay, attributed to them, indefinitely.
28
28
  5. Writes an interim audit row to `credit_log` (`delta=0`, reason carries the actor) until the dedicated `audit_log` lands (R36).
29
29
 
30
30
  Reactivation (`{ status: 'active' }`) flips them back to active. **Rank is not auto-restored** — it stays `xenos`, and an Archon re-promotes deliberately via `/builder-exit`'s sibling rank endpoint (`PATCH /api/gds/builders/:id/rank`).
@@ -3,14 +3,14 @@ name: builder-redteam
3
3
  description: File a red-team / vulnerability report against the city. Walks the builder through severity, target, title, repro, expected vs. actual, then POSTs to /api/gds/security/reports so the Archon view picks it up. Optionally drafts a follow-up idea_inbox entry for the fix. Triggers when the user says "/builder-redteam", "I found a security issue", "redteam report", "file a vuln", or describes a flaw in the system's own walls. Metic+ only — Xenos see a polite refusal.
4
4
  ---
5
5
 
6
- You are filing a vulnerability report on the Off the Boats project. The reporter is a trusted builder who has found a flaw — in the GDS, the game server, the chat broadcast, the deploy chain, the auth model — and wants the red-team bounty surface to pick it up.
6
+ You are filing a vulnerability report on the Example project. The reporter is a trusted builder who has found a flaw — in the GDS, the game server, the chat broadcast, the deploy chain, the auth model — and wants the red-team bounty surface to pick it up.
7
7
 
8
8
  This is the **bounty intake** side of V3.R63/R64/R67. Once the report is filed:
9
9
 
10
10
  - it lands in `vulnerability_reports.status='open'`;
11
11
  - the Archon view at `/builders` (R67) surfaces it for adjudication;
12
12
  - the auto-repro subagent (V3.R68, when live) will attempt to reproduce it;
13
- - if confirmed, the city pays out drachmae by severity.
13
+ - if confirmed, the city pays out example by severity.
14
14
 
15
15
  The reporter does NOT need Archon attention to file. The Archon comes to the queue, not the other way around.
16
16
 
@@ -72,7 +72,7 @@ After a successful filing, tell the user:
72
72
  ```
73
73
  Report #<id> filed at severity=<sev>, status=open.
74
74
  Visible now in /builders → Watch of the City (Archon view).
75
- Bounty if confirmed: <drachmae> (see /public/bounty-table).
75
+ Bounty if confirmed: <example> (see /public/bounty-table).
76
76
  An automated subagent will attempt to reproduce within the hour (R68);
77
77
  the Archon will adjudicate after that.
78
78
  ```
@@ -1,9 +1,9 @@
1
1
  ---
2
2
  name: builder-setup
3
- description: One-time setup for a new builder on the Off the Boats project management system. Triggers when the user says "/builder-setup", "set up builder", "register me", "set up GDS", or when a builder slash command fails with "no GDS session." Authenticates the user against GitHub via Device Flow and stores a session token at ~/.config/otb/gds-session.json so future /builder-* commands work. If a valid session already exists for another account on this machine, setup.js asks whether to continue as that builder or sign in as a different one (multi-builder-on-one-device gate).
3
+ description: One-time setup for a new builder on the Example project management system. Triggers when the user says "/builder-setup", "set up builder", "register me", "set up GDS", or when a builder slash command fails with "no GDS session." Authenticates the user against GitHub via Device Flow and stores a session token at ~/.config/otb/gds-session.json so future /builder-* commands work. If a valid session already exists for another account on this machine, setup.js asks whether to continue as that builder or sign in as a different one (multi-builder-on-one-device gate).
4
4
  ---
5
5
 
6
- You are running the one-time setup that registers this Claude Code installation as a builder on the Off the Boats GDS.
6
+ You are running the one-time setup that registers this Claude Code installation as a builder on the Example GDS.
7
7
 
8
8
  ## Background
9
9
 
@@ -5,7 +5,7 @@ description: Start a Claude Code session by listing what tasks the builder can c
5
5
 
6
6
  **Script skill (authoritative).** The core action is `node scripts/gds/start.js [--widget]`. Run it and render its output verbatim — do not rebuild the table, reorder rows, or add a recap. The card is the summary.
7
7
 
8
- You are starting a working session on the Off the Boats project. Before any other work, you check the GDS to see what's claimable.
8
+ You are starting a working session on the Example project. Before any other work, you check the GDS to see what's claimable.
9
9
 
10
10
  ## Background
11
11
 
@@ -3,7 +3,7 @@ name: dev
3
3
  description: The engineering session — the operating playbook for engineer-discipline work (code, infra, the GDS itself, bugs, performance). Triggers when the user says "/dev", "let's build this", "work on this bug/feature", "start a dev session", or when a claimed task's discipline routes here (claim.js prints a directive to invoke /dev for engineer tasks). This is the project's DEFAULT build loop, written down — the baseline the other discipline modes (/ideate, /paint) invert from.
4
4
  ---
5
5
 
6
- You are running an **engineering session** for Off the Boats. Unlike `/ideate` (which flips *who drives*) and `/paint` (which flips *the medium*), this skill introduces no new dynamic — engineering **is** the default text-and-code loop. Its job is to make the standard explicit and keep you on it. Read it before working; lean on it most when you're new here or running autonomously.
6
+ You are running an **engineering session** for Example. Unlike `/ideate` (which flips *who drives*) and `/paint` (which flips *the medium*), this skill introduces no new dynamic — engineering **is** the default text-and-code loop. Its job is to make the standard explicit and keep you on it. Read it before working; lean on it most when you're new here or running autonomously.
7
7
 
8
8
  ## The loop: understand → scoped change → verify → ship
9
9
 
@@ -3,7 +3,7 @@ name: idea-triage
3
3
  description: Daily walk through the GDS idea_inbox — for each open idea, prompt to promote (→ task), discard, or merge with another idea. Triggers when the user says "/idea-triage", "triage ideas", "review the inbox", "walk the idea inbox", or runs as a scheduled daily task. Metic+ rank only (Metic and Archon; not Xenos).
4
4
  ---
5
5
 
6
- You are running the daily idea-triage session for Off the Boats. Open ideas in the GDS `idea_inbox` table get walked one-at-a-time and verdicted, so the inbox doesn't accumulate stale entries.
6
+ You are running the daily idea-triage session for Example. Open ideas in the GDS `idea_inbox` table get walked one-at-a-time and verdicted, so the inbox doesn't accumulate stale entries.
7
7
 
8
8
  ## Rank gate — Metic+ only
9
9
 
@@ -48,7 +48,7 @@ Before walking the list, **flesh out each open idea with a subagent** so the ver
48
48
  - **Fan-out cap:** develop up to **12** ideas per session (oldest-first — `captured_at` ascending). If there are more than 12 open, note "developed the 12 oldest; the rest are walked undeveloped" so nothing is silently dropped.
49
49
  - **One idea per subagent.** Give each subagent the idea's `id`, `title`, `body_md`, `kind`, and `captured_by`, and this instruction:
50
50
 
51
- > Flesh out this Off the Boats idea for an Archon triage verdict. Read the relevant code/docs to ground yourself (start from CLAUDE.md and the surfaces the idea touches). Return ONLY a JSON object with these keys: `summary` (one sentence, what integrating it actually means), `integration_surfaces` (array of files/areas it would touch), `open_questions` (array — the decisions a human must make before this can be a task), `challenges` (array — what's hard or unclear), `risks` (array — what could break or regress), `rough_effort` (one of `S`/`M`/`L`), `recommendation` (one of `promote`, `discard`, `merge:#<id>`, `needs-info`). Keep each array item to one line. Do not invent surfaces you didn't verify exist.
51
+ > Flesh out this Example idea for an Archon triage verdict. Read the relevant code/docs to ground yourself (start from CLAUDE.md and the surfaces the idea touches). Return ONLY a JSON object with these keys: `summary` (one sentence, what integrating it actually means), `integration_surfaces` (array of files/areas it would touch), `open_questions` (array — the decisions a human must make before this can be a task), `challenges` (array — what's hard or unclear), `risks` (array — what could break or regress), `rough_effort` (one of `S`/`M`/`L`), `recommendation` (one of `promote`, `discard`, `merge:#<id>`, `needs-info`). Keep each array item to one line. Do not invent surfaces you didn't verify exist.
52
52
 
53
53
  - **Collect the results into a development cache** keyed by idea id and write it to a temp file so the deterministic walker can also surface it:
54
54
 
@@ -3,7 +3,7 @@ name: ideate
3
3
  description: The ideation session — the operating playbook for ideator-discipline work. Triggers when the user says "/ideate", "let's ideate", "I want to brainstorm", "help me think through an idea", "start an ideation session", or when a claimed task's discipline routes here (claim.js prints a directive to invoke /ideate for ideator tasks). Inverts the usual dynamic: the human ideator drives, Claude is the sounding board. Open to any rank for FILING ideas (Xenos+ can capture; only Metic+ can triage).
4
4
  ---
5
5
 
6
- You are running an **ideation session** for Off the Boats. This is not the build-and-ship loop. Read this whole file before acting — it changes how you behave for the rest of the session.
6
+ You are running an **ideation session** for Example. This is not the build-and-ship loop. Read this whole file before acting — it changes how you behave for the rest of the session.
7
7
 
8
8
  ## The one rule that makes this different: you are the instrument, not the author
9
9
 
@@ -3,7 +3,7 @@ name: merge-mode
3
3
  description: Manual fallback for the auto-merge in /builder-ship. Walks every task at status='confirmed' (= verified but not yet on main) and runs the merge + smoke + deploy chain. Triggers when the user says "/merge-mode", "merge the queue", "land confirmed tasks", "land the queue", "do a merge run", or after a /builder-ship reported the auto-merge bailed.
4
4
  ---
5
5
 
6
- You are running the manual merge-mode session for Off the Boats. **`/merge-mode` is a rare last resort, not a routine sweep — and not something to push on other builders.** The server lands merges on its own: `/builder-ship` chains into auto-merge, green PRs auto-merge, a 5-min reconciler flips `confirmed → shipped`, and the [ADR 0082](../../../docs/adr/<redacted>.md) resolver self-heals generated-file conflicts. **Before running this skill, confirm the task is genuinely stuck** — still at `confirmed` more than ~5 minutes after its ship because of a conflict or regression the server couldn't auto-resolve. If you haven't waited for the sweep yet, stop and wait. This skill is for the strand that survives all of that — usually a cross-branch / non-generated-file conflict, a smoke regression, or a `--no-merge` ship.
6
+ You are running the manual merge-mode session for Example. **`/merge-mode` is a rare last resort, not a routine sweep — and not something to push on other builders.** The server lands merges on its own: `/builder-ship` chains into auto-merge, green PRs auto-merge, a 5-min reconciler flips `confirmed → shipped`, and the [ADR 0082](../../../docs/adr/<redacted>.md) resolver self-heals generated-file conflicts. **Before running this skill, confirm the task is genuinely stuck** — still at `confirmed` more than ~5 minutes after its ship because of a conflict or regression the server couldn't auto-resolve. If you haven't waited for the sweep yet, stop and wait. This skill is for the strand that survives all of that — usually a cross-branch / non-generated-file conflict, a smoke regression, or a `--no-merge` ship.
7
7
 
8
8
  The queue this skill works against is **tasks at status='confirmed'**. Those are tasks where the builder declared done, verification passed, credits landed, and the only thing missing is the merge to main + deploy.
9
9
 
@@ -70,10 +70,13 @@ For `standalone` this composes: allocate a port → `git pull` + `npm ci --omit=
70
70
 
71
71
  The instance's sign-in code is **unchanged** — a GitHub App's user token hits the same `GET /user` the OAuth-app flow did; GitHub simply ignores the extra `scope` param for Apps.
72
72
 
73
+ > **Terminal CLI only (task 2129):** the one-click GitHub App **cannot** have Device Flow enabled via the manifest (GitHub's manifest schema has no such field, and there's no API to toggle it after creation), but the terminal `bongos login` needs it. After approving, open the app (GitHub → **Settings** → **Developer settings** → **GitHub Apps** → your app), check **Enable Device Flow**, and save. **Web sign-in works without this** — it's only for the terminal CLI. If a builder hits `device_flow_disabled` on `bongos login`, the CLI error now names the exact settings page to fix it.
74
+
73
75
  **Fallback — create an OAuth app by hand.** If there's no control-plane hall (a lone standalone box) or you prefer manual: GitHub → **your account's** Settings → **Developer settings** → **OAuth Apps** → **New OAuth App**.
74
76
  > **Guidance the standup learned:** *Developer settings is under your **account**, not the repository* — this is the #1 place owners get stuck.
75
77
  - **Homepage URL:** `https://<domain>`
76
78
  - **Authorization callback URL:** `https://<domain>/api/gds/auth/web/callback` (PINNED — `auth.js` `WEB_REDIRECT_ORIGIN`; a sign-in begun on a `builders.` subdomain still calls back to the apex).
79
+ - **Enable Device Flow:** check **“Enable Device Flow”** on the app page and save — it's **off by default**, and the terminal `bongos login` needs it (web sign-in works without it) (task 2127/2129).
77
80
  - Copy the **Client ID**; click **Generate a new client secret** and copy it (GitHub shows it **once**). Then place it **VERIFIED, never by hand (task 1979)**:
78
81
 
79
82
  ```bash
@@ -3,7 +3,7 @@ name: paint
3
3
  description: The art session — the operating playbook for artist-discipline work. Triggers when the user says "/paint", "let's make art", "I want to work on a tile/sprite", "start an art session", or when a claimed task's discipline routes here (claim.js prints a directive to invoke /paint for artist tasks). Show-first, low-text: Claude communicates in pictures, not prose, and drives the existing pixel-art pipeline underneath.
4
4
  ---
5
5
 
6
- You are running an **art session** for Off the Boats. This is not the engineer's text-heavy build loop. Read this whole file before acting — it changes how you *communicate* for the rest of the session.
6
+ You are running an **art session** for Example. This is not the engineer's text-heavy build loop. Read this whole file before acting — it changes how you *communicate* for the rest of the session.
7
7
 
8
8
  ## The one rule that makes this different: communicate in pictures, not prose
9
9
 
package/GOVERNANCE.md CHANGED
@@ -8,7 +8,7 @@ Cloud Bongos is an **AI-first build platform**: a human owner sets scope and the
8
8
 
9
9
  1. **Open, free, and protected from capture.** Cloud Bongos is released as open source under the **GNU AGPL-3.0** ([`LICENSE`](LICENSE)). The AGPL's §13 (Remote Network Interaction) closes the hosted-closed-fork loophole: anyone who runs a modified Cloud Bongos as a network service must offer that service's complete source to its users. This is the anti-monopoly guarantee — the platform stays a commons even when it is *operated*, not just when it is shipped.
10
10
 
11
- 2. **Non-profit.** The project is **not monetized from its contributors**. No one pays to contribute, and no contribution is resold by the project as a proprietary add-on. The in-platform credit/drachmae economy is an **instance-internal** mechanism (an instance rewards its own builders from its own budget) — it is not the project monetizing the commons.
11
+ 2. **Non-profit.** The project is **not monetized from its contributors**. No one pays to contribute, and no contribution is resold by the project as a proprietary add-on. The in-platform credit/example economy is an **instance-internal** mechanism (an instance rewards its own builders from its own budget) — it is not the project monetizing the commons.
12
12
 
13
13
  3. **AI-first.** The expectation is that **AI agents write the code**. This is a documented norm, not a technical gate (see [CONTRIBUTING.md](CONTRIBUTING.md)). The whole methodology — the task lifecycle, the quality grader, the session economy — is designed around agents as the primary authors.
14
14
 
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Example
2
2
 
3
- A persistent, shared 16-bit pixel-art world — the e-commerce experience for [Off the Boats](https://example.com), powered by [Example](https://example.com).
3
+ A persistent, shared 16-bit pixel-art world — the e-commerce experience for [Example](https://example.com), powered by [Example](https://example.com).
4
4
 
5
5
  Project memory — architecture, scope, V1 limitations, future ideas, session log — lives in [`CLAUDE.md`](./CLAUDE.md). Read it before editing code.
6
6
 
@@ -6,7 +6,7 @@
6
6
 
7
7
  ## Context
8
8
 
9
- Off the Boats V1 needs a persistent shared world for up to 100 concurrent players, browser-played, tile-based, with real-money purchases. The total budget for build + first year is $5,000. Monthly recurring cost must stay low and bootstrap-friendly.
9
+ Example V1 needs a persistent shared world for up to 100 concurrent players, browser-played, tile-based, with real-money purchases. The total budget for build + first year is $5,000. Monthly recurring cost must stay low and bootstrap-friendly.
10
10
 
11
11
  We needed an architecture that:
12
12
 
@@ -24,7 +24,7 @@ We will use **User OAuth (as `lars@example.com`)**.
24
24
 
25
25
  ## Alternatives considered
26
26
 
27
- - **Service account with Chat App identity.** Cleanest separation (the bot is its own persona, posts under "Off the Boats Build Bot"). Requires registering the Chat App via Google Cloud's Chat API Configuration page, a "deployment ID," and Workspace admin permission to allow the service account into the space. More setup steps; the bot identity feels less personal for a small team chat where everyone knows Lars.
27
+ - **Service account with Chat App identity.** Cleanest separation (the bot is its own persona, posts under "Example Build Bot"). Requires registering the Chat App via Google Cloud's Chat API Configuration page, a "deployment ID," and Workspace admin permission to allow the service account into the space. More setup steps; the bot identity feels less personal for a small team chat where everyone knows Lars.
28
28
  - **Incoming webhook only (outbound, no auth dance).** Dramatically simpler — paste a URL, POST to it, message appears. Good enough for outbound milestone posts but **cannot read messages, threads, or reactions**. Rejected because the inbound feedback loop is half the value.
29
29
 
30
30
  ## Consequences
@@ -6,17 +6,17 @@
6
6
 
7
7
  ## Context
8
8
 
9
- GDS-V3's incentive structure (criterion C9) adds a **red-team bounty**: a builder who finds and reports a security vulnerability against the system earns drachmae for it. The mechanism that *files* a report (`vulnerability_reports`, R63 / [#282](https://example.com/builders#/task/282)) and the mechanism that *auto-confirms and pays* one (R68) both need to agree on a single thing — **how many drachmae a report is worth, given its severity.**
9
+ GDS-V3's incentive structure (criterion C9) adds a **red-team bounty**: a builder who finds and reports a security vulnerability against the system earns example for it. The mechanism that *files* a report (`vulnerability_reports`, R63 / [#282](https://example.com/builders#/task/282)) and the mechanism that *auto-confirms and pays* one (R68) both need to agree on a single thing — **how many example a report is worth, given its severity.**
10
10
 
11
11
  Without one authoritative table, each consumer would invent its own constants and they would drift. We also need the numbers to be **tunable** by an Archon (the only rank that controls economy levers): if the bounty proves too generous or too stingy in practice, adjusting it should be an environment change, not a code edit and redeploy.
12
12
 
13
- Drachmae are the project's in-world currency, stored as integer `delta` in `credit_log` (migrations/003_pms.sql). A bounty payout is therefore a plain integer count of drachmae in the same unit as a task's `credits_reward`. The "10c / 50c" shorthand in the task spec maps to 10 / 50 drachmae; there is no sub-drachma denomination.
13
+ Example are the project's in-world currency, stored as integer `delta` in `credit_log` (migrations/003_pms.sql). A bounty payout is therefore a plain integer count of example in the same unit as a task's `credits_reward`. The "10c / 50c" shorthand in the task spec maps to 10 / 50 example; there is no sub-drachma denomination.
14
14
 
15
15
  ## Decision
16
16
 
17
17
  We will define the bounty payout table in `src/bongos/security.js` as four **default** integer amounts, each overridable by an environment variable:
18
18
 
19
- | Severity | Default drachmae | Env override |
19
+ | Severity | Default example | Env override |
20
20
  |---|---|---|
21
21
  | low | 10 | `GDS_BOUNTY_LOW` |
22
22
  | medium | 50 | `GDS_BOUNTY_MEDIUM` |
@@ -44,7 +44,7 @@ The Example repo is on GitHub. Marking a single file private is awkward (git his
44
44
 
45
45
  ### This is not security-through-obscurity
46
46
 
47
- The defense doesn't depend on the ADR's secrecy. Every protection mentioned in the full ADR is independently enforced in code (rank middleware, audit log, input validation, etc.). Withholding the document raises the cost of an attacker's reconnaissance — it doesn't *create* the defense. The bounty table ([ADR 0019](<redacted>.md)) names the gain for the attacker who reverse-engineers it anyway: a high-severity finding pays out 1000 drachmae. The system *wants* serious red-teamers; what it doesn't want is to hand them the map for free.
47
+ The defense doesn't depend on the ADR's secrecy. Every protection mentioned in the full ADR is independently enforced in code (rank middleware, audit log, input validation, etc.). Withholding the document raises the cost of an attacker's reconnaissance — it doesn't *create* the defense. The bounty table ([ADR 0019](<redacted>.md)) names the gain for the attacker who reverse-engineers it anyway: a high-severity finding pays out 1000 example. The system *wants* serious red-teamers; what it doesn't want is to hand them the map for free.
48
48
 
49
49
  ## Alternatives considered
50
50
 
@@ -6,7 +6,7 @@
6
6
 
7
7
  ## Problem
8
8
 
9
- Every task in the GDS carries a `credits_reward` value (the in-world "drachmae" payout when the task ships). Before this ADR, that value was paid 1:1 regardless of task kind. A 40-credit `cleanup` ship and a 40-credit `bug` ship both landed exactly 40c. That's a problem for two reasons:
9
+ Every task in the GDS carries a `credits_reward` value (the in-world "example" payout when the task ships). Before this ADR, that value was paid 1:1 regardless of task kind. A 40-credit `cleanup` ship and a 40-credit `bug` ship both landed exactly 40c. That's a problem for two reasons:
10
10
 
11
11
  1. **It silently disincentivises the work we want more of.** Capturing a learning that prevents a future bug, resolving a blocker that was costing the builder days, or landing a decision/ADR are all *higher leverage* per builder-hour than the average feature. Paying them the same says "we don't care which you do." In practice we care a lot.
12
12
  2. **The idea_inbox economy was unfunded.** Anyone could capture an idea, get it triaged into a task, and the task's eventual shipper got 100% of the reward. The capturer earned 0 — even though the idea was the unblocker. Capturing felt like volunteer work.
@@ -57,7 +57,7 @@ A new table `builder_memory(builder_id, path, content TEXT, mtime, sha256, byte_
57
57
 
58
58
  Two trigger points, both transactional boundaries that already exist in the methodology:
59
59
 
60
- - **Push on `/builder-ship`.** After the ship completes successfully (drachmae landed, branch merged or queued), `scripts/gds/ship.js` walks `~/.claude/projects/<project>/memory/*` and calls `POST /api/gds/memory/sync` with each file. If the push fails, ship still succeeds — work is preserved in the GDS row, memory can be resynced next time. Progress visible to the builder ("syncing 3 memory files…"). This is what [#274](https://example.com/builders#/task/274) R55 implements.
60
+ - **Push on `/builder-ship`.** After the ship completes successfully (example landed, branch merged or queued), `scripts/gds/ship.js` walks `~/.claude/projects/<project>/memory/*` and calls `POST /api/gds/memory/sync` with each file. If the push fails, ship still succeeds — work is preserved in the GDS row, memory can be resynced next time. Progress visible to the builder ("syncing 3 memory files…"). This is what [#274](https://example.com/builders#/task/274) R55 implements.
61
61
  - **Pull on `SessionStart` hook + `/builder-start`.** A new hook (or extension of the existing `.claude/hooks/sync-env-local.sh` pattern) calls `GET /api/gds/memory/since?mtime=<local-newest>` and writes any files the server has that are newer than the local copy. This is what [#275](https://example.com/builders#/task/275) R56 implements.
62
62
 
63
63
  No background polling. No Claude-Code-side daemon. No mid-session sync. The two trigger points are predictable, debuggable, and align with the natural commit/restart boundaries builders already think in.
@@ -30,21 +30,21 @@ This ADR records the architecture and, critically, the **boundaries** that turn
30
30
 
31
31
  The BFG gains three capability clusters (6A / 6B / 6C), built as independently-shippable sub-phases. Two cross-cutting rules govern all of them:
32
32
 
33
- - **The BFG is a privileged *system* agent, not a rank bypass.** Its cross-builder powers are the existing Archon-forensic-read posture, extended to a narrow audited write. They are bound to a dedicated **BFG service principal** (a `builders` row flagged as system: cannot claim work, cannot earn drachmae) and are reachable *only* by that principal — never exposed on a self-serve route. No human or agent builder can ask the system to "read/write another builder's memory." **This is an enforcement requirement, not prose intent:** 6C.1's write endpoint must gate on the *exact principal identity*, not on rank — an Archon token (or any rank-escalated / stolen token) must be rejected at the write endpoint, and that refusal must be covered by a test. "Never exposed on a self-serve route" is a property the implementation has to encode, not a promise the ADR can keep on its own.
33
+ - **The BFG is a privileged *system* agent, not a rank bypass.** Its cross-builder powers are the existing Archon-forensic-read posture, extended to a narrow audited write. They are bound to a dedicated **BFG service principal** (a `builders` row flagged as system: cannot claim work, cannot earn example) and are reachable *only* by that principal — never exposed on a self-serve route. No human or agent builder can ask the system to "read/write another builder's memory." **This is an enforcement requirement, not prose intent:** 6C.1's write endpoint must gate on the *exact principal identity*, not on rank — an Archon token (or any rank-escalated / stolen token) must be rejected at the write endpoint, and that refusal must be covered by a test. "Never exposed on a self-serve route" is a property the implementation has to encode, not a promise the ADR can keep on its own.
34
34
  - **Every cross-builder operation — read *and* write — writes an `audit_log` row.** Writes are additionally **namespaced and attributed** so a builder can always see, and delete, exactly what the BFG put there. Nothing the BFG writes ever masquerades as the builder's own note.
35
35
 
36
36
  ### 6A — Hygiene (the original charter, widened)
37
37
 
38
38
  Read-only auditor. Findings land as `idea_inbox` rows (one per finding, like `overnight-code-review`) plus a `docs/audits/bfg-<date>.md` report. The BFG **never** auto-mutates code or DB state — it reports.
39
39
 
40
- - **Doc ↔ reality:** CLAUDE.md claims vs DB (`shipped` task IDs cited, version statuses, the rank enum, drachmae/karma model), `[[link]]` resolution, ADR cross-reference integrity + numbering gaps, `docs/file-map.md` vs the actual tree, onboarding-diagram `assertions.json` vs live facts.
40
+ - **Doc ↔ reality:** CLAUDE.md claims vs DB (`shipped` task IDs cited, version statuses, the rank enum, example/karma model), `[[link]]` resolution, ADR cross-reference integrity + numbering gaps, `docs/file-map.md` vs the actual tree, onboarding-diagram `assertions.json` vs live facts.
41
41
  - **Memory hygiene:** within each builder's *own* memory dir — dangling `[[links]]`, stale frontmatter, internal contradictions, duplicate facts (the same discipline the `consolidate-memory` skill applies, but agent-driven rather than human-invoked).
42
42
  - **DB cleanliness:** cached-counter vs ledger drift (`builders.karma` vs `karma_log`, `total_credits` vs `credit_log`), orphaned rows, long-stale `idea_inbox` / `blockers`. Reported, never silently "fixed."
43
43
 
44
44
  ### 6B — Cross-builder learning ("read the room")
45
45
 
46
46
  - **Read all builders' memory** through a BFG-principal-only, per-read audit-logged endpoint (same shape as the Archon forensic read).
47
- - **Score interaction quality** by blending objective GDS signals (ships, grader pass rate, rework/abandon rate, karma, drachmae, methodology adherence visible in `audit_log` + conductor traces) with memory-quality heuristics.
47
+ - **Score interaction quality** by blending objective GDS signals (ships, grader pass rate, rework/abandon rate, karma, example, methodology adherence visible in `audit_log` + conductor traces) with memory-quality heuristics.
48
48
  - **Extract *transferable* patterns** from top performers — working habits and durable lessons, **not** builder-specific secrets, PII, or anything that only makes sense in that builder's context.
49
49
  - **Propagate** as adoption suggestions to other builders (delivered via the 6C write path as clearly-marked BFG entries, or surfaced in the audit report).
50
50
 
@@ -76,7 +76,7 @@ The BFG runs as a `SKILL.md` scheduled routine (post-ship / pre-cron cadence) an
76
76
  | **6A.2** | Extend the auditor with memory-hygiene + DB cached-vs-ledger drift checks (still report-only). | Hygiene covers all three artifact classes. |
77
77
  | **6B.1** | BFG-principal-only, audit-logged cross-builder memory **read** endpoint + interaction-quality scorer. | "Read the room" exists; reuses the forensic-read audit pattern. |
78
78
  | **6B.2** | Transferable-pattern extraction from top performers + adoption-suggestion generation. | Good practice propagates; the "most creative experience" objective gets teeth. |
79
- | **6C.1** | Migration: BFG service principal (system builder, no-claim/no-drachmae) + cross-builder memory **write** endpoint (audited, namespaced, attributed) + `karma_log` reason `bfg_correction`. | The write substrate + trust-boundary exception land in one reviewable unit. |
79
+ | **6C.1** | Migration: BFG service principal (system builder, no-claim/no-example) + cross-builder memory **write** endpoint (audited, namespaced, attributed) + `karma_log` reason `bfg_correction`. | The write substrate + trust-boundary exception land in one reviewable unit. |
80
80
  | **6C.2** | Wire dream-writes + transparent corrections into the BFG routine; kill-switch; builder-visible attribution; delete affordance. | Dreams + correction work end-to-end, safely. |
81
81
  | **6C.3** | Update [ADR 0024-mas](<redacted>.md) Phase-6 row + CLAUDE.md MAS index line. (Deferred out of [#441](https://example.com/builders#/task/441) — `CLAUDE.md` / `0024` are held by the active Phase-4 claim `#439`.) | The index reflects the shipped BFG. |
82
82
 
@@ -5,7 +5,7 @@
5
5
  - **Deciders:** Lars Kristensen (Archon), Claude
6
6
  - **Track:** `internal` (GDS)
7
7
  - **Context tasks:** GDS-V4 **[#515](https://example.com/builders#/task/515)** (the capability umbrella) · **[#539](https://example.com/builders#/task/539)** (this design task — ADR + task breakdown only, no implementation; mirrors the design-only shape of [#441](<redacted>.md)).
8
- - **Extends:** [ADR 0024 — Multi-Agent System architecture](<redacted>.md) (the BFG is its Phase 6) · [ADR 0026 — The BFG charter](<redacted>.md) (this adds a **new capability cluster, 6D**, to the BFG's "best building experience" objective) · [ADR 0016 — Trust boundary](<redacted>.md) (narrowly extended — session detail now lives server-side and is BFG-readable across builders) · [ADR 0022 — Secrets policy](0022-secrets-policy.md) (scrubbing on upload). Touches `credit_log` (drachmae), `karma_log`, `builders` (rank + tenure), `task_grades` (the upsert-unique gap), `session_logs`.
8
+ - **Extends:** [ADR 0024 — Multi-Agent System architecture](<redacted>.md) (the BFG is its Phase 6) · [ADR 0026 — The BFG charter](<redacted>.md) (this adds a **new capability cluster, 6D**, to the BFG's "best building experience" objective) · [ADR 0016 — Trust boundary](<redacted>.md) (narrowly extended — session detail now lives server-side and is BFG-readable across builders) · [ADR 0022 — Secrets policy](0022-secrets-policy.md) (scrubbing on upload). Touches `credit_log` (example), `karma_log`, `builders` (rank + tenure), `task_grades` (the upsert-unique gap), `session_logs`.
9
9
 
10
10
  ## Context
11
11
 
@@ -39,7 +39,7 @@ When `/builder-ship` lands a task, `ship.js` locates the active Claude Code sess
39
39
  | `session_id` | the Claude Code `sessionId` |
40
40
  | `builder_id` | the shipping builder |
41
41
  | `task_ids[]` | task(s) shipped from this session |
42
- | `drachmae_earned` | the session's `credit_log` delta |
42
+ | `example_earned` | the session's `credit_log` delta |
43
43
  | `total_tokens` | summed transcript `usage` (input + output + cache) |
44
44
  | `duration_seconds` | transcript first→last timestamp (or `session_logs`) |
45
45
  | `started_at` / `ended_at` / `uploaded_at` | timestamps |
@@ -52,7 +52,7 @@ When `/builder-ship` lands a task, `ship.js` locates the active Claude Code sess
52
52
 
53
53
  The server stores and serves; it does **no analysis**. Two endpoints over `session_records`:
54
54
 
55
- - **Search/filter** by *session* fields (`drachmae_earned`, `total_tokens`, `duration`, the derived metrics) **and joined `builders` fields** — **tenure** (`now − created_at`), **rank**, **karma**, **drachmae** (`total_credits`). So queries like *"rank = Xenos AND tenure < 7d AND overhead > 0.7"* (onboarding friction) or *"karma top-decile"* (good-practice mining) are expressible against one corpus.
55
+ - **Search/filter** by *session* fields (`example_earned`, `total_tokens`, `duration`, the derived metrics) **and joined `builders` fields** — **tenure** (`now − created_at`), **rank**, **karma**, **example** (`total_credits`). So queries like *"rank = Xenos AND tenure < 7d AND overhead > 0.7"* (onboarding friction) or *"karma top-decile"* (good-practice mining) are expressible against one corpus.
56
56
  - **Fetch one session's** full scrubbed detail for deep-dive.
57
57
 
58
58
  Cross-builder reads are gated to the **BFG service principal** ([ADR 0026](<redacted>.md) §6B posture — the *exact principal identity*, not rank) and write an **`audit_log` row per read**. A builder may always read their *own* sessions self-serve. Filtering is plain SQL/keyword **for now** (semantic/vector deferred, consistent with [ADR 0024](<redacted>.md)/[0026](<redacted>.md)).
@@ -7,7 +7,7 @@
7
7
 
8
8
  ## Context
9
9
 
10
- The builders hall (`public-builders/`) fetched **every panel exactly once** at `DOMContentLoaded` via `loadAll()` and then never refreshed. Onboarding checklist, standing (drachmae/karma), claimable works, leaderboard, karma feed, bounty table — all frozen until the visitor manually reloaded. The only things that updated without a reload were the two buttons a builder clicks themselves (mark primer read, pick a craft).
10
+ The builders hall (`public-builders/`) fetched **every panel exactly once** at `DOMContentLoaded` via `loadAll()` and then never refreshed. Onboarding checklist, standing (example/karma), claimable works, leaderboard, karma feed, bounty table — all frozen until the visitor manually reloaded. The only things that updated without a reload were the two buttons a builder clicks themselves (mark primer read, pick a craft).
11
11
 
12
12
  The reported symptom: a builder runs `/builder-ship` in the terminal, the "Ship thy first work" onboarding step clears server-side, but the open hall tab keeps showing the stale checklist. The underlying gap is broader than onboarding — the page had **no live-update mechanism at all**.
13
13
 
@@ -87,10 +87,10 @@ Two rules dissolve the "front every box (linear cost) vs. gate by payment (barri
87
87
  | Stage | How they work | Org cost | Builder cost |
88
88
  |---|---|---|---|
89
89
  | **Newcomer** (Xenos / onboarding) | Org provisions an **auto-suspended starter box** so there is zero payment barrier to begin | A bounded ~$5/active-newcomer (suspends when idle; de-provisioned if dormant) | Just their Claude subscription |
90
- | **Proven** (graduated → Metic) | Keeps a box | Transitions toward $0 | **Self-funds** (own DO account, or org provisions + rebills via the `costs` table, deducted from drachmae/earnings) |
90
+ | **Proven** (graduated → Metic) | Keeps a box | Transitions toward $0 | **Self-funds** (own DO account, or org provisions + rebills via the `costs` table, deducted from example/earnings) |
91
91
  | **Established** | Own box, runs it how they like | **$0** | Self-funds (1099 own-tools) |
92
92
 
93
- The barrier to *start* is zero (org pays the first box, per the decision to **not** use Anthropic's Cloud VM for onboarding). Real cost attaches only to builders who are earning. **Scale math:** naïve 100 builders × $30 always-on ≈ $36k/yr (untenable); this model ≈ $0 ongoing + a small bounded starter-box pool. None of it needs new machinery — it rides the rank ladder, the onboarding funnel, the drachmae/credits system, and the cost-logging we already have.
93
+ The barrier to *start* is zero (org pays the first box, per the decision to **not** use Anthropic's Cloud VM for onboarding). Real cost attaches only to builders who are earning. **Scale math:** naïve 100 builders × $30 always-on ≈ $36k/yr (untenable); this model ≈ $0 ongoing + a small bounded starter-box pool. None of it needs new machinery — it rides the rank ladder, the onboarding funnel, the example/credits system, and the cost-logging we already have.
94
94
 
95
95
  ### 6. Security — the container is the rank-gated source-access boundary
96
96
 
@@ -141,7 +141,7 @@ The repo is **private** (today under a personal account — see §7; a move to a
141
141
 
142
142
  ## Open questions (flagged, not blocking)
143
143
 
144
- 1. **Per-builder box ownership transition.** Mechanics of moving a builder from the org-funded starter box to self-funding — recreate on their own DO account vs. org-provisions-and-rebills via the `costs` table. Lean: rebill-via-drachmae for simplicity; revisit.
144
+ 1. **Per-builder box ownership transition.** Mechanics of moving a builder from the org-funded starter box to self-funding — recreate on their own DO account vs. org-provisions-and-rebills via the `costs` table. Lean: rebill-via-example for simplicity; revisit.
145
145
  2. **Onboarding repo-access scoping.** ✅ **RESOLVED 2026-06-05 ([#600](https://example.com/builders#/task/600)) — rank-gated, server-issued, fetched-not-baked.** A Xenos box sparse-checks out only the safe surface; full creds arrive at graduation; the box fetches a scoped credential gated on live rank rather than holding a baked one. See the resolution note below.
146
146
  3. **Auto-suspend implementation.** ✅ **RESOLVED 2026-06-04 ([#598](https://example.com/builders#/task/598)) — snapshot-and-park, NOT Coder.** See the resolution note below.
147
147
  4. **Thin-device on-ramp friction.** ✅ **RESOLVED 2026-06-06 ([#701](https://example.com/builders#/task/701)) — box reports its pairing link UP to the GDS; the builder reads it from the web.** See §9.4 below.
@@ -219,4 +219,4 @@ Not yet created; listed so the build session has a starting decomposition.
219
219
  | Managed-settings + Remote Control service | Distribute the locked `sshConfigs`/`sshHostAllowlist`; always-on `claude rc` for thin devices | C1 |
220
220
  | Rank-gated source access | Box holds the scoped GitHub credential; access granted/revoked by rank; offboarding clawback | C2 / C7 / C9 |
221
221
  | Onboarding primer page ✅ | **Done** — the §"mental model" explainer lives in [`docs/onboarding/primer.md`](../onboarding/primer.md) § "Where your work runs" (extracted in the ADR 0035 rewrite, [#718](https://example.com/builders#/task/718); closed by task 601) | C1 |
222
- | Cost passthrough wiring | Org-funded starter → self-fund transition via `costs`/drachmae | cost |
222
+ | Cost passthrough wiring | Org-funded starter → self-fund transition via `costs`/example | cost |
@@ -1,7 +1,7 @@
1
1
  # ADR 0032 — Discord as a one-way mirror of the GDS (outbound broadcast moves off Google Chat)
2
2
 
3
3
  **Date:** 2026-06-04
4
- **Context:** GDS-V3, task [#607](https://example.com/builders#/task/607) (claim `#482`). Stands up a Discord server for Off the Boats / Example — one server, permission-walled into a player wing and a builder wing — and moves the ship-broadcast off Google Chat. Companion to [ADR 0016](<redacted>.md) (the trust boundary — the load-bearing constraint here), [ADR 0018](<redacted>.md) (Xenos → Metic → Archon, the ranks Discord roles mirror), [ADR 0022](0022-secrets-policy.md) (webhook URLs are secrets, kept out of the repo), and [ADR 0008](0008-google-chat-oauth-user-auth.md) (the Google Chat broadcast this supersedes for outbound).
4
+ **Context:** GDS-V3, task [#607](https://example.com/builders#/task/607) (claim `#482`). Stands up a Discord server for Example / Example — one server, permission-walled into a player wing and a builder wing — and moves the ship-broadcast off Google Chat. Companion to [ADR 0016](<redacted>.md) (the trust boundary — the load-bearing constraint here), [ADR 0018](<redacted>.md) (Xenos → Metic → Archon, the ranks Discord roles mirror), [ADR 0022](0022-secrets-policy.md) (webhook URLs are secrets, kept out of the repo), and [ADR 0008](0008-google-chat-oauth-user-auth.md) (the Google Chat broadcast this supersedes for outbound).
5
5
  **Status:** Accepted. Phase 2 (outbound ship broadcast → Discord) implemented in [#607](https://example.com/builders#/task/607). Phases 3+ (interaction bot, inbound retirement, role sync) scoped below, not yet built.
6
6
  **Track:** `internal` (dev-system / team communication).
7
7
 
@@ -12,7 +12,7 @@ The project is opening to multiple builders (GDS-V3) and will eventually have pl
12
12
  Two existing surfaces are relevant:
13
13
 
14
14
  - The **ship broadcast** posts a plain-language "what shipped" summary to the Example team **Google Chat** space ([ADR 0008](0008-google-chat-oauth-user-auth.md); fired from `scripts/gds/ship.js` on deploy). Google Chat is a closed business space — fine for the Example owners, wrong as a builder+player community hub.
15
- - The **GDS** already holds all authoritative state: ranks, tasks, karma (`peer_upvote` is an existing reason), idea_inbox, drachmae, the builders' hall.
15
+ - The **GDS** already holds all authoritative state: ranks, tasks, karma (`peer_upvote` is an existing reason), idea_inbox, example, the builders' hall.
16
16
 
17
17
  The temptation, standing up Discord, is to let it *own* things — roles that grant power, votes that live in Discord, a second scoreboard. That would fracture the source of truth and — for roles — quietly punch a hole in the trust boundary.
18
18
 
@@ -50,4 +50,4 @@ The promotion reuses the existing rank-change machinery (refactored into a share
50
50
 
51
51
  - **Just raise the newcomer-queue target / fix supply only.** Treats the symptom. A shared pool of N newcomer tasks is always racing consumption; time-boxing the sandbox removes the dependency entirely for everyone past their 3rd ship.
52
52
  - **Auto-promote `xenos` straight to `metic`.** Rejected: Metic carries triage/trust/red-team/infra powers no automatic rule should hand out. The new intermediate rank is exactly the "breadth without trust" tier that makes auto-promotion safe.
53
- - **Promote by drachmae or karma instead of ship count.** Rejected for v1: ship count is the most legible "you've proven you can land work" signal and is already the credit-landing event. A richer policy can layer on later.
53
+ - **Promote by example or karma instead of ship count.** Rejected for v1: ship count is the most legible "you've proven you can land work" signal and is already the credit-landing event. A richer policy can layer on later.
@@ -38,7 +38,7 @@ Rationale (Lars's call, 2026-06-10):
38
38
  prompt must reason about *which* palette applies to *which* tile. That branching is exactly
39
39
  the kind of pipeline complexity the bootstrapped budget and the single-maintainer reality
40
40
  can't carry. One palette = one set of rules everywhere.
41
- - **The world has one look.** Off the Boats is a single, persistent, coherent world. There is
41
+ - **The world has one look.** Example is a single, persistent, coherent world. There is
42
42
  no "Poke Mart interior" context that needs the temperate palette — the FireRed colors were
43
43
  only ever scaffolding for the *structure*, never the intended final hues.
44
44
  - **The bias rule becomes the palette.** Today the style guide *nudges* generations toward
@@ -7,7 +7,7 @@
7
7
 
8
8
  ## Problem
9
9
 
10
- A builder working on the **game** (`public/`, `src/world/`, `src/rooms/`, the art tiles) has no way to *see their change running* before it ships. The only live instance of Off the Boats is production at `example.com`. So the loop today is: edit → ship through the grader/merge/deploy pipeline → look at prod. That is slow, it puts unreviewed game changes one mistake away from players, and a browser-only (Chromebook) builder has no local machine to run the game on at all.
10
+ A builder working on the **game** (`public/`, `src/world/`, `src/rooms/`, the art tiles) has no way to *see their change running* before it ships. The only live instance of Example is production at `example.com`. So the loop today is: edit → ship through the grader/merge/deploy pipeline → look at prod. That is slow, it puts unreviewed game changes one mistake away from players, and a browser-only (Chromebook) builder has no local machine to run the game on at all.
11
11
 
12
12
  What a builder wants is a **sandbox**: run the game live *on their own dev box* and open it in a browser to review the change — never touching the prod server.
13
13
 
@@ -1,4 +1,4 @@
1
- # ADR 0054 — Flat cost-plus session token reward (drachmae as equity)
1
+ # ADR 0054 — Flat cost-plus session token reward (example as equity)
2
2
 
3
3
  **Date:** 2026-06-13
4
4
  **Context:** GDS-V4, task [#1005](https://example.com/builders#/task/1005). Builds on [ADR 0023](<redacted>.md) (per-task kind-multiplied credits), [ADR 0028](<redacted>.md) (the `llm-pricing.js` token→USD table + session-cost capture), and [ADR 0027](<redacted>.md) (the `session_records` upload-on-ship path this reward rides). Complements — does **not** replace — the per-task `credits_reward × kind_multiplier` path. Related future work: the full-transcript capture ADR (planned, task [#1004](https://example.com/builders#/task/1004)) will give this reward a more trustworthy raw-usage source, and the token-feed hardening scoped in task [#1005](https://example.com/builders#/task/1005) itself.
@@ -7,13 +7,13 @@
7
7
 
8
8
  ## Problem
9
9
 
10
- We are about to onboard the first **incentivized** builders. Today the only payout is per-task `credits_reward` — a unitless number an author sets at task-creation time. It rewards declaring a big number, not doing expensive, real work. The owner's decision (2026-06-13) is to pay builders proportionally to the **true economic cost** of the work they did — the API token spend of the session — plus a margin, with drachmae standing in as **equity** in the project. It must go live today, be idempotent and reversible, and be impossible to inflate with a client-sent dollar figure.
10
+ We are about to onboard the first **incentivized** builders. Today the only payout is per-task `credits_reward` — a unitless number an author sets at task-creation time. It rewards declaring a big number, not doing expensive, real work. The owner's decision (2026-06-13) is to pay builders proportionally to the **true economic cost** of the work they did — the API token spend of the session — plus a margin, with example standing in as **equity** in the project. It must go live today, be idempotent and reversible, and be impossible to inflate with a client-sent dollar figure.
11
11
 
12
12
  ## Decision
13
13
 
14
14
  Per **shipped session** (the unit; per-task attribution is a later refinement — see the future-review trigger), grant a flat cost-plus reward:
15
15
 
16
- drachmae = round(true_cost_usd × (1 + REWARD_MARGIN_PCT/100) × 100) // integer cents
16
+ example = round(true_cost_usd × (1 + REWARD_MARGIN_PCT/100) × 100) // integer cents
17
17
  REWARD_MARGIN_PCT = 20
18
18
 
19
19
  - **`true_cost_usd` is computed SERVER-SIDE** from the per-model token counts the ship upload already carries (`session_records.model_usage`), priced via `src/bongos/llm-pricing.js` (the locked API list-price table). The client uploads token *counts*, never a dollar figure — that figure is never trusted from the client.
@@ -21,7 +21,7 @@ Per **shipped session** (the unit; per-task attribution is a later refinement
21
21
  - **Margin is a code constant** (`REWARD_MARGIN_PCT` in `src/bongos/db.js`), owner-changed via a commit, not a settings UI — the same review-trail rationale as `KIND_MULTIPLIERS` ([ADR 0023](<redacted>.md)). A future migration can promote it to a per-builder/per-version table if the economics ever need live tuning. No rank above Archon is introduced; the knob is an owner-scoped policy constant.
22
22
  - **Idempotent per `session_id`**: a new `credit_log.reason = 'session.token_reward'` row carries a `session_id` column backed by a partial-unique index, plus a SELECT fast-path guard inside the upsert transaction. Re-uploading the same session (re-ship, retry) is a true no-op — no double payout.
23
23
  - The existing per-task credit path is untouched. Both the token reward and per-task credits accrue to `builders.total_credits` via the existing `pms_apply_credit` trigger.
24
- - **Drachmae = equity units** (owner framing). No special code — it is the interpretation of `total_credits`.
24
+ - **Example = equity units** (owner framing). No special code — it is the interpretation of `total_credits`.
25
25
 
26
26
  ### Two drachma conventions, one ledger (the load-bearing tension)
27
27
 
@@ -32,12 +32,12 @@ We knowingly accept that a drachma now means two things on the same ledger: a *u
32
32
  A flat cost-plus reward pays **more** for a more expensive session — it can reward token *waste* (thrashing, re-reading, long unproductive loops) as much as productive spend. This was raised and explicitly accepted by the owner, for three reasons:
33
33
 
34
34
  1. **PASS-gated by construction.** Only a *successful ship* uploads a session record, so a session that burned tokens and shipped nothing earns nothing.
35
- 2. **Drachmae are equity, not cash.** A builder who pads cost dilutes a pool they themselves hold; the incentive to waste is bounded by the fact that the payout currency is ownership in the thing being built. Early builders want their percentage to be worth something, so they self-police. Inflating the denominator hurts the inflator.
35
+ 2. **Example are equity, not cash.** A builder who pads cost dilutes a pool they themselves hold; the incentive to waste is bounded by the fact that the payout currency is ownership in the thing being built. Early builders want their percentage to be worth something, so they self-police. Inflating the denominator hurts the inflator.
36
36
  3. **The waste signal already exists.** The BFG session-inefficiency evaluator ([ADR 0027](<redacted>.md)) flags wasteful sessions from the same uploaded digest; a later refinement can gate or discount the reward by a quality/efficiency factor, moving from flat cost-plus to cost-plus-adjusted-for-value. The owner's stated direction is to move toward **market dynamics** (bidding) once the builder pool is genuinely multi-party.
37
37
 
38
38
  ## Consequences
39
39
 
40
- - **Migration 090** adds `session_records.model_usage` + `session_records.token_reward_drachmae`, `credit_log.session_id` + the partial-unique index `uniq_credit_session_token_reward`, and bumps the migration counter.
40
+ - **Migration 090** adds `session_records.model_usage` + `session_records.token_reward_example`, `credit_log.session_id` + the partial-unique index `uniq_credit_session_token_reward`, and bumps the migration counter.
41
41
  - `llm-pricing.js` gains pure, tested `priceModelUsage` + `canonicalizeModelId`.
42
42
  - `db.js` gains `REWARD_MARGIN_PCT`, `computeSessionTokenReward`, `awardSessionTokenReward`, and the transactional `upsertSessionRecordWithReward` (the route now calls it instead of the bare upsert).
43
43
  - `scripts/gds/ship.js` accumulates per-model usage into the digest; `POST /api/gds/sessions` accepts `model_usage`, prices it, and returns `token_reward` on the 201.
@@ -50,14 +50,14 @@ Revisit when: (a) per-task token attribution lands (the unit becomes the task, n
50
50
 
51
51
  ## Amendment — 2026-06-15 (task [#1138](https://example.com/builders#/task/1138)): 1 drachma = $1
52
52
 
53
- **Trigger (c), partial.** An audit of the first incentivized builder's ledger (owner request) found the cents convention had inflated the balance ~100× (one builder, 31 sessions → 295,218 drachmae ≈ $2,952 of cost-plus) and that summing cents-denominated token rewards with the unitless per-task credits made the total incoherent. The owner's decision: **re-denominate the token reward so 1 drachma = $1**, not 1 cent.
53
+ **Trigger (c), partial.** An audit of the first incentivized builder's ledger (owner request) found the cents convention had inflated the balance ~100× (one builder, 31 sessions → 295,218 example ≈ $2,952 of cost-plus) and that summing cents-denominated token rewards with the unitless per-task credits made the total incoherent. The owner's decision: **re-denominate the token reward so 1 drachma = $1**, not 1 cent.
54
54
 
55
55
  **Change to the Decision formula** (supersedes the `× 100` in the formula above):
56
56
 
57
- drachmae = round(true_cost_usd × (1 + REWARD_MARGIN_PCT/100)) // whole drachmae, 1 drachma = $1
57
+ example = round(true_cost_usd × (1 + REWARD_MARGIN_PCT/100)) // whole example, 1 drachma = $1
58
58
  REWARD_MARGIN_PCT = 20 // unchanged
59
59
 
60
- - The trailing `× 100` (cents) is **dropped**. A $100 true-cost session now mints `round(100 × 1.20) = 120` drachmae (was 12,000). A sub-$0.42 session now rounds to 0 (was ~50) — intended.
60
+ - The trailing `× 100` (cents) is **dropped**. A $100 true-cost session now mints `round(100 × 1.20) = 120` example (was 12,000). A sub-$0.42 session now rounds to 0 (was ~50) — intended.
61
61
  - `computeSessionTokenReward` in `src/bongos/db.js` changed accordingly; `tests/credit_grant.mjs` updated; `llm-pricing.js` (the token→USD table) is **unchanged** — only the cents→dollars scale factor moved.
62
- - **History was re-denominated, not left mixed.** Per the "append-only, reversible" rule above, existing `session.token_reward` rows were **not mutated**; a single compensating `credit_log` row (`reason='redenominate.token_reward_dollars'`, `task_id` → [#1138](https://example.com/builders#/task/1138)) restates the running total from cents to dollars, and the `total_credits` trigger nets it automatically. The original cents rows remain as historical record; the `session_records.token_reward_drachmae` display mirror was divided by 100 to match. At amendment time builder `#1` (example-owner) was the only holder of token rewards, so this touched one builder.
62
+ - **History was re-denominated, not left mixed.** Per the "append-only, reversible" rule above, existing `session.token_reward` rows were **not mutated**; a single compensating `credit_log` row (`reason='redenominate.token_reward_dollars'`, `task_id` → [#1138](https://example.com/builders#/task/1138)) restates the running total from cents to dollars, and the `total_credits` trigger nets it automatically. The original cents rows remain as historical record; the `session_records.token_reward_example` display mirror was divided by 100 to match. At amendment time builder `#1` (example-owner) was the only holder of token rewards, so this touched one builder.
63
63
  - **The per-task `credits_reward` path (ADR 0023) is untouched** — it stays a unitless author estimate. The two-conventions tension (§"Two drachma conventions, one ledger") is now *narrower* (both paths read on a ~dollar scale) but not formally reconciled; trigger (c) remains open for a full reconciliation.
@@ -3,11 +3,11 @@
3
3
  **Date:** 2026-06-15
4
4
  **Status:** Accepted
5
5
  **Track:** `internal` (dev-system / cost oversight).
6
- **Context:** GDS-V3, task [#602](https://example.com/builders#/task/602), criterion C-cost. Implements the ledger half of ADR 0031 §5 (cost passthrough). Companion to [ADR 0031](<redacted>.md) (the dev box) and the early-stage billing policy ("tracked, not settled" — both drachmae earnings and container costs are recorded but not actually paid/charged yet).
6
+ **Context:** GDS-V3, task [#602](https://example.com/builders#/task/602), criterion C-cost. Implements the ledger half of ADR 0031 §5 (cost passthrough). Companion to [ADR 0031](<redacted>.md) (the dev box) and the early-stage billing policy ("tracked, not settled" — both example earnings and container costs are recorded but not actually paid/charged yet).
7
7
 
8
8
  ## Problem
9
9
 
10
- Builders run org-provisioned DigitalOcean dev boxes (ADR 0031). We want every box cost event recorded per builder — visible to the builder on their own profile and to the Archon for oversight — so the org can see what each box costs *before* any real self-fund/charge mechanism exists. No payment integration, no drachmae deduction yet.
10
+ Builders run org-provisioned DigitalOcean dev boxes (ADR 0031). We want every box cost event recorded per builder — visible to the builder on their own profile and to the Archon for oversight — so the org can see what each box costs *before* any real self-fund/charge mechanism exists. No payment integration, no example deduction yet.
11
11
 
12
12
  ## Decisions
13
13
 
@@ -24,5 +24,5 @@ Builders run org-provisioned DigitalOcean dev boxes (ADR 0031). We want every bo
24
24
  ## Consequences
25
25
 
26
26
  - The "compute" category in the public cost summary now also includes near-$0 spin-up rows; negligible.
27
- - When a real self-fund/charge mechanism lands (drachmae deduction or DO-account handoff), it reads this ledger — the data is already accruing.
27
+ - When a real self-fund/charge mechanism lands (example deduction or DO-account handoff), it reads this ledger — the data is already accruing.
28
28
  - Pure cost math (`storageCostUsd`, `summarizeBoxCost`) is unit-tested (`tests/box_cost.mjs`); the DB writers ride the box-lifecycle integration smoke.