@bongos/core 1.17.0 → 1.17.1
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 +154 -83
- package/CLAUDE.md +11 -238
- 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/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/README.md +5 -4
- package/docs/api/openapi.json +315 -6
- package/docs/api-reference.md +10 -5
- package/docs/architecture.md +1 -1
- package/docs/file-map.md +2 -2
- package/docs/modules-contract.md +2 -0
- package/docs/recipes/instance-deploy.md +4 -4
- package/docs/recipes/instance-first-run.md +51 -0
- package/docs/recipes/packaging-the-core.md +5 -5
- package/docs/recipes/private-npm-distribution.md +22 -12
- package/docs/recipes/self-host.md +1 -1
- package/docs/recipes/upgrading-the-core.md +8 -8
- 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/economy/CLAUDE.md +11 -44
- package/modules/grading/CLAUDE.md +11 -38
- package/modules/hall-ui/CLAUDE.md +11 -57
- package/modules/hall-ui/public/goals-page.js +227 -22
- package/modules/hall-ui/public/goals.html +16 -0
- package/modules/hall-ui/public/new-project-wizard.js +5 -4
- 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/security/CLAUDE.md +11 -40
- package/modules/sessions/CLAUDE.md +11 -35
- package/modules/status-ui/CLAUDE.md +11 -43
- package/package-lock.json +2 -2
- package/package.json +1 -1
- package/public-landing/create.html +58 -12
- package/public-landing/index.html +40 -21
- package/scripts/gds/CLAUDE.md +11 -140
- package/scripts/gds/claude-materialize.js +151 -18
- package/scripts/gds/claude-md-template.js +84 -0
- package/scripts/gds/cli-lib.js +112 -2
- package/scripts/gds/gen-api-client.js +10 -10
- package/scripts/gds/init.js +53 -13
- package/scripts/gds/migration-namespace.js +1 -1
- package/scripts/gds/module.js +118 -4
- package/scripts/gds/npmrc.js +93 -0
- package/scripts/gds/onboard.js +13 -24
- package/scripts/gds/package-core.js +56 -14
- package/scripts/gds/provision.js +102 -17
- 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/upgrade.js +58 -18
- package/src/bongos/CLAUDE.md +11 -60
- package/src/bongos/auth.js +11 -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/instance-config.js +1 -1
- package/src/module-api.js +13 -1
- package/tests/claude_materialize.mjs +105 -0
- package/tests/device_flow_start.mjs +73 -0
- package/tests/first_run_engine_check.mjs +79 -0
- package/tests/goal_membership_requests.mjs +33 -3
- package/tests/hook_user_agents.mjs +62 -0
- package/tests/init.mjs +59 -6
- package/tests/instance_mismatch_guard.mjs +101 -0
- package/tests/module_cli.mjs +130 -2
- package/tests/module_submissions.mjs +135 -0
- package/tests/npmrc.mjs +105 -0
- package/tests/onboard.mjs +49 -0
- package/tests/package_core.mjs +68 -22
- package/tests/platform_boot.mjs +5 -2
- package/tests/provision.mjs +107 -8
- package/tests/provisioning_github_app_routes.mjs +29 -2
- package/tests/served_paths_shipped.mjs +2 -2
- package/tests/task_cli.mjs +99 -0
- package/tests/upgrade.mjs +89 -25
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
> Implements [ADR 0100 §1](../adr/<redacted>.md) (the two-repo instance model). This is **R84**, the first step of the `R84 → R85 → R86` spine: package the core → stand a downstream instance up on a pinned core → make `bongos upgrade` a real update channel. Tooling: [`scripts/gds/package-core.js`](../../scripts/gds/package-core.js) (`bongos package-core`).
|
|
4
4
|
>
|
|
5
|
-
> **Real installable npm package ([ADR 0108](../adr/<redacted>.md) §2, task 1882/W2, shipped):** the artifact is `package/`-rooted (the npm convention `npm install ./x.tgz` requires) and carries a synthesized `package.json` — `name: "@
|
|
5
|
+
> **Real installable npm package ([ADR 0108](../adr/<redacted>.md) §2, task 1882/W2, shipped):** the artifact is `package/`-rooted (the npm convention `npm install ./x.tgz` requires) and carries a synthesized `package.json` — `name: "@bongos/core"`, `version` = `CORE_VERSION`, `main: "src/platform-server.js"`, `exports` for the default entry (`buildPlatformApp`) plus `./serve-internal` (`mountInternalSurfaces`) and `./module-api`, `bin: "bongos"` — and a **pruned** `package-lock.json` (express + pg's own transitive closure only, resolved offline from the source lockfile — no colyseus/phaser/sharp/discord.js). Both files are synthesized fresh, never copied verbatim from the source repo's game-heavy `package.json`. `resolveCoreRoot()`/`resolveInstanceRoot()` ([`src/instance-config.js`](../../src/instance-config.js), W1/task 1881) are what a consumer's own code routes through once installed.
|
|
6
6
|
|
|
7
7
|
## What the artifact is
|
|
8
8
|
|
|
@@ -12,9 +12,9 @@ A Cloud Bongos *instance* can be its **own repository** that installs a **pinned
|
|
|
12
12
|
|
|
13
13
|
| Output | What it is |
|
|
14
14
|
|---|---|
|
|
15
|
-
| `
|
|
16
|
-
| `
|
|
17
|
-
| `
|
|
15
|
+
| `bongos-core-<version>.tgz` | the installable unit — a gzip'd tar of the redacted core tree, rooted at `package/` (the npm convention `npm install ./x.tgz` requires), carrying a synthesized `@bongos/core` `package.json` + pruned `package-lock.json` (task 1882) |
|
|
16
|
+
| `bongos-core-<version>.manifest.json` | the **pin** — version, source commit, per-file hashes, and the tree hash a consumer verifies against |
|
|
17
|
+
| `bongos-core-<version>/` | the same redacted tree unpacked, for inspection |
|
|
18
18
|
|
|
19
19
|
The version is the **platform version** — `CORE_VERSION` from [`src/module-api.js`](../../src/module-api.js), the same coordinate the module loader and `bongos upgrade` compare against ([#1203](https://example.com/builders#/task/1203)). That shared coordinate is what keeps the spine coherent: a module pinned to `^core_contract` is guaranteed to load against the packaged core.
|
|
20
20
|
|
|
@@ -36,7 +36,7 @@ If the no-leak gate fails, it names the file + the residual literal. Fix the red
|
|
|
36
36
|
|
|
37
37
|
A downstream instance repo:
|
|
38
38
|
|
|
39
|
-
1. **Installs** the `.tgz` — `npm install ./
|
|
39
|
+
1. **Installs** the `.tgz` — `npm install ./bongos-core-<version>.tgz` (or a fetched-in-CI path) — which lands it at `node_modules/@bongos/core/`, a directory the consumer does not hand-edit.
|
|
40
40
|
2. **Pins** by recording `core_version` + `source_commit` + `tree_sha256` from the manifest.
|
|
41
41
|
3. **Verifies** the install by recomputing `tree_sha256` from the unpacked tree — for each core file, `sha256(content)` with a canonical mode (`0000644`/`0000755`), then `sha256` over the sorted `"<path> <mode> <filesha>"` lines. It must equal the manifest's `tree_sha256`. The tree hash is **compression-independent**, so it is a stable pin even though `.tgz` bytes are an implementation detail (`tarball.sha256` separately verifies the exact download).
|
|
42
42
|
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
# Recipe — private-first npm distribution (core + client)
|
|
2
2
|
|
|
3
|
-
> Implements [ADR 0134](../adr/<redacted>.md). Pre-launch, `@
|
|
3
|
+
> Implements [ADR 0134](../adr/<redacted>.md). Pre-launch, `@bongos/core` and `@bongos/client` publish as **private, scoped** npm packages on the owner's paid `bongos` npm org (the canonical brand); at launch they flip to public. The daily command is `bongos` regardless of package name.
|
|
4
4
|
>
|
|
5
|
-
> **Why private must be scoped:** on npm, *unscoped* names
|
|
5
|
+
> **Why private must be scoped:** on npm, *unscoped* names are always public — only *scoped* names (`@bongos/…`) can be private, and only on a paid plan. So the packages publish under the `@bongos` scope, which maps to the paid `bongos` org.
|
|
6
6
|
|
|
7
7
|
## The pieces
|
|
8
8
|
|
|
9
9
|
| Package | What it is | Built by |
|
|
10
10
|
|---|---|---|
|
|
11
|
-
| `@
|
|
12
|
-
| `@
|
|
11
|
+
| `@bongos/core` | the platform an instance installs + the `bongos` CLI (`bin`) | `bongos package-core` (`scripts/gds/package-core.js`) — synthesizes the package.json + a pruned lockfile, redacts, and packs a `.tgz` |
|
|
12
|
+
| `@bongos/client` | the generated typed API client | `node scripts/gds/gen-api-client.js` (regenerates `clients/bongos-client/`) |
|
|
13
13
|
|
|
14
14
|
Both carry `publishConfig: { access: "restricted" }`, so **publishing them is private by default** — no public leak if a flag is forgotten.
|
|
15
15
|
|
|
@@ -17,8 +17,8 @@ Both carry `publishConfig: { access: "restricted" }`, so **publishing them is pr
|
|
|
17
17
|
|
|
18
18
|
These involve payment and permanent, account-level actions. They are **not** done inside a build session.
|
|
19
19
|
|
|
20
|
-
1. **Put the `
|
|
21
|
-
2. **Create an access token.** npmjs.com → Access Tokens → *Generate New Token* → **
|
|
20
|
+
1. **Put the `bongos` npm org on a paid plan.** Private scoped publishing requires it. On npmjs.com → your org → Billing → upgrade to a plan that allows private packages (npm Teams, ~$7/member/month). Add as members only the people who need to publish or install during pre-launch — each is a billed seat.
|
|
21
|
+
2. **Create an access token.** npmjs.com → Access Tokens → *Generate New Token* → **Classic → Automation** (bypasses 2FA, which npm requires to publish), with **read-write** on the `@bongos` packages — a **read-only** token is enough for machines that only install. Store it as an environment variable, never in a committed file:
|
|
22
22
|
```sh
|
|
23
23
|
export NPM_TOKEN=<redacted>
|
|
24
24
|
```
|
|
@@ -32,7 +32,7 @@ Always preview with a dry-run first (no upload, no login needed):
|
|
|
32
32
|
node scripts/gds/package-core.js --publish
|
|
33
33
|
```
|
|
34
34
|
|
|
35
|
-
Look for `restricted access` and the `@
|
|
35
|
+
Look for `restricted access` and the `@bongos/core@<version>` line. When it looks right, publish for real (this is **permanent** — npm can't delete a name after 72h):
|
|
36
36
|
|
|
37
37
|
```sh
|
|
38
38
|
npm login # once per machine (+ 2FA)
|
|
@@ -58,13 +58,23 @@ Add a one-line `.npmrc` (repo-root or `~/.npmrc`) that reads the token from the
|
|
|
58
58
|
Then, with `NPM_TOKEN` set in the environment:
|
|
59
59
|
|
|
60
60
|
```sh
|
|
61
|
-
npm install -g @
|
|
62
|
-
npm install @
|
|
61
|
+
npm install -g @bongos/core # global → the `bongos` command, then `bongos init`
|
|
62
|
+
npm install @bongos/client # in a project that calls the API
|
|
63
63
|
```
|
|
64
64
|
|
|
65
65
|
Without a valid token + org membership the install 404s — that is the private gate working.
|
|
66
66
|
|
|
67
|
-
|
|
67
|
+
## Provisioning: registry pull vs vendored tarball (task 2090)
|
|
68
|
+
|
|
69
|
+
Provisioning defaults to installing the core from a **vendored tarball** committed into each instance repo (task 2053) — offline, needs no token, and stays the default/fallback until the registry path is proven on a real greenfield standup. The registry pull is **opt-in and fail-soft**:
|
|
70
|
+
|
|
71
|
+
- **Turn it on** by setting `PROVISION_CORE_FROM_REGISTRY=1` in the control-plane runner's environment (e.g. `/etc/cloudbongos/box.env`) **and** providing a read-only `NPM_TOKEN` (a Classic **Automation** token — read-only — from the paid `bongos` org). With both present, the standalone scaffold pins `@bongos/core@<version>` from the registry and writes an env-fed `.npmrc` (`_authToken=<redacted> instead of vendoring a tarball; `npm ci` then pulls the private package (the token is inherited from the runner env — never committed).
|
|
72
|
+
- **Fail-soft**: if the flag is set but `NPM_TOKEN` is absent, provisioning logs a notice and **falls back to the vendored tarball**, so a tokenless standup still works.
|
|
73
|
+
- **Directly**: `bongos init --registry-core` scaffolds the registry shape (caret pin + `.npmrc`; generates the lockfile when `NPM_TOKEN` is set). `bongos upgrade --to <v> --registry` bumps a consumer to a registry version. Both are mutually exclusive with the vendored `--vendor-core` / `--from` inputs.
|
|
74
|
+
|
|
75
|
+
A tokenless registry `npm ci` 404s cleanly (`E404 … @bongos/core … could not be found or you do not have permission to access it`) — the expected pre-launch outcome.
|
|
76
|
+
|
|
77
|
+
> **Proven end-to-end (2026-07-08, task 2118 / blocker 71).** A real `bongos init --registry-core` scaffold, with a valid read-only token in `NPM_TOKEN`, resolved `@bongos/core@1.17.0` straight from `registry.npmjs.org` and generated a reproducible `package-lock.json`. Both legs are confirmed: the registry pull works with a token and fails closed (404) without one. Provisioning still defaults to the vendored tarball until an owner explicitly sets `PROVISION_CORE_FROM_REGISTRY=1` on a live runner.
|
|
68
78
|
|
|
69
79
|
## Going public at launch
|
|
70
80
|
|
|
@@ -72,8 +82,8 @@ Pick either — both keep the daily `bongos` command working:
|
|
|
72
82
|
|
|
73
83
|
- **Flip the same scoped packages public** (simplest):
|
|
74
84
|
```sh
|
|
75
|
-
npm access public @
|
|
76
|
-
npm access public @
|
|
85
|
+
npm access public @bongos/core
|
|
86
|
+
npm access public @bongos/client
|
|
77
87
|
```
|
|
78
88
|
(Or change `publishConfig.access` to `"public"` and republish.) Public installs need no token; the paid seats can be dropped.
|
|
79
89
|
- **Also publish the unscoped vanity name** for `npm install -g cloudbongos` — that is [task 2025](https://example.com/builders#/task/2025) (rename in `package-core.js`/`upgrade.js` + docs), done at launch.
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Bring up a vanilla Cloud Bongos instance — the build platform + builders' hall + status dashboard, with no game — on any machine with Docker. Shipped by V4.R63 ([task #1202](https://example.com/builders#/task/1202), [ADR 0062](../adr/<redacted>.md)).
|
|
4
4
|
|
|
5
|
-
> **Relation to configurable-root ([ADR 0108](../adr/<redacted>.md)):** this is the **single-checkout** self-host shape — the whole repo (core + config) is baked into one image, so `resolveCoreRoot()` and `resolveInstanceRoot()` ([`src/instance-config.js`](../../src/instance-config.js)) both resolve to `/app` inside the container. ADR 0108 does not deprecate this path — it stays the cheap, supported shape for a quick reskin (this is how `cloudbongos.com` runs). The *installed-as-a-dependency* shape (a consumer repo running `npm install @
|
|
5
|
+
> **Relation to configurable-root ([ADR 0108](../adr/<redacted>.md)):** this is the **single-checkout** self-host shape — the whole repo (core + config) is baked into one image, so `resolveCoreRoot()` and `resolveInstanceRoot()` ([`src/instance-config.js`](../../src/instance-config.js)) both resolve to `/app` inside the container. ADR 0108 does not deprecate this path — it stays the cheap, supported shape for a quick reskin (this is how `cloudbongos.com` runs). The *installed-as-a-dependency* shape (a consumer repo running `npm install @bongos/core`) is the separate, heavier path ADR 0108 targets for a project that wants its own repo and its own upgrade cadence — see [`docs/recipes/packaging-the-core.md`](packaging-the-core.md).
|
|
6
6
|
|
|
7
7
|
## One command
|
|
8
8
|
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
# Recipe — upgrading a consumer instance's Cloud Bongos core (`bongos upgrade`)
|
|
2
2
|
|
|
3
|
-
> The R86 update-consumption channel ([ADR 0100](../adr/<redacted>.md) §2, [ADR 0103](../adr/<redacted>.md) §4, task [#1690](https://example.com/builders#/task/1690)). How a **two-repo consumer instance** — one that installs `@
|
|
3
|
+
> The R86 update-consumption channel ([ADR 0100](../adr/<redacted>.md) §2, [ADR 0103](../adr/<redacted>.md) §4, task [#1690](https://example.com/builders#/task/1690)). How a **two-repo consumer instance** — one that installs `@bongos/core` as a vendored-tarball dependency — pulls the core from version N → N+1. Tooling: [`scripts/gds/upgrade.js`](../../scripts/gds/upgrade.js) (`bongos upgrade`). First proven live on emersonian-circles 1.15.0 → 1.16.0 (task [#1976](https://example.com/builders#/task/1976)).
|
|
4
4
|
|
|
5
5
|
## What the channel does
|
|
6
6
|
|
|
7
7
|
`bongos upgrade --to <version> --from <tgz>` runs, from a consumer instance root:
|
|
8
8
|
|
|
9
9
|
1. **pre-flight** — module-compat vs the target core + a clean git tree (skip with `--force`).
|
|
10
|
-
2. **bump the pin** — vendor the new `
|
|
11
|
-
3. **`npm install`** — `node_modules/@
|
|
10
|
+
2. **bump the pin** — vendor the new `bongos-core-<version>.tgz` and rewrite the `"@bongos/core": "file:vendor/…"` dependency.
|
|
11
|
+
3. **`npm install`** — `node_modules/@bongos/core` becomes the new version.
|
|
12
12
|
4. **`npm run migrate`** — the core's `migrate.sh` applies additive `core_*` migrations (merged three-root: core + instance + modules).
|
|
13
13
|
5. **materialize `.claude/`** — refresh skills/settings/hooks from the new core (`materializeClaude`), rewriting invocations to the `bongos` bin.
|
|
14
14
|
6. **restart** — `--service <unit>` or `--restart-cmd "<cmd>"`.
|
|
@@ -21,8 +21,8 @@ Run bare (`bongos upgrade`, no `--to`) it stays the module-compat **pre-check**
|
|
|
21
21
|
The channel ships *in* the core. On the FIRST bump, the consumer's installed core is the OLD version (whose `bongos upgrade` may be the pre-check stub or lack a fix). So drive the first bump with the **new version's** `upgrade.js`, run out of its extracted package against `--instance <consumer>`:
|
|
22
22
|
|
|
23
23
|
```bash
|
|
24
|
-
cd /tmp && rm -rf pkg && mkdir pkg && tar xzf
|
|
25
|
-
node /tmp/pkg/package/scripts/gds/upgrade.js --to <version> --from /tmp/
|
|
24
|
+
cd /tmp && rm -rf pkg && mkdir pkg && tar xzf bongos-core-<version>.tgz -C pkg
|
|
25
|
+
node /tmp/pkg/package/scripts/gds/upgrade.js --to <version> --from /tmp/bongos-core-<version>.tgz --instance <consumer-root> …
|
|
26
26
|
```
|
|
27
27
|
|
|
28
28
|
Once a consumer is on a core that carries the channel, its own `bongos upgrade` drives later bumps.
|
|
@@ -33,15 +33,15 @@ The instance runs on the droplet (co-tenant): systemd `emersonian-circles.servic
|
|
|
33
33
|
|
|
34
34
|
1. **Cut the canonical tarball from `main`** (after the core change has merged, so the pin is a real release):
|
|
35
35
|
```bash
|
|
36
|
-
node scripts/gds/package-core.js --version <version> # → dist/
|
|
36
|
+
node scripts/gds/package-core.js --version <version> # → dist/bongos-core-<version>.tgz (+ manifest)
|
|
37
37
|
```
|
|
38
|
-
`package-core` archives committed `HEAD`, **not the working tree** — commit + merge first, then verify the artifact (`ls dist/
|
|
38
|
+
`package-core` archives committed `HEAD`, **not the working tree** — commit + merge first, then verify the artifact (`ls dist/bongos-core-<version>/…`).
|
|
39
39
|
2. **Back up the instance DB** — `pg_dump emersonian_circles | gzip > /tmp/…sql.gz`.
|
|
40
40
|
3. **`scp` the tarball to the droplet**, verify `sha256sum` matches.
|
|
41
41
|
4. **`--dry-run` first**, then the real run — extracted-package bootstrap, with the instance DB pinned:
|
|
42
42
|
```bash
|
|
43
43
|
PGDATABASE=emersonian_circles CLOUDBONGOS_INSTANCE_ROOT=/home/lars/emersonian-circles \
|
|
44
|
-
node /tmp/pkg/package/scripts/gds/upgrade.js --to <version> --from /tmp/
|
|
44
|
+
node /tmp/pkg/package/scripts/gds/upgrade.js --to <version> --from /tmp/bongos-core-<version>.tgz \
|
|
45
45
|
--instance /home/lars/emersonian-circles \
|
|
46
46
|
--restart-cmd "sudo systemctl restart emersonian-circles.service" \
|
|
47
47
|
--health-url http://127.0.0.1:3004/healthz
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
-- core_191_module_submissions.sql — the ADR 0107 §1 upstreaming review queue.
|
|
2
|
+
--
|
|
3
|
+
-- task 1770: `bongos module submit <key>` packages a module (manifest +
|
|
4
|
+
-- attribution + file contents) + its DCO-style sign-off and files it into a
|
|
5
|
+
-- rank-gated review queue. Real cross-repo submission (an instance filing into
|
|
6
|
+
-- the CORE repo's own review process) is not wired up yet — the extracted core
|
|
7
|
+
-- (github.com/lars589/cloud-bongos, private) has no reachable submission API
|
|
8
|
+
-- today, and R85 (the forcing-function second consumer) was abandoned in favor
|
|
9
|
+
-- of the already-proven two-repo model (see task 1689's value_summary). So this
|
|
10
|
+
-- table is the interim, buildable-now queue: it lives in THIS instance's own
|
|
11
|
+
-- Bongos DB (the same DB the module was built against), rank-gated identically
|
|
12
|
+
-- to the eventual core-side surface. Task 1771 (core-side review & accept flow)
|
|
13
|
+
-- reviews rows here; if/when a live cross-repo core endpoint exists, filing
|
|
14
|
+
-- becomes a network hop instead of a local INSERT with no schema change to the
|
|
15
|
+
-- caller. See docs/adr/0135-module-upstream-submission-interim-queue.md.
|
|
16
|
+
--
|
|
17
|
+
-- files jsonb = [{ path, contentBase64, bytes }, ...] — a full snapshot of the
|
|
18
|
+
-- module tree at submit time (ADR 0107 §1 "packages the module + ... into a
|
|
19
|
+
-- ... queue"), so a reviewer (task 1771) can inspect the submitted code without
|
|
20
|
+
-- needing network/filesystem access to the submitting instance's repo.
|
|
21
|
+
--
|
|
22
|
+
-- Idempotent: safe to re-run.
|
|
23
|
+
|
|
24
|
+
CREATE TABLE IF NOT EXISTS module_submissions (
|
|
25
|
+
id bigserial PRIMARY KEY,
|
|
26
|
+
module_key text NOT NULL,
|
|
27
|
+
submitted_by bigint NOT NULL REFERENCES builders(id),
|
|
28
|
+
manifest jsonb NOT NULL,
|
|
29
|
+
files jsonb NOT NULL,
|
|
30
|
+
sign_off jsonb NOT NULL,
|
|
31
|
+
precheck_passed_at timestamptz NOT NULL,
|
|
32
|
+
source_repo text,
|
|
33
|
+
status text NOT NULL DEFAULT 'pending'
|
|
34
|
+
CHECK (status IN ('pending', 'accepted', 'rejected')),
|
|
35
|
+
reviewed_by bigint REFERENCES builders(id),
|
|
36
|
+
reviewed_at timestamptz,
|
|
37
|
+
review_notes text,
|
|
38
|
+
submitted_at timestamptz NOT NULL DEFAULT now()
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
CREATE INDEX IF NOT EXISTS idx_module_submissions_status ON module_submissions (status, submitted_at DESC);
|
|
42
|
+
CREATE INDEX IF NOT EXISTS idx_module_submissions_key ON module_submissions (module_key, submitted_at DESC);
|
|
43
|
+
|
|
44
|
+
INSERT INTO schema_migrations (version) VALUES ('core_191_module_submissions')
|
|
45
|
+
ON CONFLICT (version) DO NOTHING;
|
|
@@ -1,49 +1,15 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @bongos/core — installed platform dependency (not your project's CLAUDE.md)
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
This file is a placeholder shipped inside the **@bongos/core** package. The core's own
|
|
4
|
+
internal agent notes are intentionally omitted from the published artifact so they cannot
|
|
5
|
+
load into your instance's context.
|
|
4
6
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
- the **Conductor** mid-flight dispatch CLI (Phase 4, task 439) and the **Architect** bounded first-principles `--scope` audit CLI (Phase 5, task 459) — domain commands.
|
|
7
|
+
**It does not govern this repository.** Your own root `CLAUDE.md`, your `.claude/`
|
|
8
|
+
directory, and the live Bongos database are the source of truth for how work happens here
|
|
9
|
+
and who may do what.
|
|
9
10
|
|
|
10
|
-
|
|
11
|
+
You are seeing this only because an agent opened a file under `node_modules/@bongos/core/`.
|
|
12
|
+
Nothing in here needs to be read to use the platform — run `bongos help` for commands.
|
|
11
13
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
## Cross-cutting: it OBSERVES lifecycle (the seams)
|
|
15
|
-
|
|
16
|
-
This is the cross-cutting domain the carve sequence flagged. Two inbound core→autonomy edges existed; each was inverted so the module is wired, not imported:
|
|
17
|
-
|
|
18
|
-
1. **The routine timer** (was `routineTimers.start()` in `server.js`) → now a **POLLER** (`contributes.pollers:["routine-timers"]`). The loader's `startModulePollers` requires `pollers/routine-timers.js` and calls `start()` at boot / `stop()` at shutdown — the module-agnostic successor to the hardcoded block (the Discord-bot-poller pattern, BV1.R47). server.js is the only `startModulePollers` caller (not `src/platform-server.js`), so a second always-on instance can't double-run. The timer's work is the lifecycle **`tallyPeerVotes`** capability (the SAME transaction `POST /tasks/peer-votes/tally` runs — route + timer share ONE path), reached through the **doorway** (`api.tallyPeerVotes`, a tracked lifecycle leak — it writes karma_log/peer_votes/tasks, all core-owned; relocates behind a `lifecycle.*` port at R86), never a core require.
|
|
19
|
-
2. **The autonomy precheck route** (was mounted in `src/bongos/routes.js`) → now a **module route** (`contributes.routes:["autonomy"]`, mounted by `mountModuleRoutes`). `GET /autonomy/precheck` (Archon-gated) calls the gate's `precheck`.
|
|
20
|
-
|
|
21
|
-
## No port (the sessions/memory shape)
|
|
22
|
-
|
|
23
|
-
Like `sessions`/`memory`, autonomy registers **no kernel port** (`provides: []`) — **core never calls back into it.** The timer is a loader-started poller, the precheck a module route, and the gate/conductor/architect are CLIs. There is nothing for a port to expose. (`consumes: []` too — `tallyPeerVotes` is a doorway export, not a seam port.)
|
|
24
|
-
|
|
25
|
-
## Files
|
|
26
|
-
|
|
27
|
-
| File | What |
|
|
28
|
-
|---|---|
|
|
29
|
-
| `db.js` | the `autonomy_runs` db slice — `recordAutonomyRun` (audit each precheck decision) + `lastAutonomyHead` (the stored last-`go` head the no-signal check compares origin/main against). Reaches Postgres through the doorway `pool`. |
|
|
30
|
-
| `pollers/routine-timers.js` | the in-process weekly **peer-vote-tally** timer (the loader's poller entry — `start`/`stop`). `runPeerVoteTally` resolves the lifecycle `tallyPeerVotes` via the doorway; pure w.r.t. injected `deps` (tests pass `deps.db`). Kill-switch `ROUTINE_TIMERS_DISABLED`; unref'd, best-effort. |
|
|
31
|
-
| `routes/autonomy.js` | `GET /autonomy/precheck` (Archon-gated) — the autonomy precheck over HTTP; wraps the gate CLI's `precheck`. Inert (always `go`) until `OTB_AUTONOMY_ENABLED=1`. |
|
|
32
|
-
|
|
33
|
-
## NOT in this module (the domain CLIs travel with the domain but stay under `scripts/`)
|
|
34
|
-
|
|
35
|
-
A command travels with its domain but stays a CLI (design 02§1; the sessions/memory precedent). These live under `scripts/gds/` — **outside** the kernel boundary (fitness scans `src/` + `modules/`, not `scripts/`), so they may still read the ideas/economy/lifecycle signals + the grader directly, which a `modules/` file may not:
|
|
36
|
-
|
|
37
|
-
- **`scripts/gds/autonomy-gate.js`** — the gate CLI (Step 0 of the nightly routines). Its pure decision logic (`decide`, `autofixAllowed`) is `$0`; its `gatherSignals` reads claimable tasks (core db), open ideas (`modules/ideas`), autonomous MTD spend (`modules/economy`), and the autonomy_runs head/record (**this module's `db.js`**). The precheck route + scheduled tasks invoke it.
|
|
38
|
-
- **`scripts/gds/conductor-dispatch.js`** — the Conductor mid-flight dispatch (runs grader specialists on the current diff; reuses `modules/grading/grader` + `src/bongos/sensitive-surfaces` + `src/bongos/path-match`).
|
|
39
|
-
- **`scripts/gds/architect-audit.js`** — the Architect's bounded `--scope` audit → `docs/audits/` + seed ideas (reuses the grader + `src/bongos/llm-cache`).
|
|
40
|
-
- **`scripts/gds/run-routine.js`** — the deterministic-first cron dispatcher (parses a routine's SKILL.md, runs steps at the cheapest sufficient tier).
|
|
41
|
-
- **`.claude/scheduled-tasks/`** — the cron routine SKILL.md files that invoke these CLIs (re-pointed at the moved gate; the scripts they call are unchanged paths).
|
|
42
|
-
|
|
43
|
-
## Tables (owned, not moved)
|
|
44
|
-
|
|
45
|
-
`autonomy_runs` (migration 126) was created before the module system and stays in core `migrations/` (the shared-schema additive rule the sessions/onboarding carves established). The module owns the *queries*; any **new** autonomy migration belongs in `modules/autonomy/migrations/` namespaced `autonomy_*`.
|
|
46
|
-
|
|
47
|
-
## Tests
|
|
48
|
-
|
|
49
|
-
`tests/autonomy_gate.mjs` (the pure gate decision — DB-free), `tests/routine_timers.mjs` (the peer-vote timer — pure w.r.t. injected deps), `tests/conductor.mjs`, `tests/architect.mjs`, `tests/run_routine.mjs` exercise the CLIs (which import from `scripts/gds/…`). The carve discovery-key membership is asserted in `tests/fitness.mjs` / `tests/module_loader.mjs` / `tests/modules.mjs`; the doorway `tallyPeerVotes` export in `tests/module_api.mjs`.
|
|
14
|
+
_To work ON the platform core itself, use the standalone @bongos/core source repository,
|
|
15
|
+
not this vendored copy._
|
|
@@ -1,58 +1,15 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @bongos/core — installed platform dependency (not your project's CLAUDE.md)
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
This file is a placeholder shipped inside the **@bongos/core** package. The core's own
|
|
4
|
+
internal agent notes are intentionally omitted from the published artifact so they cannot
|
|
5
|
+
load into your instance's context.
|
|
4
6
|
|
|
5
|
-
|
|
7
|
+
**It does not govern this repository.** Your own root `CLAUDE.md`, your `.claude/`
|
|
8
|
+
directory, and the live Bongos database are the source of truth for how work happens here
|
|
9
|
+
and who may do what.
|
|
6
10
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
- **skill** ([`skill-prefs.js`](skill-prefs.js)) — the per-skill model ceiling a spawn is clamped to (`skill_model_prefs` jsonb, migration 037).
|
|
10
|
-
- **model-allocation** ([`model-alloc-prefs.js`](model-alloc-prefs.js)) — the subagent model-routing policy (task 2011): the tier for main / subagent-default / routine-plumbing slots. Resolved builder override → instance default (`branding.models`) → code default (`opus`/`opus`/`haiku`); surfaced on `/me` (`model_allocation.effective`) + `GET`/`PATCH /me/model-allocation`. Replaces the hardcoded CLAUDE.md §2 routing table. PURE lib (instance default passed in). Stored in `behavior_prefs`.
|
|
11
|
-
- **sound** ([`sound-prefs.js`](sound-prefs.js)) + **event-sound** ([`event-sound-prefs.js`](event-sound-prefs.js)) — per-sound on/off + volume (`sound_prefs`, migration 075) and per-event sound-variant selection (`event_sound_prefs`, migration 164). The local `.claude/sounds/play.js` reads a mirror written by `scripts/gds/fetch-sound-prefs.js`.
|
|
12
|
-
- **render** ([`render-prefs.js`](render-prefs.js)) — the "render the deterministic session cards as a rich HTML widget vs. plain text" toggle (shares `behavior_prefs`, migration 119).
|
|
13
|
-
- **builder-needs** ([`builder-needs.js`](builder-needs.js)) — the consistent "the system needs an input from you" list (today: the image-generation key).
|
|
11
|
+
You are seeing this only because an agent opened a file under `node_modules/@bongos/core/`.
|
|
12
|
+
Nothing in here needs to be read to use the platform — run `bongos help` for commands.
|
|
14
13
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
This module reaches core **only** through the published doorway [`../../src/module-api.js`](../../src/module-api.js) (`coreVersion ^1.8.0`). It must **never** `require()` a core internal directly, and never another module. Core, in turn, must never `require()` a file in here — it reaches the prefs/needs read surface only through the `builder-settings` port (below). Both directions are enforced by the BV1.R44/R45 fitness checks.
|
|
18
|
-
|
|
19
|
-
## The `me`/`public` facade call (02-module-map §2)
|
|
20
|
-
|
|
21
|
-
[02-module-map §2](../../docs/design/modular-architecture/02-module-map.md) flags `me` as a cross-domain read-aggregator that becomes a **thin facade** when its domains carve out. This carve realizes that for the prefs/needs slices:
|
|
22
|
-
|
|
23
|
-
- **The five `/me/*-prefs` ROUTES moved here** ([`routes/settings.js`](routes/settings.js)) — `GET`/`PATCH` for `/me/skill-prefs`, `/me/sound-prefs`, `/me/event-sound-prefs`, `/me/wandering`, `/me/render`. They keep their **exact `/me/*` paths** (the loader mounts this router on the same `/api/gds` router, BEFORE the public catch-all), so the API is byte-identical — only the `require()` paths changed (auth/`getBuilderById` reach the doorway; the pref libs + the db slice are intra-module).
|
|
24
|
-
- **The `GET /me` AGGREGATOR stayed in core `routes/me.js`** as a thin facade. It builds the `wandering` / `render` / `needs` slices of the profile payload inline (alongside the economy `reward`-port + discord/box/art seam slices it already resolves) by resolving the `builder-settings` port — never importing the module.
|
|
25
|
-
- **`public.js` has NO builder-settings edge** — the §2 graph's `public → grader, security` is the real public coupling; prefs/needs are a `me`-only domain. `public.js` is untouched by this carve.
|
|
26
|
-
|
|
27
|
-
## The `builder-settings` kernel PORT
|
|
28
|
-
|
|
29
|
-
- **Provides — port `builder-settings`** → the read surface in [`settings.js`](settings.js): `{ getBuilderBehaviorPrefs, describeWandering, describeRender, computeNeeds, skillCeiling }`. Registered in [`routes/settings.js`](routes/settings.js)'s factory (the loader runs it at boot, and again whenever a test rebuilds the GDS router — `hasProvider`-guarded so re-instantiation never trips the single-provider guard). Mirrors `modules/economy/routes/reward.js`.
|
|
30
|
-
- **The TWO core consumers resolve it WITHOUT importing this module:**
|
|
31
|
-
- `routes/me.js` — the `GET /me` aggregator (`getBuilderBehaviorPrefs` once, then `describeWandering`/`describeRender`/`computeNeeds` off the same blob).
|
|
32
|
-
- `src/bongos/cascade-dispatch.js` — the dormant System-3 cascade router clamps a spawn to the builder's model ceiling (`skillCeiling`, the former `skillPrefs.getForBuilder`).
|
|
33
|
-
- Both degrade gracefully when the module is off (a vanilla instance): me.js's slices are best-effort; cascade's ceiling falls back to `'opus'` (its existing `|| 'opus'` default). No `CORE_VERSION` bump — the carve adds no doorway export (the port rides the already-exported seam registry, the security precedent).
|
|
34
|
-
|
|
35
|
-
## Files
|
|
36
|
-
|
|
37
|
-
| File | What |
|
|
38
|
-
|---|---|
|
|
39
|
-
| `db.js` | the builder-prefs db slice — the eight verbatim `get/set BuilderSkillPrefs / SoundPrefs / BehaviorPrefs / EventSoundPrefs` helpers carved out of core `db.js`. Reaches the shared pool through the doorway. |
|
|
40
|
-
| `skill-prefs.js` · `sound-prefs.js` · `event-sound-prefs.js` · `wandering-prefs.js` · `render-prefs.js` | the pure shapers (`validatePatch`/`applyPatch`/`listEffective`/`describeForApi`/constants) that turn a raw jsonb blob into effective values. Moved verbatim (they were already core-`require()`-free). |
|
|
41
|
-
| `builder-needs.js` | `computeNeeds(ctx)` — the "the system needs an input from you" list (the image-generation-key item). |
|
|
42
|
-
| `settings.js` | the `builder-settings` port provider surface — DELEGATES (does not spread) to `db`/the pref libs so test stubs bite at call time. |
|
|
43
|
-
| `routes/settings.js` | the five `/me/*-prefs` GET/PATCH endpoints (above) + the port registration. |
|
|
44
|
-
|
|
45
|
-
## NOT in this module (deliberately left in core)
|
|
46
|
-
|
|
47
|
-
- **The `GET /me` aggregator + every non-prefs `/me/*` route** — `routes/me.js` stays core (it's the cross-domain profile/identity surface; only the self-contained pref routes left). It resolves this module's port for its prefs/needs slices.
|
|
48
|
-
- **The per-builder Gemini KEY** (`getBuilderGeminiKeyRow` / `setBuilderGeminiKey` / `clearBuilderGeminiKey`, `gemini_key_*` columns) — stays core `db.js` + the doorway (`api.getBuilderGeminiKeyRow`). It's art-pipeline credential infra (the `/me/art-key` delivery + the `art.sharedKeyConfigured` seam), read by `computeNeeds`'s caller as `ownKeySet`, not owned by builder-settings.
|
|
49
|
-
- **`cascade-dispatch.js`** — the dormant System-3 cascade router stays a CORE lib (it belongs to the grading/autonomy plane, not builder-settings); it RESOLVES this module's `skillCeiling` port instead of importing `skill-prefs`.
|
|
50
|
-
- **The pref-mirroring CLIs** — `scripts/gds/fetch-sound-prefs.js` + `scripts/gds/session-eval.js` (which reads `wandering-prefs`) travel with the domain but stay under `scripts/` and `require('../../modules/builder-settings/…')` directly (scripts are outside the kernel boundary — the memory/economy-carve precedent).
|
|
51
|
-
|
|
52
|
-
## Tables
|
|
53
|
-
|
|
54
|
-
None owned. The five jsonb columns (`skill_model_prefs` 037, `sound_prefs` 075, `behavior_prefs` 119, `event_sound_prefs` 164) live on the CORE `builders` table and stay in core `migrations/`. This module owns the *prefs queries*; any **new** builder-settings migration belongs in `modules/builder-settings/migrations/` namespaced `builder_settings_*` (the additive rule).
|
|
55
|
-
|
|
56
|
-
## Tests
|
|
57
|
-
|
|
58
|
-
`tests/skill_prefs.mjs`, `tests/sound_prefs.mjs`, `tests/wandering_prefs.mjs`, `tests/render_prefs.mjs`, and `tests/builder_needs.mjs` import the pure shapers from `modules/builder-settings/…`. The doorway/boundary checks (`tests/fitness.mjs`, `tests/module_loader.mjs`, `tests/modules.mjs`) discover `builder-settings` as a module. See [ADR 0093](../../docs/adr/<redacted>.md).
|
|
14
|
+
_To work ON the platform core itself, use the standalone @bongos/core source repository,
|
|
15
|
+
not this vendored copy._
|
|
@@ -1,38 +1,15 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @bongos/core — installed platform dependency (not your project's CLAUDE.md)
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
This file is a placeholder shipped inside the **@bongos/core** package. The core's own
|
|
4
|
+
internal agent notes are intentionally omitted from the published artifact so they cannot
|
|
5
|
+
load into your instance's context.
|
|
4
6
|
|
|
5
|
-
|
|
7
|
+
**It does not govern this repository.** Your own root `CLAUDE.md`, your `.claude/`
|
|
8
|
+
directory, and the live Bongos database are the source of truth for how work happens here
|
|
9
|
+
and who may do what.
|
|
6
10
|
|
|
7
|
-
|
|
11
|
+
You are seeing this only because an agent opened a file under `node_modules/@bongos/core/`.
|
|
12
|
+
Nothing in here needs to be read to use the platform — run `bongos help` for commands.
|
|
8
13
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
## Files
|
|
12
|
-
|
|
13
|
-
| File | What |
|
|
14
|
-
|---|---|
|
|
15
|
-
| `routes/box.js` | the HTTP surface — `/box/*` (own box; some `allowBoxScope`) + `/boxes/*` (Archon roster). The loader mounts this; its factory also **registers this module's seams** (idempotent). |
|
|
16
|
-
| `boxes.js` | box lifecycle logic + cost ledger. Pure-ish: `pool` is passed in (DI), so it has no core require. |
|
|
17
|
-
| `box-access.js` | source-access clawback (`flagBoxReconcileForBuilder`, `decideSourceAccess`). |
|
|
18
|
-
| `box-credential.js` | per-box credential provider. |
|
|
19
|
-
| `box-onboard.js` | SSH-key validation + connect/settings renderers. |
|
|
20
|
-
| `db.js` | the module's data slice — owns `setBuilderBoxBlocked` (the box-blocked write), reached through the doorway `pool`. Lifted out of core `db.js` in BV1.R68 ([ADR 0091](../../docs/adr/<redacted>.md)); box-blocked is cleanly dev-box-owned (this module is its only writer + reader). |
|
|
21
|
-
|
|
22
|
-
## Seams (how core and this module talk without importing each other)
|
|
23
|
-
|
|
24
|
-
- **Provides — port `box.hasEverConnected`** `(builderId) → Promise<bool>`. Core (`routes/me.js`, `routes/builders.js`) reads it via `resolveOptional('box.hasEverConnected', async () => false)` so onboarding's `box_connect` step auto-clears when a box is on, and degrades to `false` on a box-less instance.
|
|
25
|
-
- **Listens — event `builder.box-reconcile-needed`** `{ builderId, rank, status, actor }`. Core `db.js` emits it (via `emitAsync`) after a rank change / deactivate / auto-graduation; this module flags the droplet reconcile. Replaces the old `db.js → box-access` direct call.
|
|
26
|
-
|
|
27
|
-
Registration happens in `routes/box.js`'s factory (the loader runs it at boot, already module-gated), guarded by `hasProvider` so re-instantiation in tests can't double-register.
|
|
28
|
-
|
|
29
|
-
## NOT in this module
|
|
30
|
-
|
|
31
|
-
- **The network clients** — `scripts/gds/do-api.js` (DigitalOcean), `scripts/gds/cf-tunnel.js` (Cloudflare tunnel), and their shared `scripts/gds/http-api-client.js`. They were operator-CLI-only (never the web process), so they moved OUT to the control-plane tier in BV1 task [#1943](https://example.com/builders#/task/1943) ([ADR 0111](../../docs/adr/<redacted>.md) §2) — the DO client is now shared by `box.js` AND the instance-provisioning runner `provision.js`, which a module→module import could never allow.
|
|
32
|
-
- **`scripts/gds/box.js`** — the operator control-plane CLI (sole holder of `DO_API_TOKEN`/`CF_API_TOKEN`, ADR 0031 §9.4). It *requires* this module's `boxes`/`box-access`/`box-onboard` (module data/logic) plus the shared `scripts/gds/do-api`/`cf-tunnel` clients, but it is core ops tooling and stays in `scripts/gds/`.
|
|
33
|
-
- **The hall UI** (`modules/hall-ui/public/`: `box-panel.js`, `harbor.js`, the `watch.js` cost section, gated mounts in `builders.js`/`settings.js`). Per-module UI sections are design **phase 6**, not this move; they stay in the hall-ui module (carved in BV1.R85), already gated by `window.__MODULES__.enabled['dev-box']`.
|
|
34
|
-
- **`secret-box.js`** — unrelated per-builder secrets crypto; stays in core despite the name.
|
|
35
|
-
|
|
36
|
-
## Tests
|
|
37
|
-
|
|
38
|
-
`scripts/gds/smoke-box.sh` + `tests/box*.mjs` (boxes, box_access, box_onboard, box_host_keys, box_cost, box_code_staleness, box_terminal_ssrf, box_connect_e2e, cf_tunnel). They import from `modules/dev-box/…` — except the moved network clients (`tests/boxes.mjs`'s `do-api` import + `tests/cf_tunnel.mjs`) now import from `scripts/gds/…` ([#1943](https://example.com/builders#/task/1943)).
|
|
14
|
+
_To work ON the platform core itself, use the standalone @bongos/core source repository,
|
|
15
|
+
not this vendored copy._
|
|
@@ -1,50 +1,15 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @bongos/core — installed platform dependency (not your project's CLAUDE.md)
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
This file is a placeholder shipped inside the **@bongos/core** package. The core's own
|
|
4
|
+
internal agent notes are intentionally omitted from the published artifact so they cannot
|
|
5
|
+
load into your instance's context.
|
|
4
6
|
|
|
5
|
-
|
|
7
|
+
**It does not govern this repository.** Your own root `CLAUDE.md`, your `.claude/`
|
|
8
|
+
directory, and the live Bongos database are the source of truth for how work happens here
|
|
9
|
+
and who may do what.
|
|
6
10
|
|
|
7
|
-
|
|
11
|
+
You are seeing this only because an agent opened a file under `node_modules/@bongos/core/`.
|
|
12
|
+
Nothing in here needs to be read to use the platform — run `bongos help` for commands.
|
|
8
13
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
| File | What |
|
|
12
|
-
|---|---|
|
|
13
|
-
| `routes/discord.js` | Archon-only `/discord/channels/{plan,reconcile}` (ADR 0037). Its factory also **registers this module's seams** (port + listener; idempotent). |
|
|
14
|
-
| `routes/bug-attachments.js` | serves `GET /bug-attachments/:name` (images attached to `#bugs` reports). Moved with the lib it reads. |
|
|
15
|
-
| `discord-bot.js` | the gateway client (reactions, inbound, role-sync timer). Started/stopped via `pollers/discord-bot.js`. |
|
|
16
|
-
| `discord-reaction.js` · `discord-inbound.js` · `discord-bugs.js` · `discord-approvals.js` | the passive bot features: 👍 applause, `#ideas` → idea_inbox, `#bugs` → task, member-approval reactions. |
|
|
17
|
-
| `discord-role-sync.js` · `discord-channels.js` | rank→role badge reconcile + channel/topic/view management from `docs/discord/channels.json`. |
|
|
18
|
-
| `discord-message-buffer.js` · `discord-audit.js` · `bug-attachments.js` | message-pair aggregator, bot-action audit helper, attachment persistence (pure). |
|
|
19
|
-
| `ship-broadcast.js` | the server-side ship poster — fired by the `task.shipped` seam listener, not a core import. |
|
|
20
|
-
| `db.js` | the module's data layer — owns the `discord_links`/`discord_applause` queries (via the doorway `pool`) + re-exports kernel db helpers. |
|
|
21
|
-
| `auth.js` · `webhook.js` | **vendored twins** of core helpers (see below). |
|
|
22
|
-
| `pollers/discord-bot.js` | the loader's web-process poller entry — `start()`/`stop()` over the bot. |
|
|
23
|
-
|
|
24
|
-
## Seams (how core and this module talk without importing each other)
|
|
25
|
-
|
|
26
|
-
- **Provides — port `discord.isLinked`** `(builderId) → Promise<bool>`. Core (`routes/me.js`, `routes/builders.js`) reads it via `resolveOptional('discord.isLinked', async () => false)` so the hall renders Connect/Unlink and onboarding's discord step auto-clears; degrades to `false` on a discord-less instance. (`discord.configured` — does the server hold OAuth creds — stays **core**: the account-LINK flow in `routes/auth.js` is not part of this module.)
|
|
27
|
-
- **Listens — event `task.shipped`** `(shippedTaskRow)`. Core (`publish-reconciler.js`, `routes/tasks.js`) emits it on the confirmed→shipped transition; this module posts the `#ship-news`/`#ship-feed` broadcast. Replaces the old `require('./ship-broadcast')` core→discord import.
|
|
28
|
-
- No consumed ports.
|
|
29
|
-
|
|
30
|
-
Registration happens in `routes/discord.js`'s factory (the loader runs it at boot, already module-gated): the port is `hasProvider`-guarded; the `task.shipped` listener is off→on replaced so a test re-instantiating the router never accumulates duplicates.
|
|
31
|
-
|
|
32
|
-
## Vendored twins (boundary-forced — keep in sync)
|
|
33
|
-
|
|
34
|
-
The kernel doorway must stay module-agnostic (the "core carries no module code" fitness check forbids naming a module in `src/module-api.js`), and a module can't require core/scripts. So three small helpers are **copied** here, with their core originals kept for the parts of Discord that stay core:
|
|
35
|
-
|
|
36
|
-
- **`auth.js`** — `isValidDiscordUserId` + `loadDiscordBotToken`. Core `src/bongos/auth.js` keeps its copies for the OAuth account-LINK flow (`routes/auth.js`).
|
|
37
|
-
- **`webhook.js`** — `postWebhook`/`loadWebhooks`/`CHANNELS`, a twin of `scripts/discord/lib.js` (which stays for core `approval-broadcast.js` + the `scripts/discord/post.js` CLI).
|
|
38
|
-
- **`db.js`** — `getDiscordLink`/`recordApplause` are also defined in core `src/bongos/db.js` (still used by the link flow / a seed); the others (`getBuilderByDiscordUserId`, `listDiscordLinks`, `countRecentDiscordBugFilings`) are owned here.
|
|
39
|
-
|
|
40
|
-
## NOT in this module
|
|
41
|
-
|
|
42
|
-
- **The OAuth account-link flow** — `routes/auth.js` + the Discord OAuth helpers in `src/bongos/auth.js` (`discordConfigured`, `addDiscordGuildMember`, …). Linking writes a core `builders`-adjacent row; it stays core. This module only surfaces the resulting *state* via the `discord.isLinked` port.
|
|
43
|
-
- **`migrations/<redacted>.sql`** — stays in **core** `migrations/`. It also `ALTER`s core tables (`builders.system_role`, `audit_log.surface`) and seeds the `discord_bot` principal, so the module-migration namespacing rule (which forbids a module migration touching non-`discord_` objects) can't host it. Any *future* discord migration that touches only `discord_*` objects can live in `modules/discord/migrations/`.
|
|
44
|
-
- **`ship-card.js`** — the CLI lifecycle card (claimed→shipped) used by `claim.js`/`ship.js` on every instance; not a Discord concern, stays in `src/bongos/`.
|
|
45
|
-
- **`approval-broadcast.js` · `scripts/discord/{lib,post}.js`** — core/CLI Discord posters (see Vendored twins).
|
|
46
|
-
- **The hall UI** (`modules/hall-ui/public/`, carved in BV1.R85) — per-module client UI is a later design phase; it stays gated by `window.__MODULES__.enabled['discord']`.
|
|
47
|
-
|
|
48
|
-
## Tests
|
|
49
|
-
|
|
50
|
-
`tests/discord_*.mjs` + `tests/bug_attachments.mjs` import from `modules/discord/…`. `scripts/discord/smoke*.sh` (if present) exercises the outbound poster.
|
|
14
|
+
_To work ON the platform core itself, use the standalone @bongos/core source repository,
|
|
15
|
+
not this vendored copy._
|
|
@@ -1,48 +1,15 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @bongos/core — installed platform dependency (not your project's CLAUDE.md)
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
This file is a placeholder shipped inside the **@bongos/core** package. The core's own
|
|
4
|
+
internal agent notes are intentionally omitted from the published artifact so they cannot
|
|
5
|
+
load into your instance's context.
|
|
4
6
|
|
|
5
|
-
|
|
7
|
+
**It does not govern this repository.** Your own root `CLAUDE.md`, your `.claude/`
|
|
8
|
+
directory, and the live Bongos database are the source of truth for how work happens here
|
|
9
|
+
and who may do what.
|
|
6
10
|
|
|
7
|
-
|
|
11
|
+
You are seeing this only because an agent opened a file under `node_modules/@bongos/core/`.
|
|
12
|
+
Nothing in here needs to be read to use the platform — run `bongos help` for commands.
|
|
8
13
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
## The `reward` kernel PORT (ADR 0093 §1-2 — the headline of this carve)
|
|
12
|
-
|
|
13
|
-
- **Provides — port `reward`** → the economy module's reward surface (`modules/economy/reward.js`). Registered in `routes/reward.js`'s factory (the loader runs it at boot, and again whenever a test rebuilds the GDS router — `hasProvider`-guarded so re-instantiation never trips the single-provider duplicate guard).
|
|
14
|
-
- **It is a TRANSACTION-PARTICIPANT port** (unlike the stateless `grade` port): the credit-allocation methods (`insertMultipliedConfirmCredit`, `maybeAwardIdeaPromotionBonus`, `awardNetNegativeBonus`, `awardSessionTokenReward`) and the claim/ship gamification hooks (`evaluateAfterClaim/Ship/CreditAward`) take the **caller's tx `client` as the first arg**. The core lifecycle opens the `withTx`, runs the state-machine SQL (FOR UPDATE, `task_grades` upsert, `UPDATE tasks status`, claim-holder lookup, `logGradeAttempt`) itself, and calls `reward.*(client, …)` inside that same transaction — so the credit write commits atomically with the status flip. Extract the capability; keep the state machine (ADR 0091 §4).
|
|
15
|
-
- **Core consumes it WITHOUT importing this module:**
|
|
16
|
-
- the LIFECYCLE — `db.applyGrade` / `db.confirmTask` / `db.decideOverrideRequest` / `db.claimTask` / `db.upsertSessionRecordWithReward` resolve it via `seams.resolveOptional('reward')` and call the credit/achievement methods inside their own `withTx`.
|
|
17
|
-
- the READ routes — `routes/me.js` (achievement getters + streak preview + `getBuilderCostStatus`), `routes/public.js` (`costSummary` + `getLeaderboardWithAchievements`), `routes/builders.js` (`setBuilderMonthlyBudget`), `routes/sessions.js` (`sumCreditsForTasks`), and `publish-reconciler.js` (`reconcileSessionCosts`) resolve the same port and call its read surface. economy registers ONE port; its provider exposes both the lifecycle methods and the read surface (the grading precedent registers the whole module surface on its single port too).
|
|
18
|
-
- This replaced the former `const achievements = require('./achievements')` / `cost` / `cost-summary-shape` core→domain requires in `db.js`, the `db.leaderboard`/`db.logCost`/etc. monolith helpers, and the `require('../streak')` core-route imports.
|
|
19
|
-
|
|
20
|
-
## Files
|
|
21
|
-
|
|
22
|
-
| File | What |
|
|
23
|
-
|---|---|
|
|
24
|
-
| `credits.js` | the credit-allocation model: `KIND_MULTIPLIERS`/`IDEA_BONUS_FRACTION`/`REWARD_MARGIN_PCT`, `applyKindMultiplier`, `computeSessionTokenReward`, `insertMultipliedConfirmCredit`, `maybeAwardIdeaPromotionBonus`, `awardSessionTokenReward`, `awardNetNegativeBonus` (+ `NET_NEGATIVE_BONUS`/`SUBTRACTOR_THRESHOLD`/`netNegativeBonusAmount`), the `leaderboard`, and `sumCreditsForTasks`. Writes `credit_log`. |
|
|
25
|
-
| `cost.js` | the cost ledger: `logCost` (the one `cost_log` writer), `reconcileSessionCosts`, `costSummary`/`costCalibrationSummary`, `getBuilderCostStatus`, `setBuilderMonthlyBudget`, `autonomousApiSpendMtd`. |
|
|
26
|
-
| `cost-classify.js` | pure cost-attribution audit + budget classification (`classifyCostStatus`, `auditCostAttribution`, `formatAuditReport`, `OWNERLESS_CATEGORIES`, `SOFT_CAP_FRACTION`). Moved from `src/bongos/cost.js` (renamed to avoid colliding with `cost.js`). |
|
|
27
|
-
| `cost-summary-shape.js` | pure cost-summary dimension shapers (`shapeBySource`/`shapeByTier`/`shapeSavings`/`shapeCostCalibration`). |
|
|
28
|
-
| `streak.js` | streak math + anti-gaming guards (`computeStreak`, `wouldExtendStreak`, …). Reaches the shared pool through the doorway. |
|
|
29
|
-
| `achievements.js` | the achievement evaluators (`evaluateAfterClaim/Ship/CreditAward`, `alreadyUnlocked`, `unlockAchievement`, `filesForBadges`) PLUS the getter slice moved from `db.js` (`listAchievements`, `getBuilderAchievements`, `getLeaderboardWithAchievements`, `getLockedAchievementsProgress`, `renderProgressText`). `require('./streak')` is an intra-module sibling. |
|
|
30
|
-
| `reward.js` | the `reward` port provider surface — DELEGATES (does not spread) to `credits`/`achievements`/`cost`/`streak` so test stubs bite at call time. |
|
|
31
|
-
| `routes/reward.js` | registers the `reward` port (above); no HTTP endpoint. |
|
|
32
|
-
| `routes/cost.js` | `POST /cost` — log a cost row (idempotent). Reaches auth/validators via the doorway; the writer via `../cost`. |
|
|
33
|
-
| `routes/leaderboard.js` | `GET /leaderboard` — public drachmae-ordered leaderboard, via `../credits`. |
|
|
34
|
-
|
|
35
|
-
## NOT in this module (deliberately left in core)
|
|
36
|
-
|
|
37
|
-
- **`llm-pricing.js`** — the shared token→USD pricing lib stays core shared LLM-cost infra (consumed by BOTH this module's reward/cost paths AND core cost scripts `ship.js`/`session-cost.js`, so it can't be economy-owned). It is exposed to this module on the doorway as `api.llmPricing` (a tracked R73-style domain leak, like `api.llmCache`). It relocates behind a port if/when an llm-infra domain is carved (tranche 2). The economy scope-map glob lists `src/bongos/llm-pricing.js` for task-affinity even though the FILE stays in core.
|
|
38
|
-
- **The recent-ships feed + estimation-drift + grade-trend reads** (`db.recentShippedTasks`, `<redacted>`, `getEstVsActualRatio`, `estimationDriftSummary`, `recentGradesForBuilder`, `builderRollingAvgGrade`, `rollingAvgGrade`, `gradeTrendByDay`) — these stay `db.*` (lifecycle/sessions reads, not economy ledger SQL); out of scope for this carve.
|
|
39
|
-
- **The karma feed** (`recentKarmaForBuilder`, `karmaDelta30d`, `karma_log`) — stays in core `db.js` (a separate social-signal domain).
|
|
40
|
-
- **The economy-owned CLIs** — a command travels with its domain but stays under `scripts/`: `backfill-cost.js` (requires `../../modules/economy/cost-classify`), `diagnose-achievements.js` (requires `../../modules/economy/streak`). (The memory/grading-carve precedent.)
|
|
41
|
-
|
|
42
|
-
## Tables
|
|
43
|
-
|
|
44
|
-
None owned. `credit_log`, `cost_log`, `cost_baseline`, `achievements`, `builder_achievements` (+ their migrations) were created before the module system and stay in core `migrations/` (the schema-migrations stem-key makes a later relocation a no-op). The module owns the *queries*; any **new** economy migration belongs in `modules/economy/migrations/` namespaced `economy_*` (the additive rule).
|
|
45
|
-
|
|
46
|
-
## Tests
|
|
47
|
-
|
|
48
|
-
`tests/credit_grant.mjs` (credits.js), `tests/cost.mjs`/`tests/cost_audit.mjs`/`tests/cost_budget_status.mjs` (cost-classify.js), `tests/cost_summary_shape.mjs`, `tests/streak.mjs`, and `tests/diff_derived_signals.mjs` import from `modules/economy/…`. The lifecycle-attribution tests (`tests/grade_attribution.mjs`, `tests/confirm_attribution.mjs`, `tests/grade_server_authoritative.mjs`, `tests/override_attribution.mjs`, `tests/override_request_ownership.mjs`) register the `reward` port (and stub `achievements` on the live module object) before driving `db.applyGrade`/`confirmTask`/`decideOverrideRequest`. See ADR 0093.
|
|
14
|
+
_To work ON the platform core itself, use the standalone @bongos/core source repository,
|
|
15
|
+
not this vendored copy._
|