@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.
Files changed (214) hide show
  1. package/.bongos-core.json +186 -496
  2. package/.claude/skills/planning-session/SKILL.md +2 -2
  3. package/clients/bongos-client/README.md +1 -1
  4. package/clients/bongos-client/bongos-client.global.js +0 -6
  5. package/clients/bongos-client/index.cjs +0 -6
  6. package/clients/bongos-client/index.d.ts +0 -6
  7. package/clients/bongos-client/index.mjs +0 -6
  8. package/config/scheduled-routines.json +3 -8
  9. package/docs/adr/0042-builder-self-deploy-ci-auto-merge.md +3 -2
  10. package/docs/adr/0091-bounding-the-kernel-and-db-carve.md +1 -1
  11. package/docs/adr/0093-tranche-2-core-carve-sequence.md +1 -1
  12. package/docs/api/openapi.json +1 -87
  13. package/docs/api-reference.md +1 -8
  14. package/docs/canonical-permissions.md +4 -4
  15. package/docs/copy-inventory.md +25 -39
  16. package/docs/copy-registry.json +73 -200
  17. package/docs/file-map.md +6 -11
  18. package/docs/handoff-template.md +1 -1
  19. package/docs/module-api-changelog.md +4 -0
  20. package/docs/modules-contract.md +2 -2
  21. package/docs/onboarding/diagrams/README.md +3 -7
  22. package/docs/onboarding/diagrams/assertions.json +3 -3
  23. package/docs/page-inventory.json +4 -7
  24. package/docs/page-readings.json +1520 -1569
  25. package/docs/recipes/ops-gotchas.md +3 -1
  26. package/modules/autonomy/db.js +9 -0
  27. package/modules/autonomy/module.json +2 -2
  28. package/modules/autonomy/pollers/daily-checks.js +262 -0
  29. package/modules/autonomy/pollers/routine-timers.js +7 -5
  30. package/modules/autonomy/rank-roles.js +64 -0
  31. package/modules/autonomy/server-schedule.js +37 -0
  32. package/modules/government/catalog.js +10 -7
  33. package/modules/government/decision-board.js +0 -1
  34. package/modules/government/decision-rules.js +0 -1
  35. package/modules/government/docket.js +0 -1
  36. package/modules/government/protected-surfaces.js +1 -1
  37. package/modules/government/protected-surfaces.json +2 -3
  38. package/modules/hall-ui/public/atlas.html +1 -1
  39. package/modules/hall-ui/public/blockers.html +1 -1
  40. package/modules/hall-ui/public/board-room.html +1 -1
  41. package/modules/hall-ui/public/city.html +1 -1
  42. package/modules/hall-ui/public/collab.html +1 -1
  43. package/modules/hall-ui/public/commands.html +1 -1
  44. package/modules/hall-ui/public/copy-desk.html +1 -1
  45. package/modules/hall-ui/public/deploy.html +1 -1
  46. package/modules/hall-ui/public/diagrams.html +1 -1
  47. package/modules/hall-ui/public/drachmae.html +1 -1
  48. package/modules/hall-ui/public/fleet.html +1 -1
  49. package/modules/hall-ui/public/gate.css +4 -26
  50. package/modules/hall-ui/public/gate.html +12 -27
  51. package/modules/hall-ui/public/gate.js +26 -176
  52. package/modules/hall-ui/public/gate.states.json +4 -22
  53. package/modules/hall-ui/public/goal-map.html +1 -1
  54. package/modules/hall-ui/public/goals.html +1 -1
  55. package/modules/hall-ui/public/government.html +1 -1
  56. package/modules/hall-ui/public/idea.html +1 -1
  57. package/modules/hall-ui/public/ideas.html +1 -1
  58. package/modules/hall-ui/public/index.html +1 -1
  59. package/modules/hall-ui/public/modules.html +1 -1
  60. package/modules/hall-ui/public/my-agents.html +1 -1
  61. package/modules/hall-ui/public/primer.html +1 -1
  62. package/modules/hall-ui/public/profile.html +1 -1
  63. package/modules/hall-ui/public/project-settings.html +1 -1
  64. package/modules/hall-ui/public/ranks.html +1 -1
  65. package/modules/hall-ui/public/roadmap.html +1 -1
  66. package/modules/hall-ui/public/roster.html +1 -1
  67. package/modules/hall-ui/public/sessions.html +1 -1
  68. package/modules/hall-ui/public/settings.html +1 -1
  69. package/modules/hall-ui/public/shell.js +1 -1
  70. package/modules/hall-ui/public/street-card.js +5 -9
  71. package/modules/hall-ui/public/street-desk.js +2 -2
  72. package/modules/hall-ui/public/street-inside.js +1 -1
  73. package/modules/hall-ui/public/street.html +1 -1
  74. package/modules/hall-ui/public/studio.html +1 -1
  75. package/modules/hall-ui/public/task.html +1 -1
  76. package/modules/hall-ui/public/thinking.html +1 -1
  77. package/modules/hall-ui/public/tweak-editor.html +1 -1
  78. package/modules/hall-ui/public/watch.html +1 -1
  79. package/modules/hall-ui/public/work.html +1 -1
  80. package/modules/lifecycle/matter-acts.js +0 -6
  81. package/modules/lifecycle/module.json +0 -1
  82. package/package-lock.json +2 -2
  83. package/package.json +1 -1
  84. package/release-notes.json +36 -0
  85. package/scripts/bongos/adopt-preflight.js +3 -3
  86. package/scripts/bongos/api-alias-caller-scan.js +2 -2
  87. package/scripts/bongos/audit-authorship.sh +1 -8
  88. package/scripts/bongos/audit-rank-roles.js +15 -56
  89. package/scripts/bongos/bump-version.js +46 -9
  90. package/scripts/bongos/codemod-rename-scripts-gds.js +0 -1
  91. package/scripts/bongos/diagram-facts.js +1 -1
  92. package/scripts/bongos/do-api.js +1 -1
  93. package/scripts/bongos/doc-cli-guard.js +2 -0
  94. package/scripts/bongos/doc-control-claims.js +2 -2
  95. package/scripts/bongos/fitness-checks-identity.js +4 -15
  96. package/scripts/bongos/gen-diagrams.js +3 -3
  97. package/scripts/bongos/government-walk.js +3 -9
  98. package/scripts/bongos/hard-floor.js +52 -0
  99. package/scripts/bongos/publish-manifest.js +3 -3
  100. package/scripts/bongos/pulse.js +5 -3
  101. package/scripts/bongos/routine-schedule.js +38 -3
  102. package/scripts/bongos/run-unit-tests.js +17 -5
  103. package/scripts/bongos/ship-regen.js +2 -3
  104. package/scripts/gds/{goal-names.js → hard-floor.js} +3 -4
  105. package/scripts/security/dep-audit.js +50 -124
  106. package/src/bongos/module-scope-map.js +2 -2
  107. package/src/bongos/permission-path-check.js +1 -1
  108. package/src/bongos/route-rank-check.js +1 -8
  109. package/src/bongos/routes.js +1 -2
  110. package/src/module-api.js +1 -1
  111. package/src/modules.js +1 -1
  112. package/tests/acclaim_feed_evidence_db.mjs +42 -23
  113. package/tests/adr_0089_scope.mjs +7 -5
  114. package/tests/autonomy_daily_checks.mjs +201 -0
  115. package/tests/bump_version.mjs +52 -18
  116. package/tests/claude_materialize.mjs +12 -12
  117. package/tests/copy_desk_flags_db.mjs +22 -14
  118. package/tests/effective_visibility_predicate.mjs +0 -18
  119. package/tests/gating_review_retired.mjs +1 -1
  120. package/tests/government_act_alone_buildings.mjs +1 -3
  121. package/tests/government_board_membership_db.mjs +35 -22
  122. package/tests/government_protected_surfaces.mjs +29 -13
  123. package/tests/governor_docket.mjs +0 -2
  124. package/tests/governor_matter_acts.mjs +6 -8
  125. package/tests/hall_city.mjs +1 -1
  126. package/tests/hall_matter_card.mjs +2 -2
  127. package/tests/hall_oversight_world.mjs +16 -12
  128. package/tests/hall_street_desk.mjs +4 -3
  129. package/tests/hall_street_inside.mjs +1 -1
  130. package/tests/helpers.mjs +34 -0
  131. package/tests/howto_state.mjs +33 -56
  132. package/tests/howto_state_db.mjs +68 -0
  133. package/tests/idea_credit_streams_db.mjs +11 -3
  134. package/tests/integration_parked_ratchet.mjs +7 -1
  135. package/tests/nav_permission_atoms.mjs +1 -1
  136. package/tests/page_notes_db.mjs +12 -8
  137. package/tests/page_tweak_no_rearm.mjs +50 -0
  138. package/tests/publish_manifest.mjs +64 -0
  139. package/tests/routine_capture_kind.mjs +18 -7
  140. package/tests/routine_schedule.mjs +42 -0
  141. package/tests/search_isolation.mjs +5 -103
  142. package/tests/search_isolation_db.mjs +140 -0
  143. package/tests/session_earnings_mirror_db.mjs +2 -0
  144. package/tests/workflow_exec_paths.mjs +9 -11
  145. package/modules/lifecycle/routes/gate-approvals.js +0 -299
  146. package/scripts/bongos/artifact-staleness.js +0 -267
  147. package/scripts/bongos/ci-grade.js +0 -82
  148. package/scripts/bongos/classify-discipline.js +0 -153
  149. package/scripts/bongos/codemod-rename-src-gds.js +0 -145
  150. package/scripts/bongos/coreB-carve-proof.sh +0 -725
  151. package/scripts/bongos/gate-review.js +0 -330
  152. package/scripts/bongos/goal-names.js +0 -102
  153. package/scripts/bongos/rename-goals.js +0 -109
  154. package/scripts/bongos/seed-adopt-tasks.js +0 -75
  155. package/scripts/bongos/seed-api-contract-goal-tasks.js +0 -141
  156. package/scripts/bongos/seed-board-room-tasks.js +0 -196
  157. package/scripts/bongos/seed-bongos-app-tasks.js +0 -294
  158. package/scripts/bongos/seed-bongos-coreB-tranche1-tasks.js +0 -81
  159. package/scripts/bongos/seed-bongos-coreB-tranche2-tasks.js +0 -100
  160. package/scripts/bongos/seed-bongos-goal-hierarchy-tasks.js +0 -307
  161. package/scripts/bongos/seed-bongos-module-system-tasks.js +0 -346
  162. package/scripts/bongos/seed-bongos-tasks.js +0 -214
  163. package/scripts/bongos/seed-bongos-v1-seo-tasks.js +0 -104
  164. package/scripts/bongos/seed-bv1-community-tasks.js +0 -131
  165. package/scripts/bongos/seed-bv1-privacy-invites-tasks.js +0 -133
  166. package/scripts/bongos/seed-bv1-profile-page-tasks.js +0 -161
  167. package/scripts/bongos/seed-bv1-r01-delta-tasks.js +0 -154
  168. package/scripts/bongos/seed-bv2-tweak-mode-tasks.js +0 -277
  169. package/scripts/bongos/seed-gds-v4-tasks.js +0 -624
  170. package/scripts/bongos/seed-governance-tasks.js +0 -340
  171. package/scripts/bongos/seed-medusa-tasks.js +0 -440
  172. package/scripts/bongos/seed-module-upstreaming.js +0 -219
  173. package/scripts/bongos/seed-productization-tasks.js +0 -235
  174. package/scripts/bongos/seed-project-admin-console-tasks.js +0 -88
  175. package/scripts/bongos/seed-provisioning-tasks.js +0 -83
  176. package/scripts/bongos/seed-strict-versioning-tasks.js +0 -275
  177. package/scripts/bongos/seed-v2-world-tasks.js +0 -283
  178. package/scripts/gds/artifact-staleness.js +0 -7
  179. package/scripts/gds/ci-grade.js +0 -7
  180. package/scripts/gds/classify-discipline.js +0 -7
  181. package/scripts/gds/codemod-rename-src-gds.js +0 -7
  182. package/scripts/gds/coreB-carve-proof.sh +0 -8
  183. package/scripts/gds/gate-review.js +0 -7
  184. package/scripts/gds/rename-goals.js +0 -7
  185. package/scripts/gds/seed-adopt-tasks.js +0 -7
  186. package/scripts/gds/seed-api-contract-goal-tasks.js +0 -7
  187. package/scripts/gds/seed-board-room-tasks.js +0 -6
  188. package/scripts/gds/seed-bongos-app-tasks.js +0 -7
  189. package/scripts/gds/seed-bongos-coreB-tranche1-tasks.js +0 -7
  190. package/scripts/gds/seed-bongos-coreB-tranche2-tasks.js +0 -7
  191. package/scripts/gds/seed-bongos-goal-hierarchy-tasks.js +0 -7
  192. package/scripts/gds/seed-bongos-module-system-tasks.js +0 -7
  193. package/scripts/gds/seed-bongos-tasks.js +0 -7
  194. package/scripts/gds/seed-bongos-v1-seo-tasks.js +0 -6
  195. package/scripts/gds/seed-bv1-community-tasks.js +0 -6
  196. package/scripts/gds/seed-bv1-privacy-invites-tasks.js +0 -6
  197. package/scripts/gds/seed-bv1-profile-page-tasks.js +0 -6
  198. package/scripts/gds/seed-bv1-r01-delta-tasks.js +0 -6
  199. package/scripts/gds/seed-bv2-tweak-mode-tasks.js +0 -6
  200. package/scripts/gds/seed-gds-v4-tasks.js +0 -7
  201. package/scripts/gds/seed-governance-tasks.js +0 -7
  202. package/scripts/gds/seed-medusa-tasks.js +0 -7
  203. package/scripts/gds/seed-module-upstreaming.js +0 -7
  204. package/scripts/gds/seed-productization-tasks.js +0 -7
  205. package/scripts/gds/seed-project-admin-console-tasks.js +0 -6
  206. package/scripts/gds/seed-provisioning-tasks.js +0 -7
  207. package/scripts/gds/seed-strict-versioning-tasks.js +0 -7
  208. package/scripts/gds/seed-v2-world-tasks.js +0 -7
  209. package/scripts/migrate_cost_ledger.sh +0 -178
  210. package/tests/artifact_staleness.mjs +0 -207
  211. package/tests/gate_approvals.mjs +0 -611
  212. package/tests/gate_review.mjs +0 -152
  213. package/tests/goal_names.mjs +0 -120
  214. package/tests/newcomer_generator.mjs +0 -48
@@ -1,152 +0,0 @@
1
- // tests/gate_review.mjs
2
- //
3
- // Unit tests for the automatic gate-surface gatekeeper classifier (ADR 0058,
4
- // task 1139). classifyChanges is PURE (diff-as-data in, verdict out) so the whole
5
- // policy — including every red-team evasion the design workflow surfaced — is a
6
- // regression case here. DB-free / network-free → runs in the unit gate.
7
- //
8
- // Verdicts: pass (auto-merge) | needs_trust (Metic+ auto / else escalate) | escalate
9
- // (hard floor — rank-independent, always pings the owner).
10
- //
11
- // Run: node tests/gate_review.mjs
12
-
13
- import { strict as assert } from 'node:assert';
14
- import { createRequire } from 'node:module';
15
-
16
- const require = createRequire(import.meta.url);
17
- const gk = require('../scripts/bongos/gate-review.js');
18
- const permPath = require('../src/bongos/permission-path-check.js');
19
-
20
- let passed = 0, failed = 0;
21
- function test(name, fn) {
22
- try { fn(); passed++; console.log(` ok ${name}`); }
23
- catch (e) { failed++; console.log(` FAIL ${name}\n ${e.message}`); }
24
- }
25
-
26
- // Build a classifyChanges call from a compact spec.
27
- // files: [{path, mode?, deleted?}] blobs: { 'base:path':..., 'head:path':... }
28
- function classify(files, blobs = {}, diffBytes = 0) {
29
- const blobAt = (which, p) => (Object.prototype.hasOwnProperty.call(blobs, `${which}:${p}`) ? blobs[`${which}:${p}`] : null);
30
- return gk.classifyChanges({ files: files.map((f) => ({ mode: '100644', deleted: false, ...f })), blobAt, diffBytes });
31
- }
32
- const verdictOf = (...a) => classify(...a).verdict;
33
-
34
- // --- PASS: no gate surface / pure-narrowing AUTO -------------------------------------
35
- test('no gate surface (game/art/docs) → pass', () => {
36
- assert.equal(verdictOf([{ path: 'public/game/main.js' }, { path: 'docs/foo.md' }, { path: 'art/x.png' }]), 'pass');
37
- });
38
- test('adding a new test file → pass', () => {
39
- assert.equal(verdictOf([{ path: 'tests/new_thing.mjs' }], { 'head:tests/new_thing.mjs': 'test(...)' }), 'pass');
40
- });
41
- test('run-unit-tests.js REMOVING from INTEGRATION (un-mute) → pass (AUTO)', () => {
42
- const base = `const INTEGRATION = new Set(['a','b']);\nconst KNOWN_FAILING = new Set(['x']);\nconst Z=1;`;
43
- const head = `const INTEGRATION = new Set(['a']);\nconst KNOWN_FAILING = new Set(['x']);\nconst Z=1;`;
44
- const r = classify([{ path: 'scripts/bongos/run-unit-tests.js' }], { 'base:scripts/bongos/run-unit-tests.js': base, 'head:scripts/bongos/run-unit-tests.js': head });
45
- assert.equal(r.verdict, 'pass');
46
- assert.deepEqual(r.autoPassed, ['scripts/bongos/run-unit-tests.js']);
47
- });
48
- test('secrets-allowlist.txt REMOVING a line (narrow) → pass (AUTO)', () => {
49
- const r = classify([{ path: '.husky/secrets-allowlist.txt' }], { 'base:.husky/secrets-allowlist.txt': 'aaa\nbbb\n', 'head:.husky/secrets-allowlist.txt': 'aaa\n' });
50
- assert.equal(r.verdict, 'pass');
51
- });
52
-
53
- // --- NEEDS_TRUST: sensitive-but-routine (rank-trustable) -----------------------------
54
- test('new migration → needs_trust', () => assert.equal(verdictOf([{ path: 'migrations/120_thing.sql' }]), 'needs_trust'));
55
- test('package.json bump → needs_trust', () => assert.equal(verdictOf([{ path: 'package.json' }]), 'needs_trust'));
56
- test('a route file → needs_trust', () => assert.equal(verdictOf([{ path: 'src/bongos/routes/tasks.js' }]), 'needs_trust'));
57
- test('server.js → needs_trust', () => assert.equal(verdictOf([{ path: 'server.js' }]), 'needs_trust'));
58
- test('ship.js → needs_trust', () => assert.equal(verdictOf([{ path: 'scripts/bongos/ship.js' }]), 'needs_trust'));
59
- test('db.js change OUTSIDE the rank-tier region → needs_trust', () => {
60
- const base = `const REQUIRES_RANK_TIER = { foo: 1 };\nfunction q(){ return 1 }`;
61
- const head = `const REQUIRES_RANK_TIER = { foo: 1 };\nfunction q(){ return 2 }`;
62
- assert.equal(verdictOf([{ path: 'src/bongos/db.js' }], { 'base:src/bongos/db.js': base, 'head:src/bongos/db.js': head }), 'needs_trust');
63
- });
64
- test('deleting a test file → needs_trust', () => assert.equal(verdictOf([{ path: 'tests/route_rank.mjs', deleted: true }]), 'needs_trust'));
65
- test('shrinking a test file → needs_trust', () => {
66
- assert.equal(verdictOf([{ path: 'tests/route_rank.mjs' }], { 'base:tests/route_rank.mjs': 'x'.repeat(500), 'head:tests/route_rank.mjs': 'x'.repeat(50) }), 'needs_trust');
67
- });
68
-
69
- // --- ESCALATE: HARD FLOOR (rank-independent) -----------------------------------------
70
- for (const p of [
71
- 'scripts/bongos/gate-review.js', 'src/bongos/permission-path-check.js', 'src/bongos/auth.js',
72
- 'src/bongos/route-rank-check.js', 'modules/grading/grader.js', 'modules/grading/grader-workers/narc.js',
73
- 'scripts/bongos/main-audit.js', 'scripts/migrate.sh', 'scripts/deploy/deploy-prod.sh',
74
- 'config/deploy.json', 'infra/branch-protection.json', '.github/workflows/gate-review.yml',
75
- 'CODEOWNERS', '.husky/pre-push', '.claude/hooks/stop-sound.js', '.claude/settings.json',
76
- ]) {
77
- test(`hard floor: ${p} → escalate`, () => assert.equal(verdictOf([{ path: p }]), 'escalate'));
78
- }
79
- test('db.js with the rank-tier region CHANGED → escalate', () => {
80
- const base = `const REQUIRES_RANK_TIER = { foo: 1 };\nfunction q(){}`;
81
- const head = `const REQUIRES_RANK_TIER = { foo: 4, bar: 1 };\nfunction q(){}`;
82
- assert.equal(verdictOf([{ path: 'src/bongos/db.js' }], { 'base:src/bongos/db.js': base, 'head:src/bongos/db.js': head }), 'escalate');
83
- });
84
-
85
- // --- ESCALATE: red-team evasions -----------------------------------------------------
86
- test('Hole(mute): run-unit-tests.js ADDING to KNOWN_FAILING → escalate (AUTO cert fails → floor)', () => {
87
- const base = `const INTEGRATION = new Set(['a']);\nconst KNOWN_FAILING = new Set(['x']);`;
88
- const head = `const INTEGRATION = new Set(['a']);\nconst KNOWN_FAILING = new Set(['x','grader_panel']);`;
89
- assert.equal(verdictOf([{ path: 'scripts/bongos/run-unit-tests.js' }], { 'base:scripts/bongos/run-unit-tests.js': base, 'head:scripts/bongos/run-unit-tests.js': head }), 'escalate');
90
- });
91
- test('Hole(mute): run-unit-tests.js non-set code changed → escalate', () => {
92
- const base = `const INTEGRATION = new Set(['a']);\nconst KNOWN_FAILING = new Set([]);\nconst TIMEOUT=90000;`;
93
- const head = `const INTEGRATION = new Set(['a']);\nconst KNOWN_FAILING = new Set([]);\nconst TIMEOUT=1;`;
94
- assert.equal(verdictOf([{ path: 'scripts/bongos/run-unit-tests.js' }], { 'base:scripts/bongos/run-unit-tests.js': base, 'head:scripts/bongos/run-unit-tests.js': head }), 'escalate');
95
- });
96
- test('Hole(allowlist): secrets-allowlist.txt ADDING a broadening line → escalate', () => {
97
- assert.equal(verdictOf([{ path: '.husky/secrets-allowlist.txt' }], { 'base:.husky/secrets-allowlist.txt': 'aaa\n', 'head:.husky/secrets-allowlist.txt': 'aaa\nLEAKED_KEY=.*\n' }), 'escalate');
98
- });
99
- test('Hole8: a symlink in the diff → escalate (alias evasion)', () => {
100
- assert.equal(verdictOf([{ path: 'src/bongos/routes/x.js', mode: '120000' }]), 'escalate');
101
- });
102
- test('Hole6/8: a non-ASCII/homoglyph path → escalate', () => {
103
- assert.equal(verdictOf([{ path: 'src/bongos/аuth.js' /* cyrillic a */ }]), 'escalate');
104
- });
105
- test('Hole10: oversize diff → escalate', () => {
106
- assert.equal(verdictOf([{ path: 'public/game/main.js' }], {}, 9 * 1024 * 1024), 'escalate');
107
- });
108
- test('Hole2: editing gate-review.yml (self-neuter) → escalate', () => {
109
- assert.equal(verdictOf([{ path: '.github/workflows/gate-review.yml' }]), 'escalate');
110
- });
111
- test('Hole4: adding a new middleware + editing routes.js → escalate (auth.js floor) / needs_trust (routes)', () => {
112
- // routes.js is needs_trust; but pairing with a hard-floor file makes the PR escalate.
113
- assert.equal(verdictOf([{ path: 'src/bongos/routes.js' }, { path: 'src/bongos/auth.js' }]), 'escalate');
114
- });
115
-
116
- // --- DRIFT GUARD: no PROTECTED_GLOBS entry is silently un-routed (never pass) ---------
117
- test('drift guard: every PROTECTED_GLOBS entry routes to escalate or needs_trust (never pass)', () => {
118
- for (const glob of permPath.PROTECTED_GLOBS) {
119
- // Synthesize a representative path under each glob.
120
- const sample = glob.endsWith('/') ? `${glob}__sample__.js` : glob;
121
- // db.js needs blobs to classify; give it a no-op (region unchanged) → needs_trust (still not pass).
122
- const blobs = sample === 'src/bongos/db.js'
123
- ? { 'base:src/bongos/db.js': 'const REQUIRES_RANK_TIER = {};\nx', 'head:src/bongos/db.js': 'const REQUIRES_RANK_TIER = {};\ny' }
124
- : {};
125
- const v = verdictOf([{ path: sample }], blobs);
126
- assert.notEqual(v, 'pass', `PROTECTED glob ${glob} (sample ${sample}) classified as PASS — gate-surface leak`);
127
- }
128
- });
129
- test('drift guard: every HARD_FLOOR glob is also covered by PROTECTED_GLOBS (sub-Metic floor protects the gate machinery)', () => {
130
- for (const g of gk.HARD_FLOOR_GLOBS) {
131
- // a floor glob must be matched by SOME protected glob (subtree-aware): a file under it is protected.
132
- const sample = g.endsWith('/') ? `${g}__s__` : g;
133
- assert.equal(permPath.matchProtected([sample]).length > 0, true, `hard-floor ${g} is not in PROTECTED_GLOBS`);
134
- }
135
- });
136
-
137
- // --- resolveAction: rank clears needs_trust; ONLY an owner review clears the hard floor (task 1142) ---
138
- const RA = (verdict, trusted, ownerApproved) => gk.resolveAction({ verdict, trusted, ownerApproved });
139
- test('resolveAction: pass → pass regardless of trust', () => {
140
- assert.equal(RA('pass', false, false), 'pass');
141
- });
142
- test('resolveAction: needs_trust + Metic+ attestation → pass', () => assert.equal(RA('needs_trust', true, false), 'pass'));
143
- test('resolveAction: needs_trust + untrusted + no approval → block', () => assert.equal(RA('needs_trust', false, false), 'block'));
144
- test('resolveAction: needs_trust + owner approval (untrusted) → pass', () => assert.equal(RA('needs_trust', false, true), 'pass'));
145
- test('resolveAction: escalate + trusted but NOT owner-approved → block (rank never clears the hard floor)', () => {
146
- assert.equal(RA('escalate', true, false), 'block');
147
- });
148
- test('resolveAction: escalate + owner approval → pass (only the owner clears the floor)', () => assert.equal(RA('escalate', false, true), 'pass'));
149
- test('resolveAction: escalate + nothing → block', () => assert.equal(RA('escalate', false, false), 'block'));
150
-
151
- console.log(`\ngate-review (task 1139) tests: ${passed} passed, ${failed} failed`);
152
- process.exit(failed > 0 ? 1 : 0);
@@ -1,120 +0,0 @@
1
- // tests/goal_names.mjs — the goal rename mapping (task 1003225, goal 1000072,
2
- // criterion legibility-goal-names-and-claude-text).
3
- //
4
- // The mapping IS the decision, so these tests are the review that a shell
5
- // history could never get: no name may still carry its own explanation, no two
6
- // goals may end up with the same name, and re-running must be a no-op.
7
- import { strict as assert } from 'node:assert';
8
- import { test } from 'node:test';
9
- import { createRequire } from 'node:module';
10
- import path from 'node:path';
11
- import { fileURLToPath } from 'node:url';
12
-
13
- const require = createRequire(import.meta.url);
14
- const ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
15
- const { GOAL_NAMES, ALREADY_NAMES, SEPARATOR } = require(path.join(ROOT, 'scripts', 'bongos', 'goal-names.js'));
16
- const { planFor } = require(path.join(ROOT, 'scripts', 'bongos', 'rename-goals.js'));
17
-
18
- const entries = () => Object.entries(GOAL_NAMES).map(([id, v]) => [Number(id), v]);
19
-
20
- test('THE POINT: no new title carries its own explanation', () => {
21
- // A dash or a colon in the name means the split did not happen.
22
- for (const [id, v] of entries()) {
23
- assert.ok(!SEPARATOR.test(v.title), `${id} still jams its explanation into the name: ${v.title}`);
24
- }
25
- });
26
-
27
- test('no two goals end up with the same name', () => {
28
- // The failure a mechanical split would have produced: 1000038/39/40 all head
29
- // "Agents module", so splitting on the separator leaves three identical names.
30
- const seen = new Map();
31
- for (const [id, v] of entries()) {
32
- const key = v.title.toLowerCase();
33
- assert.ok(!seen.has(key), `${id} and ${seen.get(key)} would both be named "${v.title}"`);
34
- seen.set(key, id);
35
- }
36
- });
37
-
38
- test('the three Agents goals are genuinely distinguishable', () => {
39
- const [a, b, c] = [1000038, 1000039, 1000040].map((id) => GOAL_NAMES[id]);
40
- for (const g of [a, b, c]) assert.ok(g, 'all three are mapped');
41
- const names = new Set([a.title, b.title, c.title]);
42
- assert.equal(names.size, 3, 'three distinct names');
43
- // And each says what IT is, not merely that it is an agents goal.
44
- for (const g of [a, b, c]) {
45
- assert.ok(g.title.length > 'Agents module'.length, `"${g.title}" must add something`);
46
- }
47
- });
48
-
49
- test('every goal keeps an explanation — nothing is dropped', () => {
50
- for (const [id, v] of entries()) {
51
- assert.equal(typeof v.subtitle, 'string', `${id} has a subtitle`);
52
- assert.ok(v.subtitle.trim().length >= 20, `${id}'s subtitle must carry the real explanation, not a stub`);
53
- assert.notEqual(v.subtitle.trim().toLowerCase(), v.title.trim().toLowerCase(), `${id} must not restate its name`);
54
- }
55
- });
56
-
57
- test('a name reads as a name, not a sentence', () => {
58
- for (const [id, v] of entries()) {
59
- assert.ok(v.title.length <= 40, `${id} "${v.title}" is ${v.title.length} chars — too long to scan in a list`);
60
- assert.ok(!v.title.endsWith('.'), `${id} "${v.title}" should not be punctuated like prose`);
61
- }
62
- });
63
-
64
- test('every name written with JUDGMENT records why', () => {
65
- // Where the new name is not simply the old head, the reason is part of the
66
- // artifact — that is what makes this reviewable rather than asserted.
67
- for (const id of [1000003, 1000038, 1000039, 1000040, 1000053, 1000064, 1000075, 1000077, 1000078]) {
68
- const v = GOAL_NAMES[id];
69
- assert.ok(v, `${id} is mapped`);
70
- assert.ok(v.why && v.why.length > 25, `${id} must record why its name was rewritten`);
71
- }
72
- });
73
-
74
- test('the mapping and the leave-alone list are disjoint', () => {
75
- for (const id of ALREADY_NAMES) {
76
- assert.ok(!GOAL_NAMES[id], `${id} cannot be both renamed and deliberately untouched`);
77
- }
78
- });
79
-
80
- test('mapping + leave-alone accounts for every open goal', () => {
81
- // 38 = 32 mapping entries + 6 already-names. This is a fact about THIS FILE, not
82
- // about how many goals are currently open — the two drifted apart and saying
83
- // otherwise is how the first version of this comment became false.
84
- //
85
- // The live BONGOS-V1 open set is 37: goal 1000077 was mapped and renamed while
86
- // open and has since been ACHIEVED, so 31 of the 32 entries have an open goal to
87
- // apply to (hence the applier's 'applied: 31'), and 31 + 6 = 37 covers every open
88
- // goal. A stale entry is harmless — planFor is idempotent and simply never matches.
89
- //
90
- // Pinned rather than derived on purpose: derived from the live set it would pass
91
- // forever and never catch a NEW goal. That pin is what surfaced 1000080.
92
- assert.equal(Object.keys(GOAL_NAMES).length + ALREADY_NAMES.length, 38);
93
- });
94
-
95
- test('re-running is a no-op — planFor is idempotent', () => {
96
- const want = GOAL_NAMES[1000027];
97
- const already = { id: 1000027, title: want.title, subtitle: want.subtitle };
98
- assert.deepEqual(planFor(already, want), {}, 'nothing to patch when already correct');
99
- });
100
-
101
- test('planFor patches only what differs', () => {
102
- const want = GOAL_NAMES[1000027];
103
- const titleOnly = { id: 1, title: 'Findability — the grep path (ADR 0095)', subtitle: want.subtitle };
104
- assert.deepEqual(Object.keys(planFor(titleOnly, want)), ['title']);
105
- const subOnly = { id: 1, title: want.title, subtitle: '' };
106
- assert.deepEqual(Object.keys(planFor(subOnly, want)), ['subtitle']);
107
- });
108
-
109
- test('a NULL subtitle is treated as absent, not as a value', () => {
110
- const want = GOAL_NAMES[1000027];
111
- const fresh = { id: 1, title: want.title, subtitle: null };
112
- assert.deepEqual(Object.keys(planFor(fresh, want)), ['subtitle'], 'null must still be filled in');
113
- });
114
-
115
- test('the version catch-all is named for what it is', () => {
116
- const v = GOAL_NAMES[1000003];
117
- assert.ok(!/BONGOS-V1/.test(v.title), 'a version id is not a name');
118
- assert.ok(!/general/i.test(v.title), '"general" names nothing');
119
- assert.match(v.subtitle, /catch-all/i, 'and the subtitle says what it actually is');
120
- });
@@ -1,48 +0,0 @@
1
- // tests/newcomer_generator.mjs — the daily newcomer-generator routine runs to the end.
2
- //
3
- // task 1004860: the routine's artist lane read a curated prompt library from
4
- // modules/art-pipeline/template/, a module this core no longer carries. The read
5
- // threw ENOENT, so every run exited 1 straight after the engineer lane. The lane is
6
- // gone; this drives a whole run through an injected API and checks it finishes.
7
-
8
- import { test } from 'node:test';
9
- import assert from 'node:assert/strict';
10
- import { createRequire } from 'node:module';
11
-
12
- const require = createRequire(import.meta.url);
13
- const { main } = require('../.claude/scheduled-tasks/newcomer-generator/generate.js');
14
-
15
- function fakeApi() {
16
- const calls = [];
17
- const api = async (method, p, body) => {
18
- calls.push({ method, p, body });
19
- if (method === 'GET' && p.startsWith('/api/bongos/tasks')) return { ok: true, data: { tasks: [] } };
20
- if (method === 'GET' && p.startsWith('/api/bongos/inbox')) {
21
- return { ok: true, data: { ideas: [{ id: 7, title: 'Tidy a helper', kind: 'cleanup', priority: 5, body_md: 'x' }] } };
22
- }
23
- if (method === 'POST') return { ok: true, data: { task: { id: 99, title: body.title } } };
24
- if (method === 'PATCH') return { ok: true, data: {} };
25
- return { ok: false, status: 404, data: {} };
26
- };
27
- return { api, calls };
28
- }
29
-
30
- test('a below-target run tops up the engineer lane and finishes without reading a prompt library', async () => {
31
- // Arrange
32
- const { api, calls } = fakeApi();
33
- const log = console.log;
34
- console.log = () => {};
35
-
36
- // Act
37
- try {
38
- await main({ apiCall: api });
39
- } finally {
40
- console.log = log;
41
- }
42
-
43
- // Assert
44
- const created = calls.filter((c) => c.method === 'POST');
45
- assert.equal(created.length, 1, 'exactly one task is created');
46
- assert.equal(created[0].body.discipline, 'engineer');
47
- assert.ok(calls.some((c) => c.method === 'PATCH' && c.p === '/api/bongos/inbox/7'), 'the idea is marked promoted');
48
- });