@bongos/core 1.22.1 → 1.23.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (160) hide show
  1. package/.bongos-core.json +186 -161
  2. package/docs/copy-inventory.md +1 -1
  3. package/docs/copy-registry.json +1 -1
  4. package/docs/module-api-changelog.md +8 -0
  5. package/docs/page-readings.json +40 -40
  6. package/modules/agents/lib/answer-hold.js +1 -1
  7. package/modules/agents/lib/fire-budget.js +1 -1
  8. package/modules/autonomy/cadence.js +3 -3
  9. package/modules/autonomy/config-idle.js +1 -1
  10. package/modules/autonomy/fence.js +1 -1
  11. package/modules/autonomy/gauge.js +2 -2
  12. package/modules/autonomy/governor-docket.js +0 -1
  13. package/modules/autonomy/server-schedule.js +1 -1
  14. package/modules/builder-settings/builder-needs.js +1 -3
  15. package/modules/builder-settings/event-sound-prefs.js +0 -1
  16. package/modules/builder-settings/law-locks.js +0 -1
  17. package/modules/builder-settings/model-alloc-prefs.js +0 -5
  18. package/modules/builder-settings/profile-nudge-prefs.js +0 -1
  19. package/modules/builder-settings/render-prefs.js +0 -1
  20. package/modules/builder-settings/skill-prefs.js +0 -2
  21. package/modules/builder-settings/sound-prefs.js +0 -3
  22. package/modules/builder-settings/wandering-prefs.js +0 -2
  23. package/modules/copy-desk/artist-stats.js +1 -1
  24. package/modules/copy-desk/flags.js +1 -1
  25. package/modules/copy-desk/guarded-lines.js +1 -1
  26. package/modules/copy-desk/page-status.js +0 -5
  27. package/modules/copy-desk/proposals.js +0 -2
  28. package/modules/copy-desk/registry.js +1 -1
  29. package/modules/copy-desk/stuck-tweaks.js +1 -1
  30. package/modules/economy/credits-by-craft.js +0 -2
  31. package/modules/economy/streak.js +0 -3
  32. package/modules/government/asks-db.js +1 -1
  33. package/modules/government/asks.js +0 -1
  34. package/modules/government/decision-board.js +0 -1
  35. package/modules/government/docket.js +0 -6
  36. package/modules/government/leads.js +0 -1
  37. package/modules/government/positions.js +1 -1
  38. package/modules/government/recommendations.js +0 -3
  39. package/modules/government/routing.js +1 -1
  40. package/modules/government/treasury-db.js +1 -1
  41. package/modules/government/treasury.js +2 -2
  42. package/modules/grading/grade-engine.js +0 -1
  43. package/modules/hall-ui/public/deploy.js +3 -3
  44. package/modules/hall-ui/public/dom-utils.js +5 -1
  45. package/modules/hall-ui/public/genesis-home.js +1 -1
  46. package/modules/ideas/completeness.js +1 -1
  47. package/modules/ideas/descent.js +0 -1
  48. package/modules/ideas/governor-docket.js +0 -2
  49. package/modules/ideas/idea-state.js +0 -1
  50. package/modules/ideas/ideator-stats.js +1 -1
  51. package/modules/ideas/votes.js +1 -1
  52. package/modules/lifecycle/autopickup-files.js +0 -3
  53. package/modules/lifecycle/conflict-resolve.js +0 -1
  54. package/modules/lifecycle/criterion-uat-db.js +0 -4
  55. package/modules/lifecycle/dead-deps.js +2 -2
  56. package/modules/lifecycle/est-advisory.js +1 -1
  57. package/modules/lifecycle/github-push.js +1 -2
  58. package/modules/lifecycle/goal-category.js +0 -3
  59. package/modules/lifecycle/goal-spec-task.js +1 -1
  60. package/modules/lifecycle/governor-docket.js +0 -1
  61. package/modules/lifecycle/kickoff-seed.js +1 -1
  62. package/modules/lifecycle/mingle.js +3 -3
  63. package/modules/lifecycle/page-tweak-claim.js +1 -1
  64. package/modules/lifecycle/rebase-gate.js +1 -1
  65. package/modules/lifecycle/removal-derivation.js +0 -1
  66. package/modules/lifecycle/routes/abandon-handler.js +1 -1
  67. package/modules/lifecycle/routes/version-route-authz.js +0 -1
  68. package/modules/lifecycle/ship-card.js +1 -1
  69. package/modules/lifecycle/ship-preflight.js +0 -1
  70. package/modules/lifecycle/sky.js +1 -1
  71. package/modules/lifecycle/task-classifier.js +0 -1
  72. package/modules/lifecycle/task-visuals.js +0 -2
  73. package/modules/lifecycle/version-close.js +0 -1
  74. package/modules/memory/memory.js +0 -1
  75. package/modules/memory/search-chunker.js +1 -1
  76. package/modules/memory/search.js +0 -3
  77. package/modules/npm-release/preview/divert.js +1 -1
  78. package/modules/npm-release/preview/runtime.js +1 -1
  79. package/modules/npm-release/preview/supervisor.js +2 -1
  80. package/modules/onboarding/founding-builders.js +1 -1
  81. package/modules/onboarding/founding-mode.js +1 -1
  82. package/modules/onboarding/howto-guide.js +1 -1
  83. package/modules/onboarding/howto-state.js +1 -1
  84. package/modules/onboarding/onboarding-state.js +0 -4
  85. package/modules/onboarding/onboarding.js +0 -6
  86. package/modules/page-notes/notes.js +0 -1
  87. package/modules/platform-identity/community-leaderboard.js +0 -1
  88. package/modules/platform-identity/hub-keys.js +0 -2
  89. package/modules/platform-identity/instance-feedback.js +0 -1
  90. package/modules/platform-identity/project-stats.js +2 -1
  91. package/modules/platform-identity/read-rate-limit.js +1 -1
  92. package/modules/platform-identity/visibility-pull.js +0 -9
  93. package/modules/provisioning/app-status.js +1 -1
  94. package/modules/provisioning/catalog-bridge.js +0 -1
  95. package/modules/provisioning/core-upgrade.js +1 -1
  96. package/modules/provisioning/credential-preflight.js +1 -1
  97. package/modules/provisioning/demo.js +2 -2
  98. package/modules/provisioning/look.js +1 -1
  99. package/modules/provisioning/routes/callback-page.js +1 -1
  100. package/modules/raise/raise.js +1 -1
  101. package/modules/render-deploy/deploys.js +1 -1
  102. package/modules/security/artifact-scan/aggregate.js +0 -4
  103. package/modules/security/artifact-scan/detectors/capabilities.js +1 -1
  104. package/modules/security/artifact-scan/detectors/config-obfuscation.js +1 -1
  105. package/modules/security/artifact-scan/detectors/credentials.js +1 -1
  106. package/modules/security/artifact-scan/detectors/dependencies.js +1 -1
  107. package/modules/security/artifact-scan/detectors/injection.js +1 -1
  108. package/modules/security/artifact-scan/detectors/network.js +1 -1
  109. package/modules/security/artifact-scan/detectors/npm-lifecycle.js +1 -1
  110. package/modules/security/artifact-scan/detectors/permissions.js +1 -1
  111. package/modules/security/artifact-scan/detectors/shared.js +0 -3
  112. package/modules/security/artifact-scan/floor.js +0 -3
  113. package/modules/security/artifact-scan/mirror.js +1 -1
  114. package/modules/security/artifact-scan/quarantine.js +0 -1
  115. package/modules/security/artifact-scan/rebuild-spec.js +0 -2
  116. package/modules/security/artifact-scan/report.js +1 -1
  117. package/modules/security/artifact-scan/sanitize.js +0 -2
  118. package/modules/security/secret-scrub.js +0 -4
  119. package/modules/security/security.js +0 -2
  120. package/modules/sessions/accessibility.js +0 -2
  121. package/modules/sessions/bfg.js +0 -4
  122. package/modules/sessions/upload-health.js +0 -3
  123. package/modules/specialities/db.js +1 -1
  124. package/modules/specialities/specialities.js +1 -1
  125. package/modules/ui-design/kit/lib.js +2 -2
  126. package/package-lock.json +2 -2
  127. package/package.json +1 -1
  128. package/release-notes.json +13 -0
  129. package/scripts/bongos/autobongos-run.js +2 -1
  130. package/scripts/bongos/autonomy-gauge.js +2 -1
  131. package/scripts/bongos/backfill-disciplines.js +1 -1
  132. package/scripts/bongos/backfill-sessions.js +1 -1
  133. package/scripts/bongos/backup.js +2 -1
  134. package/scripts/bongos/dev.js +1 -1
  135. package/scripts/bongos/do-api.js +2 -1
  136. package/scripts/bongos/fitness.js +5 -6
  137. package/scripts/bongos/local-preview.js +2 -1
  138. package/scripts/bongos/login.js +1 -1
  139. package/scripts/bongos/page-reader.js +2 -1
  140. package/scripts/bongos/probe-cache.js +2 -1
  141. package/scripts/bongos/provision-core-upgrade.js +2 -1
  142. package/scripts/bongos/provision.js +5 -4
  143. package/scripts/bongos/publish-integration-gate.js +2 -1
  144. package/scripts/bongos/render-api.js +2 -1
  145. package/scripts/bongos/sandbox-stage.js +2 -1
  146. package/scripts/bongos/seed-bongos-v1-idea-routing-tasks.js +1 -1
  147. package/scripts/bongos/seed-bv1-profiles-tasks.js +1 -1
  148. package/scripts/bongos/seed-bv2-ideator-surface-tasks.js +1 -1
  149. package/scripts/bongos/session-eval.js +2 -1
  150. package/scripts/bongos/setup.js +2 -1
  151. package/scripts/bongos/sleep-helper-guard.js +88 -0
  152. package/scripts/bongos/upgrade.js +2 -2
  153. package/scripts/gds/sleep-helper-guard.js +6 -0
  154. package/src/bongos/module-scope-map.js +1 -0
  155. package/src/module-api.js +6 -1
  156. package/src/sleep.js +24 -0
  157. package/tests/deploy_page_projects.mjs +2 -1
  158. package/tests/module_api.mjs +1 -0
  159. package/tests/modules_external_export_contract.mjs +48 -0
  160. package/tests/sleep_helper.mjs +99 -0
@@ -36,6 +36,7 @@ const net = require('node:net');
36
36
  // prove it belongs to the project it is filed under; the ship-link path in
37
37
  // platform-identity.js reads the identical rule from the identical place.
38
38
  const { urlWithinOrigin } = require('./origin-containment');
39
+ const { sleep } = require('../../src/module-api'); // the one shared sleep (task 1004893)
39
40
 
40
41
  const TTL_MS = 10 * 60 * 1000; // owner's choice, 2026-08-13
41
42
  const FETCH_TIMEOUT_MS = 2500; // per request
@@ -322,7 +323,7 @@ async function getProjectStats(origins = []) {
322
323
  if (cold.length) {
323
324
  await Promise.race([
324
325
  Promise.allSettled(cold.map((o) => refresh(o))),
325
- new Promise((r) => setTimeout(r, COLD_DEADLINE_MS)),
326
+ sleep(COLD_DEADLINE_MS),
326
327
  ]);
327
328
  }
328
329
 
@@ -65,4 +65,4 @@ function createReadRateLimit({ scope, limit, windowMs = 60 * 1000, maxTrackedIps
65
65
  return limiter;
66
66
  }
67
67
 
68
- module.exports = { createReadRateLimit, MAX_TRACKED_IPS };
68
+ module.exports = { createReadRateLimit };
@@ -59,14 +59,6 @@ const { pool: defaultPool } = require('../../src/module-api');
59
59
  const { ORB_BY_STATE } = require('./projects-feed');
60
60
  const projectStats = require('./project-stats');
61
61
 
62
- // The manifest route every Cloud Bongos instance already serves, unauthenticated and
63
- // CORS-open (ADR 0114's discovery surface; `src/bongos/routes/instance.js`). Nothing is
64
- // added to it by this task — ADR 0252 §2.3: the field already ships in every core, so
65
- // there is no wire change on anyone else's upgrade schedule. The API router is
66
- // dual-mounted at `/api/bongos` (canonical) and at the permanent legacy alias ADR 0252
67
- // happened to write, so either prefix reaches it; the fetch uses the canonical one.
68
- const MANIFEST_ROUTE = '/api/bongos/instance';
69
-
70
62
  // Rows the PULL may write: the ones the ADR 0246 control-plane bridge has never claimed.
71
63
  // `IS DISTINCT FROM` rather than `<> `, deliberately — a NULL source is the unclaimed
72
64
  // state and plain inequality would drop exactly those rows on a NULL comparison.
@@ -190,7 +182,6 @@ async function sweepVisibilityOnce({ pool = defaultPool, limit = 200, fetchVisib
190
182
  }
191
183
 
192
184
  module.exports = {
193
- MANIFEST_ROUTE,
194
185
  PULLABLE_SQL,
195
186
  visibilityFromManifest,
196
187
  pullDecision,
@@ -93,4 +93,4 @@ function retryAnswers(h) {
93
93
  return r;
94
94
  }
95
95
 
96
- module.exports = { appStatus, appUrl, serviceLinks, oneSentence, retryAnswers, STAGES, QUIET_AFTER_MS, RENDER_URL_RE, SERVICE_ID_RE };
96
+ module.exports = { appStatus, appUrl, serviceLinks, oneSentence, retryAnswers, STAGES, QUIET_AFTER_MS, RENDER_URL_RE };
@@ -161,7 +161,6 @@ async function healInstanceCatalog(db, row) {
161
161
  }
162
162
 
163
163
  module.exports = {
164
- CATALOG_HIDDEN_STATES,
165
164
  catalogEntryForInstance,
166
165
  // the disconnect runner leg forgets exactly what a publish wrote (task 1003249)
167
166
  catalogOriginForInstance, ownerGithubIdForInstance,
@@ -551,5 +551,5 @@ function makeUpdateChannelHandler({ provisioning, pool, parseId, validateOrRespo
551
551
  };
552
552
  }
553
553
 
554
- module.exports = { loadPreview, UPDATE_CHANNELS, DEFAULT_UPDATE_CHANNEL, updateChannelOf, selfUpdateChannel, makeUpdateChannelHandler, CORE_UPGRADE_FROM, lastCoreMove, lastMoveSuperseded, parseRepoNote, preflightForOffer, UPGRADE_SHAPES, VERSION_RE, isCoreVersion, coreUpgradeFault, enqueueCoreUpgrade, makeCoreUpgradeHandler, previewFromSnapshot, makeCoreUpgradePreviewHandler, makeControlPlaneHandler };
554
+ module.exports = { loadPreview, UPDATE_CHANNELS, DEFAULT_UPDATE_CHANNEL, updateChannelOf, selfUpdateChannel, makeUpdateChannelHandler, lastCoreMove, lastMoveSuperseded, parseRepoNote, UPGRADE_SHAPES, VERSION_RE, coreUpgradeFault, enqueueCoreUpgrade, makeCoreUpgradeHandler, previewFromSnapshot, makeCoreUpgradePreviewHandler, makeControlPlaneHandler };
555
555
 
@@ -167,4 +167,4 @@ async function adoptCredentialFault({ builderId, onboardMode, targetRef }, deps)
167
167
  return null;
168
168
  }
169
169
 
170
- module.exports = { adoptCredentialFault, parseTargetRef, readOwnerRepoToken, fetchRepoVisibility };
170
+ module.exports = { adoptCredentialFault, parseTargetRef };
@@ -171,6 +171,6 @@ async function sweepDemos(db, { enqueueTeardown, recordEvent, now = new Date() }
171
171
  }
172
172
 
173
173
  module.exports = {
174
- DEMO_LIMITS, DEMO_OFFLINE_DAYS, DEMO_WARN_DAYS, DEMO_DETAIL, DEMO_SETTINGS, OUTCOMES,
175
- parseDemo, fitCheck, withDemoDetail, demoRecord, demoView, startDemo, startDemoProject, settleDemo, sweepDemos,
174
+ DEMO_LIMITS, DEMO_SETTINGS, OUTCOMES,
175
+ parseDemo, fitCheck, withDemoDetail, demoRecord, demoView, startDemoProject, settleDemo, sweepDemos,
176
176
  };
@@ -165,5 +165,5 @@ module.exports = {
165
165
  upsertLogo, deleteLogo, readLogo,
166
166
  LIBRARY_LOOKS, LOOK_SETTINGS_VOCAB, LOOK_DEFAULTS, LOOK_COMPANION_ENV,
167
167
  lookChoice, lookAdjustAccent, lookAccentOf, logoUrlOf,
168
- LOGO_MAX_BYTES, LOGO_MIME, screenLogo, sniffLogo, logoFileName, LOGO_FILE,
168
+ LOGO_MAX_BYTES, LOGO_MIME, screenLogo, logoFileName, LOGO_FILE,
169
169
  };
@@ -190,4 +190,4 @@ function callbackPage({ ok, title, body, state, domain, next }) {
190
190
  </body></html>`;
191
191
  }
192
192
 
193
- module.exports = { esc, callbackPage, returnHref, RETURN_PATH };
193
+ module.exports = { esc, callbackPage, returnHref };
@@ -170,5 +170,5 @@ module.exports = {
170
170
  TOKENS, SETTING_KEYS, MAX_BLOCK, EDIT_MIN_RANK, TBA,
171
171
  defaultCopy, defaultSettings, ndaBody, ndaVersion, isEditableKey,
172
172
  esc, usd, kindOf, normalizeBlock, renderInline, renderBlock, renderContext, fill, cleanSetting,
173
- hashPassword, passwordOk, validLinkedin, normalizeSignin, newSessionToken, hashToken, plainForDiscord,
173
+ hashPassword, passwordOk, normalizeSignin, newSessionToken, hashToken, plainForDiscord,
174
174
  };
@@ -197,7 +197,7 @@ async function saveApp(pool, { ownerId, serviceId, serviceName, builderId }) {
197
197
  }
198
198
 
199
199
  module.exports = {
200
- KEY_RE, OWNER_RE, SERVICE_RE, DEPLOY_RE, HISTORY_LIMIT,
200
+ KEY_RE, OWNER_RE, SERVICE_RE, DEPLOY_RE,
201
201
  statusWords, taskIdsIn, previewOf, costOf, shapeHistory, readHistory, getApp, saveApp,
202
202
  ROLLBACK_STATUSES,
203
203
  };
@@ -33,7 +33,6 @@ const TIER_CLAMP = Object.freeze({
33
33
  // A lens that did not finish cleanly contributes caution, never silence: an
34
34
  // errored/timed-out/budget-exhausted lens means its surface went UNREVIEWED.
35
35
  const LENS_OK = 'ok';
36
- const LENS_PROBLEM_STATUSES = Object.freeze(['error', 'timeout', 'budget_exhausted']);
37
36
 
38
37
  const rank = (v) => VERDICT_RANK[v] ?? VERDICT_RANK.dangerous; // unknown → worst
39
38
  const maxVerdict = (a, b) => (rank(a) >= rank(b) ? a : b);
@@ -123,11 +122,8 @@ function reduceVerdict({ floorReport = {}, lenses = [], tier = 'low', declaredDe
123
122
 
124
123
  module.exports = {
125
124
  VERDICTS,
126
- TIER_CLAMP,
127
125
  LENS_OK,
128
- LENS_PROBLEM_STATUSES,
129
126
  panelOutcome,
130
- lensHealth,
131
127
  coverageCap,
132
128
  reduceVerdict,
133
129
  };
@@ -50,4 +50,4 @@ function inventory(corpus) {
50
50
 
51
51
  // Constants exported as the white-box surface: the reducer/report stages and
52
52
  // tests read them to stay in lockstep with what the inventory actually covers.
53
- module.exports = { inventory, CAPABILITY_PATTERNS, SCRIPT_EXTENSIONS };
53
+ module.exports = { inventory };
@@ -38,4 +38,4 @@ function detect(corpus) {
38
38
  return findings;
39
39
  }
40
40
 
41
- module.exports = { detect, isJsonConfig };
41
+ module.exports = { detect };
@@ -114,4 +114,4 @@ function detect(corpus) {
114
114
  return findings;
115
115
  }
116
116
 
117
- module.exports = { detect, perFileHits, CREDENTIAL_PATTERNS };
117
+ module.exports = { detect, perFileHits };
@@ -112,4 +112,4 @@ function detect(corpus) {
112
112
  return findings;
113
113
  }
114
114
 
115
- module.exports = { detect, specSeverity, DEP_SECTIONS };
115
+ module.exports = { detect };
@@ -115,4 +115,4 @@ function detect(corpus) {
115
115
  return findings;
116
116
  }
117
117
 
118
- module.exports = { detect, OVERRIDE_PHRASES, SCANNER_PHRASES, codepointClasses };
118
+ module.exports = { detect };
@@ -64,4 +64,4 @@ function detect(corpus) {
64
64
  return findings;
65
65
  }
66
66
 
67
- module.exports = { detect, perFileHits, NETWORK_PATTERNS };
67
+ module.exports = { detect, perFileHits };
@@ -78,4 +78,4 @@ function detect(corpus) {
78
78
  return findings;
79
79
  }
80
80
 
81
- module.exports = { detect, AUTO_RUN_SCRIPTS };
81
+ module.exports = { detect };
@@ -88,4 +88,4 @@ function detect(corpus) {
88
88
  return findings;
89
89
  }
90
90
 
91
- module.exports = { detect, BYPASS_MARKERS };
91
+ module.exports = { detect };
@@ -202,14 +202,11 @@ function escapedConfigKeyCount(text) {
202
202
  }
203
203
 
204
204
  module.exports = {
205
- EXCERPT_MAX_CHARS,
206
205
  SEVERITIES,
207
- SENSITIVE_BASENAMES,
208
206
  isSensitivePath,
209
207
  basename,
210
208
  finding,
211
209
  excerpt,
212
- sanitizeDetail,
213
210
  lineAt,
214
211
  parseJsonStrict,
215
212
  rawKeyCounts,
@@ -359,12 +359,9 @@ async function runFloor({ pristineDir, quarantineRoot, entries, sha = null, cont
359
359
 
360
360
  module.exports = {
361
361
  FLOOR_VERSION,
362
- REPORT_BASENAME,
363
362
  VERDICT_RANK,
364
363
  DETECTORS,
365
364
  buildCorpus,
366
- computeFloorVerdict,
367
- countBySeverity,
368
365
  coOccurrence,
369
366
  coverageFindings,
370
367
  dedupeFindings,
@@ -155,4 +155,4 @@ async function buildMirror({ pristineDir, mirrorDir, quarantineRoot, entries, ca
155
155
  return { mirrored, stubs, unreviewedBytes, fenceDelim, indexPath };
156
156
  }
157
157
 
158
- module.exports = { buildMirror, MIRROR_CAPS, INDEX_BASENAME };
158
+ module.exports = { buildMirror, MIRROR_CAPS };
@@ -254,7 +254,6 @@ function createQuarantine({ tmpRoot = os.tmpdir(), forbiddenRoots } = {}) {
254
254
  module.exports = {
255
255
  canonical,
256
256
  isInsideLexical,
257
- canonicalUncached,
258
257
  clearCanonicalCache,
259
258
  CAPS,
260
259
  REPO_ROOT,
@@ -112,8 +112,6 @@ function assembleRebuildSpec({
112
112
  }
113
113
 
114
114
  module.exports = {
115
- SPEC_LIMITS,
116
- GROUND_RULES,
117
115
  isDocPath,
118
116
  selectDocFiles,
119
117
  assembleRebuildSpec,
@@ -152,4 +152,4 @@ function assembleReport({
152
152
  return out.join('\n');
153
153
  }
154
154
 
155
- module.exports = { assembleReport, findingLine };
155
+ module.exports = { assembleReport };
@@ -313,8 +313,6 @@ async function buildSanitizedCopy({ pristineDir, quarantineRoot, entries, remova
313
313
  }
314
314
 
315
315
  module.exports = {
316
- SANITIZED_DIRNAME,
317
- DIFF_BASENAME,
318
316
  hasMaliceIndicator,
319
317
  planSanitize,
320
318
  buildSanitizedCopy,
@@ -255,15 +255,11 @@ function scrubSecrets(text, extraSecrets = [], opts = undefined) {
255
255
  module.exports = {
256
256
  REDACTED,
257
257
  SECRET_PATTERNS,
258
- SECRET_ASSIGNMENT_RE,
259
258
  shannonEntropy,
260
- charClasses,
261
259
  looksHighEntropySecret,
262
- ENTROPY_CANDIDATE_RE,
263
260
  redactHighEntropy,
264
261
  ENV_SECRET_KEY_RE,
265
262
  ENV_SECRET_PREFIX_RE,
266
- ENV_BENIGN_KEY_RE,
267
263
  collectEnvSecrets,
268
264
  scrubSecrets,
269
265
  };
@@ -283,8 +283,6 @@ async function linkVulnerabilityReportFix(id, fixTaskId) {
283
283
  module.exports = {
284
284
  SEVERITIES,
285
285
  VULN_STATUSES,
286
- DEFAULT_BOUNTY,
287
- SEVERITY_BLURB,
288
286
  envName,
289
287
  bountyTable,
290
288
  bountyTableDetailed,
@@ -356,7 +356,6 @@ module.exports = {
356
356
  scoreAccessibility,
357
357
  // Exported so the tests can pin the contracts (waivers, leniency, each
358
358
  // detector) without reconstructing a whole digest for every case.
359
- resolveProfile,
360
359
  waiversFor,
361
360
  leniencyFor,
362
361
  assistantProse,
@@ -366,7 +365,6 @@ module.exports = {
366
365
  bandFor,
367
366
  SIGNAL_SPEC,
368
367
  JARGON_TERMS,
369
- UI_BACKED_SUBJECTS,
370
368
  LOW_CONFIDENCE_CHARS,
371
369
  PROFILE_DEFAULTS,
372
370
  PROFILE_VALUES,
@@ -346,12 +346,8 @@ module.exports = {
346
346
  buildAdoptionSuggestion,
347
347
  // 6C.2 correction builder
348
348
  buildCorrection,
349
- TRANSFERABLE_TYPES,
350
- PII_PATTERNS,
351
349
  // exported for tests + reuse
352
350
  parseFrontmatter,
353
- stripFrontmatter,
354
351
  clamp01,
355
352
  QUALITY_WEIGHTS,
356
- ALLOWED_MEMORY_TYPES,
357
353
  };
@@ -187,11 +187,8 @@ function uploadHealthVerdict(rows, opts = {}) {
187
187
  module.exports = {
188
188
  DEFAULT_WINDOW_HOURS,
189
189
  DEFAULT_LOOKBACK_DAYS,
190
- DEFAULT_MIN_SHIPS,
191
- DEFAULT_MAX_UNCOVERED_SHARE,
192
190
  clampLookbackDays,
193
191
  clampWindowHours,
194
192
  clampSampleLimit,
195
- normalizeBuilderRows,
196
193
  uploadHealthVerdict,
197
194
  };
@@ -278,5 +278,5 @@ module.exports = {
278
278
  createSpeciality, getSpeciality, listVisibleTo, updateSpeciality,
279
279
  addDocument, listDocuments, deleteDocument,
280
280
  linkLearning, countTraining,
281
- adopt, abandon, deactivateCraft, activeForCraft, listAdoptions, setEnabledSkills,
281
+ adopt, abandon, activeForCraft, listAdoptions, setEnabledSkills,
282
282
  };
@@ -303,4 +303,4 @@ function offeredTo(specialities, viewer, adoptions = []) {
303
303
  });
304
304
  }
305
305
 
306
- module.exports = { VISIBILITIES, LIMITS, SKILL_NAME_RE, slugify, validateDraft, skillListErrors, enabledSkillsErrors, canAdopt, describeForApi, offeredTo };
306
+ module.exports = { VISIBILITIES, LIMITS, SKILL_NAME_RE, slugify, validateDraft, enabledSkillsErrors, canAdopt, describeForApi, offeredTo };
@@ -524,9 +524,9 @@ function packColors(pack) {
524
524
  }
525
525
 
526
526
  module.exports = {
527
- REPO_ROOT, KIT_DIR, STYLES_DIR, EXIT, FLOORS, SIZES, DEFAULT_SIZES, MODES, CHANNELS, SETTLE_MS, ACTIONS, EXPECT_KEYS,
527
+ REPO_ROOT, KIT_DIR, STYLES_DIR, EXIT, FLOORS, SIZES, DEFAULT_SIZES, MODES, CHANNELS, SETTLE_MS, ACTIONS,
528
528
  argOf, hasFlag, listArg, pageName, normalizePageArg, resolveSurfaceDir, sidecarPath, readJson,
529
- validateActions, runActions, validateExpect, factsInPage, expectProblems, auditFloors, reducedMotionProblems, craftTells,
529
+ runActions, factsInPage, expectProblems, auditFloors, reducedMotionProblems, craftTells,
530
530
  validateStatesFile, validateProbesFile, NoBrowserError, launchBrowser, attachCollectors, withMode,
531
531
  freePort, startStub, parseColor, composite, luminance, contrastRatio, instancePack, packColors,
532
532
  listStyles, resolveStyle, styleBrandingFile,
package/package-lock.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@bongos/core",
3
- "version": "1.22.1",
3
+ "version": "1.23.1",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@bongos/core",
9
- "version": "1.22.1",
9
+ "version": "1.23.1",
10
10
  "license": "AGPL-3.0-or-later",
11
11
  "dependencies": {
12
12
  "express": "^4.21.2",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bongos/core",
3
- "version": "1.22.1",
3
+ "version": "1.23.1",
4
4
  "description": "Cloud Bongos — the AI-first build platform core (GDS + platform surfaces + module system), installed as a versioned dependency (ADR 0108).",
5
5
  "license": "AGPL-3.0-or-later",
6
6
  "main": "src/platform-server.js",
@@ -10376,5 +10376,18 @@
10376
10376
  "id": "1004876",
10377
10377
  "text": "Builder-written text now goes through one safety filter in the browser and one on the server instead of 42 hand-made copies, six of which let a stray quote through — and a check stops a new copy from creeping back."
10378
10378
  }
10379
+ ],
10380
+ "1.22.2": [
10381
+ {
10382
+ "id": "1004891",
10383
+ "text": "Cleaned up 220 internal code hooks nothing else used, cutting the project's dead-code count from 439 to 213."
10384
+ }
10385
+ ],
10386
+ "1.23.0": [],
10387
+ "1.23.1": [
10388
+ {
10389
+ "id": "1004893",
10390
+ "text": "The ~30 copy-pasted \"wait a moment\" helpers across the codebase now all use one shared helper (one for the browser, one for the server), and a fitness check stops new copies from creeping back in. Nothing users see changes."
10391
+ }
10379
10392
  ]
10380
10393
  }
@@ -54,6 +54,7 @@ const { matchProtected } = require('../../src/bongos/permission-path-check');
54
54
  const { resolveEnv, envPrefix, LEGACY_ENV_PREFIXES } = require('../../src/instance-config');
55
55
  const cadence = require('../../modules/autonomy/cadence.js');
56
56
  const configIdle = require('../../modules/autonomy/config-idle.js');
57
+ const { sleep: sharedSleep } = require('../../src/sleep'); // the one shared sleep (task 1004893)
57
58
 
58
59
  const REPO_ROOT = path.resolve(__dirname, '..', '..');
59
60
 
@@ -1149,7 +1150,7 @@ async function runFetchHead(deps = {}) {
1149
1150
  async function waitOrJump(waitS, deps = {}, cfg = {}) {
1150
1151
  if (!(waitS > 0)) return { waited: 0, jumped: false };
1151
1152
  const pollEveryS = cfg.pollEveryS ?? 60;
1152
- const sleep = deps.sleep || ((ms) => new Promise((r) => setTimeout(r, ms)));
1153
+ const sleep = deps.sleep || sharedSleep;
1153
1154
  const poll = deps.pollSignals || pollSignals;
1154
1155
 
1155
1156
  const before = await poll(deps);
@@ -18,6 +18,7 @@
18
18
 
19
19
  const fs = require('node:fs');
20
20
  const { decideCapacity } = require('../../modules/autonomy/gauge.js');
21
+ const { sleep: sharedSleep } = require('../../src/sleep'); // the one shared sleep (task 1004893)
21
22
 
22
23
  function gaugePath() {
23
24
  if (process.env.AUTOBONGOS_GAUGE_FILE) return process.env.AUTOBONGOS_GAUGE_FILE;
@@ -70,7 +71,7 @@ async function main(argv) {
70
71
  const now = Math.floor(Date.now() / 1000);
71
72
  const waitS = d.sleepUntil ? Math.max(1, d.sleepUntil - now) : 60;
72
73
  if (!json) console.log(` sleeping ${waitS}s…`);
73
- await new Promise((r) => setTimeout(r, waitS * 1000));
74
+ await sharedSleep(waitS * 1000);
74
75
  }
75
76
  }
76
77
 
@@ -47,7 +47,7 @@ function classify(task) {
47
47
  return { discipline: FALLBACK, reasoned: false, confidence: null };
48
48
  }
49
49
 
50
- const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
50
+ const { sleep } = require('../../src/sleep'); // the one shared sleep (task 1004893)
51
51
 
52
52
  // PATCH one row, WAITING OUT the per-session rate limit rather than counting it as a
53
53
  // failure. The first run of this backfill treated a 429 as a failed row and stopped
@@ -241,7 +241,7 @@ function loadExisting() {
241
241
  return set;
242
242
  }
243
243
 
244
- const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
244
+ const { sleep } = require('../../src/sleep'); // the one shared sleep (task 1004893)
245
245
 
246
246
  async function main() {
247
247
  const existing = loadExisting();
@@ -8,6 +8,7 @@
8
8
  // Rank gate: metic+archon.
9
9
 
10
10
  const { cliClient, requireSession } = require('./cli-lib');
11
+ const { sleep } = require('../../src/sleep'); // the one shared sleep (task 1004893)
11
12
 
12
13
  function fmtBytes(n) {
13
14
  if (n == null) return '(unknown size)';
@@ -84,7 +85,7 @@ async function trigger() {
84
85
  const deadline = Date.now() + 60_000;
85
86
  let landed = false;
86
87
  while (Date.now() < deadline) {
87
- await new Promise(resolve => setTimeout(resolve, 3_000));
88
+ await sleep(3_000);
88
89
  const status = await fetchStatus();
89
90
  const nowFile = status.latest_dump && status.latest_dump.filename;
90
91
  if (nowFile && nowFile !== beforeFile) {
@@ -57,7 +57,7 @@ function tail(s, n = 6) {
57
57
  }
58
58
  // Portable synchronous pause (no subprocess, no foreground-sleep dependency).
59
59
  function sleepSync(ms) { Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms); }
60
- const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
60
+ const { sleep } = require('../../src/sleep'); // the one shared sleep (task 1004893)
61
61
 
62
62
  function usage() {
63
63
  console.log(`bongos dev — run THIS instance, in one command.
@@ -24,6 +24,7 @@
24
24
  // createDroplet · getDroplet · deleteDroplet · settleDroplet (poll to active)
25
25
 
26
26
  const { JsonHttpApi, makeApiError } = require('./http-api-client');
27
+ const { sleep: sharedSleep } = require('../../src/sleep'); // the one shared sleep (task 1004893)
27
28
 
28
29
  const DO_API_BASE = 'https://api.digitalocean.com/v2';
29
30
 
@@ -79,7 +80,7 @@ class DoApi extends JsonHttpApi {
79
80
  // Returns the stopping value, or { timedOut:true } after `tries` rounds.
80
81
  // `sleepFn` lets tests drive the loop with no real clock.
81
82
  async _poll({ tries = 60, sleepMs = 5000, sleepFn } = {}, step) {
82
- const sleep = sleepFn || ((ms) => new Promise((r) => setTimeout(r, ms)));
83
+ const sleep = sleepFn || sharedSleep;
83
84
  for (let i = 0; i < tries; i++) {
84
85
  const r = await step(i);
85
86
  if (r && r.done) return r.value;
@@ -523,7 +523,7 @@ const KERNEL_FILES = [
523
523
  'src/module-api.js', // the published doorway
524
524
  'src/modules.js', // the registry/resolver facade
525
525
  'src/module-seams.js', // the seam registry (ports/events/contributions)
526
- 'src/role-responsibilities.js', 'src/html-escape.js', // owner's role statements (task 1003732) + THE server HTML escaper (task 1004876) — both import nothing
526
+ 'src/role-responsibilities.js', 'src/html-escape.js', 'src/sleep.js', // owner's role statements (task 1003732) + THE server HTML escaper (task 1004876) + THE server sleep (task 1004893) — all import nothing
527
527
  'src/module-loader/loader.js', // the disk loader (discover → validate → mount)
528
528
  'src/module-loader/manifest-schema.js', // the manifest validator
529
529
  'src/module-loader/semver.js', // coreVersion compatibility
@@ -1365,13 +1365,12 @@ const CHECKS = [
1365
1365
  require('./doc-control-claims.js').checkDocControlClaims, // Check 37 — task 1003418 / audit A14: a doc cannot describe an enforcement control that does not exist (derived from the docs, not a hand list)
1366
1366
  require('./doc-cli-guard.js').checkDocNamesRealCli, // Check 22 — task 1003165 / G01: a doc that names a CLI invocation must match the real CLI
1367
1367
  require('./skill-preflight.js').checkOpsSkillsDeclareMachine, // Check 23 — task 1003167 / G03: an ops skill declares the machine it needs
1368
- // Check 24 — task 1003166 / G02: no ops script hardcodes a version id. It landed
1369
- // sharing Check 23's line, deliberately, because fitness.js was ~500 lines over
1370
- // the excess-lines ratchet and a new check could not afford one (idea 1000810).
1371
- // Task 1003206 carved this file from 2,004 lines to ~1,350, so that toll is paid
1372
- // and the check gets its own line back.
1368
+ // Check 24 — task 1003166 / G02: no ops script hardcodes a version id. It once shared
1369
+ // Check 23's line because fitness.js was over the excess-lines ratchet (idea 1000810);
1370
+ // task 1003206 carved this file from 2,004 lines to ~1,350, so it has its own line back.
1373
1371
  require('./version-literal-guard.js').checkNoVersionLiterals,
1374
1372
  require('./escape-helper-guard.js').checkOneHtmlEscaper, // task 1004876: ONE HTML escaper per side (dom-utils.js / src/html-escape.js), and hall pages load dom-utils first
1373
+ require('./sleep-helper-guard.js').checkOneSleepHelper, // task 1004893: ONE sleep per side (dom-utils.js OTB.sleep / src/sleep.js)
1375
1374
  require('./dev-box-guard.js').checkNoDevBox, // task 1003899 / ADR 0346: the retired dev box stays out (its exemption list lives in that file)
1376
1375
  require('./control-manifest.js').checkControlsExist, // Check 21 — task 1003131: goal-1000076 controls assert their own existence (the ADR 0022 assurance-of-assurance)
1377
1376
  require('./routine-schedule.js').checkRoutineCadencesScheduled, // Check 25 — task 1003209: a routine that declares a cadence must have a scheduler firing it AT that period (ADR 0188)
@@ -15,12 +15,13 @@
15
15
  // shipped. Set OTB_PREVIEW_PORT to override the default 3100.
16
16
 
17
17
  const lib = require('./local-preview-lib');
18
+ const { sleep } = require('../../src/sleep'); // the one shared sleep (task 1004893)
18
19
 
19
20
  async function pollHealthy(ms = 20_000) {
20
21
  const end = Date.now() + ms;
21
22
  while (Date.now() < end) {
22
23
  if (await lib.health()) return true;
23
- await new Promise((r) => setTimeout(r, 500));
24
+ await sleep(500);
24
25
  }
25
26
  return false;
26
27
  }
@@ -86,7 +86,7 @@ function prompt(q) {
86
86
  return new Promise((resolve) => rl.question(q, (a) => { rl.close(); resolve(String(a || '').trim()); }));
87
87
  }
88
88
 
89
- const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
89
+ const { sleep } = require('../../src/sleep'); // the one shared sleep (task 1004893)
90
90
 
91
91
  // Run the device flow and return one of:
92
92
  // { state: 'ok', token, builder } | { state: 'not_approved' } | { state: 'expired' }
@@ -57,6 +57,7 @@ const fs = require('node:fs');
57
57
  const path = require('node:path');
58
58
  const crypto = require('node:crypto');
59
59
  const { spawn, spawnSync } = require('node:child_process');
60
+ const { sleep } = require('../../src/sleep'); // the one shared sleep (task 1004893)
60
61
 
61
62
  const REPO_ROOT = path.resolve(__dirname, '..', '..');
62
63
  const INVENTORY_REL = 'docs/page-inventory.json';
@@ -511,7 +512,7 @@ async function renderOne(browser, kit, plan, base) {
511
512
  try { await kit.runActions(page, plan.actions); } catch (e) { notes.push(`${plan.state}: an action failed (${String(e.message).split('\n')[0].slice(0, 120)}); read as it stood`); }
512
513
  // A body read on a response from a page that has since navigated away never
513
514
  // settles, so the wait for the data is bounded.
514
- await Promise.race([Promise.all(pending), new Promise((r) => setTimeout(r, 2000))]);
515
+ await Promise.race([Promise.all(pending), sleep(2000)]);
515
516
  const got = await page.evaluate(captureInPage);
516
517
  if (got.branding) collectStrings(got.branding, data);
517
518
  return { state: plan.state, strings: got.strings, notes, data };
@@ -38,6 +38,7 @@ const fs = require('node:fs');
38
38
  const os = require('node:os');
39
39
  const path = require('node:path');
40
40
  const crypto = require('node:crypto');
41
+ const { sleep } = require('../../src/sleep'); // the one shared sleep (task 1004893)
41
42
 
42
43
  // Default freshness. The probes this serves answer questions that change on a
43
44
  // deploy or a ship — minutes, not seconds — so 60s is generous for a session brief
@@ -156,7 +157,7 @@ const POLL_MS = 100;
156
157
  async function waitForRecord(file, ttlMs, now) {
157
158
  const deadline = Date.now() + WAIT_MS;
158
159
  while (Date.now() < deadline) {
159
- await new Promise((r) => setTimeout(r, POLL_MS));
160
+ await sleep(POLL_MS);
160
161
  const rec = readRecord(file);
161
162
  if (isFresh(rec, ttlMs, now())) return rec;
162
163
  // The holder is gone and left nothing: stop waiting and do the work ourselves.