@bongos/core 1.17.0 → 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.
- package/.bongos-core.json +363 -312
- package/.claude/skills/blocker-review/SKILL.md +1 -1
- package/.claude/skills/builder-claim/SKILL.md +2 -0
- package/.claude/skills/builder-exit/SKILL.md +2 -2
- package/.claude/skills/builder-redteam/SKILL.md +3 -3
- package/.claude/skills/builder-setup/SKILL.md +2 -2
- package/.claude/skills/builder-start/SKILL.md +1 -1
- package/.claude/skills/dev/SKILL.md +1 -1
- package/.claude/skills/idea-triage/SKILL.md +2 -2
- package/.claude/skills/ideate/SKILL.md +1 -1
- package/.claude/skills/merge-mode/SKILL.md +1 -1
- package/.claude/skills/new-project/SKILL.md +3 -0
- package/.claude/skills/paint/SKILL.md +1 -1
- package/CLAUDE.md +11 -238
- package/GOVERNANCE.md +1 -1
- package/README.md +1 -1
- package/bin/bongos.js +1 -0
- package/clients/bongos-client/README.md +4 -4
- package/clients/bongos-client/bongos-client.global.js +14 -1
- package/clients/bongos-client/index.cjs +14 -1
- package/clients/bongos-client/index.d.ts +19 -2
- package/clients/bongos-client/index.mjs +11 -1
- package/clients/bongos-client/package.json +1 -1
- package/docs/adr/0001-stack-choice-single-vps.md +1 -1
- package/docs/adr/0008-google-chat-oauth-user-auth.md +1 -1
- package/docs/adr/0019-red-team-bounty-payout-table.md +3 -3
- package/docs/adr/0020-security-model-public-stub.md +1 -1
- package/docs/adr/0023-kind-multipliers-and-idea-bonus.md +1 -1
- package/docs/adr/0024-cloneable-repo-local-first-memory.md +1 -1
- package/docs/adr/0026-bfg-memory-hygiene-and-cross-builder-learning.md +4 -4
- package/docs/adr/0027-bfg-session-inefficiency-evaluator.md +3 -3
- package/docs/adr/0030-builders-hall-live-updates.md +1 -1
- package/docs/adr/0031-cloud-dev-environments-for-builders.md +4 -4
- package/docs/adr/0032-discord-mirror-of-gds.md +2 -2
- package/docs/adr/0034-thetes-graduated-newcomer-rank.md +1 -1
- package/docs/adr/0044-mediterranean-palette-replacement.md +1 -1
- package/docs/adr/0044-per-box-live-game-preview.md +1 -1
- package/docs/adr/0054-session-token-reward-cost-plus.md +10 -10
- package/docs/adr/0057-container-cost-ledger.md +3 -3
- package/docs/adr/0062-medusa-instance-model-decoupling.md +4 -4
- package/docs/adr/0065-agpl-nonprofit-ai-first-governance.md +2 -2
- package/docs/adr/0085-remove-default-per-builder-spend-cap.md +1 -1
- package/docs/adr/0086-goal-scoped-work-hierarchy.md +1 -1
- package/docs/adr/0096-require-reward-before-workable.md +9 -9
- package/docs/adr/0097-retroactive-reward-backfill.md +3 -3
- package/docs/adr/0100-two-repo-instance-model.md +1 -1
- package/docs/adr/0101-goal-hierarchy-phase-5-judge-membership-reward.md +3 -3
- package/docs/adr/0103-core-first-extraction-cloud-bongos-trunk.md +3 -3
- package/docs/adr/0107-module-upstreaming-contribution-to-core-catalog.md +1 -1
- package/docs/adr/0120-pay-on-land-and-builder-owned-rebase-gate.md +6 -6
- package/docs/adr/0133-github-app-manifest-onboarding-signin.md +2 -0
- package/docs/adr/0134-private-first-npm-distribution.md +20 -6
- package/docs/adr/0135-module-upstream-submission-interim-queue.md +34 -0
- package/docs/adr/0136-update-channel-subscription-policy.md +51 -0
- package/docs/adr/0137-upstream-publish-policy-manual-owner-gated.md +40 -0
- package/docs/adr/0138-bundled-module-deps-declared-per-module.md +45 -0
- package/docs/adr/README.md +14 -10
- package/docs/api/openapi.json +315 -6
- package/docs/api-reference.md +10 -5
- package/docs/architecture.md +3 -3
- package/docs/branding-contract.md +5 -4
- package/docs/canonical-permissions.md +1 -1
- package/docs/design/vanilla-hall-ui-redesign-scope.md +1 -1
- package/docs/file-map.md +20 -19
- package/docs/handoff-template.md +2 -2
- package/docs/modules-contract.md +8 -1
- package/docs/onboarding/diagrams/README.md +7 -7
- package/docs/onboarding/drachmae-and-karma.md +18 -18
- package/docs/onboarding/primer.md +9 -9
- package/docs/recipes/audit-replay.md +2 -2
- package/docs/recipes/builder-box-lifecycle.md +2 -2
- package/docs/recipes/claude-design-loop.md +1 -1
- package/docs/recipes/instance-deploy.md +4 -4
- package/docs/recipes/instance-first-run.md +51 -0
- package/docs/recipes/ops-gotchas.md +1 -1
- package/docs/recipes/packaging-the-core.md +5 -5
- package/docs/recipes/private-npm-distribution.md +39 -12
- package/docs/recipes/self-host.md +1 -1
- package/docs/recipes/staging-environment.md +1 -1
- package/docs/recipes/upgrading-the-core.md +63 -8
- package/docs/research/cursor-competitive-analysis.md +1 -1
- package/docs/research/llm-model-agnostic-and-cheaper-grader.md +1 -1
- package/migrations/core_191_module_submissions.sql +45 -0
- package/modules/autonomy/CLAUDE.md +11 -45
- package/modules/builder-settings/CLAUDE.md +11 -54
- package/modules/dev-box/CLAUDE.md +11 -34
- package/modules/discord/CLAUDE.md +11 -46
- package/modules/discord/module.json +2 -1
- package/modules/economy/CLAUDE.md +11 -44
- package/modules/economy/achievements.js +9 -1
- package/modules/economy/credits.js +10 -1
- package/modules/grading/CLAUDE.md +11 -38
- package/modules/hall-ui/CLAUDE.md +11 -57
- package/modules/hall-ui/public/builders.js +71 -4
- package/modules/hall-ui/public/goal-inbox.js +191 -0
- package/modules/hall-ui/public/goals-page.js +227 -22
- package/modules/hall-ui/public/goals.html +16 -0
- package/modules/hall-ui/public/hall-widgets.js +14 -1
- package/modules/hall-ui/public/index.html +3 -0
- package/modules/hall-ui/public/new-project-wizard.js +6 -4
- package/modules/hall-ui/public/style.css +43 -0
- package/modules/ideas/CLAUDE.md +11 -33
- package/modules/lifecycle/CLAUDE.md +11 -59
- package/modules/lifecycle/routes/goals.js +80 -0
- package/modules/memory/CLAUDE.md +11 -36
- package/modules/onboarding/CLAUDE.md +11 -51
- package/modules/provisioning/CLAUDE.md +15 -0
- package/modules/provisioning/migrations/provisioning_001_tables.sql +160 -0
- package/modules/provisioning/migrations/provisioning_002_standalone_shape.sql +11 -0
- package/modules/provisioning/migrations/provisioning_003_github_app_manifest.sql +95 -0
- package/modules/provisioning/module.json +17 -0
- package/modules/provisioning/onboard-plan.js +37 -0
- package/modules/provisioning/provisioning.js +539 -0
- package/modules/provisioning/rate-limit.js +35 -0
- package/modules/provisioning/routes/provisioning.js +607 -0
- package/modules/provisioning/tests/provisioning.mjs +232 -0
- package/modules/provisioning/ui/.gitkeep +0 -0
- package/modules/security/CLAUDE.md +11 -40
- package/modules/security/secret-scrub.js +10 -0
- package/modules/sessions/CLAUDE.md +11 -35
- package/modules/status-ui/CLAUDE.md +11 -43
- package/package-lock.json +2 -2
- package/package.json +7 -2
- package/public-landing/create.html +58 -12
- package/public-landing/index.html +40 -21
- package/scripts/discord/README.md +1 -1
- package/scripts/gds/CLAUDE.md +11 -140
- package/scripts/gds/claim.js +98 -48
- package/scripts/gds/claude-materialize.js +174 -20
- package/scripts/gds/claude-md-template.js +84 -0
- package/scripts/gds/cli-lib.js +112 -2
- package/scripts/gds/cutover-codemod.js +241 -0
- package/scripts/gds/fitness.js +54 -0
- package/scripts/gds/gen-api-client.js +10 -10
- package/scripts/gds/init.js +112 -16
- package/scripts/gds/lint-infra-exec.js +70 -0
- package/scripts/gds/lint-workflow-exec.js +63 -0
- package/scripts/gds/migration-namespace.js +1 -1
- package/scripts/gds/mirror-lineage-check.js +14 -5
- package/scripts/gds/mirror-redact.js +8 -0
- package/scripts/gds/module.js +118 -4
- package/scripts/gds/npmrc.js +93 -0
- package/scripts/gds/onboard.js +17 -24
- package/scripts/gds/package-core.js +74 -17
- package/scripts/gds/provision.js +102 -17
- package/scripts/gds/publish-manifest.js +60 -2
- package/scripts/gds/run-routine.js +51 -13
- package/scripts/gds/run-unit-tests.js +4 -0
- package/scripts/gds/seed-adopt-tasks.js +1 -1
- package/scripts/gds/status.js +6 -1
- package/scripts/gds/task.js +166 -0
- package/scripts/gds/update-channel.js +186 -0
- package/scripts/gds/upgrade.js +172 -25
- package/src/bongos/CLAUDE.md +11 -60
- package/src/bongos/auth.js +24 -0
- package/src/bongos/module-submissions.js +56 -0
- package/src/bongos/route-rank-check.js +6 -0
- package/src/bongos/routes/CLAUDE.md +11 -39
- package/src/bongos/routes/auth.js +6 -1
- package/src/bongos/routes/modules.js +123 -21
- package/src/bongos/serve-internal.js +10 -1
- package/src/branding.js +1 -0
- package/src/instance-config.js +1 -1
- package/src/module-api.js +24 -1
- package/src/module-loader/loader.js +36 -4
- package/src/module-loader/manifest-schema.js +16 -1
- package/tests/branding.mjs +11 -0
- package/tests/claim_error_surface.mjs +107 -0
- package/tests/claude_materialize.mjs +125 -0
- package/tests/consumer_layout_boot.mjs +302 -0
- package/tests/cutover_codemod.mjs +184 -0
- package/tests/device_flow_start.mjs +96 -0
- package/tests/first_run_engine_check.mjs +79 -0
- package/tests/goal_membership_requests.mjs +33 -3
- package/tests/hook_core_resolve.mjs +125 -0
- package/tests/hook_user_agents.mjs +62 -0
- package/tests/infra_exec_paths.mjs +104 -0
- package/tests/init.mjs +106 -6
- package/tests/instance_mismatch_guard.mjs +101 -0
- package/tests/mirror_lineage_proof.mjs +14 -0
- package/tests/module_cli.mjs +130 -2
- package/tests/module_loader.mjs +42 -0
- package/tests/module_manifest.mjs +19 -0
- package/tests/module_submissions.mjs +135 -0
- package/tests/npmrc.mjs +105 -0
- package/tests/onboard.mjs +62 -0
- package/tests/package_core.mjs +76 -22
- package/tests/platform_boot.mjs +5 -2
- package/tests/provision.mjs +107 -8
- package/tests/provisioning_github_app_routes.mjs +44 -2
- package/tests/publish_manifest.mjs +52 -1
- package/tests/run_routine.mjs +26 -1
- package/tests/run_routine_two_root.mjs +77 -0
- package/tests/scrubber_corpus.mjs +17 -0
- package/tests/served_paths_shipped.mjs +2 -2
- package/tests/task_cli.mjs +99 -0
- package/tests/update_channel.mjs +186 -0
- package/tests/upgrade.mjs +220 -25
- package/tests/workflow_exec_paths.mjs +98 -0
- package/docs/design/container-exterior-tiles.md +0 -49
- package/docs/design/container-exterior.md +0 -81
- package/docs/design/container-interior.md +0 -77
- package/docs/design/world-map-scroll.md +0 -41
- package/docs/recipes/claude-gemini-bongos-doors.md +0 -155
- package/docs/recipes/cloudbongos-staging-gate.md +0 -139
- package/docs/recipes/cloudbongos-standup.md +0 -111
- package/docs/recipes/parallel-load-results-2026-05-30.md +0 -63
- package/docs/recipes/parallel-load-test.md +0 -32
- package/docs/recipes/pixel-art-pipeline.md +0 -411
- package/docs/recipes/staging-data.md +0 -50
- package/migrations/instance/018_pms_v3_planning_seed.sql +0 -131
- package/migrations/instance/080_gds_v4_planning_seed.sql +0 -75
- package/migrations/instance/110_medusa_planning_seed.sql +0 -70
- package/migrations/instance/120_bongos_v1_planning_seed.sql +0 -69
- package/migrations/instance/144_bongos_v1_module_system_criterion.sql +0 -26
- package/migrations/instance/159_bongos_v1_goal_hierarchy_criterion.sql +0 -29
- package/migrations/instance/172_v2_world_planning_seed.sql +0 -163
- package/migrations/instance/173_bongos_v1_c7_core_modularized.sql +0 -33
- package/migrations/instance/182_gdsv4_bongos_consolidation.sql +0 -132
- package/migrations/instance/183_gdsv4_carryover_themed_goals.sql +0 -116
- package/migrations/instance/186_bongos_v1_governance_planning_seed.sql +0 -69
- package/scripts/gds/art-stage.js +0 -152
- package/server.js +0 -212
- package/tests/art_key.mjs +0 -121
- package/tests/day_cycle.mjs +0 -197
- package/tests/snapshot_picker.mjs +0 -233
- package/tests/sprite_facing.mjs +0 -35
- package/tests/terrain_picker.mjs +0 -298
- package/tests/turn_in_place.mjs +0 -280
- package/tests/walkability.mjs +0 -188
|
@@ -1,6 +1,9 @@
|
|
|
1
|
-
// @
|
|
1
|
+
// @bongos/client (CommonJS build) — GENERATED from index.mjs by
|
|
2
2
|
// scripts/gds/gen-api-client.js. DO NOT EDIT BY HAND. Same behavior as the ESM
|
|
3
3
|
// build; only the module bindings differ. For require()-based consumers.
|
|
4
|
+
// @bongos/client — GENERATED from the OpenAPI spec by
|
|
5
|
+
// scripts/gds/gen-api-client.js (task 1995 / ADR 0118). DO NOT EDIT BY HAND —
|
|
6
|
+
// regenerate on spec change. Zero deps; uses the platform fetch.
|
|
4
7
|
'use strict';
|
|
5
8
|
|
|
6
9
|
const API_VERSION = "v1";
|
|
@@ -303,10 +306,14 @@ function createClient(opts = {}) {
|
|
|
303
306
|
patchGoalsIdMembersBuilderId: (args) => request("PATCH", "/goals/{id}/members/{builderId}", { hasBody: true }, args),
|
|
304
307
|
// POST /goals/{id}/reopen — rank: metic+archon — POST /goals/:id/reopen
|
|
305
308
|
postGoalsIdReopen: (args) => request("POST", "/goals/{id}/reopen", { hasBody: true }, args),
|
|
309
|
+
// GET /goals/{id}/requests — rank: any-builder — GET /goals/:id/requests
|
|
310
|
+
getGoalsIdRequests: (args) => request("GET", "/goals/{id}/requests", { hasBody: false }, args),
|
|
306
311
|
// POST /goals/{id}/requests — rank: any-builder — POST /goals/:id/requests
|
|
307
312
|
postGoalsIdRequests: (args) => request("POST", "/goals/{id}/requests", { hasBody: true }, args),
|
|
308
313
|
// POST /goals/{id}/requests/{reqId}/respond — rank: any-builder — POST /goals/:id/requests/:reqId/respond
|
|
309
314
|
postGoalsIdRequestsReqIdRespond: (args) => request("POST", "/goals/{id}/requests/{reqId}/respond", { hasBody: true }, args),
|
|
315
|
+
// POST /goals/{id}/requests/{reqId}/withdraw — rank: any-builder — POST /goals/:id/requests/:reqId/withdraw
|
|
316
|
+
postGoalsIdRequestsReqIdWithdraw: (args) => request("POST", "/goals/{id}/requests/{reqId}/withdraw", { hasBody: true }, args),
|
|
310
317
|
// POST /goals/{id}/scope — rank: metic+archon — POST /goals/:id/scope
|
|
311
318
|
postGoalsIdScope: (args) => request("POST", "/goals/{id}/scope", { hasBody: true }, args),
|
|
312
319
|
// POST /goals/{id}/tasks — rank: any-builder — POST /goals/:id/tasks
|
|
@@ -439,6 +446,8 @@ function createClient(opts = {}) {
|
|
|
439
446
|
postModulesKeyEnable: (args) => request("POST", "/modules/{key}/enable", { hasBody: true }, args),
|
|
440
447
|
// POST /modules/{key}/submit — rank: metic+archon — POST /modules/:key/submit
|
|
441
448
|
postModulesKeySubmit: (args) => request("POST", "/modules/{key}/submit", { hasBody: true }, args),
|
|
449
|
+
// GET /modules/submissions — rank: metic+archon — GET /modules/submissions
|
|
450
|
+
getModulesSubmissions: (args) => request("GET", "/modules/submissions", { hasBody: false }, args),
|
|
442
451
|
},
|
|
443
452
|
"overrideRequests": {
|
|
444
453
|
// GET /override-requests — rank: archon — GET /override-requests
|
|
@@ -453,6 +462,8 @@ function createClient(opts = {}) {
|
|
|
453
462
|
getProvisioningFleetCostLedger: (args) => request("GET", "/provisioning/fleet/cost-ledger", { hasBody: false }, args),
|
|
454
463
|
// GET /provisioning/github-app/callback — rank: public — GET /provisioning/github-app/callback
|
|
455
464
|
getProvisioningGithubAppCallback: (args) => request("GET", "/provisioning/github-app/callback", { hasBody: false }, args),
|
|
465
|
+
// GET /provisioning/github-app/status — rank: public — GET /provisioning/github-app/status
|
|
466
|
+
getProvisioningGithubAppStatus: (args) => request("GET", "/provisioning/github-app/status", { hasBody: false }, args),
|
|
456
467
|
// GET /provisioning/health — rank: public — GET /provisioning/health
|
|
457
468
|
getProvisioningHealth: (args) => request("GET", "/provisioning/health", { hasBody: false }, args),
|
|
458
469
|
// GET /provisioning/instances — rank: any-builder — GET /provisioning/instances
|
|
@@ -467,6 +478,8 @@ function createClient(opts = {}) {
|
|
|
467
478
|
postProvisioningInstancesIdGithubApp: (args) => request("POST", "/provisioning/instances/{id}/github-app", { hasBody: true }, args),
|
|
468
479
|
// POST /provisioning/instances/{id}/teardown — rank: any-builder — POST /provisioning/instances/:id/teardown
|
|
469
480
|
postProvisioningInstancesIdTeardown: (args) => request("POST", "/provisioning/instances/{id}/teardown", { hasBody: true }, args),
|
|
481
|
+
// GET /provisioning/onboard-plan — rank: public — GET /provisioning/onboard-plan
|
|
482
|
+
getProvisioningOnboardPlan: (args) => request("GET", "/provisioning/onboard-plan", { hasBody: false }, args),
|
|
470
483
|
// GET /provisioning/tls-check — rank: public — GET /provisioning/tls-check
|
|
471
484
|
getProvisioningTlsCheck: (args) => request("GET", "/provisioning/tls-check", { hasBody: false }, args),
|
|
472
485
|
},
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// GENERATED — TypeScript types for @
|
|
1
|
+
// GENERATED — TypeScript types for @bongos/client (task 1995; field-level
|
|
2
2
|
// request typing added in task 2050 / ADR 0118). DO NOT EDIT BY HAND.
|
|
3
3
|
export declare const API_VERSION: string;
|
|
4
4
|
export declare const DEFAULT_BASE_URL: string;
|
|
@@ -34,6 +34,7 @@ export interface GetDemoHealthResponse { module: unknown; ok: boolean; coreVersi
|
|
|
34
34
|
export interface GetDiscordChannelsPlanResponse { ok: boolean; guild_id: unknown; op_count: unknown; ops: unknown; warnings: unknown }
|
|
35
35
|
export interface GetDoneWhenPendingReviewResponse { criteria: unknown; count: unknown }
|
|
36
36
|
export interface GetGoalsIdConflictsResponse { ok: boolean; goal_id: unknown; conflicts: unknown; cross_goals_considered: unknown }
|
|
37
|
+
export interface GetGoalsIdRequestsResponse { requests: unknown }
|
|
37
38
|
export interface GetGoalsIdResponse { goal: unknown; members: unknown; criteria: unknown; dependencies: unknown }
|
|
38
39
|
export interface GetGoalsResponse { goals: unknown }
|
|
39
40
|
export interface GetGradesByBuilderResponse { window_days: unknown; builders: unknown }
|
|
@@ -54,11 +55,14 @@ export interface GetMemoryBfgBuildersBuilderIdFilesResponse { builder_id: unknow
|
|
|
54
55
|
export interface GetMemoryFileResponse { builder_id: unknown; path: unknown; content: unknown; sha256: unknown; byte_len: unknown; mtime: unknown; updated_at: unknown; created_at: unknown }
|
|
55
56
|
export interface GetMemoryFilesResponse { builder_id: unknown; count: unknown; files: unknown }
|
|
56
57
|
export interface GetModulesResponse { modules: unknown; own_built: unknown; core_loaded: unknown; submit_pipeline_live: boolean }
|
|
58
|
+
export interface GetModulesSubmissionsResponse { submissions: unknown }
|
|
57
59
|
export interface GetOverrideRequestsResponse { requests: unknown }
|
|
58
60
|
export interface GetProvisioningFleetResponse { instances: unknown }
|
|
61
|
+
export interface GetProvisioningGithubAppStatusResponse { ok: boolean; status: unknown; ready: unknown; terminal: unknown; domain: unknown; instance_status: unknown }
|
|
59
62
|
export interface GetProvisioningHealthResponse { module: unknown; ok: boolean; coreVersion: unknown }
|
|
60
63
|
export interface GetProvisioningInstancesIdResponse { instance: unknown; open_intent: unknown }
|
|
61
64
|
export interface GetProvisioningInstancesResponse { instances: unknown }
|
|
65
|
+
export interface GetProvisioningOnboardPlanResponse { mode: unknown; steps: unknown }
|
|
62
66
|
export interface GetPublicBlockersIdResponse { blocker: unknown }
|
|
63
67
|
export interface GetPublicBountyTableResponse { table: unknown; currency: unknown }
|
|
64
68
|
export interface GetPublicGradesResponse { window_days: unknown; rolling: unknown; trend: unknown; threshold: unknown; grader_version: unknown }
|
|
@@ -177,6 +181,7 @@ export interface PostGoalsIdMembersResponse { ok: boolean; member: unknown }
|
|
|
177
181
|
export interface PostGoalsIdReopenResponse { ok: boolean; goal: unknown }
|
|
178
182
|
export interface PostGoalsIdRequestsReqIdRespondRequest { action: string }
|
|
179
183
|
export interface PostGoalsIdRequestsReqIdRespondResponse { ok: boolean; action: unknown; request: unknown; member?: unknown }
|
|
184
|
+
export interface PostGoalsIdRequestsReqIdWithdrawResponse { ok: boolean; request: unknown }
|
|
180
185
|
export interface PostGoalsIdRequestsRequest { note?: string }
|
|
181
186
|
export interface PostGoalsIdRequestsResponse { ok: boolean; request: unknown }
|
|
182
187
|
export interface PostGoalsIdScopeRequest { add: string[] }
|
|
@@ -205,6 +210,8 @@ export interface PostMemoryBuildersBuilderIdBfgWriteResponse { ok: boolean; buil
|
|
|
205
210
|
export interface PostMemorySyncRequest { files?: unknown[] }
|
|
206
211
|
export interface PostModulesKeyEnableRequest { enabled?: unknown }
|
|
207
212
|
export interface PostModulesKeyEnableResponse { ok: boolean; key: unknown; enabled: unknown; note: unknown }
|
|
213
|
+
export interface PostModulesKeySubmitRequest { signed_by?: string }
|
|
214
|
+
export interface PostModulesKeySubmitResponse { ok: boolean; submission: unknown }
|
|
208
215
|
export interface PostOverrideRequestsIdDecideRequest { decision: string; note?: string }
|
|
209
216
|
export interface PostProvisioningInstancesIdForceTeardownResponse { ok: boolean; queued: unknown; action: unknown; status: unknown; message: unknown }
|
|
210
217
|
export interface PostProvisioningInstancesIdGithubAppRequest { account?: string }
|
|
@@ -483,10 +490,14 @@ export interface BongosClient {
|
|
|
483
490
|
patchGoalsIdMembersBuilderId(args: RequestArgs & { body: PatchGoalsIdMembersBuilderIdRequest }): Promise<PatchGoalsIdMembersBuilderIdResponse>;
|
|
484
491
|
/** POST /goals/{id}/reopen — rank: metic+archon */
|
|
485
492
|
postGoalsIdReopen(args?: RequestArgs): Promise<PostGoalsIdReopenResponse>;
|
|
493
|
+
/** GET /goals/{id}/requests — rank: any-builder */
|
|
494
|
+
getGoalsIdRequests(args?: RequestArgs): Promise<GetGoalsIdRequestsResponse>;
|
|
486
495
|
/** POST /goals/{id}/requests — rank: any-builder */
|
|
487
496
|
postGoalsIdRequests(args?: RequestArgs & { body?: PostGoalsIdRequestsRequest }): Promise<PostGoalsIdRequestsResponse>;
|
|
488
497
|
/** POST /goals/{id}/requests/{reqId}/respond — rank: any-builder */
|
|
489
498
|
postGoalsIdRequestsReqIdRespond(args: RequestArgs & { body: PostGoalsIdRequestsReqIdRespondRequest }): Promise<PostGoalsIdRequestsReqIdRespondResponse>;
|
|
499
|
+
/** POST /goals/{id}/requests/{reqId}/withdraw — rank: any-builder */
|
|
500
|
+
postGoalsIdRequestsReqIdWithdraw(args?: RequestArgs): Promise<PostGoalsIdRequestsReqIdWithdrawResponse>;
|
|
490
501
|
/** POST /goals/{id}/scope — rank: metic+archon */
|
|
491
502
|
postGoalsIdScope(args: RequestArgs & { body: PostGoalsIdScopeRequest }): Promise<PostGoalsIdScopeResponse>;
|
|
492
503
|
/** POST /goals/{id}/tasks — rank: any-builder */
|
|
@@ -618,7 +629,9 @@ export interface BongosClient {
|
|
|
618
629
|
/** POST /modules/{key}/enable — rank: metic+archon */
|
|
619
630
|
postModulesKeyEnable(args?: RequestArgs & { body?: PostModulesKeyEnableRequest }): Promise<PostModulesKeyEnableResponse>;
|
|
620
631
|
/** POST /modules/{key}/submit — rank: metic+archon */
|
|
621
|
-
postModulesKeySubmit(args?: RequestArgs): Promise<
|
|
632
|
+
postModulesKeySubmit(args?: RequestArgs & { body?: PostModulesKeySubmitRequest }): Promise<PostModulesKeySubmitResponse>;
|
|
633
|
+
/** GET /modules/submissions — rank: metic+archon */
|
|
634
|
+
getModulesSubmissions(args?: RequestArgs): Promise<GetModulesSubmissionsResponse>;
|
|
622
635
|
};
|
|
623
636
|
"overrideRequests": {
|
|
624
637
|
/** GET /override-requests — rank: archon */
|
|
@@ -633,6 +646,8 @@ export interface BongosClient {
|
|
|
633
646
|
getProvisioningFleetCostLedger(args?: RequestArgs): Promise<ApiResponse>;
|
|
634
647
|
/** GET /provisioning/github-app/callback — rank: public */
|
|
635
648
|
getProvisioningGithubAppCallback(args?: RequestArgs): Promise<ApiResponse>;
|
|
649
|
+
/** GET /provisioning/github-app/status — rank: public */
|
|
650
|
+
getProvisioningGithubAppStatus(args?: RequestArgs): Promise<GetProvisioningGithubAppStatusResponse>;
|
|
636
651
|
/** GET /provisioning/health — rank: public */
|
|
637
652
|
getProvisioningHealth(args?: RequestArgs): Promise<GetProvisioningHealthResponse>;
|
|
638
653
|
/** GET /provisioning/instances — rank: any-builder */
|
|
@@ -647,6 +662,8 @@ export interface BongosClient {
|
|
|
647
662
|
postProvisioningInstancesIdGithubApp(args?: RequestArgs & { body?: PostProvisioningInstancesIdGithubAppRequest }): Promise<PostProvisioningInstancesIdGithubAppResponse>;
|
|
648
663
|
/** POST /provisioning/instances/{id}/teardown — rank: any-builder */
|
|
649
664
|
postProvisioningInstancesIdTeardown(args?: RequestArgs): Promise<PostProvisioningInstancesIdTeardownResponse>;
|
|
665
|
+
/** GET /provisioning/onboard-plan — rank: public */
|
|
666
|
+
getProvisioningOnboardPlan(args?: RequestArgs): Promise<GetProvisioningOnboardPlanResponse>;
|
|
650
667
|
/** GET /provisioning/tls-check — rank: public */
|
|
651
668
|
getProvisioningTlsCheck(args?: RequestArgs): Promise<ApiResponse>;
|
|
652
669
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// @
|
|
1
|
+
// @bongos/client — GENERATED from the OpenAPI spec by
|
|
2
2
|
// scripts/gds/gen-api-client.js (task 1995 / ADR 0118). DO NOT EDIT BY HAND —
|
|
3
3
|
// regenerate on spec change. Zero deps; uses the platform fetch.
|
|
4
4
|
'use strict';
|
|
@@ -303,10 +303,14 @@ export function createClient(opts = {}) {
|
|
|
303
303
|
patchGoalsIdMembersBuilderId: (args) => request("PATCH", "/goals/{id}/members/{builderId}", { hasBody: true }, args),
|
|
304
304
|
// POST /goals/{id}/reopen — rank: metic+archon — POST /goals/:id/reopen
|
|
305
305
|
postGoalsIdReopen: (args) => request("POST", "/goals/{id}/reopen", { hasBody: true }, args),
|
|
306
|
+
// GET /goals/{id}/requests — rank: any-builder — GET /goals/:id/requests
|
|
307
|
+
getGoalsIdRequests: (args) => request("GET", "/goals/{id}/requests", { hasBody: false }, args),
|
|
306
308
|
// POST /goals/{id}/requests — rank: any-builder — POST /goals/:id/requests
|
|
307
309
|
postGoalsIdRequests: (args) => request("POST", "/goals/{id}/requests", { hasBody: true }, args),
|
|
308
310
|
// POST /goals/{id}/requests/{reqId}/respond — rank: any-builder — POST /goals/:id/requests/:reqId/respond
|
|
309
311
|
postGoalsIdRequestsReqIdRespond: (args) => request("POST", "/goals/{id}/requests/{reqId}/respond", { hasBody: true }, args),
|
|
312
|
+
// POST /goals/{id}/requests/{reqId}/withdraw — rank: any-builder — POST /goals/:id/requests/:reqId/withdraw
|
|
313
|
+
postGoalsIdRequestsReqIdWithdraw: (args) => request("POST", "/goals/{id}/requests/{reqId}/withdraw", { hasBody: true }, args),
|
|
310
314
|
// POST /goals/{id}/scope — rank: metic+archon — POST /goals/:id/scope
|
|
311
315
|
postGoalsIdScope: (args) => request("POST", "/goals/{id}/scope", { hasBody: true }, args),
|
|
312
316
|
// POST /goals/{id}/tasks — rank: any-builder — POST /goals/:id/tasks
|
|
@@ -439,6 +443,8 @@ export function createClient(opts = {}) {
|
|
|
439
443
|
postModulesKeyEnable: (args) => request("POST", "/modules/{key}/enable", { hasBody: true }, args),
|
|
440
444
|
// POST /modules/{key}/submit — rank: metic+archon — POST /modules/:key/submit
|
|
441
445
|
postModulesKeySubmit: (args) => request("POST", "/modules/{key}/submit", { hasBody: true }, args),
|
|
446
|
+
// GET /modules/submissions — rank: metic+archon — GET /modules/submissions
|
|
447
|
+
getModulesSubmissions: (args) => request("GET", "/modules/submissions", { hasBody: false }, args),
|
|
442
448
|
},
|
|
443
449
|
"overrideRequests": {
|
|
444
450
|
// GET /override-requests — rank: archon — GET /override-requests
|
|
@@ -453,6 +459,8 @@ export function createClient(opts = {}) {
|
|
|
453
459
|
getProvisioningFleetCostLedger: (args) => request("GET", "/provisioning/fleet/cost-ledger", { hasBody: false }, args),
|
|
454
460
|
// GET /provisioning/github-app/callback — rank: public — GET /provisioning/github-app/callback
|
|
455
461
|
getProvisioningGithubAppCallback: (args) => request("GET", "/provisioning/github-app/callback", { hasBody: false }, args),
|
|
462
|
+
// GET /provisioning/github-app/status — rank: public — GET /provisioning/github-app/status
|
|
463
|
+
getProvisioningGithubAppStatus: (args) => request("GET", "/provisioning/github-app/status", { hasBody: false }, args),
|
|
456
464
|
// GET /provisioning/health — rank: public — GET /provisioning/health
|
|
457
465
|
getProvisioningHealth: (args) => request("GET", "/provisioning/health", { hasBody: false }, args),
|
|
458
466
|
// GET /provisioning/instances — rank: any-builder — GET /provisioning/instances
|
|
@@ -467,6 +475,8 @@ export function createClient(opts = {}) {
|
|
|
467
475
|
postProvisioningInstancesIdGithubApp: (args) => request("POST", "/provisioning/instances/{id}/github-app", { hasBody: true }, args),
|
|
468
476
|
// POST /provisioning/instances/{id}/teardown — rank: any-builder — POST /provisioning/instances/:id/teardown
|
|
469
477
|
postProvisioningInstancesIdTeardown: (args) => request("POST", "/provisioning/instances/{id}/teardown", { hasBody: true }, args),
|
|
478
|
+
// GET /provisioning/onboard-plan — rank: public — GET /provisioning/onboard-plan
|
|
479
|
+
getProvisioningOnboardPlan: (args) => request("GET", "/provisioning/onboard-plan", { hasBody: false }, args),
|
|
470
480
|
// GET /provisioning/tls-check — rank: public — GET /provisioning/tls-check
|
|
471
481
|
getProvisioningTlsCheck: (args) => request("GET", "/provisioning/tls-check", { hasBody: false }, args),
|
|
472
482
|
},
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
## Context
|
|
8
8
|
|
|
9
|
-
|
|
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 "
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
|
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 "
|
|
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 (
|
|
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
|
|
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,
|
|
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,
|
|
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-
|
|
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` (
|
|
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
|
-
| `
|
|
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 (`
|
|
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 (
|
|
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
|
|
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
|
|
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-
|
|
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`/
|
|
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
|
|
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,
|
|
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
|
|
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.**
|
|
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
|
|
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 (
|
|
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
|
|
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
|
-
|
|
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
|
-
- **
|
|
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. **
|
|
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.
|
|
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
|
|
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
|
-
|
|
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`
|
|
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.
|
|
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
|
|
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
|
|
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 (
|
|
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.
|
|
@@ -17,7 +17,7 @@ Today it is one fused codebase. A file-grounded coupling analysis (2026-06-18) f
|
|
|
17
17
|
|
|
18
18
|
1. **Process/HTTP** — one Express app + one Colyseus server. The GDS (`/api/gds`, hall, status) mounts host-agnostic *first*; the **game is the fall-through default**, not a module. Good news: `src/rooms/register.js` + `src/preview-server.js` already factor the game-room set out — the cleanest existing seam and the template for the cut.
|
|
19
19
|
2. **DB** — *one shared `pg` Pool*: `src/bongos/db.js` does `require('../db')` and reuses the game's pool. Game tables (`world_events`, `players`, migrations 001/002) and ~78 GDS tables share one pool and one flat migration sequence. `track` is a 2-value `CHECK (track IN ('product','internal'))` column on `versions`, woven into analytics + hall UI — an OTB-specific taxonomy.
|
|
20
|
-
3. **Brand/identity** — leaked, not single-config. "Example" is hardcoded across ~50 hits / 28 files; `example.com` across ~90 (cookie domain `.example.com`, OAuth origin, `*.dev.` SSH allowlist); "
|
|
20
|
+
3. **Brand/identity** — leaked, not single-config. "Example" is hardcoded across ~50 hits / 28 files; `example.com` across ~90 (cookie domain `.example.com`, OAuth origin, `*.dev.` SSH allowlist); "example" in 23 files; "Example"/"Example" baked into **grader/architect/onboarding LLM prompts**. Only `devbox-app/src/brand.js` honors the single-config ideal.
|
|
21
21
|
4. **Methodology/skills** — already clean: `.claude/skills/builder-*` + idea/blocker/planning/status/recall are portable; the four `otb-*` art skills + `stop-sound.js` are host; `art/` is self-contained (no `src/` imports); Discord is already `DISCORD_BOT_ENABLED`-gated.
|
|
22
22
|
|
|
23
23
|
Why a spike-ADR first: 24 structural tasks (R51–R74) depend on this. They need **one** locked boundary, branding-contract schema, and module mechanism to build against, or they will diverge.
|
|
@@ -46,7 +46,7 @@ Why a spike-ADR first: 24 structural tasks (R51–R74) depend on this. They need
|
|
|
46
46
|
|
|
47
47
|
- **Engine entrypoint** (R51, [#1190](https://example.com/builders#/task/1190)): boots Express + `buildGdsRouter()` + hall + status, host-agnostic, **no Colyseus, no game/tile mounts** — sibling to `src/preview-server.js`. Today's `server.js` becomes the *OTB instance boot* (engine + game module).
|
|
48
48
|
- **A host instance** = branding pack (§3) + feature-module flags (§4) + owner/repo/OAuth binding (R62, [#1201](https://example.com/builders#/task/1201)) + its own DB (R52).
|
|
49
|
-
- Customer 0 = vanilla brand, no modules (the dogfood); customer 1 = OTB (game + art + discord + dev-box,
|
|
49
|
+
- Customer 0 = vanilla brand, no modules (the dogfood); customer 1 = OTB (game + art + discord + dev-box, example, Greek pack).
|
|
50
50
|
|
|
51
51
|
### 3. The branding contract (`config/branding.*` — R53 keystone, [#1192](https://example.com/builders#/task/1192))
|
|
52
52
|
|
|
@@ -54,7 +54,7 @@ One per-instance config; **resolution precedence: env var → instance config
|
|
|
54
54
|
|
|
55
55
|
- **Identity:** `productName`, `worldName` (the in-world / civilization name), `company` (+ site).
|
|
56
56
|
- **Domains:** `publicOrigin`, `buildersOrigin`, `statusOrigin`, `cookieDomain`, box subdomain pattern (`*.dev.`/`sandbox-`/`term-`). *(Load-bearing security strings — a swap must not widen cookie/SSH scope.)*
|
|
57
|
-
- **Currency label** (R56, [#1195](https://example.com/builders#/task/1195)): "
|
|
57
|
+
- **Currency label** (R56, [#1195](https://example.com/builders#/task/1195)): "example" → configurable; the cost-plus reward **math is unchanged**.
|
|
58
58
|
- **Tracks:** replace the 2-value `product|internal` CHECK with a configurable set (R52, [#1191](https://example.com/builders#/task/1191)).
|
|
59
59
|
- **Theme/palette + copy pack:** hall lore/primer/404 copy, Discord persona, and — critically — the **grader/architect/onboarding prompt brand header** must read the project name from config, or a non-OTB instance grades against the wrong project identity.
|
|
60
60
|
|
|
@@ -103,5 +103,5 @@ R50 (this ADR) → **R51 entrypoint + R52 DB pool** (independent foundations)
|
|
|
103
103
|
|
|
104
104
|
- A clear, file-grounded target the 24 epics build against — one boundary, one contract, one module mechanism.
|
|
105
105
|
- The trust boundary + rank enforcement stay core and unchanged; a feature-module must never be able to bypass server-side rank checks (a Path-C assertion).
|
|
106
|
-
- **Hardest knots (called out so the epics plan for them):** (1) shared Pool + flat migrations; (2) the brand-saturated, *not* data-driven hall UI (~50 brand hits,
|
|
106
|
+
- **Hardest knots (called out so the epics plan for them):** (1) shared Pool + flat migrations; (2) the brand-saturated, *not* data-driven hall UI (~50 brand hits, example in 23 files) — the largest mechanical job; (3) inverting game-as-default into a mounted module; (4) domains woven into auth/security — config swaps must not widen cookie/SSH scope; (5) brand inside LLM prompts (grader/architect/onboarding).
|
|
107
107
|
- **Risk: scope.** Mitigation: R53 keystone first; modules incremental; Path-C enforces no regression; customer-0 dogfood ([#1206](https://example.com/builders#/task/1206)) is the falsifiable proof the cut actually worked.
|