@bongos/core 1.19.1074 → 1.19.1076
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 +196 -211
- package/.claude/skills/blocker-solve/SKILL.md +1 -1
- package/README.md +1 -1
- package/bin/bongos.js +1 -3
- package/docs/adr/0031-cloud-dev-environments-for-builders.md +1 -1
- package/docs/adr/0035-builder-onboarding-three-paths.md +1 -1
- package/docs/adr/0044-per-box-live-game-preview.md +1 -1
- package/docs/adr/0045-devbox-desktop-app.md +1 -1
- package/docs/adr/0046-sandbox-first-review-gate.md +1 -1
- package/docs/adr/0052-sandbox-for-everyone-game-only-preview.md +1 -1
- package/docs/adr/0053-scoped-dev-box-session.md +1 -1
- package/docs/adr/0055-server-mediated-branch-publish.md +1 -1
- package/docs/adr/0057-container-cost-ledger.md +1 -1
- package/docs/adr/0059-single-approval-remove-devbox-approval-gate.md +1 -1
- package/docs/adr/0071-box-confirm-before-destroyed-and-drift-reconcile.md +1 -1
- package/docs/adr/0072-bongos-app-mac-signed-first-windows-deferred.md +1 -1
- package/docs/adr/0072-dev-box-code-staleness-visibility.md +1 -1
- package/docs/adr/0104-trust-gds-api-channel-in-auto-mode.md +1 -1
- package/docs/adr/0123-box-idle-sweep-autosave-before-destroy.md +1 -1
- package/docs/adr/0144-devbox-rehome-onto-cloudbongos-plane.md +1 -1
- package/docs/adr/0145-devbox-app-branding-driven-module.md +1 -1
- package/docs/adr/0148-task-scoped-box-source-access.md +2 -2
- package/docs/adr/0151-governance-permissions-as-atom-ranks-as-roles.md +1 -1
- package/docs/adr/0193-pause-task-scoped-box-slices.md +1 -1
- package/docs/adr/0277-a-box-is-in-use-only-while-a-human-is-attached.md +1 -1
- package/docs/adr/0346-dev-boxes-are-retired.md +69 -0
- package/docs/adr/README.md +1 -0
- package/docs/api/openapi.json +4 -4
- package/docs/architecture.md +5 -6
- package/docs/branding-contract.md +2 -2
- package/docs/canonical-permissions.md +10 -18
- package/docs/copy-inventory.md +3 -3
- package/docs/copy-registry.json +3 -3
- package/docs/design/gate-navigation-direction.md +1 -1
- package/docs/design/hall-direction-v2.md +3 -3
- package/docs/design/modular-architecture/00-research-report.md +1 -1
- package/docs/design/modular-architecture/01-architecture.md +3 -3
- package/docs/design/modular-architecture/02-module-map.md +1 -2
- package/docs/design/modular-architecture/03-builder-flows.md +22 -20
- package/docs/design/modular-architecture/04-module-lifecycle.md +1 -1
- package/docs/design/modular-architecture/README.md +4 -2
- package/docs/design/reviews/hall-v2/README.md +2 -2
- package/docs/design/vanilla-hall-ui-redesign-scope.md +4 -4
- package/docs/file-map.md +5 -5
- package/docs/handoff-template.md +1 -1
- package/docs/module-api-changelog.md +8 -0
- package/docs/modules-contract.md +11 -14
- package/docs/page-readings.json +63 -63
- package/docs/recipes/bongos-cli-release.md +1 -2
- package/docs/recipes/multi-builder-merge.md +1 -1
- package/docs/recipes/ops-gotchas.md +0 -9
- package/docs/recipes/self-host.md +1 -1
- package/docs/recipes/windows-builders.md +1 -1
- package/migrations/core_258_drop_dev_box_tables.sql +3 -0
- package/modules/copy-desk/routes/copy-desk.js +1 -1
- package/modules/discord/ship-broadcast.js +3 -3
- package/modules/economy/credits.js +2 -2
- package/modules/hall-ui/public/palette.js +143 -3
- package/modules/ideas/projection.js +1 -1
- package/modules/lifecycle/db-ship.js +4 -4
- package/modules/lifecycle/github-push.js +12 -14
- package/modules/lifecycle/publish-reconciler.js +10 -10
- package/modules/lifecycle/routes/tasks.js +8 -8
- package/modules/lifecycle/ship-card.js +1 -1
- package/modules/lifecycle/task-visuals.js +2 -2
- package/modules/memory/routes/memory.js +2 -2
- package/modules/platform-identity/routes/sso.js +3 -2
- package/modules/provisioning/capacity.js +1 -1
- package/modules/provisioning/provisioning.js +4 -3
- package/modules/provisioning/routes/provisioning.js +4 -4
- package/modules/sessions/db.js +1 -1
- package/package-lock.json +2 -2
- package/package.json +1 -1
- package/release-notes.json +28 -0
- package/scripts/gds/artifact-staleness.js +2 -2
- package/scripts/gds/backfill-task-rewards.js +5 -5
- package/scripts/gds/claude-materialize.js +2 -2
- package/scripts/gds/cli-lib.js +7 -7
- package/scripts/gds/codemod-rename-src-gds.js +1 -1
- package/scripts/gds/context-pack.js +5 -7
- package/scripts/gds/dev-box-guard.js +165 -0
- package/scripts/gds/doctor.js +3 -3
- package/scripts/gds/fitness-checks-packaging.js +4 -4
- package/scripts/gds/fitness-lib.js +10 -0
- package/scripts/gds/fitness-ratchets.js +1 -1
- package/scripts/gds/fitness.js +2 -10
- package/scripts/gds/gen-api-client.js +4 -4
- package/scripts/gds/gen-api-docs.js +1 -1
- package/scripts/gds/gen-repo-map.js +13 -14
- package/scripts/gds/gen-session-index.js +8 -8
- package/scripts/gds/leak-scan-allowlist.js +1 -1
- package/scripts/gds/plain-cards.js +1 -1
- package/scripts/gds/push-path-brief.js +10 -10
- package/scripts/gds/rename-history-check.js +1 -1
- package/scripts/gds/run-unit-tests.js +4 -0
- package/scripts/gds/session-digest-build.js +2 -2
- package/scripts/gds/ship-deploy-target.js +13 -13
- package/scripts/gds/ship-flow.js +1 -1
- package/scripts/gds/ship-land.js +6 -6
- package/scripts/gds/ship-merge.js +4 -4
- package/scripts/gds/ship-preflight-steps.js +4 -4
- package/scripts/gds/ship-regen.js +9 -12
- package/scripts/gds/ship.js +9 -9
- package/scripts/gds/skill-preflight.js +9 -8
- package/src/bongos/api-prefix.js +4 -4
- package/src/bongos/module-scope-map.js +1 -1
- package/src/bongos/platform-visibility-gate.js +1 -1
- package/src/bongos/routes/me.js +1 -1
- package/src/bongos/routes/security.js +3 -3
- package/src/bongos/routes.js +2 -2
- package/src/bongos/serve-internal.js +5 -6
- package/src/bongos-downloads.js +1 -6
- package/src/branding.js +2 -2
- package/src/build-info.js +4 -6
- package/src/instance-config.js +2 -2
- package/src/module-api.js +3 -3
- package/src/module-loader/manifest-schema.js +1 -1
- package/tests/api_alias_caller_ratchet.mjs +1 -1
- package/tests/api_alias_exceptions.mjs +1 -1
- package/tests/api_client.mjs +1 -1
- package/tests/api_path_404.mjs +1 -1
- package/tests/backfill_task_rewards.mjs +1 -1
- package/tests/{box_ship_permissions.mjs → cli_allowlist_permissions.mjs} +5 -5
- package/tests/cli_sessions.mjs +1 -1
- package/tests/context_pack.mjs +13 -13
- package/tests/copy_inventory.mjs +7 -7
- package/tests/core_258_box_session_claims_db.mjs +180 -0
- package/tests/credit_grant.mjs +2 -2
- package/tests/criterion_suggest.mjs +1 -1
- package/tests/design_tokens_sync.mjs +3 -2
- package/tests/fitness.mjs +89 -0
- package/tests/fitness_ratchets.mjs +2 -2
- package/tests/github_push_land_proof.mjs +1 -1
- package/tests/goal_advisory.mjs +3 -3
- package/tests/goal_suggest.mjs +3 -3
- package/tests/government_abuse_matrix.mjs +4 -3
- package/tests/hall_audit.mjs +1 -1
- package/tests/hall_palette.mjs +224 -11
- package/tests/helpers.mjs +1 -1
- package/tests/host_topology_skips.mjs +2 -2
- package/tests/migration_namespace.mjs +6 -6
- package/tests/module_api.mjs +2 -2
- package/tests/module_cli.mjs +5 -5
- package/tests/module_manifest.mjs +13 -13
- package/tests/module_route_rank.mjs +2 -2
- package/tests/modules_route_wiring.mjs +1 -1
- package/tests/onboarding_route_signals.mjs +1 -1
- package/tests/paste_token_session_store.mjs +1 -1
- package/tests/platform_visibility_gate.mjs +1 -1
- package/tests/project_modules_ui.mjs +17 -17
- package/tests/projects_hub_module_picker.mjs +75 -74
- package/tests/provisioning_capacity.mjs +1 -1
- package/tests/provisioning_recommendations.mjs +3 -2
- package/tests/publish_branch_route.mjs +1 -1
- package/tests/publish_manifest.mjs +1 -1
- package/tests/publish_reconciler.mjs +8 -8
- package/tests/push_path_brief.mjs +10 -9
- package/tests/regrade_eligibility.mjs +1 -1
- package/tests/rename_history_restraint.mjs +1 -1
- package/tests/repo_map.mjs +9 -9
- package/tests/seam_wiring_guard.mjs +11 -11
- package/tests/search_isolation.mjs +3 -3
- package/tests/session_records.mjs +1 -1
- package/tests/session_rename_fallback.mjs +1 -1
- package/tests/session_start_freshness.mjs +3 -3
- package/tests/session_token_hash_db.mjs +1 -1
- package/tests/ship_card.mjs +1 -1
- package/tests/ship_ci_deploy.mjs +17 -17
- package/tests/ship_premerge.mjs +1 -1
- package/tests/ship_resume.mjs +1 -1
- package/tests/skill_preflight.mjs +2 -2
- package/tests/skip_is_not_pass.mjs +1 -1
- package/tests/terms_acceptance.mjs +1 -1
- package/docs/design/reviews/hall-v2/harbor--archon.webp +0 -0
- package/docs/design/reviews/hall-v2/harbor--metic.webp +0 -0
- package/docs/design/reviews/hall-v2/harbor--xenos.webp +0 -0
- package/docs/design/reviews/hall-v2/pair--archon.webp +0 -0
- package/docs/design/reviews/hall-v2/pair--metic.webp +0 -0
- package/docs/design/reviews/hall-v2/pair--xenos.webp +0 -0
|
@@ -26,8 +26,8 @@
|
|
|
26
26
|
// node scripts/gds/gen-session-index.js --check-block # exit 2 only if the tracked CLAUDE.md §13 snippet drifts (CI gate)
|
|
27
27
|
// node scripts/gds/gen-session-index.js --check-whole # exit 2 only if docs/session-log-index.md drifts
|
|
28
28
|
// node scripts/gds/gen-session-index.js --whole-only # WRITE the index only; never touch the tracked
|
|
29
|
-
// # CLAUDE.md snippet (sparse
|
|
30
|
-
// docs/session-log-index.md is GITIGNORED + regenerated at deploy
|
|
29
|
+
// # CLAUDE.md snippet (sparse-checkout use; task 1002962)
|
|
30
|
+
// docs/session-log-index.md is GITIGNORED + regenerated at deploy since ADR 0110 (task 1926).
|
|
31
31
|
// node scripts/gds/gen-session-index.js --json # print the parsed entries as JSON (debug)
|
|
32
32
|
|
|
33
33
|
const fs = require('node:fs');
|
|
@@ -164,7 +164,7 @@ function computeWrites() {
|
|
|
164
164
|
const writes = [];
|
|
165
165
|
|
|
166
166
|
// Two buckets (ADR 0110, task 1926): 'whole' = docs/session-log-index.md, now
|
|
167
|
-
// GITIGNORED + regenerated at deploy
|
|
167
|
+
// GITIGNORED + regenerated at deploy (no committed copy → no branch
|
|
168
168
|
// collisions); 'block' = the bounded CLAUDE.md §13 snippet, still tracked, so it
|
|
169
169
|
// stays a HARD CI gate. main() gates them separately (--check-block vs --check-whole).
|
|
170
170
|
const idxNext = renderIndex(entries);
|
|
@@ -197,11 +197,11 @@ function main() {
|
|
|
197
197
|
return;
|
|
198
198
|
}
|
|
199
199
|
// WRITE-side bucket selection — the sibling of the --check-* flags (task 1002962,
|
|
200
|
-
// the gen-repo-map --whole-only twin).
|
|
201
|
-
//
|
|
202
|
-
//
|
|
203
|
-
//
|
|
204
|
-
//
|
|
200
|
+
// the gen-repo-map --whole-only twin). On a SPARSE checkout, writing the TRACKED
|
|
201
|
+
// bucket dirties the tree and the next `git pull` aborts on "local changes would
|
|
202
|
+
// be overwritten" — a silent, permanent sync deadlock. A sparse checkout
|
|
203
|
+
// regenerates only the gitignored artifact; the tracked CLAUDE.md §13 snippet
|
|
204
|
+
// arrives with the pull, generated from the whole tree.
|
|
205
205
|
const wholeOnly = process.argv.includes('--whole-only');
|
|
206
206
|
const all = computeWrites().writes;
|
|
207
207
|
const writes = wholeOnly ? all.filter((w) => w.bucket === 'whole') : all;
|
|
@@ -167,7 +167,7 @@ const FILE_ALLOWLIST = [
|
|
|
167
167
|
path: 'tests/lib_sh_resolution.mjs',
|
|
168
168
|
classes: ['token'],
|
|
169
169
|
reason:
|
|
170
|
-
'Carries the host-identity scan pattern it runs over the
|
|
170
|
+
'Carries the host-identity scan pattern it runs over the bash smoke scripts — a detector '
|
|
171
171
|
+ 'pattern, the same case as fitness-checks-identity.js.',
|
|
172
172
|
},
|
|
173
173
|
{
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
// what happened, what the agent will do next, whether a PERSON is needed (and who), and
|
|
9
9
|
// whether this is a rule rather than a fault. That last one is the expensive mistake:
|
|
10
10
|
// an agent that reads a deliberate restriction as breakage goes looking for a way round
|
|
11
|
-
// it (the
|
|
11
|
+
// it (the agent that asked the owner for a personal access token).
|
|
12
12
|
//
|
|
13
13
|
// STATIC TEXT ONLY. A card interpolates nothing — no task title, no server message — so
|
|
14
14
|
// printing it adds no prompt-injection surface (the strand-watch / push-path-brief rule).
|
|
@@ -4,19 +4,19 @@
|
|
|
4
4
|
// scripts/gds/push-path-brief.js — say out loud, at session start, that this machine
|
|
5
5
|
// cannot push (task 1003259 / idea 1000838).
|
|
6
6
|
//
|
|
7
|
-
// THE GAP. On 2026-08-24 a
|
|
8
|
-
// concluded "no push credential exists", and asked the owner to
|
|
9
|
-
// PAT and store it in ~/.git-credentials
|
|
10
|
-
// server-mediated publish path (ADR 0055) exists to avoid. The agent was not being
|
|
11
|
-
// careless:
|
|
12
|
-
// token
|
|
7
|
+
// THE GAP. On 2026-08-24 an agent on a credential-less checkout hit auth failures on
|
|
8
|
+
// every raw git probe, concluded "no push credential exists", and asked the owner to
|
|
9
|
+
// mint a fine-grained PAT and store it in ~/.git-credentials — the exact anti-pattern
|
|
10
|
+
// the server-mediated publish path (ADR 0055) exists to avoid. The agent was not being
|
|
11
|
+
// careless: on that checkout every direct GitHub probe failed BY DESIGN (the
|
|
12
|
+
// clone token was one-shot and scrubbed from .git/config after each fetch — ADR 0031 §6),
|
|
13
13
|
// so "missing credential" is the only story the local evidence supports, and the true
|
|
14
14
|
// state at the time (branch already pushed, PR open, CI red) was invisible to it.
|
|
15
|
-
// Nothing the
|
|
15
|
+
// Nothing the session loads says the model out loud. This says it out loud.
|
|
16
16
|
//
|
|
17
17
|
// SO: the third SessionStart truth-teller, beside deploy-divergence.js and
|
|
18
18
|
// strand-watch.js. On the server-publish path (pushVia() 'server' — no authenticated
|
|
19
|
-
// gh, i.e.
|
|
19
|
+
// gh, i.e. any credential-less checkout) it prints ONE line stating the
|
|
20
20
|
// credential model and where the truth about published work lives
|
|
21
21
|
// (GET /api/bongos/tasks/:id/publish-status). On a laptop that pushes locally
|
|
22
22
|
// (pushVia() 'local') it prints NOTHING — a line that fires on every healthy laptop
|
|
@@ -58,7 +58,7 @@ function briefLine(via) {
|
|
|
58
58
|
|
|
59
59
|
// Lazy require so a broken or partial checkout degrades to silence, not a stack
|
|
60
60
|
// trace injected into the session. pushVia() honors <PREFIX>_PUSH_VIA_SERVER, else
|
|
61
|
-
// probes for an authenticated gh (absent on
|
|
61
|
+
// probes for an authenticated gh (absent on a credential-less checkout → 'server' instantly).
|
|
62
62
|
function detectVia() {
|
|
63
63
|
return require('./ship-deploy-target.js').pushVia();
|
|
64
64
|
}
|
|
@@ -70,7 +70,7 @@ function report(via) {
|
|
|
70
70
|
console.log(' Publish path');
|
|
71
71
|
console.log(' ──────────────────────────────────────────────────────────');
|
|
72
72
|
if (via === 'server') {
|
|
73
|
-
console.log(' server-mediated (no authenticated gh — a
|
|
73
|
+
console.log(' server-mediated (no authenticated gh — a credential-less checkout).');
|
|
74
74
|
console.log(` ${BRIEF}`);
|
|
75
75
|
for (const line of plainCardLines('no_push_credential')) console.log(line);
|
|
76
76
|
} else if (via === 'local') {
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
// notices if a blanket find-replace rewrites them. This does.
|
|
46
46
|
//
|
|
47
47
|
// 4. ALIAS MOUNTS — '/api/gds' is a PERMANENT alias (src/bongos/api-prefix.js
|
|
48
|
-
// says never to remove it: shipped
|
|
48
|
+
// says never to remove it: shipped binaries and live instances
|
|
49
49
|
// call it and cannot be force-updated). Asserted against the real exported
|
|
50
50
|
// mount list. The DISPATCH half — that the alias is a live mount and so
|
|
51
51
|
// gets no corrective 404 hint — is already covered by
|
|
@@ -118,6 +118,10 @@ const INTEGRATION = new Set([
|
|
|
118
118
|
// (Prose here avoids single-quoted tokens: the pairing guard below parses this
|
|
119
119
|
// set out of the source, so a quoted word in a comment reads as an entry.)
|
|
120
120
|
'copy_desk_flags_db',
|
|
121
|
+
// task 1004362: core_258 against a real Postgres holding a claim created from a
|
|
122
|
+
// dev box session. The claims foreign key that failed the live upgrade is a
|
|
123
|
+
// schema fact only a transaction engine enforces. Always rolled back.
|
|
124
|
+
'core_258_box_session_claims_db',
|
|
121
125
|
'discord_autojoin', 'discord_oauth',
|
|
122
126
|
// task 1003000 (IC6): the three ideator credit streams against a real Postgres.
|
|
123
127
|
// The three DB-free sibling suites stub the client and SIMULATE the
|
|
@@ -155,7 +155,7 @@ function buildSessionDigest(entries, opts = {}) {
|
|
|
155
155
|
mu.input += tin; mu.output += tout; mu.cache_read += tcr; mu.cache_creation += tcc;
|
|
156
156
|
} else {
|
|
157
157
|
// task 1676: a token-bearing turn with NO model id. Previously dropped
|
|
158
|
-
// from model_usage (→ total_tokens>0 but priced $0 on the
|
|
158
|
+
// from model_usage (→ total_tokens>0 but priced $0 on the CI
|
|
159
159
|
// path; ADR 0097). Accumulate the unlabeled tokens so the digest can
|
|
160
160
|
// attribute them to a real, priceable family bucket after the loop.
|
|
161
161
|
m._unlabeled.input += tin; m._unlabeled.output += tout;
|
|
@@ -233,7 +233,7 @@ function buildSessionDigest(entries, opts = {}) {
|
|
|
233
233
|
m.total_tokens = m.tokens.input + m.tokens.output + m.tokens.cache_read + m.tokens.cache_creation;
|
|
234
234
|
// task 1676 — cost-plus reward zero-out fix. The cost-plus session reward
|
|
235
235
|
// (ADR 0054) prices `model_usage` server-side. model_usage is keyed on msg.model
|
|
236
|
-
// and SKIPS any token-bearing turn whose model id is missing. On the
|
|
236
|
+
// and SKIPS any token-bearing turn whose model id is missing. On the CI
|
|
237
237
|
// agent path that gap was the difference between total_tokens>0 (so the digest
|
|
238
238
|
// passes the route's empty-session guard + gets stored) and model_usage={} (so
|
|
239
239
|
// priceModelUsage returns $0 → 0 drachmae) — ADR 0097's "upload no priced model
|
|
@@ -32,7 +32,7 @@ const { REPO_ROOT } = require('./ship-state.js');
|
|
|
32
32
|
// `bongos upgrade` (pin-bump), NOT an SSH deploy (ADR 0108). When a target IS
|
|
33
33
|
// set it requires that host's SSH key, so only the operator can land.
|
|
34
34
|
//
|
|
35
|
-
// 'ci' — NO builder
|
|
35
|
+
// 'ci' — NO builder machine holds the prod key. ship pushes the branch, opens a
|
|
36
36
|
// PR, and enables GitHub auto-merge; once required checks pass, GitHub
|
|
37
37
|
// merges to main and .github/workflows/deploy-prod.yml deploys from
|
|
38
38
|
// Actions. ship then CONFIRMS the deploy landed (PR merged + the
|
|
@@ -62,8 +62,8 @@ function parseDeployMode(envVal, configRaw) {
|
|
|
62
62
|
// effectiveDeployMode — credential- and protection-aware adjustment of the parsed
|
|
63
63
|
// mode (pure; exported for the regression test). The 'laptop' land path pushes
|
|
64
64
|
// main + SSHes the droplet FROM THIS MACHINE, so it requires a local GitHub push
|
|
65
|
-
// credential. A machine without one — a
|
|
66
|
-
//
|
|
65
|
+
// credential. A machine without one — a fresh/stale local clone that can't
|
|
66
|
+
// even `git pull` (token-less origin, ADR 0053) — physically cannot run it;
|
|
67
67
|
// it must ship via the 'ci' server-mediated publish path instead
|
|
68
68
|
// (pushVia()==='server', ADR 0055), which lets the GDS server push with its own
|
|
69
69
|
// credential. So when the parsed mode is 'laptop' but the machine can't push
|
|
@@ -314,10 +314,10 @@ function fetchDeployedVersion(url = deployedVersionUrl()) {
|
|
|
314
314
|
// pushVia — which publish path ship uses in 'ci' mode (ADR 0055 / task 1025):
|
|
315
315
|
// 'local' — this machine pushes the branch + opens the PR with git + gh
|
|
316
316
|
// (laptop: gh present + authenticated). Today's behaviour.
|
|
317
|
-
// 'server' — this machine has NO GitHub push credential (
|
|
317
|
+
// 'server' — this machine has NO GitHub push credential (no gh, a
|
|
318
318
|
// credential-less origin). ship uploads a thin branch bundle to the
|
|
319
319
|
// GDS, which pushes + opens the PR + auto-merges with the SERVER's
|
|
320
|
-
// credential.
|
|
320
|
+
// credential. This machine holds nothing (#919 model preserved).
|
|
321
321
|
// Override with <PREFIX>_PUSH_VIA_SERVER=1 (force server) / =0 (force local) for tests.
|
|
322
322
|
function ghAvailableAndAuthed() {
|
|
323
323
|
try {
|
|
@@ -338,15 +338,15 @@ function pushVia() {
|
|
|
338
338
|
if (o === '1') return 'server';
|
|
339
339
|
if (o === '0') return 'local';
|
|
340
340
|
// No explicit override: a machine that can run an authenticated gh (laptop)
|
|
341
|
-
// takes the local path; everything else
|
|
341
|
+
// takes the local path; everything else goes server-mediated.
|
|
342
342
|
return ghAvailableAndAuthed() ? 'local' : 'server';
|
|
343
343
|
}
|
|
344
344
|
|
|
345
345
|
// broadcastHandledByServer — task 1045: on the server-mediated publish path the
|
|
346
346
|
// SERVER posts the Discord ship-broadcast after it confirms the deploy (it holds
|
|
347
|
-
// the webhook secrets; the
|
|
348
|
-
// locally there, or
|
|
349
|
-
// as before, fail silently. True only when the publish actually goes server-side:
|
|
347
|
+
// the webhook secrets; the local machine does NOT — ADR 0053). So ship.js must NOT
|
|
348
|
+
// also post locally there, or this machine would either double-post (impossible — no
|
|
349
|
+
// secret) or, as before, fail silently. True only when the publish actually goes server-side:
|
|
350
350
|
// ci deploy mode AND this machine has no GitHub push credential (pushVia 'server').
|
|
351
351
|
// The laptop path (pushVia 'local') keeps posting locally, exactly as today. Pure
|
|
352
352
|
// w.r.t. its inputs (env + committed deploy.json) + exported so the gate is tested.
|
|
@@ -355,12 +355,12 @@ function broadcastHandledByServer() {
|
|
|
355
355
|
}
|
|
356
356
|
|
|
357
357
|
// shouldBailOnFetchFailure — autoMerge's decision when `git fetch origin main`
|
|
358
|
-
// fails. A credential-less
|
|
358
|
+
// fails. A credential-less checkout (private origin, no creds —
|
|
359
359
|
// ADR 0053) CANNOT fetch origin, and that is FINE for the server-mediated
|
|
360
|
-
// publish path (ADR 0055): ciLandServer bundles against
|
|
360
|
+
// publish path (ADR 0055): ciLandServer bundles against this machine's LOCAL
|
|
361
361
|
// origin/main and the SERVER tops up main with its own credential. So a fetch
|
|
362
|
-
// failure is fatal ONLY when we are NOT taking that path — otherwise
|
|
363
|
-
// never reach ciLand and strands every ship at confirmed (the bug task 1027
|
|
362
|
+
// failure is fatal ONLY when we are NOT taking that path — otherwise such a
|
|
363
|
+
// machine can never reach ciLand and strands every ship at confirmed (the bug task 1027
|
|
364
364
|
// surfaced: ADR 0055 shipped the server path but left this fetch guard in front
|
|
365
365
|
// of it). Pure + exported for the regression test (no git, no network).
|
|
366
366
|
// NOTE: callers must still guard the pushVia() gh-probe behind `!fetchedMain` so
|
package/scripts/gds/ship-flow.js
CHANGED
|
@@ -318,7 +318,7 @@ async function shipMain() {
|
|
|
318
318
|
|
|
319
319
|
// ---- Module drift check (BV1.R53, task 1422) ----
|
|
320
320
|
// If the task carries a module_key, verify the committed diff doesn't stray
|
|
321
|
-
// into a DIFFERENT module's territory. "You said game, you touched
|
|
321
|
+
// into a DIFFERENT module's territory. "You said game, you touched provisioning" is
|
|
322
322
|
// the semantic violation this catches. Files no module owns are allowed —
|
|
323
323
|
// they're cross-cutting — as is the territory of a CROSS-CUTTING module, which
|
|
324
324
|
// every craft legitimately writes into. Only contact with a different OWNING
|
package/scripts/gds/ship-land.js
CHANGED
|
@@ -274,11 +274,11 @@ function reconciledCardStatus(liveStatus, preMergeStatus) {
|
|
|
274
274
|
return liveStatus === 'shipped' ? 'shipped' : preMergeStatus;
|
|
275
275
|
}
|
|
276
276
|
|
|
277
|
-
// task 1052 (E): the
|
|
278
|
-
// 'confirmed' without finishing. A
|
|
279
|
-
// CANNOT run /merge-mode (it needs gh + a main checkout), so the old
|
|
280
|
-
// /merge-mode" advice was a dead end
|
|
281
|
-
// had to reverse-engineer recovery from source). Point a
|
|
277
|
+
// task 1052 (E): the machine-appropriate next step when a ship lands the task at
|
|
278
|
+
// 'confirmed' without finishing. A machine with no push credential (pushVia 'server' —
|
|
279
|
+
// no authed gh) CANNOT run /merge-mode (it needs gh + a main checkout), so the old
|
|
280
|
+
// "for /merge-mode" advice was a dead end there (the #1027 retrospective: the agent
|
|
281
|
+
// had to reverse-engineer recovery from source). Point such a machine at the resume
|
|
282
282
|
// instead (task 941); a laptop keeps /merge-mode (with resume as the alternative).
|
|
283
283
|
// Pure + exported for unit tests.
|
|
284
284
|
function strandNextStep(taskId, via) {
|
|
@@ -371,7 +371,7 @@ function prAssigneeLine(login) {
|
|
|
371
371
|
}
|
|
372
372
|
|
|
373
373
|
// task 1003988 — what to tell a builder while their PR sits RED. The poll used to
|
|
374
|
-
// wait out its nine minutes in silence, so a credential-less
|
|
374
|
+
// wait out its nine minutes in silence, so a credential-less checkout learned only that
|
|
375
375
|
// the land was "pending" and pushed the same commit again (PR 922: nine red runs).
|
|
376
376
|
// `md` is publish-status's merge_driver; null means nothing red to report. Pure +
|
|
377
377
|
// exported so the wording is pinned by tests/unit_report_status.mjs.
|
|
@@ -103,7 +103,7 @@ function regenerateShipArtifacts() {
|
|
|
103
103
|
regenerateCopyInventory();
|
|
104
104
|
// Refresh the generated OpenAPI spec + API reference from the shipped route tree (task 1918).
|
|
105
105
|
regenerateApiDocs();
|
|
106
|
-
// ...then the typed client FROM that spec
|
|
106
|
+
// ...then the typed client FROM that spec on the same beat (task 2051).
|
|
107
107
|
regenerateApiClient();
|
|
108
108
|
}
|
|
109
109
|
|
|
@@ -168,10 +168,10 @@ async function mergeLocally(taskId, valueSummary, { dbOnly = false } = {}) {
|
|
|
168
168
|
// nothing to push, merge, or deploy. Short-circuit so the caller's POST
|
|
169
169
|
// /tasks/:id/ship still flips status to shipped instead of stranding the
|
|
170
170
|
// task at confirmed forever.
|
|
171
|
-
// A credential-less
|
|
171
|
+
// A credential-less checkout can't `git fetch origin main` (private origin, no
|
|
172
172
|
// creds — ADR 0053), but that's only fatal OFF the server-publish path: the
|
|
173
|
-
//
|
|
174
|
-
// up main. Without this,
|
|
173
|
+
// ADR-0055 path bundles against its LOCAL origin/main and the server tops
|
|
174
|
+
// up main. Without this, such a checkout dead-ends here and strands every ship at
|
|
175
175
|
// confirmed (task 1027). The `!fetchedMain &&` short-circuit keeps the gh-probe
|
|
176
176
|
// (pushVia) off the happy laptop path, so laptop behavior is byte-for-byte.
|
|
177
177
|
const fetchedMain = shellOk('git fetch origin main');
|
|
@@ -238,22 +238,22 @@ function decidePreMerge({ branch, behind, via }) {
|
|
|
238
238
|
if (!branch || branch === 'main' || branch === 'HEAD') {
|
|
239
239
|
return { action: 'skip', reason: `not on a feature branch (${branch})` };
|
|
240
240
|
}
|
|
241
|
-
// Server-mediated publish (ADR 0055): a credential-less partial-clone
|
|
241
|
+
// Server-mediated publish (ADR 0055): a credential-less partial-clone checkout
|
|
242
242
|
// (blob:none, HTTPS origin, no gh/credential-helper — ADR 0053) CANNOT run a
|
|
243
243
|
// local `git merge origin/main` — the ort merge lazily fetches main's blobs
|
|
244
244
|
// from the promisor remote and there are no credentials to authenticate that
|
|
245
|
-
// fetch, so
|
|
245
|
+
// fetch, so such a checkout strands here and can never ship while behind main, i.e.
|
|
246
246
|
// ≈always (idea #364). It also does not NEED to: ciLandServer bundles
|
|
247
247
|
// `origin/main..HEAD` and the SERVER reconciles the branch with the real main
|
|
248
248
|
// when it pushes + opens + auto-merges the PR; a genuine conflict surfaces
|
|
249
249
|
// server-side as merge_conflict (publish-reconciler / conflict-resolve,
|
|
250
250
|
// ADR 0082). The local pre-merge (#1068) is a LAPTOP-path optimization (so the
|
|
251
251
|
// sandbox-reviewed tree == the shipped tree); it stays exactly as-is there
|
|
252
|
-
// (via 'local'/undefined) and is simply skipped on the
|
|
252
|
+
// (via 'local'/undefined) and is simply skipped on the server path.
|
|
253
253
|
if (via === 'server') {
|
|
254
254
|
return {
|
|
255
255
|
action: 'skip',
|
|
256
|
-
reason: 'server-mediated publish reconciles with origin/main server-side (credential-less partial-clone
|
|
256
|
+
reason: 'server-mediated publish reconciles with origin/main server-side (credential-less partial-clone checkout cannot fetch main blobs locally — idea #364)',
|
|
257
257
|
};
|
|
258
258
|
}
|
|
259
259
|
if (!Number.isFinite(behind) || behind === 0) {
|
|
@@ -26,21 +26,21 @@ function currentBranch() {
|
|
|
26
26
|
//
|
|
27
27
|
// Returns a status string ('skipped-server' | 'regen-failed' | 'current' |
|
|
28
28
|
// 'committed' | 'committed-nofatal') so the regression test (task 1046) can
|
|
29
|
-
// prove the
|
|
29
|
+
// prove the server-publish skip without git or a headless browser.
|
|
30
30
|
function regenerateDiagrams() {
|
|
31
|
-
// task 1046: on the server-mediated-publish path (
|
|
31
|
+
// task 1046: on the server-mediated-publish path (pushVia 'server'),
|
|
32
32
|
// there is no headless browser, so render-diagrams.sh fails and gen-diagrams.js
|
|
33
33
|
// exits non-zero AFTER writing the regenerated .mmd + assertions.json — which
|
|
34
34
|
// shellOk() then treats as a failed regen and returns BEFORE the commit below,
|
|
35
35
|
// leaving those files UNCOMMITTED in the builder's tree (had to be reverted by
|
|
36
|
-
// hand).
|
|
36
|
+
// hand). That path must not attempt the regen at all: skip here and let a
|
|
37
37
|
// render-capable ship (the laptop path, which CAN render the PNGs) refresh them
|
|
38
38
|
// as a matched .mmd+.png+assertions set; the diagram-drift routine backstops any
|
|
39
39
|
// staleness in the meantime. Skipping entirely (vs --no-render) avoids committing
|
|
40
40
|
// a .mmd/.png mismatch to main. Mirrors gen-diagrams.js's own non-fatal skip when
|
|
41
41
|
// bash itself is absent (ENOENT).
|
|
42
42
|
if (pushVia() === 'server') {
|
|
43
|
-
console.log(' diagram regen skipped on the
|
|
43
|
+
console.log(' diagram regen skipped on the server-publish ship path (no GDS session for the conceptual diagrams) — a full-clone ship refreshes the .mmd; drift checker backstops staleness');
|
|
44
44
|
return 'skipped-server';
|
|
45
45
|
}
|
|
46
46
|
// ADR 0110 pt.3 (task 2027): the .svg/.png RENDERS are now gitignored and
|
|
@@ -74,7 +74,7 @@ function regenerateDiagrams() {
|
|
|
74
74
|
|
|
75
75
|
// task 1224 (Path B / ADR 0063): refresh the generated symbol skeleton from the shipped tree so the
|
|
76
76
|
// altitude map can't drift. Pure JS (no headless browser, no render) — unlike the diagrams it is safe
|
|
77
|
-
// on EVERY ship path, including the
|
|
77
|
+
// on EVERY ship path, including the server-publish path. Non-fatal: a hiccup must never block
|
|
78
78
|
// a ship. ADR 0110 (task 1926): docs/repo-map.md is now GITIGNORED + regenerated at deploy — the
|
|
79
79
|
// generator still WRITES it (untracked, harmless), but ship commits ONLY the tracked nested-doc
|
|
80
80
|
// blocks. It is deliberately absent from the git add/status lists below: `git add <ignored path>`
|
|
@@ -101,12 +101,12 @@ function regenerateRepoMap() {
|
|
|
101
101
|
|
|
102
102
|
// Refresh the generated session-log index (docs/session-log-index.md) + the bounded CLAUDE.md §13
|
|
103
103
|
// "recent sessions" snippet from the shipped tree's docs/session-logs/*.md (ADR 0062 §8, task 1226).
|
|
104
|
-
// Pure JS (reads files, no DB, no headless browser) — safe on EVERY ship path including the
|
|
104
|
+
// Pure JS (reads files, no DB, no headless browser) — safe on EVERY ship path including the
|
|
105
105
|
// server-publish path. Non-fatal: a hiccup must never block a ship; the Path-C CI gate
|
|
106
106
|
// (`gen-session-index --check`) backstops staleness on main.
|
|
107
107
|
// Refresh the generated API docs (docs/api/openapi.json + docs/api-reference.md +
|
|
108
108
|
// docs/routes-permissions.md) from the shipped route tree (task 1918). Pure JS (reads
|
|
109
|
-
// route files, no DB, no headless browser) — safe on EVERY ship path incl. the
|
|
109
|
+
// route files, no DB, no headless browser) — safe on EVERY ship path incl. the
|
|
110
110
|
// server-publish path. Non-fatal: a hiccup must never block a ship; the fitness
|
|
111
111
|
// `gen-api-docs --check` gate backstops staleness on main.
|
|
112
112
|
function regenerateApiDocs() {
|
|
@@ -135,10 +135,7 @@ function regenerateApiDocs() {
|
|
|
135
135
|
// so a route change left the client stale until the api_client test caught it in CI.
|
|
136
136
|
// Non-fatal + safe on every ship path; the api_client freshness test backstops main.
|
|
137
137
|
|
|
138
|
-
// The regenerated client's git pathspec
|
|
139
|
-
// a vendored copy inside a desktop app, named only when on disk because `git add` of an
|
|
140
|
-
// unmatched pathspec aborts the whole stage (task 1002417). The app is gone (task
|
|
141
|
-
// 1003891), so the pathspec is the one directory the generator writes.
|
|
138
|
+
// The regenerated client's git pathspec: the one directory the generator writes.
|
|
142
139
|
const API_CLIENT_PATHSPEC = 'clients/bongos-client';
|
|
143
140
|
|
|
144
141
|
function regenerateApiClient() {
|
|
@@ -186,7 +183,7 @@ function regenerateSessionIndex() {
|
|
|
186
183
|
// Refresh the generated file-map sections (.claude/skills/ + .claude/scheduled-tasks/ trees in
|
|
187
184
|
// docs/file-map.md) from what is on disk (ADR 0066, task 1276). Pure JS (reads dirs + the
|
|
188
185
|
// docs/file-map.notes.json sidecar, no DB, no headless browser) — safe on EVERY ship path including
|
|
189
|
-
// the
|
|
186
|
+
// the server-publish path. Non-fatal: a hiccup must never block a ship; the Path-C CI gate
|
|
190
187
|
// (`gen-file-map --check`, in fitness.js) backstops staleness on main. NB gen-file-map exits 2 when
|
|
191
188
|
// a skill/routine has no note, so shellOk may report "failed" on a legit note-gap ship — that is
|
|
192
189
|
// fine, we still commit whatever it wrote and CI surfaces the missing note.
|
package/scripts/gds/ship.js
CHANGED
|
@@ -273,8 +273,8 @@ module.exports = {
|
|
|
273
273
|
// preflight's upstream-deletion warning — exported so it's unit-tested
|
|
274
274
|
// without a live git repo.
|
|
275
275
|
parseDeletedUpstreamPaths,
|
|
276
|
-
// task 1052 (E):
|
|
277
|
-
// (via 'server') is pointed at the resume, never at gh-only /merge-mode.
|
|
276
|
+
// task 1052 (E): path-aware "what to do next" for a confirmed-strand — a machine
|
|
277
|
+
// on the server path (via 'server') is pointed at the resume, never at gh-only /merge-mode.
|
|
278
278
|
strandNextStep,
|
|
279
279
|
// task 1002606: the success-pending banner lines, pure — pinned so the strand
|
|
280
280
|
// detection story ("NOT a failure" + how you WILL find out if it fails) can't drift.
|
|
@@ -293,20 +293,20 @@ module.exports = {
|
|
|
293
293
|
// #858: commit-pinned deploy confirmation via the /version endpoint.
|
|
294
294
|
deployedCommitStatus,
|
|
295
295
|
// ADR 0055 / task 1025: which ci-mode publish path this machine uses
|
|
296
|
-
// ('local' = git+gh here; 'server' = server-mediated,
|
|
296
|
+
// ('local' = git+gh here; 'server' = server-mediated, no local push credential) — so
|
|
297
297
|
// doctor.js reports the same path ship will take instead of failing on
|
|
298
298
|
// missing gh where gh isn't needed.
|
|
299
299
|
pushVia,
|
|
300
|
-
// task 1046: diagram regen returns a status string and SKIPS on the
|
|
301
|
-
//
|
|
302
|
-
//
|
|
300
|
+
// task 1046: diagram regen returns a status string and SKIPS on the server-publish
|
|
301
|
+
// path so such a checkout never leaves uncommitted .mmd/assertions in its tree —
|
|
302
|
+
// exported so the regression test proves the skip without git.
|
|
303
303
|
regenerateDiagrams,
|
|
304
304
|
regenerateRepoMap,
|
|
305
305
|
regenerateSessionIndex,
|
|
306
306
|
// ADR 0066 / task 1276: regenerate docs/file-map.md's skills + scheduled-tasks sections from disk.
|
|
307
307
|
regenerateFileMap,
|
|
308
308
|
// task 1037: autoMerge's fetch-failure decision — fatal only OFF the server-
|
|
309
|
-
// publish path (a credential-less
|
|
309
|
+
// publish path (a credential-less checkout can't fetch but ships via ADR 0055).
|
|
310
310
|
// Exported pure so the regression test proves the truth table without git.
|
|
311
311
|
shouldBailOnFetchFailure,
|
|
312
312
|
// task 391 (idea #37): autoMerge's zero-commit verdict — refuse a zero-commit
|
|
@@ -342,8 +342,8 @@ module.exports = {
|
|
|
342
342
|
if (require.main === module) {
|
|
343
343
|
// --print-deploy-mode (task 1003221): the EFFECTIVE mode, one word, no session or
|
|
344
344
|
// network. The /merge-mode skill used to probe parseDeployMode directly, which
|
|
345
|
-
// defaults to 'laptop' when config/deploy.json is absent —
|
|
346
|
-
//
|
|
345
|
+
// defaults to 'laptop' when config/deploy.json is absent — sending the
|
|
346
|
+
// builder down a push path they had no credential for.
|
|
347
347
|
if (process.argv.slice(2).includes('--print-deploy-mode')) {
|
|
348
348
|
console.log(require('./ship-deploy-target.js').resolveDeployMode());
|
|
349
349
|
process.exit(0);
|
|
@@ -4,12 +4,13 @@
|
|
|
4
4
|
// 1000077; criterion guards-skill-declares-machine).
|
|
5
5
|
//
|
|
6
6
|
// THE INCIDENT. /merge-mode states in its own prose that it assumes the Archon's
|
|
7
|
-
// Mac or the droplet. It was run on a
|
|
8
|
-
// strandNextStep() tells a
|
|
9
|
-
// a main checkout this machine doesn't have." So the
|
|
10
|
-
// places and neither stopped the run, because prose cannot
|
|
11
|
-
// executable copy was on a different code path. A capability a
|
|
12
|
-
// must be a declaration the machine can CHECK, not a sentence a
|
|
7
|
+
// Mac or the droplet. It was run on a machine with no push credential anyway. Worse,
|
|
8
|
+
// ship.js ALREADY knew: strandNextStep() tells such a machine "/merge-mode is NOT
|
|
9
|
+
// available here — it needs gh + a main checkout this machine doesn't have." So the
|
|
10
|
+
// knowledge existed in two places and neither stopped the run, because prose cannot
|
|
11
|
+
// refuse and the one executable copy was on a different code path. A capability a
|
|
12
|
+
// procedure needs must be a declaration the machine can CHECK, not a sentence a
|
|
13
|
+
// reader can skim.
|
|
13
14
|
//
|
|
14
15
|
// THREE PARTS, matching that diagnosis:
|
|
15
16
|
// 1. `requires:` in the skill's own YAML frontmatter — the declaration.
|
|
@@ -74,7 +75,7 @@ const CAPABILITIES = {
|
|
|
74
75
|
what: 'an authenticated GitHub CLI',
|
|
75
76
|
probe: () => ghAuthed(),
|
|
76
77
|
missing: 'no authenticated `gh` on this machine. Run `gh auth login`, or use a machine that has it — '
|
|
77
|
-
+ 'a
|
|
78
|
+
+ 'a machine with no push credential normally does not, by design (it publishes through the server instead, ADR 0055).',
|
|
78
79
|
},
|
|
79
80
|
'main-checkout': {
|
|
80
81
|
what: 'the main checkout, not a linked worktree',
|
|
@@ -318,7 +319,7 @@ function checkOpsSkillsDeclareMachine({ dir = SKILLS_DIR, read = null, names: in
|
|
|
318
319
|
violations.push(
|
|
319
320
|
`${n} fences commands needing [${undeclared.join(', ')}] but does not declare them. `
|
|
320
321
|
+ 'Add them to `requires:` in the frontmatter so the preflight can refuse early — '
|
|
321
|
-
+ 'prose cannot refuse, which is how /merge-mode came to be run on a
|
|
322
|
+
+ 'prose cannot refuse, which is how /merge-mode came to be run on a machine that could not run it (task 1003167).'
|
|
322
323
|
);
|
|
323
324
|
}
|
|
324
325
|
}
|
package/src/bongos/api-prefix.js
CHANGED
|
@@ -9,10 +9,10 @@
|
|
|
9
9
|
//
|
|
10
10
|
// The URL rename (Part B / B1, task 1919) flipped the canonical here: the API is
|
|
11
11
|
// now served at '/api/bongos', and '/api/gds' stays mounted FOREVER as a silent
|
|
12
|
-
// alias (LEGACY_API_PREFIXES). "Forever" is deliberate — shipped
|
|
13
|
-
//
|
|
14
|
-
//
|
|
15
|
-
//
|
|
12
|
+
// alias (LEGACY_API_PREFIXES). "Forever" is deliberate — shipped older CLI
|
|
13
|
+
// releases and the separately-hosted status-dashboard mirror all call '/api/gds'
|
|
14
|
+
// and can't be force-updated. serve-internal.js mounts the router + discovery
|
|
15
|
+
// index at API_PREFIX and every LEGACY_API_PREFIXES entry.
|
|
16
16
|
const API_PREFIX = '/api/bongos';
|
|
17
17
|
|
|
18
18
|
// Prefixes the server ALSO answers on, for callers pinned to the previous path.
|
|
@@ -431,7 +431,7 @@ const MODULE_GLOBS = {
|
|
|
431
431
|
'scripts/gds/scope-roster-guard.js',
|
|
432
432
|
'scripts/gds/route-shadow-guard.js', 'scripts/gds/routine-schedule.js',
|
|
433
433
|
'scripts/gds/seam-wiring-guard.js', 'scripts/gds/skill-preflight.js',
|
|
434
|
-
'scripts/gds/test-path-guard.js', 'scripts/gds/version-literal-guard.js',
|
|
434
|
+
'scripts/gds/test-path-guard.js', 'scripts/gds/version-literal-guard.js', 'scripts/gds/dev-box-guard.js',
|
|
435
435
|
|
|
436
436
|
// ADOPTED (task 1004111): the enforcement surfaces this module already IS.
|
|
437
437
|
// install-git-hooks.js + scripts/gds/hooks/ are the pre-push hook beside the
|
|
@@ -65,7 +65,7 @@ const API = `(?:${ALL_API_PREFIXES.map(escRe).join('|')})`;
|
|
|
65
65
|
// Caddy's on-demand-TLS `ask` and the provisioning probe —
|
|
66
66
|
// server-to-server, cookie-less, and on a control plane a
|
|
67
67
|
// refused ask means no project ever gets a certificate.
|
|
68
|
-
// /downloads/* the installer script and the
|
|
68
|
+
// /downloads/* the installer script and the release downloads — a
|
|
69
69
|
// cookie-less `curl … | sh`, and release redirects carry
|
|
70
70
|
// no project data.
|
|
71
71
|
// /__prelaunch the pre-launch gate's own submit, when both gates are on.
|
package/src/bongos/routes/me.js
CHANGED
|
@@ -510,7 +510,7 @@ module.exports = function buildMeRouter() {
|
|
|
510
510
|
};
|
|
511
511
|
// Module→core contribution seam (BV1.R42, ADR 0083). Let each enabled module
|
|
512
512
|
// add its own profile slice instead of core hardcoding it — the strangler
|
|
513
|
-
// prerequisite that lets
|
|
513
|
+
// prerequisite that lets discord/art leave this route. ADD-ONLY (core
|
|
514
514
|
// keys win); a collision means a move task took over a core key without
|
|
515
515
|
// dropping the core copy. Empty until a module registers → byte-identical today.
|
|
516
516
|
const slices = await seams.collectContributions('profile.fields', {
|
|
@@ -113,9 +113,9 @@ module.exports = function buildSecurityRouter() {
|
|
|
113
113
|
//
|
|
114
114
|
// The DATED security engagement reports (exploit detail — full repro,
|
|
115
115
|
// evidence, the attacker cookbook) are served from the DB, NOT committed to
|
|
116
|
-
// the git clone: the repo is cloned in full onto every Metic+
|
|
117
|
-
// (threat-model §6.3 / ADR 0020), so a committed exploit report is an
|
|
118
|
-
// attacker cookbook on every
|
|
116
|
+
// the git clone: the repo is cloned in full onto every Metic+ builder's
|
|
117
|
+
// machine (threat-model §6.3 / ADR 0020), so a committed exploit report is an
|
|
118
|
+
// attacker cookbook on every machine. The SAFE conceptual docs (threat-model.md,
|
|
119
119
|
// the README) stay in docs/security/; only the dated reports live here, and
|
|
120
120
|
// ALL three routes gate on requirePermission('security.report.adjudicate')
|
|
121
121
|
// — an archon-floored atom (BV1.R104; was requireRank('archon') and admits
|
package/src/bongos/routes.js
CHANGED
|
@@ -167,8 +167,8 @@ function buildGdsRouter() {
|
|
|
167
167
|
// core to every instance, not an OTB feature.
|
|
168
168
|
router.use(buildLiveRouter());
|
|
169
169
|
// Feature-module-gated mounts (R54, task 1193, ADR 0062 §4). Off on a vanilla
|
|
170
|
-
// instance; ON for OTB via config/modules.json so prod is unchanged.
|
|
171
|
-
//
|
|
170
|
+
// instance; ON for OTB via config/modules.json so prod is unchanged. art-pipeline
|
|
171
|
+
// and discord (with its bug-attachments route) have both graduated
|
|
172
172
|
// into real modules (modules/<key>/) — they are discovered + mounted by
|
|
173
173
|
// moduleLoader.mountModuleRoutes below, not here (BV1.R43 / R48 / R47 / R72).
|
|
174
174
|
// gate-approvals likewise moved to the lifecycle module (BV1.R86).
|
|
@@ -622,8 +622,8 @@ function mountInternalSurfaces(app) {
|
|
|
622
622
|
//
|
|
623
623
|
// Dual-mount (task 1919): the router + this discovery index are mounted at the
|
|
624
624
|
// canonical API_PREFIX (/api/bongos) AND every LEGACY_API_PREFIXES entry
|
|
625
|
-
// (/api/gds) — the legacy alias stays FOREVER so
|
|
626
|
-
// cached status mirror
|
|
625
|
+
// (/api/gds) — the legacy alias stays FOREVER so older CLI releases and the
|
|
626
|
+
// cached status mirror keep working (src/bongos/api-prefix.js). The
|
|
627
627
|
// SAME router instance is mounted at each path. Each discovery GET is registered
|
|
628
628
|
// BEFORE its router mount so the exact base-path GET wins; every other
|
|
629
629
|
// method/subpath falls through to the router.
|
|
@@ -670,7 +670,7 @@ function mountInternalSurfaces(app) {
|
|
|
670
670
|
// below only prefixes non-/api paths, so without this placement /downloads/*
|
|
671
671
|
// would be rewritten to /builders/downloads/* and 404). The installer scripts are served with the
|
|
672
672
|
// server's PINNED origin substituted for __GDS_API_BASE__ — never a request
|
|
673
|
-
// header, so a spoofed Host can't redirect a `curl | sh
|
|
673
|
+
// header, so a spoofed Host can't redirect a `curl | sh`.
|
|
674
674
|
const bongosCfg = tryLoadInstanceConfig('bongos-cli.json');
|
|
675
675
|
if (bongosCfg) {
|
|
676
676
|
const bongosDownloads = buildBongosDownloads(bongosCfg);
|
|
@@ -894,8 +894,7 @@ function mountInternalSurfaces(app) {
|
|
|
894
894
|
// them to the hall, and an unauthenticated visitor into sign-in). The subdomain
|
|
895
895
|
// shim above has already rewritten the bare /watch + /gate onto /builders/*.
|
|
896
896
|
// (Defense in depth: every data endpoint these pages call carries its own
|
|
897
|
-
// server-side gate.)
|
|
898
|
-
// box: its page is gone, and a gate in front of nothing is a dead guard.
|
|
897
|
+
// server-side gate.)
|
|
899
898
|
const WATCH_PAGE_RE = /^\/builders\/watch(?:\.html)?\/?$/;
|
|
900
899
|
const GATE_PAGE_RE = /^\/builders\/gate(?:\.html)?\/?$/;
|
|
901
900
|
// /sessions (the session-log ledger) belongs to that same Governance group and
|
|
@@ -1144,7 +1143,7 @@ function mountInternalSurfaces(app) {
|
|
|
1144
1143
|
// the landing card + GitHub button render for a stranger.
|
|
1145
1144
|
//
|
|
1146
1145
|
// ONE tier of gate: ANY SIGNED-IN BUILDER — the Work Board, Roadmap, the Goals
|
|
1147
|
-
// page, the task-detail page, the Repo Atlas,
|
|
1146
|
+
// page, the task-detail page, the Repo Atlas, Settings
|
|
1148
1147
|
// (#748, #904, task 1293, task 1757, task 751) and, since task 1002710, the
|
|
1149
1148
|
// orientation reading rooms (primer, diagrams). A Xenos IS allowed; an
|
|
1150
1149
|
// unauthenticated visitor is bounced into sign-in rather than served the shell.
|
package/src/bongos-downloads.js
CHANGED
|
@@ -4,8 +4,7 @@
|
|
|
4
4
|
// The compiled per-platform binaries can't ride the git-based deploy (private
|
|
5
5
|
// repo, no LFS, GitHub's 100MB cap), so CI publishes them as release assets on a
|
|
6
6
|
// PUBLIC releases repo (config/bongos-cli.json — the same off-repo pattern as the
|
|
7
|
-
//
|
|
8
|
-
// module turns that committed config into:
|
|
7
|
+
// ADR 0029 status mirror). This module turns that committed config into:
|
|
9
8
|
//
|
|
10
9
|
// GET /downloads/bongos/latest.json → { version, assets: { target: {file,url} } }
|
|
11
10
|
// GET /downloads/bongos/version → { version, assets: { target: url } }
|
|
@@ -14,10 +13,6 @@
|
|
|
14
13
|
// so every URL a user sees or the installer fetches stays on the instance apex,
|
|
15
14
|
// and a release bump is a one-file config change that rides the normal ship flow.
|
|
16
15
|
// Pure (config in, urls out) so tests need no server.
|
|
17
|
-
//
|
|
18
|
-
// (A near-twin of src/devbox-downloads.js by design — same off-repo release
|
|
19
|
-
// pattern, different artifact. Kept as its own module for a clear name + its own
|
|
20
|
-
// config pointer; the two are independent instance features.)
|
|
21
16
|
|
|
22
17
|
function buildBongosDownloads(cfg) {
|
|
23
18
|
if (!cfg || typeof cfg !== 'object') throw new Error('bongos-downloads: missing config');
|