@bongos/core 1.21.176 → 1.21.178
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 +186 -496
- package/.claude/skills/planning-session/SKILL.md +2 -2
- package/clients/bongos-client/README.md +1 -1
- package/clients/bongos-client/bongos-client.global.js +0 -6
- package/clients/bongos-client/index.cjs +0 -6
- package/clients/bongos-client/index.d.ts +0 -6
- package/clients/bongos-client/index.mjs +0 -6
- package/config/scheduled-routines.json +3 -8
- package/docs/adr/0042-builder-self-deploy-ci-auto-merge.md +3 -2
- package/docs/adr/0091-bounding-the-kernel-and-db-carve.md +1 -1
- package/docs/adr/0093-tranche-2-core-carve-sequence.md +1 -1
- package/docs/api/openapi.json +1 -87
- package/docs/api-reference.md +1 -8
- package/docs/canonical-permissions.md +4 -4
- package/docs/copy-inventory.md +25 -39
- package/docs/copy-registry.json +73 -200
- package/docs/file-map.md +6 -11
- package/docs/handoff-template.md +1 -1
- package/docs/module-api-changelog.md +4 -0
- package/docs/modules-contract.md +2 -2
- package/docs/onboarding/diagrams/README.md +3 -7
- package/docs/onboarding/diagrams/assertions.json +3 -3
- package/docs/page-inventory.json +4 -7
- package/docs/page-readings.json +1520 -1569
- package/docs/recipes/ops-gotchas.md +3 -1
- package/modules/autonomy/db.js +9 -0
- package/modules/autonomy/module.json +2 -2
- package/modules/autonomy/pollers/daily-checks.js +262 -0
- package/modules/autonomy/pollers/routine-timers.js +7 -5
- package/modules/autonomy/rank-roles.js +64 -0
- package/modules/autonomy/server-schedule.js +37 -0
- package/modules/government/catalog.js +10 -7
- package/modules/government/decision-board.js +0 -1
- package/modules/government/decision-rules.js +0 -1
- package/modules/government/docket.js +0 -1
- package/modules/government/protected-surfaces.js +1 -1
- package/modules/government/protected-surfaces.json +2 -3
- package/modules/hall-ui/public/atlas.html +1 -1
- package/modules/hall-ui/public/blockers.html +1 -1
- package/modules/hall-ui/public/board-room.html +1 -1
- package/modules/hall-ui/public/city.html +1 -1
- package/modules/hall-ui/public/collab.html +1 -1
- package/modules/hall-ui/public/commands.html +1 -1
- package/modules/hall-ui/public/copy-desk.html +1 -1
- package/modules/hall-ui/public/deploy.html +1 -1
- package/modules/hall-ui/public/diagrams.html +1 -1
- package/modules/hall-ui/public/drachmae.html +1 -1
- package/modules/hall-ui/public/fleet.html +1 -1
- package/modules/hall-ui/public/gate.css +4 -26
- package/modules/hall-ui/public/gate.html +12 -27
- package/modules/hall-ui/public/gate.js +26 -176
- package/modules/hall-ui/public/gate.states.json +4 -22
- package/modules/hall-ui/public/goal-map.html +1 -1
- package/modules/hall-ui/public/goals.html +1 -1
- package/modules/hall-ui/public/government.html +1 -1
- package/modules/hall-ui/public/idea.html +1 -1
- package/modules/hall-ui/public/ideas.html +1 -1
- package/modules/hall-ui/public/index.html +1 -1
- package/modules/hall-ui/public/modules.html +1 -1
- package/modules/hall-ui/public/my-agents.html +1 -1
- package/modules/hall-ui/public/primer.html +1 -1
- package/modules/hall-ui/public/profile.html +1 -1
- package/modules/hall-ui/public/project-settings.html +1 -1
- package/modules/hall-ui/public/ranks.html +1 -1
- package/modules/hall-ui/public/roadmap.html +1 -1
- package/modules/hall-ui/public/roster.html +1 -1
- package/modules/hall-ui/public/sessions.html +1 -1
- package/modules/hall-ui/public/settings.html +1 -1
- package/modules/hall-ui/public/shell.js +1 -1
- package/modules/hall-ui/public/street-card.js +5 -9
- package/modules/hall-ui/public/street-desk.js +2 -2
- package/modules/hall-ui/public/street-inside.js +1 -1
- package/modules/hall-ui/public/street.html +1 -1
- package/modules/hall-ui/public/studio.html +1 -1
- package/modules/hall-ui/public/task.html +1 -1
- package/modules/hall-ui/public/thinking.html +1 -1
- package/modules/hall-ui/public/tweak-editor.html +1 -1
- package/modules/hall-ui/public/watch.html +1 -1
- package/modules/hall-ui/public/work.html +1 -1
- package/modules/lifecycle/matter-acts.js +0 -6
- package/modules/lifecycle/module.json +0 -1
- package/package-lock.json +2 -2
- package/package.json +1 -1
- package/release-notes.json +36 -0
- package/scripts/bongos/adopt-preflight.js +3 -3
- package/scripts/bongos/api-alias-caller-scan.js +2 -2
- package/scripts/bongos/audit-authorship.sh +1 -8
- package/scripts/bongos/audit-rank-roles.js +15 -56
- package/scripts/bongos/bump-version.js +46 -9
- package/scripts/bongos/codemod-rename-scripts-gds.js +0 -1
- package/scripts/bongos/diagram-facts.js +1 -1
- package/scripts/bongos/do-api.js +1 -1
- package/scripts/bongos/doc-cli-guard.js +2 -0
- package/scripts/bongos/doc-control-claims.js +2 -2
- package/scripts/bongos/fitness-checks-identity.js +4 -15
- package/scripts/bongos/gen-diagrams.js +3 -3
- package/scripts/bongos/government-walk.js +3 -9
- package/scripts/bongos/hard-floor.js +52 -0
- package/scripts/bongos/publish-manifest.js +3 -3
- package/scripts/bongos/pulse.js +5 -3
- package/scripts/bongos/routine-schedule.js +38 -3
- package/scripts/bongos/run-unit-tests.js +17 -5
- package/scripts/bongos/ship-regen.js +2 -3
- package/scripts/gds/{goal-names.js → hard-floor.js} +3 -4
- package/scripts/security/dep-audit.js +50 -124
- package/src/bongos/module-scope-map.js +2 -2
- package/src/bongos/permission-path-check.js +1 -1
- package/src/bongos/route-rank-check.js +1 -8
- package/src/bongos/routes.js +1 -2
- package/src/module-api.js +1 -1
- package/src/modules.js +1 -1
- package/tests/acclaim_feed_evidence_db.mjs +42 -23
- package/tests/adr_0089_scope.mjs +7 -5
- package/tests/autonomy_daily_checks.mjs +201 -0
- package/tests/bump_version.mjs +52 -18
- package/tests/claude_materialize.mjs +12 -12
- package/tests/copy_desk_flags_db.mjs +22 -14
- package/tests/effective_visibility_predicate.mjs +0 -18
- package/tests/gating_review_retired.mjs +1 -1
- package/tests/government_act_alone_buildings.mjs +1 -3
- package/tests/government_board_membership_db.mjs +35 -22
- package/tests/government_protected_surfaces.mjs +29 -13
- package/tests/governor_docket.mjs +0 -2
- package/tests/governor_matter_acts.mjs +6 -8
- package/tests/hall_city.mjs +1 -1
- package/tests/hall_matter_card.mjs +2 -2
- package/tests/hall_oversight_world.mjs +16 -12
- package/tests/hall_street_desk.mjs +4 -3
- package/tests/hall_street_inside.mjs +1 -1
- package/tests/helpers.mjs +34 -0
- package/tests/howto_state.mjs +33 -56
- package/tests/howto_state_db.mjs +68 -0
- package/tests/idea_credit_streams_db.mjs +11 -3
- package/tests/integration_parked_ratchet.mjs +7 -1
- package/tests/nav_permission_atoms.mjs +1 -1
- package/tests/page_notes_db.mjs +12 -8
- package/tests/page_tweak_no_rearm.mjs +50 -0
- package/tests/publish_manifest.mjs +64 -0
- package/tests/routine_capture_kind.mjs +18 -7
- package/tests/routine_schedule.mjs +42 -0
- package/tests/search_isolation.mjs +5 -103
- package/tests/search_isolation_db.mjs +140 -0
- package/tests/session_earnings_mirror_db.mjs +2 -0
- package/tests/workflow_exec_paths.mjs +9 -11
- package/modules/lifecycle/routes/gate-approvals.js +0 -299
- package/scripts/bongos/artifact-staleness.js +0 -267
- package/scripts/bongos/ci-grade.js +0 -82
- package/scripts/bongos/classify-discipline.js +0 -153
- package/scripts/bongos/codemod-rename-src-gds.js +0 -145
- package/scripts/bongos/coreB-carve-proof.sh +0 -725
- package/scripts/bongos/gate-review.js +0 -330
- package/scripts/bongos/goal-names.js +0 -102
- package/scripts/bongos/rename-goals.js +0 -109
- package/scripts/bongos/seed-adopt-tasks.js +0 -75
- package/scripts/bongos/seed-api-contract-goal-tasks.js +0 -141
- package/scripts/bongos/seed-board-room-tasks.js +0 -196
- package/scripts/bongos/seed-bongos-app-tasks.js +0 -294
- package/scripts/bongos/seed-bongos-coreB-tranche1-tasks.js +0 -81
- package/scripts/bongos/seed-bongos-coreB-tranche2-tasks.js +0 -100
- package/scripts/bongos/seed-bongos-goal-hierarchy-tasks.js +0 -307
- package/scripts/bongos/seed-bongos-module-system-tasks.js +0 -346
- package/scripts/bongos/seed-bongos-tasks.js +0 -214
- package/scripts/bongos/seed-bongos-v1-seo-tasks.js +0 -104
- package/scripts/bongos/seed-bv1-community-tasks.js +0 -131
- package/scripts/bongos/seed-bv1-privacy-invites-tasks.js +0 -133
- package/scripts/bongos/seed-bv1-profile-page-tasks.js +0 -161
- package/scripts/bongos/seed-bv1-r01-delta-tasks.js +0 -154
- package/scripts/bongos/seed-bv2-tweak-mode-tasks.js +0 -277
- package/scripts/bongos/seed-gds-v4-tasks.js +0 -624
- package/scripts/bongos/seed-governance-tasks.js +0 -340
- package/scripts/bongos/seed-medusa-tasks.js +0 -440
- package/scripts/bongos/seed-module-upstreaming.js +0 -219
- package/scripts/bongos/seed-productization-tasks.js +0 -235
- package/scripts/bongos/seed-project-admin-console-tasks.js +0 -88
- package/scripts/bongos/seed-provisioning-tasks.js +0 -83
- package/scripts/bongos/seed-strict-versioning-tasks.js +0 -275
- package/scripts/bongos/seed-v2-world-tasks.js +0 -283
- package/scripts/gds/artifact-staleness.js +0 -7
- package/scripts/gds/ci-grade.js +0 -7
- package/scripts/gds/classify-discipline.js +0 -7
- package/scripts/gds/codemod-rename-src-gds.js +0 -7
- package/scripts/gds/coreB-carve-proof.sh +0 -8
- package/scripts/gds/gate-review.js +0 -7
- package/scripts/gds/rename-goals.js +0 -7
- package/scripts/gds/seed-adopt-tasks.js +0 -7
- package/scripts/gds/seed-api-contract-goal-tasks.js +0 -7
- package/scripts/gds/seed-board-room-tasks.js +0 -6
- package/scripts/gds/seed-bongos-app-tasks.js +0 -7
- package/scripts/gds/seed-bongos-coreB-tranche1-tasks.js +0 -7
- package/scripts/gds/seed-bongos-coreB-tranche2-tasks.js +0 -7
- package/scripts/gds/seed-bongos-goal-hierarchy-tasks.js +0 -7
- package/scripts/gds/seed-bongos-module-system-tasks.js +0 -7
- package/scripts/gds/seed-bongos-tasks.js +0 -7
- package/scripts/gds/seed-bongos-v1-seo-tasks.js +0 -6
- package/scripts/gds/seed-bv1-community-tasks.js +0 -6
- package/scripts/gds/seed-bv1-privacy-invites-tasks.js +0 -6
- package/scripts/gds/seed-bv1-profile-page-tasks.js +0 -6
- package/scripts/gds/seed-bv1-r01-delta-tasks.js +0 -6
- package/scripts/gds/seed-bv2-tweak-mode-tasks.js +0 -6
- package/scripts/gds/seed-gds-v4-tasks.js +0 -7
- package/scripts/gds/seed-governance-tasks.js +0 -7
- package/scripts/gds/seed-medusa-tasks.js +0 -7
- package/scripts/gds/seed-module-upstreaming.js +0 -7
- package/scripts/gds/seed-productization-tasks.js +0 -7
- package/scripts/gds/seed-project-admin-console-tasks.js +0 -6
- package/scripts/gds/seed-provisioning-tasks.js +0 -7
- package/scripts/gds/seed-strict-versioning-tasks.js +0 -7
- package/scripts/gds/seed-v2-world-tasks.js +0 -7
- package/scripts/migrate_cost_ledger.sh +0 -178
- package/tests/artifact_staleness.mjs +0 -207
- package/tests/gate_approvals.mjs +0 -611
- package/tests/gate_review.mjs +0 -152
- package/tests/goal_names.mjs +0 -120
- package/tests/newcomer_generator.mjs +0 -48
|
@@ -1,41 +1,33 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
// Dependency vulnerability scan — single source of truth for
|
|
3
|
-
//
|
|
2
|
+
// Dependency vulnerability scan — single source of truth for the CLI and the
|
|
3
|
+
// server's daily check (V3.R37 / #258; in-process since task 1004878).
|
|
4
4
|
//
|
|
5
|
-
//
|
|
6
|
-
//
|
|
7
|
-
//
|
|
5
|
+
// One scan: `npm audit --audit-level=high --json` against the root package.json.
|
|
6
|
+
// (A second scan, pip-audit over art/pipeline/requirements.txt, went with the art
|
|
7
|
+
// pipeline it audited — task 1004860 deleted that pipeline, task 1004878 the scan.)
|
|
8
8
|
//
|
|
9
|
-
// The script parses
|
|
10
|
-
//
|
|
11
|
-
//
|
|
9
|
+
// The script parses the output and emits ONE deterministic JSON report on stdout
|
|
10
|
+
// containing every high/critical finding. A short, builder-readable summary goes
|
|
11
|
+
// to stderr so a log is skim-able.
|
|
12
12
|
//
|
|
13
13
|
// Two modes:
|
|
14
14
|
//
|
|
15
|
-
// --report-mode=ci (default
|
|
16
|
-
// exit
|
|
17
|
-
// exit 0 if both scans clean.
|
|
15
|
+
// --report-mode=ci (default) exit 1 if ANY finding is high or critical,
|
|
16
|
+
// exit 0 if the scan is clean, exit 2 if npm is missing.
|
|
18
17
|
//
|
|
19
|
-
// --report-mode=nightly
|
|
20
|
-
// ALWAYS exit 0 — a nightly cron must not block the
|
|
21
|
-
// droplet's other routines. The skill consumes the
|
|
22
|
-
// JSON, posts to the team chat-inbox, and creates a
|
|
23
|
-
// vulnerability_report row in the Archon security
|
|
24
|
-
// view via src/bongos/security.js.
|
|
18
|
+
// --report-mode=nightly ALWAYS exit 0 — the report is the product.
|
|
25
19
|
//
|
|
26
|
-
//
|
|
27
|
-
//
|
|
28
|
-
//
|
|
29
|
-
//
|
|
30
|
-
//
|
|
31
|
-
// mode decides whether to fail.
|
|
20
|
+
// WHERE IT RUNS ON A SCHEDULE. Nowhere through this CLI: the always-on server runs
|
|
21
|
+
// the same scan daily in-process (modules/autonomy/pollers/daily-checks.js), with an
|
|
22
|
+
// ASYNC spawn — spawnSync here would freeze every request for the whole scan — and
|
|
23
|
+
// hands the output to parseNpmAudit below, so the two cannot disagree about what a
|
|
24
|
+
// finding is.
|
|
32
25
|
//
|
|
33
26
|
// Output schema (stdout, always valid JSON, even on failure):
|
|
34
27
|
// {
|
|
35
28
|
// "ran_at": "<ISO timestamp>",
|
|
36
29
|
// "mode": "ci" | "nightly",
|
|
37
30
|
// "npm": { "ok": true|false, "tool_missing": false|true, "findings": [...] },
|
|
38
|
-
// "pip": { "ok": true|false, "tool_missing": false|true, "findings": [...] },
|
|
39
31
|
// "high_or_critical_count": <int>,
|
|
40
32
|
// "exit_code": <int>
|
|
41
33
|
// }
|
|
@@ -46,10 +38,8 @@
|
|
|
46
38
|
|
|
47
39
|
const { spawnSync } = require('node:child_process');
|
|
48
40
|
const path = require('node:path');
|
|
49
|
-
const fs = require('node:fs');
|
|
50
41
|
|
|
51
42
|
const REPO_ROOT = path.resolve(__dirname, '..', '..');
|
|
52
|
-
const PIP_REQUIREMENTS = path.join(REPO_ROOT, 'art', 'pipeline', 'requirements.txt');
|
|
53
43
|
|
|
54
44
|
// CLI args ----------------------------------------------------------------
|
|
55
45
|
|
|
@@ -77,33 +67,47 @@ function printHelp() {
|
|
|
77
67
|
|
|
78
68
|
// npm audit ---------------------------------------------------------------
|
|
79
69
|
|
|
80
|
-
// npm
|
|
81
|
-
// only — the JSON still contains every level
|
|
82
|
-
//
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
70
|
+
// The npm invocation, shared with the server's async spawn. `--audit-level=high`
|
|
71
|
+
// controls the EXIT CODE only — the JSON still contains every level, and
|
|
72
|
+
// extractNpmFindings filters to high+critical itself.
|
|
73
|
+
const NPM_AUDIT_ARGS = ['audit', '--audit-level=high', '--json'];
|
|
74
|
+
|
|
75
|
+
function runNpmAudit({ cwd = REPO_ROOT } = {}) {
|
|
76
|
+
const res = spawnSync('npm', NPM_AUDIT_ARGS, {
|
|
77
|
+
cwd,
|
|
87
78
|
encoding: 'utf8',
|
|
88
79
|
maxBuffer: 32 * 1024 * 1024,
|
|
89
80
|
});
|
|
90
|
-
// npm audit exits 1 when findings >= the threshold, 0 otherwise. Both cases
|
|
91
|
-
// still produce JSON on stdout. We don't trust the exit code; we read the
|
|
92
|
-
// JSON and decide for ourselves.
|
|
93
81
|
if (res.error) {
|
|
94
82
|
return { ok: false, tool_missing: true, findings: [], raw_error: String(res.error.message || res.error) };
|
|
95
83
|
}
|
|
84
|
+
return parseNpmAudit(res.stdout, res.stderr);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// parseNpmAudit — npm audit's raw output → { ok, tool_missing, findings }. Pure.
|
|
88
|
+
// npm audit exits 1 when findings >= the threshold, 0 otherwise, and both cases
|
|
89
|
+
// still produce JSON on stdout — so the exit code is never read; the JSON decides.
|
|
90
|
+
function parseNpmAudit(stdout, stderr = '') {
|
|
96
91
|
let parsed;
|
|
97
92
|
try {
|
|
98
|
-
parsed = JSON.parse(
|
|
93
|
+
parsed = JSON.parse(stdout || '{}');
|
|
99
94
|
} catch (e) {
|
|
100
95
|
return {
|
|
101
96
|
ok: false, tool_missing: false, findings: [],
|
|
102
|
-
raw_error: `npm audit JSON parse failed: ${e.message}; stderr=${
|
|
97
|
+
raw_error: `npm audit JSON parse failed: ${e.message}; stderr=${String(stderr || '').slice(0, 500)}`,
|
|
103
98
|
};
|
|
104
99
|
}
|
|
105
|
-
|
|
106
|
-
|
|
100
|
+
// npm reports its own failures (no lockfile, registry unreachable) as JSON with
|
|
101
|
+
// an `error` object and no vulnerabilities. That is "could not audit", never a
|
|
102
|
+
// clean bill of health.
|
|
103
|
+
if (parsed && parsed.error && !parsed.vulnerabilities) {
|
|
104
|
+
const e = parsed.error;
|
|
105
|
+
return {
|
|
106
|
+
ok: false, tool_missing: false, findings: [],
|
|
107
|
+
raw_error: `npm audit failed: ${(e && (e.summary || e.code)) || 'unknown error'}`,
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
return { ok: true, tool_missing: false, findings: extractNpmFindings(parsed) };
|
|
107
111
|
}
|
|
108
112
|
|
|
109
113
|
// npm audit v7+ JSON shape: `vulnerabilities` is an object keyed by package
|
|
@@ -143,81 +147,6 @@ function extractNpmFindings(parsed) {
|
|
|
143
147
|
return out;
|
|
144
148
|
}
|
|
145
149
|
|
|
146
|
-
// pip-audit ---------------------------------------------------------------
|
|
147
|
-
|
|
148
|
-
function runPipAudit() {
|
|
149
|
-
if (!fs.existsSync(PIP_REQUIREMENTS)) {
|
|
150
|
-
return {
|
|
151
|
-
ok: false, tool_missing: false, findings: [],
|
|
152
|
-
raw_error: `requirements file not found: ${PIP_REQUIREMENTS}`,
|
|
153
|
-
};
|
|
154
|
-
}
|
|
155
|
-
const res = spawnSync('python3', [
|
|
156
|
-
'-m', 'pip_audit',
|
|
157
|
-
'-r', PIP_REQUIREMENTS,
|
|
158
|
-
'--format', 'json',
|
|
159
|
-
'--vulnerability-service', 'pypi',
|
|
160
|
-
], {
|
|
161
|
-
cwd: REPO_ROOT,
|
|
162
|
-
encoding: 'utf8',
|
|
163
|
-
maxBuffer: 32 * 1024 * 1024,
|
|
164
|
-
});
|
|
165
|
-
if (res.error) {
|
|
166
|
-
return { ok: false, tool_missing: true, findings: [], raw_error: String(res.error.message || res.error) };
|
|
167
|
-
}
|
|
168
|
-
if (res.status !== 0 && res.status !== 1) {
|
|
169
|
-
// pip-audit exits 0 on clean, 1 on findings. Anything else (missing module,
|
|
170
|
-
// bad requirements file) is a tool problem.
|
|
171
|
-
const stderr = (res.stderr || '').slice(0, 1000);
|
|
172
|
-
const missing = /No module named ['"]?pip_audit/.test(stderr);
|
|
173
|
-
return {
|
|
174
|
-
ok: false, tool_missing: missing, findings: [],
|
|
175
|
-
raw_error: `pip-audit exit=${res.status}; stderr=${stderr}`,
|
|
176
|
-
};
|
|
177
|
-
}
|
|
178
|
-
let parsed;
|
|
179
|
-
try {
|
|
180
|
-
parsed = JSON.parse(res.stdout || '{}');
|
|
181
|
-
} catch (e) {
|
|
182
|
-
return {
|
|
183
|
-
ok: false, tool_missing: false, findings: [],
|
|
184
|
-
raw_error: `pip-audit JSON parse failed: ${e.message}; stderr=${res.stderr.slice(0, 500)}`,
|
|
185
|
-
};
|
|
186
|
-
}
|
|
187
|
-
const findings = extractPipFindings(parsed);
|
|
188
|
-
return { ok: true, tool_missing: false, findings };
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
// pip-audit JSON shape: { "dependencies": [ { "name", "version",
|
|
192
|
-
// "vulns": [ { "id", "fix_versions": [], "description", "aliases": [] } ] } ] }
|
|
193
|
-
// pip-audit does NOT classify severity itself — PyPI/OSV advisories carry it
|
|
194
|
-
// in `aliases` (CVE IDs) plus a `description` field. To stay conservative, we
|
|
195
|
-
// treat EVERY pip-audit finding as high — by the time PyPI's advisory DB has
|
|
196
|
-
// picked it up, the project's posture is "fix or document." This is the same
|
|
197
|
-
// stance the GitHub `pip-audit-action` takes by default.
|
|
198
|
-
function extractPipFindings(parsed) {
|
|
199
|
-
const out = [];
|
|
200
|
-
const deps = (parsed && parsed.dependencies) || [];
|
|
201
|
-
for (const dep of deps) {
|
|
202
|
-
const vulns = Array.isArray(dep.vulns) ? dep.vulns : [];
|
|
203
|
-
for (const v of vulns) {
|
|
204
|
-
out.push({
|
|
205
|
-
ecosystem: 'pypi',
|
|
206
|
-
package: dep.name,
|
|
207
|
-
version: dep.version,
|
|
208
|
-
severity: 'high', // see note above
|
|
209
|
-
id: v.id || (Array.isArray(v.aliases) && v.aliases[0]) || null,
|
|
210
|
-
summary: (v.description || '').split('\n')[0].slice(0, 240) || `${dep.name} ${dep.version}: ${v.id}`,
|
|
211
|
-
fix: Array.isArray(v.fix_versions) && v.fix_versions.length
|
|
212
|
-
? `upgrade to ${v.fix_versions.join(' / ')}`
|
|
213
|
-
: 'no fix available',
|
|
214
|
-
url: v.id ? `https://osv.dev/vulnerability/${v.id}` : null,
|
|
215
|
-
});
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
return out;
|
|
219
|
-
}
|
|
220
|
-
|
|
221
150
|
// Main --------------------------------------------------------------------
|
|
222
151
|
|
|
223
152
|
function main() {
|
|
@@ -226,14 +155,13 @@ function main() {
|
|
|
226
155
|
|
|
227
156
|
const ranAt = new Date().toISOString();
|
|
228
157
|
const npm = runNpmAudit();
|
|
229
|
-
const pip = runPipAudit();
|
|
230
158
|
|
|
231
|
-
const allFindings =
|
|
159
|
+
const allFindings = npm.findings;
|
|
232
160
|
const highCount = allFindings.filter(f => f.severity === 'high' || f.severity === 'critical').length;
|
|
233
161
|
|
|
234
162
|
// CI mode: a tool being entirely missing in a CI environment is a build
|
|
235
163
|
// problem, not a security problem — fail loudly so we don't ship blind.
|
|
236
|
-
const toolProblem =
|
|
164
|
+
const toolProblem = npm.tool_missing && args.mode === 'ci';
|
|
237
165
|
|
|
238
166
|
let exitCode = 0;
|
|
239
167
|
if (toolProblem) exitCode = 2;
|
|
@@ -244,7 +172,6 @@ function main() {
|
|
|
244
172
|
ran_at: ranAt,
|
|
245
173
|
mode: args.mode,
|
|
246
174
|
npm,
|
|
247
|
-
pip,
|
|
248
175
|
high_or_critical_count: highCount,
|
|
249
176
|
findings: allFindings,
|
|
250
177
|
exit_code: exitCode,
|
|
@@ -253,8 +180,7 @@ function main() {
|
|
|
253
180
|
// Human summary to stderr.
|
|
254
181
|
const lines = [];
|
|
255
182
|
lines.push(`dep-audit [${args.mode}] @ ${ranAt}`);
|
|
256
|
-
lines.push(` npm:
|
|
257
|
-
lines.push(` pip-audit: ${pip.tool_missing ? 'TOOL MISSING' : (pip.ok ? `${pip.findings.length} high/critical` : `ERROR — ${pip.raw_error}`)}`);
|
|
183
|
+
lines.push(` npm: ${npm.tool_missing ? 'TOOL MISSING' : (npm.ok ? `${npm.findings.length} high/critical` : `ERROR — ${npm.raw_error}`)}`);
|
|
258
184
|
if (allFindings.length) {
|
|
259
185
|
lines.push(` findings:`);
|
|
260
186
|
for (const f of allFindings) {
|
|
@@ -271,6 +197,6 @@ function main() {
|
|
|
271
197
|
|
|
272
198
|
if (require.main === module) main();
|
|
273
199
|
|
|
274
|
-
// Exported for unit testing
|
|
275
|
-
//
|
|
276
|
-
module.exports = { runNpmAudit,
|
|
200
|
+
// Exported for unit testing and for the server's in-process daily check, which
|
|
201
|
+
// spawns NPM_AUDIT_ARGS itself (asynchronously) and parses with parseNpmAudit.
|
|
202
|
+
module.exports = { runNpmAudit, parseNpmAudit, extractNpmFindings, NPM_AUDIT_ARGS };
|
|
@@ -93,7 +93,7 @@ const MODULE_GLOBS = {
|
|
|
93
93
|
],
|
|
94
94
|
// --- the build state machine + ship/grade/deploy orchestration + schema ---
|
|
95
95
|
// Carved into modules/lifecycle/ (BV1.R86 / ADR 0093 §1,§3): the task/claim/
|
|
96
|
-
// version/goal/done-when/dependency
|
|
96
|
+
// version/goal/done-when/dependency routes + the db slice, the
|
|
97
97
|
// task-classifier + hierarchy + done-when libs, github-push + ship-card +
|
|
98
98
|
// ship-preflight + merge-lock + conflict-resolve + publish-reconciler +
|
|
99
99
|
// version-close, and the `lifecycle` kernel PORT — all under the
|
|
@@ -115,7 +115,7 @@ const MODULE_GLOBS = {
|
|
|
115
115
|
'scripts/bongos/ship-regen.js', 'scripts/bongos/ship-resume.js', 'scripts/bongos/ship-session-upload.js',
|
|
116
116
|
'scripts/bongos/ship-state.js', 'scripts/bongos/ship-surprise.js', 'scripts/bongos/ship-visual.js',
|
|
117
117
|
'scripts/bongos/merge-mode.js', 'scripts/bongos/confirm.js', 'scripts/bongos/main-audit.js',
|
|
118
|
-
'scripts/bongos/
|
|
118
|
+
'scripts/bongos/hard-floor.js', 'scripts/bongos/push-main.js',
|
|
119
119
|
'scripts/bongos/merge-lock.js', 'scripts/bongos/version-close.js',
|
|
120
120
|
'migrations/',
|
|
121
121
|
|
|
@@ -43,7 +43,7 @@ const RANK_TIER = { xenos: 1, thetes: 2, metic: 3, archon: 4 };
|
|
|
43
43
|
// modules/government/protected-surfaces.json — no longer a constant baked into
|
|
44
44
|
// this file. Re-mapping a floor there is a POLICY edit. It cannot move
|
|
45
45
|
// enforcement into the app: the three layers above (git pre-push hook, grader
|
|
46
|
-
// pre-pass, post-push main audit) plus
|
|
46
|
+
// pre-pass, post-push main audit) plus the goal-scope check
|
|
47
47
|
// read the registry out of band — no DB, no server, no HTTP — and remain the
|
|
48
48
|
// authority (ADR 0043). Making the request path the enforcer is the exact
|
|
49
49
|
// regression this task exists to prevent.
|
|
@@ -220,7 +220,7 @@ const EXPECTED_RANKS = {
|
|
|
220
220
|
'GET /builders/directory': 'any-builder',
|
|
221
221
|
// (the lifecycle fleet pins — task authoring/promotion/abandonment, override
|
|
222
222
|
// adjudication, polymorphic dependency edges, goal tier + ask-to-widen,
|
|
223
|
-
// criterion confirmation
|
|
223
|
+
// and criterion confirmation — moved to MODULE_EXPECTED_RANKS
|
|
224
224
|
// ['lifecycle'] below in BV1.R86. They live in the lifecycle module now
|
|
225
225
|
// (modules/lifecycle/routes/…), so they're verified only when that module is in
|
|
226
226
|
// scope, not unconditionally from this core list — the pins follow the routes.)
|
|
@@ -500,13 +500,6 @@ const MODULE_EXPECTED_RANKS = {
|
|
|
500
500
|
'POST /done-when/:criterionId/uat/recording': 'perm:criterion.review',
|
|
501
501
|
'POST /done-when/:criterionId/uat': 'perm:criterion.review',
|
|
502
502
|
'PUT /done-when/:criterionId/backend-only': 'perm:criterion.create',
|
|
503
|
-
// gate-surface PR approval from the hall (task 1179, ADR 0058 amendment). ADR 0157
|
|
504
|
-
// SPLIT these two: the list route is `gate_approval.read` (metic — the Gate page
|
|
505
|
-
// opens to the working rank), while APPROVING still clears the gate-review hard
|
|
506
|
-
// floor and stays `gate_approval.decide` (archon, system). The split is the reason
|
|
507
|
-
// the page is usable at all — see the atom's note in catalog.js.
|
|
508
|
-
'GET /gate-approvals': 'perm:gate_approval.read',
|
|
509
|
-
'POST /gate-approvals/:pr/approve': 'perm:gate_approval.decide',
|
|
510
503
|
},
|
|
511
504
|
// Ratifying a criterion proposal WRITES scope-truth (it creates a done-when
|
|
512
505
|
// criterion). Metic+ may file the proposal; ADR 0157 also lets Metic ratify it
|
package/src/bongos/routes.js
CHANGED
|
@@ -31,7 +31,7 @@ const buildMySessionsRouter = require('./routes/my-sessions');
|
|
|
31
31
|
const buildMyPasskeysRouter = require('./routes/my-passkeys');
|
|
32
32
|
const buildBuildersRouter = require('./routes/builders');
|
|
33
33
|
// The LIFECYCLE routes (tasks · claims · versions · done-when · goals ·
|
|
34
|
-
// dependencies ·
|
|
34
|
+
// dependencies · analytics) carved into modules/lifecycle/
|
|
35
35
|
// (BV1.R86 / ADR 0093 §1,§3); moduleLoader.mountModuleRoutes (below) mounts them
|
|
36
36
|
// via the lifecycle module's route factories — no core require. The `/tasks/:id/
|
|
37
37
|
// publish-branch` body-parser bypass below STAYS (the route carries its own larger
|
|
@@ -187,7 +187,6 @@ function buildGdsRouter() {
|
|
|
187
187
|
// and discord (with its bug-attachments route) have both graduated
|
|
188
188
|
// into real modules (modules/<key>/) — they are discovered + mounted by
|
|
189
189
|
// moduleLoader.mountModuleRoutes below, not here (BV1.R43 / R48 / R47 / R72).
|
|
190
|
-
// gate-approvals likewise moved to the lifecycle module (BV1.R86).
|
|
191
190
|
router.use(buildLlmCacheRouter());
|
|
192
191
|
|
|
193
192
|
// Loader-mounted module routers (ADR 0083 / BV1.R41). Discovers + mounts every
|
package/src/module-api.js
CHANGED
|
@@ -75,7 +75,7 @@ const { responsibilityFor, ROLE_RESPONSIBILITIES } = require('./role-responsibil
|
|
|
75
75
|
// MAJOR (see allowBoxScope below): passes the request through untouched.
|
|
76
76
|
function deprecatedNoopMiddleware(_req, _res, next) { next(); }
|
|
77
77
|
|
|
78
|
-
const CORE_VERSION = '1.21.
|
|
78
|
+
const CORE_VERSION = '1.21.178'; // CI auto-patch carrier (ADR 0161); changelog: docs/module-api-changelog.md
|
|
79
79
|
|
|
80
80
|
// A namespaced logger so a module's log lines are attributable + consistent.
|
|
81
81
|
// Usage: const log = api.logger('discord'); log.info('mounted');
|
package/src/modules.js
CHANGED
|
@@ -44,7 +44,7 @@ const INSTANCE_PATH = path.join(resolveInstanceRoot(), 'config', 'modules.json')
|
|
|
44
44
|
//
|
|
45
45
|
// CORE (always on, never a module): auth, builders, tasks, claims, versions,
|
|
46
46
|
// done-when, credits/cost, inbox, blockers, leaderboard, analytics,
|
|
47
|
-
// audit-log, security, access-requests, sessions,
|
|
47
|
+
// audit-log, security, access-requests, sessions, healthz,
|
|
48
48
|
// public. These mount unconditionally. The optional feature modules AND the
|
|
49
49
|
// first TWO carved CORE-domain modules have graduated to modules/<key>/ (discord
|
|
50
50
|
// BV1.R47, art-pipeline BV1.R48, game BV1.R49, memory BV1.R72 —
|
|
@@ -16,21 +16,22 @@
|
|
|
16
16
|
// - a ship with several cost rows must sum them, not pick one;
|
|
17
17
|
// - the two LATERALs and the grades join must not multiply the row out.
|
|
18
18
|
//
|
|
19
|
-
//
|
|
20
|
-
//
|
|
19
|
+
// Calls the REAL route handler (GET /tasks/peer-votes/feed from the lifecycle
|
|
20
|
+
// router) against the database, so a future edit to the route is tested rather
|
|
21
|
+
// than a copy of it. It used to slice the query text out of the route's source and
|
|
22
|
+
// re-interpolate it by hand; the route grew a second interpolation (the helper
|
|
23
|
+
// join), the copy stopped resolving, and the test failed on its own scaffolding
|
|
24
|
+
// rather than on the route (task 1004863). Driving the handler cannot drift that way.
|
|
21
25
|
// Self-skips without a reachable Postgres; in the INTEGRATION set, so the
|
|
22
26
|
// DB-free unit gate never runs it and .github/workflows/integration.yml does.
|
|
23
27
|
//
|
|
24
28
|
// Run: DATABASE_URL=... node tests/acclaim_feed_evidence_db.mjs
|
|
25
29
|
import { createRequire } from 'node:module';
|
|
26
30
|
import { strict as assert } from 'node:assert';
|
|
27
|
-
import
|
|
28
|
-
import path from 'node:path';
|
|
29
|
-
import { fileURLToPath } from 'node:url';
|
|
31
|
+
import { insertTestBuilders } from './helpers.mjs';
|
|
30
32
|
|
|
31
33
|
const require = createRequire(import.meta.url);
|
|
32
34
|
const { Pool } = require('pg');
|
|
33
|
-
const ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
|
|
34
35
|
|
|
35
36
|
const pool = new Pool({ connectionString: process.env.DATABASE_URL || undefined });
|
|
36
37
|
try {
|
|
@@ -41,18 +42,30 @@ try {
|
|
|
41
42
|
process.exit(0);
|
|
42
43
|
}
|
|
43
44
|
|
|
44
|
-
// The
|
|
45
|
-
//
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
const
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
assert.ok(
|
|
52
|
-
const
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
45
|
+
// The handler under test: the last stack entry of the shipped route (the first is
|
|
46
|
+
// auth.requireBuilder, which needs a session; the handler reads req.builder, which
|
|
47
|
+
// we supply). The router's pool is the core pool, which reads DATABASE_URL — the
|
|
48
|
+
// same database this file writes its fixtures to.
|
|
49
|
+
const buildTasksRouter = require('../modules/lifecycle/routes/tasks.js');
|
|
50
|
+
const feedLayer = buildTasksRouter().stack
|
|
51
|
+
.find((l) => l.route && l.route.path === '/tasks/peer-votes/feed' && l.route.methods.get);
|
|
52
|
+
assert.ok(feedLayer, 'the lifecycle router still serves GET /tasks/peer-votes/feed');
|
|
53
|
+
const feedHandler = feedLayer.route.stack[feedLayer.route.stack.length - 1].handle;
|
|
54
|
+
|
|
55
|
+
// Call the route as `builder` and return its JSON body; a failure surfaces as a throw.
|
|
56
|
+
async function feed(builder, limit = 100) {
|
|
57
|
+
let body = null;
|
|
58
|
+
let failure = null;
|
|
59
|
+
const res = {
|
|
60
|
+
json(b) { body = b; return res; },
|
|
61
|
+
fail(code, opts) { failure = { code, opts }; return res; },
|
|
62
|
+
status() { return res; },
|
|
63
|
+
};
|
|
64
|
+
await feedHandler({ builder, query: { limit: String(limit) }, params: {}, headers: {}, get: () => undefined }, res);
|
|
65
|
+
if (failure) throw new Error(`the feed route failed: ${JSON.stringify(failure)}`);
|
|
66
|
+
assert.ok(body && Array.isArray(body.tasks), 'the feed answered with a task list');
|
|
67
|
+
return body;
|
|
68
|
+
}
|
|
56
69
|
|
|
57
70
|
const VOTER = 90000801;
|
|
58
71
|
const SHIPPER = 90000802;
|
|
@@ -82,10 +95,13 @@ const check = (name, fn) => {
|
|
|
82
95
|
try {
|
|
83
96
|
await cleanup();
|
|
84
97
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
98
|
+
// 'building', not 'planning': versions_one_planning_idx allows ONE planning row and
|
|
99
|
+
// the seeds own it — the collision that parked this test (task 1004042).
|
|
100
|
+
await q("INSERT INTO versions (id, name, status) VALUES ($1, 'acclaim evidence fixture', 'building')", [VER]);
|
|
101
|
+
await insertTestBuilders(pool, [
|
|
102
|
+
{ id: VOTER, login: 'zz-acc-voter', rank: 'metic' },
|
|
103
|
+
{ id: SHIPPER, login: 'zz-acc-shipper', rank: 'metic' },
|
|
104
|
+
], { onConflict: '' });
|
|
89
105
|
for (const [id, title] of [
|
|
90
106
|
[T.GOOD, '__acc__ graded and costed'],
|
|
91
107
|
[T.OUTAGE, '__acc__ grader outage'],
|
|
@@ -123,7 +139,10 @@ try {
|
|
|
123
139
|
await cost(T.FREE, '0');
|
|
124
140
|
// T.OUTAGE and T.UNGRADED get no cost row at all.
|
|
125
141
|
|
|
126
|
-
|
|
142
|
+
// A metic caller: cost reaches only the ranks that can vote, so this is the view
|
|
143
|
+
// that carries every figure under test.
|
|
144
|
+
const body = await feed({ id: VOTER, rank: 'metic' });
|
|
145
|
+
const rows = body.tasks;
|
|
127
146
|
const byId = new Map(rows.map((r) => [String(r.id), r]));
|
|
128
147
|
const got = (id) => {
|
|
129
148
|
const row = byId.get(String(id));
|
package/tests/adr_0089_scope.mjs
CHANGED
|
@@ -28,9 +28,11 @@ const adr = read('docs/adr/0089-modular-multi-model-adversarial-grader.md');
|
|
|
28
28
|
const section = adr.slice(adr.indexOf('### 8. Scope: what the engine does NOT own'), adr.indexOf('## Consequences'))
|
|
29
29
|
.replaceAll('scripts/gds/', 'scripts/bongos/'); // rename-keep
|
|
30
30
|
|
|
31
|
+
// §8 also names scripts/bongos/gate-review.js. Task 1004859 deleted it (the CI check it
|
|
32
|
+
// drove never ran), so there is nothing left to hold to the boundary; the ADR keeps the
|
|
33
|
+
// name as history.
|
|
31
34
|
const SURFACES = [
|
|
32
35
|
'scripts/bongos/session-eval.js',
|
|
33
|
-
'scripts/bongos/gate-review.js',
|
|
34
36
|
'scripts/bongos/main-audit.js',
|
|
35
37
|
'scripts/bongos/architect-audit.js',
|
|
36
38
|
];
|
|
@@ -40,7 +42,7 @@ test('ADR 0089 carries the §8 scope section, before Consequences', () => {
|
|
|
40
42
|
assert.ok(section.length > 200, 'the section sits between §7 and Consequences');
|
|
41
43
|
});
|
|
42
44
|
|
|
43
|
-
test('§8 names each of the
|
|
45
|
+
test('§8 names each of the remaining surfaces by path, and each path exists', () => {
|
|
44
46
|
for (const p of SURFACES) {
|
|
45
47
|
assert.ok(section.includes(p), `§8 names ${p}`);
|
|
46
48
|
assert.ok(fs.existsSync(new URL(`../${p}`, import.meta.url)), `${p} exists`);
|
|
@@ -56,14 +58,14 @@ test('the Architect uses exactly the three grader helpers §8 names — nothing
|
|
|
56
58
|
for (const name of used) assert.ok(section.includes(name), `§8 names ${name}`);
|
|
57
59
|
});
|
|
58
60
|
|
|
59
|
-
test('session-eval
|
|
61
|
+
test('session-eval and main-audit import no grading module', () => {
|
|
60
62
|
for (const p of SURFACES.filter((s) => !s.endsWith('architect-audit.js'))) {
|
|
61
63
|
assert.doesNotMatch(read(p), /require\([^)]*modules\/grading/, `${p} must not require grading code`);
|
|
62
64
|
}
|
|
63
65
|
});
|
|
64
66
|
|
|
65
|
-
test('main-audit
|
|
66
|
-
for (const p of ['scripts/bongos/main-audit.js'
|
|
67
|
+
test('main-audit reads the rank-permission checker §8 names', () => {
|
|
68
|
+
for (const p of ['scripts/bongos/main-audit.js']) {
|
|
67
69
|
assert.match(read(p), /permission-path-check/, `${p} reads the checker`);
|
|
68
70
|
}
|
|
69
71
|
assert.ok(section.includes('src/bongos/permission-path-check.js'), '§8 names the shared checker');
|