@bongos/core 1.17.2 → 1.18.0
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 +426 -96
- package/.devcontainer/healthcheck.sh +0 -0
- package/.devcontainer/init-firewall.sh +0 -0
- package/.devcontainer/post-create.sh +0 -0
- package/GOVERNANCE.md +1 -1
- package/README.md +26 -22
- package/bin/bongos.js +0 -0
- package/clients/bongos-client/README.md +1 -1
- package/clients/bongos-client/bongos-client.global.js +2 -0
- package/clients/bongos-client/index.cjs +2 -0
- package/clients/bongos-client/index.d.ts +4 -2
- package/clients/bongos-client/index.mjs +2 -0
- package/docker-entrypoint.sh +0 -0
- package/docs/adr/0139-platform-history-migration-to-cloudbongos.md +94 -0
- package/docs/adr/0140-cloudbongos-standalone-reprovision.md +43 -0
- package/docs/adr/README.md +3 -0
- package/docs/api/openapi.json +68 -370
- package/docs/api-reference.md +7 -18
- package/docs/file-map.md +7 -25
- package/docs/onboarding/diagrams/05-versioning.mmd +4 -6
- package/docs/onboarding/diagrams/assertions.json +5 -9
- package/modules/hall-ui/public/builders.js +132 -645
- package/modules/hall-ui/public/goal-inbox.js +67 -26
- package/modules/hall-ui/public/goals-page.js +102 -177
- package/modules/hall-ui/public/goals.css +183 -0
- package/modules/hall-ui/public/goals.html +35 -253
- package/modules/hall-ui/public/goals.js +7 -2
- package/modules/hall-ui/public/hall-kit.js +474 -0
- package/modules/hall-ui/public/hall-widgets.js +24 -20
- package/modules/hall-ui/public/instances-panel.js +24 -3
- package/modules/hall-ui/public/new-project-wizard.js +6 -5
- package/modules/hall-ui/public/settings.css +355 -0
- package/modules/hall-ui/public/settings.html +86 -414
- package/modules/hall-ui/public/settings.js +96 -35
- package/modules/hall-ui/public/style.css +156 -0
- package/modules/hall-ui/public/watch.css +184 -0
- package/modules/hall-ui/public/watch.html +111 -285
- package/modules/hall-ui/public/watch.js +59 -21
- package/modules/hall-ui/public/work.css +194 -0
- package/modules/hall-ui/public/work.html +46 -374
- package/modules/hall-ui/public/work.js +137 -102
- package/modules/lifecycle/criterion-suggest.js +80 -0
- package/modules/lifecycle/db.js +42 -5
- package/modules/lifecycle/routes/goals.js +26 -0
- package/modules/lifecycle/routes/tasks.js +21 -0
- package/package-lock.json +2 -2
- package/package.json +1 -1
- package/public-landing/create.html +83 -7
- package/public-landing/index.html +11 -76
- package/scripts/cron/style_guide_audit.sh +0 -0
- package/scripts/gds/api.js +0 -0
- package/scripts/gds/architect-audit.js +0 -0
- package/scripts/gds/audit-authorship.sh +0 -0
- package/scripts/gds/audit-replay.sh +0 -0
- package/scripts/gds/box.js +0 -0
- package/scripts/gds/capture.js +0 -0
- package/scripts/gds/conductor-dispatch.js +0 -0
- package/scripts/gds/coreB-carve-proof.sh +0 -0
- package/scripts/gds/db-backup-nightly.sh +0 -0
- package/scripts/gds/db-backup-offsite.sh +0 -0
- package/scripts/gds/doctor.js +0 -0
- package/scripts/gds/grade-smoke.js +0 -0
- package/scripts/gds/hooks/pre-push.js +0 -0
- package/scripts/gds/install-git-hooks.js +0 -0
- package/scripts/gds/main-audit.js +0 -0
- package/scripts/gds/oauth-secret.js +0 -0
- package/scripts/gds/onboarding-analyze.js +0 -0
- package/scripts/gds/onboarding-ship.js +0 -0
- package/scripts/gds/paste-token.js +0 -0
- package/scripts/gds/portability-smoke-art.sh +0 -0
- package/scripts/gds/portability-smoke-memory.sh +0 -0
- package/scripts/gds/provision.js +125 -4
- package/scripts/gds/push-main.js +0 -0
- package/scripts/gds/render-ideas.js +0 -0
- package/scripts/gds/security-baseline-check.sh +0 -0
- package/scripts/gds/session.js +0 -0
- package/scripts/gds/ship.js +11 -1
- package/scripts/gds/smoke-batch-claim.sh +0 -0
- package/scripts/gds/smoke-batch-release.sh +0 -0
- package/scripts/gds/smoke-box.sh +0 -0
- package/scripts/gds/smoke-claim-consistency.sh +0 -0
- package/scripts/gds/smoke-dependencies.sh +0 -0
- package/scripts/gds/smoke-write.sh +0 -0
- package/scripts/hall-preview/README.md +103 -0
- package/scripts/hall-preview/fixtures/access-requests.json +20 -0
- package/scripts/hall-preview/fixtures/achievements.json +76 -0
- package/scripts/hall-preview/fixtures/analytics__builder.json +251 -0
- package/scripts/hall-preview/fixtures/audit-log.json +68 -0
- package/scripts/hall-preview/fixtures/blockers__detail.json +12 -0
- package/scripts/hall-preview/fixtures/box__me.json +5 -0
- package/scripts/hall-preview/fixtures/boxes__cost-ledger.json +69 -0
- package/scripts/hall-preview/fixtures/builders__active-claims.json +1 -0
- package/scripts/hall-preview/fixtures/builders__directory.json +81 -0
- package/scripts/hall-preview/fixtures/builders__roster.json +48 -0
- package/scripts/hall-preview/fixtures/goals.json +502 -0
- package/scripts/hall-preview/fixtures/goals__25.json +96 -0
- package/scripts/hall-preview/fixtures/goals__26.json +67 -0
- package/scripts/hall-preview/fixtures/goals__3.json +103 -0
- package/scripts/hall-preview/fixtures/goals__35.json +49 -0
- package/scripts/hall-preview/fixtures/goals__conflicts.json +154 -0
- package/scripts/hall-preview/fixtures/goals__detail.json +96 -0
- package/scripts/hall-preview/fixtures/goals__inbox.json +5 -0
- package/scripts/hall-preview/fixtures/goals__requests.json +3 -0
- package/scripts/hall-preview/fixtures/grades__by-builder.json +32 -0
- package/scripts/hall-preview/fixtures/inbox.json +330 -0
- package/scripts/hall-preview/fixtures/inbox__detail.json +15 -0
- package/scripts/hall-preview/fixtures/instance.json +124 -0
- package/scripts/hall-preview/fixtures/leaderboard.json +184 -0
- package/scripts/hall-preview/fixtures/me.json +476 -0
- package/scripts/hall-preview/fixtures/me__art-key__own.json +6 -0
- package/scripts/hall-preview/fixtures/me__event-sound-prefs.json +209 -0
- package/scripts/hall-preview/fixtures/me__recent-ships.json +304 -0
- package/scripts/hall-preview/fixtures/me__render.json +5 -0
- package/scripts/hall-preview/fixtures/me__skill-prefs.json +143 -0
- package/scripts/hall-preview/fixtures/me__sound-prefs.json +67 -0
- package/scripts/hall-preview/fixtures/me__wandering.json +43 -0
- package/scripts/hall-preview/fixtures/override-requests.json +15 -0
- package/scripts/hall-preview/fixtures/provisioning__fleet.json +1 -0
- package/scripts/hall-preview/fixtures/provisioning__fleet__cost-ledger.json +1 -0
- package/scripts/hall-preview/fixtures/provisioning__instances.json +1 -0
- package/scripts/hall-preview/fixtures/public__analytics__ecosystem.json +516 -0
- package/scripts/hall-preview/fixtures/public__bounty-table.json +37 -0
- package/scripts/hall-preview/fixtures/public__cost-summary.json +742 -0
- package/scripts/hall-preview/fixtures/public__estimation-drift.json +41 -0
- package/scripts/hall-preview/fixtures/public__grades.json +50 -0
- package/scripts/hall-preview/fixtures/public__progress.json +124 -0
- package/scripts/hall-preview/fixtures/public__recent-shipped.json +426 -0
- package/scripts/hall-preview/fixtures/public__repo-health.json +160 -0
- package/scripts/hall-preview/fixtures/public__repo-info.json +5 -0
- package/scripts/hall-preview/fixtures/security__docs.json +10 -0
- package/scripts/hall-preview/fixtures/security__reports.json +31 -0
- package/scripts/hall-preview/fixtures/sessions__search.json +9 -0
- package/scripts/hall-preview/fixtures/tasks.json +2420 -0
- package/scripts/hall-preview/fixtures/tasks__claimable.json +2555 -0
- package/scripts/hall-preview/fixtures/tasks__detail.json +111 -0
- package/scripts/hall-preview/fixtures/tasks__peer-votes__feed.json +330 -0
- package/scripts/hall-preview/fixtures/versions.json +89 -0
- package/scripts/hall-preview/refresh-fixtures.js +77 -0
- package/scripts/hall-preview/server.js +195 -0
- package/scripts/migrate.sh +29 -4
- package/scripts/migrate_cost_ledger.sh +0 -0
- package/scripts/render-diagrams.sh +0 -0
- package/scripts/security/dep-audit.js +0 -0
- package/scripts/setup-builder.js +0 -0
- package/scripts/setup-builder.sh +0 -0
- package/scripts/snapshots/maybe-render-on-deploy.sh +0 -0
- package/src/bongos/optimizer.js +37 -2
- package/src/module-api.js +20 -1
- package/tests/criterion_suggest.mjs +106 -0
- package/tests/migrate_root_resolution.mjs +97 -0
- package/tests/provision.mjs +69 -0
|
File without changes
|
|
File without changes
|
|
File without changes
|
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
|
|
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 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,10 +1,21 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Cloud Bongos
|
|
2
2
|
|
|
3
|
-
A
|
|
3
|
+
**Cloud Bongos is an AI-first software build platform.** A human owner sets scope, direction, and the hard gates (rank, approval, deploy); AI agents claim tasks and do the day-to-day building — code, docs, migrations, reviews. This repository is the **portable core**: the methodology, the Game Development System (GDS) that tracks all work, the platform engine, and a neutral branding template each instance fills in.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Cloud Bongos is free software under the **GNU AGPL-3.0** (see [`LICENSE`](./LICENSE)), with non-profit, AI-first governance ([`GOVERNANCE.md`](./GOVERNANCE.md)).
|
|
6
6
|
|
|
7
|
-
> **
|
|
7
|
+
> **Provenance.** This core was extracted with fresh history from **Amazonprimea** — the reference instance, built by Hermeslines, and the first project to run on Cloud Bongos. Amazonprimea now consumes this core as a pinned dependency, the same shape as any other instance. The extraction is a redacted subtree (no instance secrets, IPs, or private identity); the exact pin — `core_version`, `source_commit`, `tree_sha256` — is recorded in [`.cloudbongos-core.json`](./.cloudbongos-core.json).
|
|
8
|
+
|
|
9
|
+
The durable framing for AI agents — methodology, working rules, session protocol, architecture — lives in [`CLAUDE.md`](./CLAUDE.md). Read it before editing code.
|
|
10
|
+
|
|
11
|
+
## What's in here
|
|
12
|
+
|
|
13
|
+
- **The GDS** (`src/`, `modules/`, `scripts/gds/`) — the build state machine: tasks, claims, versions, goals, dependencies, the claim→ship→grade→credit lifecycle, and the `/builder-*` CLI.
|
|
14
|
+
- **Platform modules** (`modules/`) — lifecycle, grading, economy, memory, onboarding, ideas, sessions, autonomy, security, the builders' hall + status dashboard, dev-box, and Discord integration. Each is configurable (and most are toggleable) per instance.
|
|
15
|
+
- **Neutral branding template** (`config/*.neutral.json`, `docs/project-context.template.md`) — the identity scaffold a new instance fills in ([`docs/branding-contract.md`](./docs/branding-contract.md)). The vanilla pack in `config/branding.neutral.json` is the identity Cloud Bongos itself runs on.
|
|
16
|
+
- **Methodology + decisions** (`CLAUDE.md`, `docs/adr/`, `docs/recipes/`, `.claude/skills/`).
|
|
17
|
+
|
|
18
|
+
> **This is the core, not a ready-to-run instance.** An instance layers its own content, branding, and product modules on top of a pinned core (that is the whole point of the two-repo model). `server.js` and some entrypoints still reference the reference instance's product layer; standing the core up standalone — a clean vanilla boot — is deliberately the job of the consumer path, proven first by the next instance to install it.
|
|
8
19
|
|
|
9
20
|
## New builder? Start here
|
|
10
21
|
|
|
@@ -14,16 +25,11 @@ You'll need three things on your machine first:
|
|
|
14
25
|
|
|
15
26
|
- **Git** — the tool that copies the code down. Check with `git --version`; install from [git-scm.com](https://git-scm.com/downloads) if it's missing.
|
|
16
27
|
- **Claude Code** — your pair-programmer for every session. Download the desktop app at [claude.com/download](https://claude.com/download) (Mac and Windows).
|
|
17
|
-
- **A GitHub account with access to this repo
|
|
28
|
+
- **A GitHub account with access to this repo.** While the repo is private, the owner must invite you first; accept the invitation before cloning. (The bootstrap below also checks for Node ≥ 22 and Python ≥ 3.10, and prints the install command if either is missing.)
|
|
18
29
|
|
|
19
30
|
### Step 0 — get the project onto your machine
|
|
20
31
|
|
|
21
|
-
Clone the repo, then `cd` into it. Everything below runs from inside that folder
|
|
22
|
-
|
|
23
|
-
```sh
|
|
24
|
-
git clone https://github.com/example-owner/example.git
|
|
25
|
-
cd example
|
|
26
|
-
```
|
|
32
|
+
Clone the repo, then `cd` into it. Everything below runs from inside that folder.
|
|
27
33
|
|
|
28
34
|
### Step 1 — bootstrap
|
|
29
35
|
|
|
@@ -36,15 +42,15 @@ One command bootstraps a fresh clone end-to-end — toolchain checks, JS deps, l
|
|
|
36
42
|
node scripts/setup-builder.js
|
|
37
43
|
```
|
|
38
44
|
|
|
39
|
-
It checks Node ≥ 22 and Python ≥ 3.10 (prints the install command if either is missing), runs `npm ci`, copies `.env.local.example` to `.env.local
|
|
45
|
+
It checks Node ≥ 22 and Python ≥ 3.10 (prints the install command if either is missing), runs `npm ci`, copies `.env.local.example` to `.env.local`, and hands off to `node scripts/gds/setup.js` to authenticate against the GDS via the GitHub Device Flow. The script is idempotent: re-running on an already-set-up checkout reports "already done" rather than clobbering.
|
|
40
46
|
|
|
41
47
|
When it finishes, open Claude Code and run `/builder-start` to see what tasks are claimable.
|
|
42
48
|
|
|
43
49
|
## Secrets scanning
|
|
44
50
|
|
|
45
|
-
We keep secrets (`.env` files, API keys, private keys) out of the repo with two layers:
|
|
51
|
+
We keep secrets (`.env` files, API keys, private keys) out of the repo with two layers. Both are **instance topology** — the git hook (`.husky/`) and CI (`.github/`) are provided when you stand up an instance and are not shipped in the portable core; the pattern below is the recommended posture:
|
|
46
52
|
|
|
47
|
-
- **Pre-commit hook** (
|
|
53
|
+
- **Pre-commit hook** (`.husky/pre-commit`) — scans your *staged* changes before each commit and aborts if it finds a secret. Activate it **once per clone**:
|
|
48
54
|
|
|
49
55
|
```sh
|
|
50
56
|
git config core.hooksPath .husky
|
|
@@ -54,20 +60,20 @@ We keep secrets (`.env` files, API keys, private keys) out of the repo with two
|
|
|
54
60
|
|
|
55
61
|
> **Windows:** git runs the `.husky/pre-commit` hook through the Git-Bash `sh` bundled with Git for Windows, so the hook works if you installed Git for Windows (the usual case). If you don't have a `sh` available, the local hook silently no-ops — CI's full-history TruffleHog scan is then your only gate (and it always runs regardless of platform).
|
|
56
62
|
|
|
57
|
-
- **CI scan** (
|
|
63
|
+
- **CI scan** (`.github/workflows/secrets-scan.yml`) — every PR to `main` runs TruffleHog over the **full git history**. This must pass before merge.
|
|
58
64
|
|
|
59
65
|
### If a commit is blocked, here's how to investigate
|
|
60
66
|
|
|
61
67
|
1. **Read the output.** The hook prints the offending file(s) and why.
|
|
62
|
-
2. **Is it a real secret?** Then it must never be committed. Remove it from the commit (`git restore --staged <file>`), move the value out of the repo — local secrets go in `.env.local` (gitignored; run `/builder-setup`)
|
|
68
|
+
2. **Is it a real secret?** Then it must never be committed. Remove it from the commit (`git restore --staged <file>`), and move the value out of the repo — local secrets go in `.env.local` (gitignored; run `/builder-setup`); production secrets live in your instance's secret store, never in the tree. If it was *already committed in an earlier commit*, the history scan will keep failing until the history is scrubbed — flag this to the owner, since rewriting shared history needs care.
|
|
63
69
|
3. **Is it a false positive?** (e.g. an example key in docs, a test fixture, a Stripe `pk_test_` publishable key.) Add a path regex — one per line — to [`.husky/secrets-allowlist.txt`](./.husky/secrets-allowlist.txt). Both the hook and CI read that allowlist. Keep entries narrow and only add them after confirming the match is genuinely not a secret.
|
|
64
70
|
4. **Genuine emergency commit** (you're sure it's clean and need to move now): `git commit --no-verify` skips the local hook — but CI will still scan the PR, so this only defers the check, it doesn't bypass it.
|
|
65
71
|
|
|
66
72
|
## If your CLI starts 401'ing
|
|
67
73
|
|
|
68
|
-
GDS CLI calls (`node scripts/gds/start.js`, `claim.js`, `ship.js`, etc.) authenticate against
|
|
74
|
+
GDS CLI calls (`node scripts/gds/start.js`, `claim.js`, `ship.js`, etc.) authenticate against your instance's GDS host using a session token stored under `~/.config/<configDir>/gds-session.json` (the neutral core uses `cloudbongos`; an instance may pin its own). Sessions carry a rolling TTL — every authenticated request resets it, so an active session never silently expires — but after a long idle, a token revocation, or an auth-changing deploy, the local token can stop working.
|
|
69
75
|
|
|
70
|
-
`apiCall` in `scripts/gds/cli-lib.js` detects HTTP 401 and exits with a clear recovery message rather than letting the failure cascade
|
|
76
|
+
`apiCall` in `scripts/gds/cli-lib.js` detects HTTP 401 and exits with a clear recovery message rather than letting the failure cascade. When you see it:
|
|
71
77
|
|
|
72
78
|
1. **Re-auth via Device Flow:**
|
|
73
79
|
|
|
@@ -75,7 +81,7 @@ GDS CLI calls (`node scripts/gds/start.js`, `claim.js`, `ship.js`, etc.) authent
|
|
|
75
81
|
node scripts/gds/setup.js --force
|
|
76
82
|
```
|
|
77
83
|
|
|
78
|
-
|
|
84
|
+
It pre-flights `GET /api/gds/me` against your existing session first. If the token is valid, it tells you who you're authenticated as and exits. If the token is dead (401), it falls through to the Device Flow automatically — browser opens to `github.com/login/device`; paste the printed code, authorize as the right GitHub account, you're back.
|
|
79
85
|
|
|
80
86
|
2. **If something feels off and you're not sure what,** run the doctor:
|
|
81
87
|
|
|
@@ -83,6 +89,4 @@ GDS CLI calls (`node scripts/gds/start.js`, `claim.js`, `ship.js`, etc.) authent
|
|
|
83
89
|
node scripts/gds/doctor.js
|
|
84
90
|
```
|
|
85
91
|
|
|
86
|
-
It checks session validity (`/me` returns 200, identity + rank), git plumbing (`core.hooksPath` resolves), repo state (on a branch, working-tree status), and environment files
|
|
87
|
-
|
|
88
|
-
Mirrors the "if a commit is blocked" pattern above: actionable, single command, no guessing.
|
|
92
|
+
It checks session validity (`/me` returns 200, identity + rank), git plumbing (`core.hooksPath` resolves), repo state (on a branch, working-tree status), and environment files. Green/red checklist, no arguments. Exits 0 if every check passes, 1 if any red.
|
package/bin/bongos.js
CHANGED
|
File without changes
|
|
@@ -5,7 +5,7 @@ A **generated**, zero-dependency typed client for the Bongos API — produced fr
|
|
|
5
5
|
by hand; it regenerates when the spec changes, so it can never drift from the routes.
|
|
6
6
|
|
|
7
7
|
- API version: **v1** (served at `/api/bongos/v1`)
|
|
8
|
-
-
|
|
8
|
+
- 230 operations across 40 resource groups
|
|
9
9
|
|
|
10
10
|
## Install
|
|
11
11
|
|
|
@@ -317,6 +317,8 @@ function createClient(opts = {}) {
|
|
|
317
317
|
postGoalsIdRequestsReqIdWithdraw: (args) => request("POST", "/goals/{id}/requests/{reqId}/withdraw", { hasBody: true }, args),
|
|
318
318
|
// POST /goals/{id}/scope — rank: metic+archon — POST /goals/:id/scope
|
|
319
319
|
postGoalsIdScope: (args) => request("POST", "/goals/{id}/scope", { hasBody: true }, args),
|
|
320
|
+
// GET /goals/{id}/suggest-criteria — rank: any-builder — GET /goals/:id/suggest-criteria
|
|
321
|
+
getGoalsIdSuggestCriteria: (args) => request("GET", "/goals/{id}/suggest-criteria", { hasBody: false }, args),
|
|
320
322
|
// POST /goals/{id}/tasks — rank: any-builder — POST /goals/:id/tasks
|
|
321
323
|
postGoalsIdTasks: (args) => request("POST", "/goals/{id}/tasks", { hasBody: true }, args),
|
|
322
324
|
// POST /goals/{id}/transfer — rank: any-builder — POST /goals/:id/transfer
|
|
@@ -316,6 +316,8 @@ function createClient(opts = {}) {
|
|
|
316
316
|
postGoalsIdRequestsReqIdWithdraw: (args) => request("POST", "/goals/{id}/requests/{reqId}/withdraw", { hasBody: true }, args),
|
|
317
317
|
// POST /goals/{id}/scope — rank: metic+archon — POST /goals/:id/scope
|
|
318
318
|
postGoalsIdScope: (args) => request("POST", "/goals/{id}/scope", { hasBody: true }, args),
|
|
319
|
+
// GET /goals/{id}/suggest-criteria — rank: any-builder — GET /goals/:id/suggest-criteria
|
|
320
|
+
getGoalsIdSuggestCriteria: (args) => request("GET", "/goals/{id}/suggest-criteria", { hasBody: false }, args),
|
|
319
321
|
// POST /goals/{id}/tasks — rank: any-builder — POST /goals/:id/tasks
|
|
320
322
|
postGoalsIdTasks: (args) => request("POST", "/goals/{id}/tasks", { hasBody: true }, args),
|
|
321
323
|
// POST /goals/{id}/transfer — rank: any-builder — POST /goals/:id/transfer
|
|
@@ -36,6 +36,7 @@ export interface GetDoneWhenPendingReviewResponse { criteria: unknown; count: un
|
|
|
36
36
|
export interface GetGoalsIdConflictsResponse { ok: boolean; goal_id: unknown; conflicts: unknown; cross_goals_considered: unknown }
|
|
37
37
|
export interface GetGoalsIdRequestsResponse { requests: unknown }
|
|
38
38
|
export interface GetGoalsIdResponse { goal: unknown; members: unknown; criteria: unknown; dependencies: unknown }
|
|
39
|
+
export interface GetGoalsIdSuggestCriteriaResponse { goal_id: unknown; suggestions: unknown }
|
|
39
40
|
export interface GetGoalsResponse { goals: unknown }
|
|
40
41
|
export interface GetGradesByBuilderResponse { window_days: unknown; builders: unknown }
|
|
41
42
|
export interface GetHealthzResponse { ok: boolean; auth_configured: unknown }
|
|
@@ -245,7 +246,6 @@ export interface PostTasksIdVoteRequest { vote: -1 | 0 | 1 }
|
|
|
245
246
|
export interface PostTasksIdVoteResponse { ok: boolean; task_id: unknown; my_vote: unknown; net_votes: unknown; total_votes: unknown }
|
|
246
247
|
export interface PostTasksNewcomerRestockResponse { ok: boolean; stamped: unknown; results: unknown }
|
|
247
248
|
export interface PostTasksRequest { version_id: string; title: string; description?: string; status?: string; touches?: string[]; est_minutes?: number; est_cost_usd?: number; manual_degree?: number; priority?: number; automation_tag?: string; credits_reward?: number; source?: string; source_ref?: string; value_summary?: string; kind?: string; discipline?: string; parallel_safe?: unknown; newcomer_friendly?: boolean; security_sensitive?: boolean; requires_rank?: string; auto_detect_touches?: boolean; criterion_ids?: unknown[]; module_key?: string; goal_id?: number }
|
|
248
|
-
export interface PostTasksResponse { task: unknown; needs_migration: unknown; criteria: unknown; idempotent?: boolean; credits_reward?: unknown }
|
|
249
249
|
export interface PostVersionsIdDoneWhenRequest { criterion_id: string; criterion_md: string; goal_id?: number; sort_order?: number }
|
|
250
250
|
export interface PostVersionsIdDoneWhenResponse { ok: boolean; criterion: unknown }
|
|
251
251
|
export interface PostVersionsRequest { id: string; name: string; status?: string; done_when?: string; scope_doc_path?: string; criteria?: unknown[] }
|
|
@@ -500,6 +500,8 @@ export interface BongosClient {
|
|
|
500
500
|
postGoalsIdRequestsReqIdWithdraw(args?: RequestArgs): Promise<PostGoalsIdRequestsReqIdWithdrawResponse>;
|
|
501
501
|
/** POST /goals/{id}/scope — rank: metic+archon */
|
|
502
502
|
postGoalsIdScope(args: RequestArgs & { body: PostGoalsIdScopeRequest }): Promise<PostGoalsIdScopeResponse>;
|
|
503
|
+
/** GET /goals/{id}/suggest-criteria — rank: any-builder */
|
|
504
|
+
getGoalsIdSuggestCriteria(args?: RequestArgs): Promise<GetGoalsIdSuggestCriteriaResponse>;
|
|
503
505
|
/** POST /goals/{id}/tasks — rank: any-builder */
|
|
504
506
|
postGoalsIdTasks(args: RequestArgs & { body: PostGoalsIdTasksRequest }): Promise<PostGoalsIdTasksResponse>;
|
|
505
507
|
/** POST /goals/{id}/transfer — rank: any-builder */
|
|
@@ -737,7 +739,7 @@ export interface BongosClient {
|
|
|
737
739
|
/** GET /tasks — rank: any-builder */
|
|
738
740
|
getTasks(args?: RequestArgs): Promise<GetTasksResponse>;
|
|
739
741
|
/** POST /tasks — rank: metic+archon */
|
|
740
|
-
postTasks(args: RequestArgs & { body: PostTasksRequest }): Promise<
|
|
742
|
+
postTasks(args: RequestArgs & { body: PostTasksRequest }): Promise<ApiResponse>;
|
|
741
743
|
/** GET /tasks/{id} — rank: any-builder */
|
|
742
744
|
getTasksId(args?: RequestArgs): Promise<ApiResponse>;
|
|
743
745
|
/** PATCH /tasks/{id} — rank: metic+archon */
|
|
@@ -313,6 +313,8 @@ export function createClient(opts = {}) {
|
|
|
313
313
|
postGoalsIdRequestsReqIdWithdraw: (args) => request("POST", "/goals/{id}/requests/{reqId}/withdraw", { hasBody: true }, args),
|
|
314
314
|
// POST /goals/{id}/scope — rank: metic+archon — POST /goals/:id/scope
|
|
315
315
|
postGoalsIdScope: (args) => request("POST", "/goals/{id}/scope", { hasBody: true }, args),
|
|
316
|
+
// GET /goals/{id}/suggest-criteria — rank: any-builder — GET /goals/:id/suggest-criteria
|
|
317
|
+
getGoalsIdSuggestCriteria: (args) => request("GET", "/goals/{id}/suggest-criteria", { hasBody: false }, args),
|
|
316
318
|
// POST /goals/{id}/tasks — rank: any-builder — POST /goals/:id/tasks
|
|
317
319
|
postGoalsIdTasks: (args) => request("POST", "/goals/{id}/tasks", { hasBody: true }, args),
|
|
318
320
|
// POST /goals/{id}/transfer — rank: any-builder — POST /goals/:id/transfer
|
package/docker-entrypoint.sh
CHANGED
|
File without changes
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# ADR 0139 — Migrate the platform work-history from the Off the Boats instance DB to the cloudbongos DB
|
|
2
|
+
|
|
3
|
+
- **Status:** Accepted — **MIGRATION COMPLETE 2026-07-11** (owner greenlit the production run + the cut). Load into cloudbongos + verification done; TIER-2 valuable-history sweep done; and the WS-6 clean cut **fired + verified on live amazonprimea** (now game-only). The CB↔OTB split is complete (code + data). See the **Execution record** at the end.
|
|
4
|
+
- **Date:** 2026-07-10
|
|
5
|
+
- **Track:** internal (platform)
|
|
6
|
+
- **Decides:** whether — and how — the Cloud Bongos *platform* work-history (tasks, goals, done-when criteria, the credit ledger, builder identities + balances) is physically relocated from the `amazonprimea` (Off the Boats "customer zero") Postgres database to the `cloudbongos` database, so a builder signing into the cloudbongos hall with the same GitHub sees their earned balance.
|
|
7
|
+
- **Builds on:** ADR 0103 (core-first extraction; cloud-bongos is the trunk), ADR 0108 (configurable-root; the code half), ADR 0100 §3 (per-repo GDS), ADR 0016 (server-enforced permissions / trust boundary).
|
|
8
|
+
- **Supersedes framing of:** ADR 0107 §3, which *deferred* cross-instance identity/payout as an open question, and the goal-41 "identity federated, authority per-project" design string. This ADR is the deliberate, bounded decision those left open — see Context.
|
|
9
|
+
- **Companion:** the **code half** of the CB↔OTB split (amazonprimea task 1728 / R89 cutover; cloud-bongos re-seeded to the authoritative source by amazonprimea task 2190). This ADR is the **data half**.
|
|
10
|
+
|
|
11
|
+
## Context
|
|
12
|
+
|
|
13
|
+
Off the Boats (`amazonprimea` DB) is where Cloud Bongos itself was built — "customer zero." The R89 cutover already moved the platform **code** out: amazonprimea now consumes `@bongos/core` as a vendored dependency, and cloud-bongos is the authoritative editable core source. What remains inside the `amazonprimea` database is the platform's entire **work-history**: ~2,000+ platform tasks/goals/criteria, the credit ledger, and the builder identities that earned those credits — interleaved with the game's own ~57 tasks and game-earned credits.
|
|
14
|
+
|
|
15
|
+
The requirement: a builder who signs into the cloudbongos hall with the same GitHub account should see the platform balance they earned. The platform's *own* design deliberately drew a line against this — goal-41's design says "identity is federated, authority (ranks/credits) is **not**," and ADR 0107 §3 explicitly defers cross-instance payout. So **relocating balances runs counter to that line and therefore needs its own decision record** — this ADR. It is *not* the future federation hub (goal 41), and it is not "finishing" an existing plan; it is a one-time, supervised data move.
|
|
16
|
+
|
|
17
|
+
No cross-instance data-mover exists today. The only tooling is per-instance `pg_dump` backup; provisioning creates an *empty* DB; the public-mirror export moves *source code*, not data. The mover (WS-2) is therefore bespoke and is the bulk of the effort.
|
|
18
|
+
|
|
19
|
+
## Decision
|
|
20
|
+
|
|
21
|
+
### Locked decisions (owner)
|
|
22
|
+
|
|
23
|
+
1. **Clean move, not copy.** The platform history *leaves* Off the Boats. No frozen dual copy — two diverging ledgers would double-count balances and rot.
|
|
24
|
+
2. **Game credits stay at Off the Boats.** Everything else — platform credits, including orphan/no-task session & bonus awards — moves.
|
|
25
|
+
3. **Identity is keyed by `builders.github_id`** (a stable global value present in both DBs). The migrated balance surfaces automatically on the builder's *existing* per-instance GitHub sign-in — **no federation hub is required**.
|
|
26
|
+
4. **Currency: the number moves, the label adapts.** The reward unit is the integer `credits`; the label ("drachmae" at OTB, "credits" at the neutral starter) is pure instance config (`branding.currency.label`, ADR-referenced `<redacted>`). A 1,000 balance arrives as 1,000 in cloudbongos's unit automatically. *(Open: whether cloudbongos relabels to "drachmae" — see Open Questions.)*
|
|
27
|
+
5. **The cloudbongos DB is near-empty → clean load, not a merge.** Only `lars589` (auto-seated founding Archon) and one CB-V1 test task exist; preserve them.
|
|
28
|
+
6. **The ETL runs one-time, supervised, from the owner's Mac over SSH**, reaching both droplets' databases. It is not a builder-facing tool.
|
|
29
|
+
|
|
30
|
+
### Classification is decided at the version level
|
|
31
|
+
|
|
32
|
+
Every task/goal/criterion/credit inherits its **version's** label. `versions.id` is a text PK, so version rows copy without renumbering.
|
|
33
|
+
|
|
34
|
+
| MOVE → cloudbongos (platform) | STAY at Off the Boats (game) |
|
|
35
|
+
|---|---|
|
|
36
|
+
| PMS-V1, PMS-V2, GDS-V3, GDS-V4 → BONGOS-V1 and all their tasks/goals/criteria/credits | Off the Boats V1/V2/V3 and their tasks/goals/pixel-art |
|
|
37
|
+
| The dependency graph among those records | Credits earned on game work |
|
|
38
|
+
| A copy of each builder identity (keyed by github_id) carrying the platform balance | The live game world + Colyseus server (untouched) |
|
|
39
|
+
|
|
40
|
+
Edge cases: work that *built* the art pipeline = platform (moves); *running* it to draw tiles = game (stays) — WS-1 includes a human review pass. Orphan credits (`task_id = NULL`) move with the platform (reversible if the owner disagrees).
|
|
41
|
+
|
|
42
|
+
## Workstreams (filed under switchover goal 26; execution owner-gated)
|
|
43
|
+
|
|
44
|
+
- **WS-0 — Re-provision cloudbongos.com onto core 1.17.3 on a fresh DB, FIRST.** The box still runs a lift-and-shift clone whose deploy script references R89-removed paths; a re-provision *after* a load would wipe it. Must precede any data load. Preserve/re-seat the `lars589` Archon.
|
|
45
|
+
- **WS-1 — Label every version game vs platform** (the single line that decides the move-set) + human pass over art-pipeline-style edge cases.
|
|
46
|
+
- **WS-2 — Build the one-time mover (most effort).** Renumber bigint PKs; match builders by `github_id`; remap every FK; handle the polymorphic `dependencies` table per-kind; load with sync/promotion triggers OFF; preserve the `credit_log` idempotency key. **Prove on a throwaway copy first — never run blind on live.**
|
|
47
|
+
- **WS-3 — This ADR.**
|
|
48
|
+
- **WS-4 — Move day (OWNER GREENLIGHT REQUIRED).** Brief platform-write freeze at amazonprimea; full DB snapshots of both sides; run the mover into cloudbongos; rebuild balances from the ledger. Still reversible — amazonprimea untouched until WS-6.
|
|
49
|
+
- **WS-5 — Prove it.** Reconcile record counts both sides; sample balances to the drachma; and the real test — a live GitHub sign-in at cloudbongos shows the right person with the right balance.
|
|
50
|
+
- **WS-6 — Clean cut at Off the Boats.** Only after WS-5: delete the moved records from amazonprimea (reverse FK/dependency order), rebuild amazonprimea balances to game-only, repoint platform doc-links to cloudbongos.
|
|
51
|
+
- **WS-7 — Close the switchover.** Tie off the goal; tell builders where their history now lives.
|
|
52
|
+
|
|
53
|
+
## DB mechanics (the production hazards the mover must respect)
|
|
54
|
+
|
|
55
|
+
- **Schema lives in `@bongos/core`** under `package/migrations/*.sql` (not in the amazonprimea repo anymore). `003_pms.sql` is foundational.
|
|
56
|
+
- **Bigserial PK collision.** Both DBs allocate 1,2,3…; a naive copy collides on PK and *silently mis-links* FKs. Collide: `builders/tasks/claims/goals/credit_log/cost_log/karma_log/done_when_criteria/builder_sessions/idea_inbox/learnings/goal_membership_requests/core_upgrades`. Only text/natural PKs copy cleanly (`versions`, `achievements`). People are re-keyed off the natural `builders.github_id` (UNIQUE); everything else gets a fresh offset, and **every FK is rewritten** to the remapped ids.
|
|
57
|
+
- **Polymorphic `dependencies` table — highest risk.** `(from_kind, from_id, to_kind, to_id)` over {task, goal, criterion} has **NO foreign keys** — ids are bare bigints disambiguated only by `*_kind`. The mover must remap `from_id`/`to_id` **per-kind**, or edges silently repoint. (The older `020_task_dependencies` task→task list also needs remapping.)
|
|
58
|
+
- **`credit_log` double-count trap.** `credit_log` is an append-only ledger; `builders.total_credits` is a trigger-maintained cache (`trg_credit_log_apply` → `+= delta` on INSERT). Authoritative balance = `SUM(credit_log.delta)` per builder. **Load with triggers OFF, then rebuild `total_credits` from `SUM(delta)`** — else balances double. Same shape for `karma_log` → `builders.karma`.
|
|
59
|
+
- **Idempotency key must be preserved.** A partial unique index on `credit_log(session_id) WHERE reason='session.token_reward'` enforces one token-reward payout per session. If the index or `session_id` values are lost, the token-reward path **double-pays on replay**.
|
|
60
|
+
- **Promotion triggers also fire on status writes** (auto-promote backlog→ready on ship/satisfy/achieve). Load with all triggers disabled, then re-enable.
|
|
61
|
+
|
|
62
|
+
## Consequences
|
|
63
|
+
|
|
64
|
+
- **Positive:** the platform's work-history + rewards live at their true home; builders keep their earned balance across the sign-in they already use; the CB↔OTB separation is completed (data + code); no standing federation infrastructure is incurred.
|
|
65
|
+
- **Reversibility:** everything through WS-5 is reversible — amazonprimea is untouched until WS-6, and both sides are snapshotted on move day. The point of no return is WS-6 (the clean cut).
|
|
66
|
+
- **Risk:** a mistimed trigger or a missed FK/idempotency remap corrupts balances. Mitigation: prove the mover on a throwaway clone (WS-2), triggers-off load + ledger rebuild (WS-4), and full reconciliation before the cut (WS-5).
|
|
67
|
+
|
|
68
|
+
## Open questions (owner)
|
|
69
|
+
|
|
70
|
+
1. Confirm the exact game/platform version line (the single decision that fixes the move-set).
|
|
71
|
+
2. Currency label at cloudbongos — keep "credits" or relabel to "drachmae" (one-line config; balances identical either way).
|
|
72
|
+
3. Confirm tracking home for WS-0…WS-7 (proposed: switchover goal 26).
|
|
73
|
+
4. Greenlight to *execute* (WS-4 onward) — nothing runs against production until then.
|
|
74
|
+
5. WS-0 reality check — confirm cloudbongos.com was fully re-provisioned onto core 1.17.3 on a fresh DB, not merely code-updated.
|
|
75
|
+
6. Orphan credits (`task_id = NULL`) — confirm the "move with platform" rule.
|
|
76
|
+
|
|
77
|
+
### Open questions — RESOLVED (owner, 2026-07-11)
|
|
78
|
+
|
|
79
|
+
1. Version line: **game V1/V2/V3 stay; PMS-V1, PMS-V2, GDS-V3, GDS-V4, BONGOS-V1 move** (as tabled). 2. Currency: **keep label "credits" at cloudbongos, 1:1 with drachmae** (no relabel). 3. Tracking home: **cloudbongos**. 4. **Greenlight given** — execute through production. 5. WS-0 reality check delegated to the executor → **verified: cloudbongos.com already runs @bongos/core 1.17.4 on the dependency model; no re-provision performed** (would have wiped legit native data). 6. Orphan credits: **move with platform** (confirmed).
|
|
80
|
+
|
|
81
|
+
## Execution record (2026-07-11)
|
|
82
|
+
|
|
83
|
+
Executed from the cloudbongos droplet (the ETL host): reads amazonprimea via the live `cohost-db-tunnel` (`127.0.0.1:5433`), writes the local cloudbongos DB. Scripts + full snapshots persist at `/home/lars/mig/` (`mover.js`, `verify.js`, `cut.js`, both pg_dumps, a pre-load cloudbongos snapshot). Tracked as amazonprimea switchover tasks 2192–2198.
|
|
84
|
+
|
|
85
|
+
- **WS-0 (2192):** verified already-provisioned (core 1.17.4); no re-provision.
|
|
86
|
+
- **WS-1 (2193):** per-table move-set classified (14 platform-history tables; ~50 OTB-instance-infra tables correctly stay).
|
|
87
|
+
- **WS-2 (2194):** mover built (Node ETL: +1,000,000 PK offset; builders merged by `github_id`; versions upsert; deletes the target's core-seeded placeholder platform goals/criteria first; triggers-off load then rebuild `total_credits`/`karma` from `SUM(delta)`; `credit_log` `ON CONFLICT` on the token-reward partial index `DO NOTHING`). **Rehearsed on a throwaway copy: 25/25 checks pass.**
|
|
88
|
+
- **WS-4 (2195):** **live load into cloudbongos COMMITTED** — 1,865 tasks, 27 goals, 69 criteria, 1,678 claims, 1,373 credit rows (1 token-reward idempotency skip), + full history; FK-check clean. Pre-load snapshot taken; amazonprimea untouched (fully reversible).
|
|
89
|
+
- **WS-5 (2196):** **verified on live cloudbongos — 25/25.** All table counts + all six builder balances reconcile (lars589 **37,072**; jaxri 5,341; scootermack 2,389; IAMMASTERQUA 195; LarsCode 44; kingaonline 36). Game/native preserved; 0 FK orphans. `cloudbongos.com` leaderboard serves the migrated builders.
|
|
90
|
+
- **WS-5b (2199) — TIER-2 valuable sweep (post-audit):** a full 59-table completeness audit confirmed the core move was 100% complete (2 flagged gaps were false positives), and surfaced ~13k deferred TIER-2 rows. Owner chose the valuable sweep → `sweep2.js` carried builder_memory, grading history, session_records/BFG, vulnerability_reports, builder_sessions (tokens redacted; restored 1,442 nulled claim links), + governance rows to cloudbongos; **verified 18/18**. Only the rebuildable `search_chunks` retrieval index was intentionally skipped.
|
|
91
|
+
- **WS-6 (2197) — clean cut: FIRED + verified on live amazonprimea.** Pre-fire review found the first-draft cut too aggressive (it would delete live-game learnings/ideas/blockers), so it was rewritten **surgical** (`cut2.js`): deletes only platform-version-scoped work + the platform/orphan credit ledger, and preserves game + unlinked methodology, karma, builder-level tables, and all auth/game data. Run as the non-superuser app user (no trigger-disable) with children-before-parents + FK enforcement (safer). Rehearsed clean on a fresh copy, then fired after a final backup. Result: amazonprimea is game-only (versions V1/V2/V3, 157 game tasks, 123 game claims + auth intact, lars589 38,919→**1,824**, ledger reconciles, 0 platform residue, 0 FK orphans, app healthy).
|
|
92
|
+
- **WS-7 (2198):** data + cut complete. Sole remaining owner step: announce to builders (Discord) where their history now lives.
|
|
93
|
+
|
|
94
|
+
**Notes:** the migration's own bookkeeping tasks (2192–2199, all BONGOS-V1) moved to cloudbongos and were then removed from amazonprimea by the cut — self-referential, expected; their record lives here + in session memory. The 56-credit token-reward for the shared session `1b57dcb4` is dropped by the idempotency skip. Minor residue intentionally kept on amazonprimea (harmless, also on cloudbongos): platform karma, unlinked ideas/learnings, and vuln/achievement rows with nulled platform refs. Doc-links to platform tasks in the OTB repo now resolve on the cloudbongos hall. Scripts + backups: `/home/lars/mig/` on the cloudbongos droplet.
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# ADR 0140 — cloudbongos.com re-provisioned to the standalone model, DB-preserving (closes ADR 0139 WS-0)
|
|
2
|
+
|
|
3
|
+
- **Status:** Accepted — executed 2026-07-12
|
|
4
|
+
- **Date:** 2026-07-12
|
|
5
|
+
- **Deciders:** Lars (owner)
|
|
6
|
+
- **Track:** internal (platform / infra)
|
|
7
|
+
- **Builds on:** ADR 0108 (configurable-root / standalone consumer model), ADR 0126 (dedicated cloudbongos.com droplet), ADR 0129 (pull-timer deploy), ADR 0139 (CB↔OTB data migration — this closes its WS-0)
|
|
8
|
+
|
|
9
|
+
## Context
|
|
10
|
+
|
|
11
|
+
cloudbongos.com ran as a **lift-and-shift clone of the `amazonprimea` game repo** (ADR 0126): the `cloudbongos` systemd service executed `src/platform-server.js` out of `/home/lars/cloudbongos` (a checkout whose `origin` was `lars589/amazonprimea`), branded via `GDS_BRANDING_FILE`, against the separate `cloudbongos` DB.
|
|
12
|
+
|
|
13
|
+
ADR 0139's **WS-0** called for re-provisioning cloudbongos.com onto the ADR 0108 standalone `@bongos/core` model *first, on a fresh DB*. WS-0 was recorded as "verified already-provisioned; no re-provision performed" — but that verification was wrong: the box kept running the amazonprimea clone. The data-half workstreams (WS-4/5/6) then loaded the platform history into the `cloudbongos` DB and cut OTB.
|
|
14
|
+
|
|
15
|
+
The gap surfaced on 2026-07-12: `builders.cloudbongos.com` served a bare, unstyled shell — every `/builders/*` asset 404'd. Root cause: the running process was frozen on stale amazonprimea code (its pull-deploy silently no-op'd because `origin` tracked the unchanged amazonprimea repo, not a cloudbongos instance). The site had **never run the restored code**.
|
|
16
|
+
|
|
17
|
+
The key constraint that inverts WS-0's original plan: the `cloudbongos` DB is now **full** — the migrated work-history and credit balances (e.g. `lars589` = 37,072). WS-0's "fresh DB" re-provision would wipe it. So the re-provision had to be **DB-preserving**.
|
|
18
|
+
|
|
19
|
+
## Decision
|
|
20
|
+
|
|
21
|
+
We will convert cloudbongos.com to a proper ADR 0108 **standalone instance**, preserving the existing `cloudbongos` DB, via a **build-alongside-then-flip** procedure:
|
|
22
|
+
|
|
23
|
+
1. **Its own instance repo** — `cloudbongos/cloudbongos-instance` (private): lean `config/` (`branding.json` = the real cloudbongos.com domains over the neutral "Cloud Bongos" brand; `modules.json` = game-less + `provisioning`), a `bongos.config.json` instance-root pointer, and a **pinned `@bongos/core@1.17.3`** dependency. The engine, hall, and all platform code come from the package.
|
|
24
|
+
2. **Materialize beside the old checkout** — clone + `npm ci` into a new dir (`/home/lars/cloudbongos-instance`); the old `/home/lars/cloudbongos` stays untouched as rollback.
|
|
25
|
+
3. **Prove before flipping** — boot on a spare port against the live DB; confirm the hall serves and the leaderboard reads migrated balances; confirm `migrate` is a **no-op** (the DB already carries all 112 of 1.17.3's migrations).
|
|
26
|
+
4. **Flip the service** — `cloudbongos.service` `WorkingDirectory` → the instance, `ExecStart` → `node_modules/@bongos/core/src/platform-server.js`; drop `GDS_BRANDING_FILE`; add `CLOUDBONGOS_INSTANCE_ROOT`; keep `PGDATABASE` + OAuth via `/etc/cloudbongos/web.env`. Back up the old unit first.
|
|
27
|
+
5. **Repoint the ADR 0129 pull-deploy** — rewrite `/home/lars/deploy.sh` to fetch/reset the instance repo → `npm ci` (lockfile-gated) → core-package `migrate` → restart → healthz.
|
|
28
|
+
|
|
29
|
+
The engine **source stays authoritative at `lars589/cloud-bongos`** (not relocated); the instance consumes `@bongos/core` from npm. A **verified DB backup precedes all changes**, and the old checkout + old unit + old deploy script are retained for instant rollback.
|
|
30
|
+
|
|
31
|
+
## Alternatives considered
|
|
32
|
+
|
|
33
|
+
- **Run cloudbongos.com directly from the `cloud-bongos` engine repo.** Rejected: it forces one host's identity into the shared/authoritative engine (the very anti-pattern that entangled cloudbongos with the amazonprimea repo), and it would ride the engine's development `main` with no stable pin — any work-in-progress commit could take the live site down.
|
|
34
|
+
- **Keep the amazonprimea lift-and-shift; just restart / repoint that checkout.** Rejected: leaves the intended standalone model unfinished and keeps cloudbongos coupled to the OTB repo.
|
|
35
|
+
- **Vanilla WS-0 (fresh-DB re-provision).** Rejected now: it would wipe the freshly-migrated history and balances — the whole point of ADR 0139. Hence the DB-preserving variant.
|
|
36
|
+
- **Reuse an existing repo for the site** — `cloud-bongos` (the engine) or `cloudbongos/bongos` (the public AGPL source mirror). Rejected: both hold load-bearing roles; a dedicated `cloudbongos/cloudbongos-instance` keeps host identity out of both.
|
|
37
|
+
|
|
38
|
+
## Consequences
|
|
39
|
+
|
|
40
|
+
- cloudbongos.com runs the clean standalone model: hall renders, all three hosts (apex/builders/status) healthy, DB + balances intact. Future platform updates are a one-line `@bongos/core` pin bump, auto-deployed within ~2 min by the repointed pull-timer.
|
|
41
|
+
- **Closes ADR 0139 WS-0** (belatedly, in DB-preserving form).
|
|
42
|
+
- Deploy keys had to be **enabled org-wide on the `cloudbongos` org** so the box's read-only deploy key could attach to an org repo (they were disabled by default).
|
|
43
|
+
- Follow-ups (non-blocking): retire `/home/lars/cloudbongos` + the backups after a soak; version `/home/lars/deploy.sh` into the instance repo and restore the ADR 0129 self-heal step; the packaged engine's `CORE_VERSION` constant lags its `package.json` (reports 1.17.2 while running 1.17.3) — cosmetic, flag upstream.
|
package/docs/adr/README.md
CHANGED
|
@@ -209,4 +209,7 @@ This keeps the decision history honest and traceable.
|
|
|
209
209
|
| 0137 | [Upstream publish policy: `@bongos/core` patches are published MANUALLY (owner-gated), NOT auto-published on merge (task [#2158](https://example.com/builders#/task/2158), BONGOS-V1, goal 26; the SUPPLY half split out of ADR 0136 §5 / task 2150, builds on ADR 0134). Owner chose manual over auto. Decision: the owner runs `package-core.js --publish --live` to cut a release (optional `core-v<version>` git tag as the auditable marker — triggers no CI); `CORE_VERSION` (src/module-api.js) is bumped by hand in-task with a changelog line (provenance stays in git, not a release-tool side effect); NO npm write-token at rest (preserves ADR 0134 tokenless tooling — owner auths at publish time; only the read token exists); the no-leak/mirror-redact gate is already fail-closed inside `package-core.js`, so `--publish` cannot upload a leaking artifact. The ADR 0136 subscription consumes whatever is published; freshness is owner-paced by design. Rejected: auto-publish-on-merge (needs a standing npm write-token as a CI secret — reverses the tokenless posture for little gain at low, deliberate release volume). Revisit as a tag-triggered CI publish when the managed-fleet epic (task 1948) makes the manual step a real bottleneck. Ritual: docs/recipes/private-npm-distribution.md "Cutting a core release".](<redacted>.md) | distribution / npm |
|
|
210
210
|
| 0138 | [A core-bundled module's external npm deps are declared per-module; the consumer composes them, core stays lean (task [#2160](https://example.com/builders#/task/2160), BONGOS-V1, goal 26; R89 cutover rehearsal finding F2, builds on ADR 0108 + ADR 0083). The discord module ships inside `@bongos/core` but `package-core.js` declares only express+pg, so a consumer that enables discord crashed at boot on missing `discord.js` (the only such case; discord is `default:false`). Owner chose lean-core over hoisting. Decision: core deps stay express+pg; a bundled module declares its own npm deps in `module.json` `dependencies` (schema-validated in `manifest-schema.js`; discord declares `discord.js`); greenfield `bongos init` composes the ENABLED modules' deps into the instance package.json (`enabledModuleDeps`→`buildInstancePackageJson`, existing pin wins, core always set); the R89 cutover preserves the monolith's existing closure ∪ core. Rejected: hoisting `discord.js` into core `optionalDependencies` (installs for EVERY consumer though discord is opt-in — cuts against ADR 0108 lean-core); `peerDependencies` (optional peers aren't auto-installed → crash remains; required peers = hoisting-with-warnings).](<redacted>.md) | modules / distribution |
|
|
211
211
|
|
|
212
|
+
| 0139 | [Migrate the platform work-history (tasks/goals/credits/builder identities) from the Off the Boats instance DB to the cloudbongos DB — the DATA half of the CB↔OTB split (companion to the R89 code half). Owner-locked: clean move (platform history leaves OTB), game credits stay, identity keyed by `builders.github_id` (balance surfaces on the existing GitHub sign-in, no federation hub), currency number moves + label adapts, near-empty target = clean load. Needs its own ADR because it deliberately crosses the goal-41 "authority stays per-project" line + ADR 0107 §3's deferral. WS-0 (re-provision cloudbongos.com onto core 1.17.3 first) … WS-7; the mover (WS-2) is bespoke — bigint PK renumber + full FK remap, the polymorphic `dependencies` table per-kind, `credit_log` load-with-triggers-off then rebuild `total_credits` from `SUM(delta)`, preserve the `session.token_reward` idempotency index. EXECUTION is owner-gated (WS-4+); nothing runs against production until greenlit; prove on a throwaway copy first.](<redacted>.md) | platform / migration |
|
|
213
|
+
| 0140 | [cloudbongos.com re-provisioned to the ADR 0108 standalone model, DB-PRESERVING — closing ADR 0139's skipped WS-0 (executed 2026-07-12). The site was a lift-and-shift clone of the `amazonprimea` repo frozen on stale code — every `/builders/*` asset 404'd — because its pull-deploy silently no-op'd against the unchanged game repo (`origin` was `lars589/amazonprimea`, not a cloudbongos instance); it had never run the restored code. WS-0's original fresh-DB re-provision would now WIPE the migrated history/balances, so a build-alongside-then-flip variant was used: a dedicated private `cloudbongos/cloudbongos-instance` repo (lean config over the neutral brand + a pinned `@bongos/core@1.17.3`), materialized beside the untouched old checkout, proven on a spare port against the live DB (migrate = clean no-op; leaderboard read migrated balances), then `cloudbongos.service` flipped to the instance + engine and the ADR 0129 pull-timer repointed at the instance repo. Engine source stays authoritative at `lars589/cloud-bongos` (not relocated); verified DB backup + retained old checkout/unit/deploy-script give instant rollback. Enabled org-wide deploy keys on the `cloudbongos` org so the box's read-only deploy key could attach.](<redacted>.md) | infra / Cloud Bongos |
|
|
214
|
+
|
|
212
215
|
> ⚠️ **Numbering collision (known):** two ADRs share `0008`. The numbers were assigned in parallel sessions before the lock could be enforced. The files are kept under their existing filenames to preserve git history, but the table disambiguates them as `0008-a` / `0008-b`. New ADRs should resume at `0040` to avoid further collisions. (`0024` is also a real on-disk duplicate: the cloneable-repo/local-first-memory ADR and the multi-agent-system-architecture ADR were both numbered `0024` in parallel; both keep their filenames, disambiguated as `0024-a` / `0024-b` like `0008`. Likewise `0025` ended up with two on-disk files — the offsite-backup ADR and the structured-criterion↔task-link ADR — both kept under their existing filenames and disambiguated as `0025-a` / `0025-b`; separately, the BFG ADR had also claimed `0025` on 2026-05-30 and yielded to `0026`. A third happened 2026-06-06: `0036` was claimed in parallel by the builders-subdomain ADR ([#726](https://example.com/builders#/task/726)) and this Discord-channels ADR ([#727](https://example.com/builders#/task/727)); the Discord-channels ADR yielded to `0037`. A fourth landed 2026-06-10: `0044` was claimed in parallel by the palette-replacement ADR and the per-box game-preview ADR ([#897](https://example.com/builders#/task/897)); both keep their filenames, disambiguated as `0044-a` / `0044-b` like `0008`. A fifth was caught pre-land 2026-06-13: `0050` was claimed in parallel by the device-flow-admission ADR ([#1000](https://example.com/builders#/task/1000)) and the sandbox-for-everyone ADR ([#1001](https://example.com/builders#/task/1001)); the latter yielded to `0052` before merging, so there is no `0050` duplicate. A sixth was caught pre-land 2026-06-21: the tool-agnostic-design-layer ADR ([#1375](https://example.com/builders#/task/1375)) first collided at `0079` with the value-gated-autonomous-engagement ADR, then at `0080` with the llm-cache-api-transport ADR (both part of the 0075–0080 LLM-cost-reduction series, landed on `main` in parallel); it yielded to `0081` before merging, so there is no `0079`/`0080` design-layer duplicate. A seventh landed 2026-06-23: `0084` was claimed in parallel by the auto-derived-per-task-rank-floor ADR and the remove-default-spend-cap ADR (task 1499); the rank-floor ADR landed on `main` first, so the spend-cap ADR yielded to `0085`, leaving no `0084` duplicate. An eighth landed 2026-06-27: `0095` was claimed in parallel by the borrowed-memory-and-retrieval-concepts ADR (PR #459, landed first) and the cross-agent-context-management ADR ([#1651](https://example.com/builders#/task/1651), PR #460); both keep their filenames, disambiguated as `0095-a` / `0095-b` like `0008`. These two are companions — `0095-a` adopts the memory/retrieval concepts and explicitly defers the grep-vs-semantic question to `0095-b`.)
|