@blamejs/core 0.9.15 → 0.9.16

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/CHANGELOG.md CHANGED
@@ -8,6 +8,7 @@ upgrading across more than a few patches at a time.
8
8
 
9
9
  ## v0.9.x
10
10
 
11
+ - v0.9.16 (2026-05-14) — **Operator-facing prose cleanup + `require-binding-name` detector now covers `lazyRequire` wrappers + dbStore seal round-trip test added.** Post-v0.9.15 audit surfaced three classes of follow-up. (1) **Operator-facing prose leaks (7 sites)** — the v0.9.15 mechanical rename pattern `<OLD>.` → `<NEW>.` also caught occurrences inside JSDoc `@opts` comments and error-message string literals, so operators reading `b.keychain.create(opts)` saw `// absolute nodePath; required if file fallback may engage` instead of `// absolute path`. Fixed: `lib/db.js` (stream-limit error), `lib/keychain.js` (fallback-file error + 3 JSDoc lines), `lib/restore-bundle.js` (staging-dir error), `lib/watcher.js` (fs.watch failure error). Operators see plain English; internal binding names stay internal. (2) **`require-binding-name` detector extended to cover `lazyRequire`** — the v0.9.15 detector only matched plain `var X = require("M")` and missed the framework's `var X = lazyRequire(function () { return require("M"); })` pattern (used to break load cycles). 34 additional inconsistencies surfaced (`auditFwk` / `auditMod` / `auditModule` / `lazyAudit` → `audit`, `crypto` / `fwCrypto` → `bCrypto`, `dbMod` / `dbModule` → `db`, etc.) — every minority site renamed per the same canonical-name map. (3) **dbStore seal round-trip test** — the v0.9.15 test suite covered seal-falls-back-when-vault-not-ready and cross-process-sealed-row-preserved, but did NOT exercise the actual default-ON seal/unseal path because the test environment didn't `b.vault.init(...)`. New `testDbStoreSealRoundTripWithVault` bootstraps a plaintext vault, builds a dbStore with `seal: true`, writes a record + reads it back, and asserts (a) `headers` + `body` columns carry the `vault:` envelope on disk, (b) the round-trip restores the original values, and (c) `status_code` stays plaintext so forensic SELECTs still work without unsealing.
11
12
  - v0.9.15 (2026-05-13) — **`b.middleware.idempotencyKey.dbStore` hardening + framework-wide `require()` binding-name consistency.** Two operator-surfaced gaps closed: (1) **dbStore now hashes keys + seals body/headers by default.** Operator-supplied idempotency keys sometimes carry PII (order numbers, emails, vendor prefixes); the `k` column previously stored them raw, leaving every DB dump as a PII surface. v0.9.15 sha3-512 namespace-hashes the key via `b.crypto.namespaceHash("idempotency-key", key)` before insert/lookup — round-trips are transparent (operators still pass raw keys), but the DB never sees the original. The schema also splits the previous single-`v` JSON-envelope column into discrete `fingerprint` / `status_code` / `headers` / `body` / `expires_at` columns; `headers` + `body` are sealed via `b.cryptoField.sealRow` (vault-managed AEAD envelope) when vault is initialized, so a DB dump leaks neither cached response bodies nor headers. Non-sealed columns (`status_code`, `fingerprint`, `expires_at`) stay forensic-queryable. Both defaults are operator-opt-out via `opts.hashKeys: false` and `opts.seal: false`; the seal path silently falls back to plaintext + emits an `idempotency.seal_skipped_no_vault` audit warning on first use when vault isn't ready, so test fixtures and boot scripts still work. **Schema migration**: v0.9.15's split columns are incompatible with v0.9.14's single-`v` column — operators with a v0.9.14 idempotency table `DROP TABLE <tableName>;` (or pick a fresh `tableName`) before upgrading. Pre-v1 framework breaks across patch versions for security correctness. (2) **New `require-binding-name` codebase-patterns detector enforces consistent `var X = require("M")` names framework-wide.** Inconsistent names (`fs` vs `nodeFs`, `crypto` vs `nodeCrypto`, `path` vs `nodePath`, `nb` vs `numericBounds`) made `grep` across the lib unreliable and let reviewers miss shadowing bugs (`var crypto = require("crypto")` collides with the framework's own `b.crypto`). The detector carries a `CANONICAL_REQUIRE_BINDINGS` map with safety-first defaults: Node built-ins get a `node<X>` prefix (`nodeFs` / `nodePath` / `nodeCrypto` / `nodeStream` / `nodeTls` / `nodeUrl`) so a local var named `fs` / `path` / `crypto` can never shadow them; the framework's own `lib/crypto.js` binds as `bCrypto` (matches the `b.crypto` public-namespace shape and doesn't shadow node:crypto). Modules without a declared canonical fall back to majority-wins (most-sites name wins, alphabetical tiebreak). Fix is rename, not allowlist — every minority site was updated. **Sweep**: 184 require-binding renames across 108 framework files in this release; primitives + tests unchanged in surface. (3) **`b.graphqlFederation` internal `_timingSafeEqual` now routes through `b.crypto.timingSafeEqual`** (was re-implementing the length-tolerant wrapper inline; the new require-binding-name detector surfaced this; same-patch fix per the audit-existing-code rule).
12
13
  - v0.9.14 (2026-05-13) — **Audit-existing-code sweep: `safeSql.quoteIdentifier` adopted across every framework primitive that interpolates SQL identifiers; new `raw-sql-identifier-interpolation` detector seals the bug class.** Codex P1 on PR #44 flagged that `dbStore.get`'s expired-row cleanup was an unconditional `DELETE WHERE k = ?` between SELECT and DELETE — in a multi-process deployment another process could upsert the same key in the race window, and the unconditional delete would erase the fresh row. Fix: scope the delete by the observed `expires_at`. While reviewing, a wider gap surfaced — every `db.prepare("CREATE TABLE " + tableName + ...)` site in the framework had been concatenating identifiers raw, sometimes with inline shape-regex validation that varied per module. The framework already shipped `b.safeSql.quoteIdentifier(name, dialect?)` for exactly this; per the audit-existing-code rule the same patch (a) routes every site through the helper (`lib/audit.js` segregation-of-duties trigger DDL, `lib/dsr.js` ticket store, `lib/inbox.js` message-receive table, `lib/middleware/idempotency-key.js` dbStore, `lib/vault/rotate.js` column-rotation DDL) and (b) adds a `raw-sql-identifier-interpolation` codebase-patterns detector so the bug class can't return. The detector skips variables whose names signal already-quoted identifiers (`q<X>` / `Q_<X>` / `quoted<X>` prefix), so future primitives that use the helper read naturally. **Plus: bounded JSON parse for two file-/DB-backed primitives.** `b.metrics.snapshot.read` and `b.middleware.idempotencyKey.dbStore.get` previously used bare `JSON.parse` with `allow:bare-json-parse` markers; both are read by processes separate from where they were written (CLI/sidecar reads daemon-written snapshot; multi-process fleet shares DB) where a hostile or misbehaving writer could plant a multi-GB value and OOM the reader. Both now route through `b.safeJson.parse(raw, { maxBytes: 4 MiB })`. **Three new primitives — `b.crypto.hashFilesParallel`, `b.pqcAgent.reload`, `b.middleware.idempotencyKey.dbStore` — plus republish of v0.9.13's surface**. v0.9.13's npm-publish workflow failed at the wiki-e2e gate (the Codex P1 fix removed the `opts` parameter from `b.selfUpdate.standaloneVerifier.verify` but the `@signature` JSDoc still declared four arguments — three vs. four arity drift). The v0.9.13 git tag + GH release reached operators but the npm tarball did not; the registry stayed at v0.9.12. v0.9.14 carries v0.9.13's entire shipped surface (circuitBreaker.create({...}) opts-object fix + `b.selfUpdate.standaloneVerifier` + `b.metrics.snapshot` + `b.retry.withBreaker`) plus three additional Tier 2 primitives surfaced by the same downstream consumer that flagged the v0.9.13 batch. (1) **`b.crypto.hashFilesParallel(filePaths, opts?)`** — parallel multi-digest hashing for many files in a single read pass per file. Worker-pool concurrency cap (default `min(8, paths.length)`, 1..256), operator-tunable `algorithms` list (default `["sha256", "sha3-512"]`), optional `onProgress(completed, total)` callback (throws swallowed). Returns rows in the same order as input. The common consumer-side reason to reach for this is SBOM regeneration / vendor-data integrity sweeps / release-asset bundling — situations where N files each need both SHA-256 (legacy compat) and SHA-3-512 (PQC-first) digests and rolling a worker pool by hand has cost a downstream consumer the same two-loop, capture-N-promises, settle-Q boilerplate every release. (2) **`b.pqcAgent.reload()`** — tear down the lazily-built default agent and reset to null so the next `b.pqcAgent.agent` access rebuilds against current TLS posture + `b.network.tls.applyToContext` output. Long-running daemons that rotate the framework's TLS posture (TLS-pinset reload, certificate-pinset refresh, `C.TLS_GROUP_PREFERENCE` update behind a feature flag) need a way to re-source the outbound `https.Agent` without forking a new process. `reload()` calls `.destroy()` on the existing default agent (Node closes idle keep-alive sockets, lets in-flight sockets complete) then nulls the cache. Agents handed out via explicit `b.pqcAgent.create()` are unaffected. Returns `{ destroyed: boolean }`. (3) **`b.middleware.idempotencyKey.dbStore({ db, tableName?, init? })`** — persistent-backed store for the `idempotencyKey` middleware. Same three-method interface as `memoryStore` (`get` / `set` / `delete`) but stores records in any sqlite-shaped database (`{ prepare(sql) → { run, get, all } }`) — the framework's internal `b.db`, an operator-supplied better-sqlite3 instance, or a custom adapter. Use this instead of `memoryStore` when (a) multiple processes share the request-handling fleet so retries can land on a different process than the original, (b) the daemon may restart between the original request and the retry (graceful rolling deploy, OOM kill), or (c) audit / compliance review needs to walk historic idempotency-cache decisions queryable via `SELECT * FROM <tableName>`. TTL is lazily enforced at read time; `set()` upserts on conflict so concurrent retries on different processes don't error. The `tableName` is validated via `b.safeSql.validateIdentifier` (ASCII identifier shape, 63-char cap, no reserved words). (4) **Internal fix**: `b.apiSnapshot.read` now passes `maxBytes: 64 MiB` to `safeJson.parse` — the framework-generated snapshot file outgrew safeJson's 1 MiB default after v0.9.13. Operators consuming `@blamejs/core` via npm jump from v0.9.12 directly to v0.9.14; v0.9.13's content is included.
13
14
  - v0.9.13 (2026-05-13) — **Two `b.circuitBreaker.create` / `b.retry` bug fixes plus three new operator-facing primitives: `b.selfUpdate.standaloneVerifier`, `b.metrics.snapshot`, `b.retry.withBreaker`**. (1) `b.circuitBreaker.create({...})` was rejecting the documented opts-object call shape with `name must be a non-empty string, got object` — every consumer following the docstring hit a hard error. The factory now reads `opts.name` (defaulting to empty string) and forwards to the internal `CircuitBreaker(name, opts)` constructor. (2) The breaker's open-circuit error code was documented as `retry/circuit-open` but the runtime threw `CIRCUIT_OPEN`. The docstring is corrected to match the runtime; an alias rename will follow with a deprecation cycle in a future minor. (3) **`b.selfUpdate.standaloneVerifier`** — zero-dep verifier for install-pipeline contexts that run BEFORE the framework is installed (Dockerfile build stages, `install.sh`, `update.sh`, SEA-bundle verification at deploy time). Surface: `verify(assetPath, sigPath, pubkeyPem, opts?)` returns `{ ok, sha3_512, sha256, alg }`. Streams the asset in 64 KiB chunks through SHA-256 + SHA-3-512 + the signature verifier in parallel — multi-GB SEA bundles don't OOM the install runner. Supports ECDSA P-384 (both IEEE-P1363 96-byte and DER encodings), Ed25519, and ML-DSA-87. Detects signature format from length so `verifier.verify(...)` runs exactly once (calling it twice returns stale state and silently passes tampered assets). Module is hermetic: `node:crypto` + `node:fs` only, no framework imports. Operators copy the file via `cp "$(node -p "require('@blamejs/core').selfUpdate.standaloneVerifier.path")" install/standalone-verifier.js` into version control on their side. (4) **`b.metrics.snapshot`** — out-of-process metrics export for long-running daemons. `startWriter({ path, intervalMs, fields })` atomically flushes a JSON snapshot (first flush synchronous so the file exists by return-time; subsequent flushes on the interval with `.unref()`; `stop()` clears + final-flushes). `read(path)` parses with shape validation (writtenAt + fields). `render(snap, { format, prefix })` produces operator-readable text or Prometheus 0.0.4 exposition (gauge metrics, prefixed; only finite numeric scalars with prom-compatible names emit; invalid-name / non-numeric / non-finite fields skipped silently). Lets a CLI process scrape a daemon's live metrics without opening an HTTP port. (5) **`b.retry.withBreaker(fn, { retry, breaker })`** — composition primitive collapsing the two-line wrapper every consumer rolls: `breaker.wrap(() => retry.withRetry(fn, opts.retry))`. One breaker call per retry loop (the retry budget is INSIDE the breaker's accounting, so a single transient burst doesn't open the breaker spuriously). Throws on non-function `fn` or breaker without `.wrap`.
package/lib/a2a-tasks.js CHANGED
@@ -92,14 +92,14 @@ function _emitAudit(action, metadata, outcome) {
92
92
  } catch (_e) { /* best-effort */ }
93
93
  }
94
94
 
95
- var crypto = lazyRequire(function () { return require("./crypto"); });
95
+ var bCrypto = lazyRequire(function () { return require("./crypto"); });
96
96
 
97
97
  // _newTaskId is reserved for the operator-handler path that mints
98
98
  // peer-assigned task IDs server-side. The underscore prefix already
99
99
  // satisfies the framework's unused-var policy so the helper stays
100
100
  // available without an explicit disable directive.
101
101
  function _newTaskId() {
102
- return crypto().generateToken(12); // allow:raw-byte-literal — 96-bit task id, not byte arithmetic on payload
102
+ return bCrypto().generateToken(12); // allow:raw-byte-literal — 96-bit task id, not byte arithmetic on payload
103
103
  }
104
104
 
105
105
  function _validateTaskShape(task, where) {
@@ -36,7 +36,7 @@ var C = require("../constants");
36
36
  var { AuthError } = require("../framework-error");
37
37
 
38
38
  var audit = lazyRequire(function () { return require("../audit"); });
39
- var fwCrypto = lazyRequire(function () { return require("../crypto"); });
39
+ var bCrypto = lazyRequire(function () { return require("../crypto"); });
40
40
 
41
41
  var DEFAULT_TTL_SEC = C.TIME.minutes(15) / C.TIME.seconds(1);
42
42
  var MAX_TTL_SEC = C.TIME.hours(1) / C.TIME.seconds(1);
@@ -82,7 +82,7 @@ function _macFor(payloadB64) {
82
82
 
83
83
  function _timingSafeEqualBuf(a, b) {
84
84
  if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) return false;
85
- return fwCrypto().timingSafeEqual(a, b);
85
+ return bCrypto().timingSafeEqual(a, b);
86
86
  }
87
87
 
88
88
  function create(opts) {
@@ -128,7 +128,7 @@ function create(opts) {
128
128
  }
129
129
  var nowSec = (typeof opts.now === "number" && isFinite(opts.now))
130
130
  ? opts.now : Math.floor(Date.now() / C.TIME.seconds(1));
131
- var jti = fwCrypto().generateBytes(C.BYTES.bytes(16)).toString("base64url");
131
+ var jti = bCrypto().generateBytes(C.BYTES.bytes(16)).toString("base64url");
132
132
  var payload = {
133
133
  sub: opts.subject,
134
134
  scope: opts.scope,
@@ -47,8 +47,8 @@ var _wa = require("../vendor/simplewebauthn-server.cjs");
47
47
  var { FidoMds3Error } = require("../framework-error");
48
48
 
49
49
  var httpClient = lazyRequire(function () { return require("../http-client"); });
50
- var cacheFwk = lazyRequire(function () { return require("../cache"); });
51
- var auditFwk = lazyRequire(function () { return require("../audit"); });
50
+ var cache = lazyRequire(function () { return require("../cache"); });
51
+ var audit = lazyRequire(function () { return require("../audit"); });
52
52
 
53
53
  var DEFAULT_URL = "https://mds3.fidoalliance.org/";
54
54
  var DEFAULT_TIMEOUT_MS = C.TIME.seconds(30);
@@ -289,7 +289,7 @@ function _verifyJws(jws, leafCert) {
289
289
  var _sharedCache = null;
290
290
  function _getCache() {
291
291
  if (_sharedCache) return _sharedCache;
292
- _sharedCache = cacheFwk().create({
292
+ _sharedCache = cache().create({
293
293
  namespace: "auth-fido-mds3.blob",
294
294
  ttlMs: MAX_CACHE_TTL_MS,
295
295
  maxEntries: 8, // allow:raw-byte-literal — operator-pinned URL set
@@ -440,7 +440,7 @@ async function fetch(opts) { // allow:raw-outbound-http — function name is f
440
440
  },
441
441
  });
442
442
  } catch (e) {
443
- try { auditFwk().safeEmit({
443
+ try { audit().safeEmit({
444
444
  action: "auth.fido_mds3.fetch.network",
445
445
  outcome: "failure",
446
446
  metadata: { url: url, reason: (e && e.message) || String(e) },
@@ -482,7 +482,7 @@ async function fetch(opts) { // allow:raw-outbound-http — function name is f
482
482
  // wrap-call's safe-minimum seed).
483
483
  try { await c.set(cacheKey, record, _ttlFromNextUpdate(nextUpdate)); }
484
484
  catch (_e) { /* cache.set best-effort */ }
485
- try { auditFwk().safeEmit({
485
+ try { audit().safeEmit({
486
486
  action: "auth.fido_mds3.fetch",
487
487
  outcome: "success",
488
488
  metadata: { url: url, no: payload.no, entries: payload.entries.length,
@@ -633,7 +633,7 @@ function verifyAuthenticator(blob, registrationInfo, vopts) {
633
633
  }
634
634
  var certifiedLevel = _certifiedLevel(statusReports);
635
635
  if (refusedStatus) {
636
- try { auditFwk().safeEmit({
636
+ try { audit().safeEmit({
637
637
  action: "auth.fido_mds3.verify.refused",
638
638
  outcome: "denied",
639
639
  metadata: { aaguid: registrationInfo.aaguid, status: refusedStatus },
@@ -59,7 +59,7 @@ var { AuthError } = require("../framework-error");
59
59
 
60
60
  var httpClient = lazyRequire(function () { return require("../http-client"); });
61
61
  var cache = lazyRequire(function () { return require("../cache"); });
62
- var auditFwk = lazyRequire(function () { return require("../audit"); });
62
+ var audit = lazyRequire(function () { return require("../audit"); });
63
63
 
64
64
  // ---- constants ----
65
65
 
@@ -271,7 +271,7 @@ async function verifyExternal(token, opts) {
271
271
  // outright. Operators with JWE need a separate handler wired to
272
272
  // their KMS — never a defaulted JWE path on the JWS verifier.
273
273
  if (parts.length === 5) {
274
- try { auditFwk().safeEmit({
274
+ try { audit().safeEmit({
275
275
  action: "jwt.jwe.refused",
276
276
  outcome: "denied",
277
277
  metadata: { reason: "jwe-on-jws-verifier" },
package/lib/compliance.js CHANGED
@@ -46,11 +46,10 @@ var sanctions = require("./compliance-sanctions");
46
46
  var aiAct = require("./compliance-ai-act");
47
47
  var { ComplianceError } = require("./framework-error");
48
48
 
49
- var audit = lazyRequire(function () { return require("./audit"); });
49
+ var audit = lazyRequire(function () { return require("./audit"); });
50
50
  var retentionMod = lazyRequire(function () { return require("./retention"); });
51
- var auditFwk = lazyRequire(function () { return require("./audit"); });
52
- var dbMod = lazyRequire(function () { return require("./db"); });
53
- var cryptoFieldMod = lazyRequire(function () { return require("./crypto-field"); });
51
+ var db = lazyRequire(function () { return require("./db"); });
52
+ var cryptoField = lazyRequire(function () { return require("./crypto-field"); });
54
53
 
55
54
  // Recognised posture names. Aligns with the compliance-posture
56
55
  // vocabulary every guard / retention floor / etc. accepts. Operators
@@ -371,9 +370,9 @@ function set(posture) {
371
370
  function _applyPostureCascade(posture) {
372
371
  var steps = [
373
372
  { primitive: "retention", resolver: function () { return retentionMod(); } },
374
- { primitive: "audit", resolver: function () { return auditFwk(); } },
375
- { primitive: "db", resolver: function () { return dbMod(); } },
376
- { primitive: "cryptoField", resolver: function () { return cryptoFieldMod(); } },
373
+ { primitive: "audit", resolver: function () { return audit(); } },
374
+ { primitive: "db", resolver: function () { return db(); } },
375
+ { primitive: "cryptoField", resolver: function () { return cryptoField(); } },
377
376
  ];
378
377
  for (var i = 0; i < steps.length; i += 1) {
379
378
  var step = steps[i];
package/lib/config.js CHANGED
@@ -29,7 +29,7 @@ var lazyRequire = require("./lazy-require");
29
29
  var safeAsync = require("./safe-async");
30
30
  var { defineClass } = require("./framework-error");
31
31
 
32
- var lazyAudit = lazyRequire(function () { return require("./audit"); });
32
+ var audit = lazyRequire(function () { return require("./audit"); });
33
33
 
34
34
  var REDACT_MASK = "[REDACTED]";
35
35
 
@@ -349,7 +349,7 @@ function loadDbBacked(opts) {
349
349
  try { rows = await opts.fetchRows(); }
350
350
  catch (e) {
351
351
  try {
352
- lazyAudit().safeEmit({
352
+ audit().safeEmit({
353
353
  action: "config.reload.failed", outcome: "failure",
354
354
  metadata: { phase: "fetch", reason: e && e.message },
355
355
  });
@@ -367,7 +367,7 @@ function loadDbBacked(opts) {
367
367
  value = await transformValue(row);
368
368
  } catch (e) {
369
369
  try {
370
- lazyAudit().safeEmit({
370
+ audit().safeEmit({
371
371
  action: "config.reload.failed", outcome: "failure",
372
372
  metadata: { phase: "transform", key: row.key, reason: e && e.message },
373
373
  });
@@ -376,7 +376,7 @@ function loadDbBacked(opts) {
376
376
  }
377
377
  if (typeof value !== "string") {
378
378
  try {
379
- lazyAudit().safeEmit({
379
+ audit().safeEmit({
380
380
  action: "config.reload.failed", outcome: "failure",
381
381
  metadata: { phase: "transform", key: row.key, reason: "transformValue did not return a string" },
382
382
  });
@@ -390,7 +390,7 @@ function loadDbBacked(opts) {
390
390
  // applied its newer fetch — my overlay would clobber fresher data.
391
391
  if (mySeq <= ticksAppliedMax) {
392
392
  try {
393
- lazyAudit().safeEmit({
393
+ audit().safeEmit({
394
394
  action: "config.reload.skipped", outcome: "success",
395
395
  metadata: { phase: "stale-tick", mySeq: mySeq, appliedMax: ticksAppliedMax },
396
396
  });
@@ -408,7 +408,7 @@ function loadDbBacked(opts) {
408
408
  }
409
409
  catch (e) {
410
410
  try {
411
- lazyAudit().safeEmit({
411
+ audit().safeEmit({
412
412
  action: "config.reload.failed", outcome: "failure",
413
413
  metadata: { phase: "validate", reason: e && e.message },
414
414
  });
@@ -79,7 +79,7 @@ function _shake256(secret, length) {
79
79
 
80
80
  // auth/password is required lazily because it imports the (large)
81
81
  // argon2 vendor; loading it for SHA3-only callers is wasted work.
82
- var passwordPrimitive = lazyRequire(function () { return require("./auth/password"); });
82
+ var passwordModule = lazyRequire(function () { return require("./auth/password"); });
83
83
 
84
84
  class CredentialHashError extends FrameworkError {
85
85
  constructor(message, code) {
@@ -219,7 +219,7 @@ async function hash(secret, opts) {
219
219
  }
220
220
  if (algoId === C.CRED_HASH_IDS.ARGON2ID) {
221
221
  var plain = Buffer.isBuffer(secret) ? secret.toString("utf8") : secret;
222
- var phc = await passwordPrimitive().hash(plain, opts && opts.params);
222
+ var phc = await passwordModule().hash(plain, opts && opts.params);
223
223
  var argonEnv = _envelope(algoId, Buffer.from(phc, "utf8"));
224
224
  _emitEvent("credentialHash.hash", 1, { algo: algoName });
225
225
  return argonEnv;
@@ -300,7 +300,7 @@ async function verify(secret, envelope) {
300
300
  var phc = decoded.payload.toString("utf8");
301
301
  var plain = Buffer.isBuffer(secret) ? secret.toString("utf8") : secret;
302
302
  var argOk = false;
303
- try { argOk = await passwordPrimitive().verify(phc, plain); }
303
+ try { argOk = await passwordModule().verify(phc, plain); }
304
304
  catch (_e) { argOk = false; }
305
305
  _emitEvent("credentialHash.verify", 1,
306
306
  { outcome: argOk ? "success" : "failure", algo: algoName });
@@ -377,7 +377,7 @@ function needsRehash(envelope, opts) {
377
377
  // Defer the parameter-lag check to the password primitive's
378
378
  // own needsRehash so the threshold stays in one place.
379
379
  var phc = decoded.payload.toString("utf8");
380
- try { return passwordPrimitive().needsRehash(phc, opts && opts.params); }
380
+ try { return passwordModule().needsRehash(phc, opts && opts.params); }
381
381
  catch (_e) { return true; }
382
382
  }
383
383
  return false;
@@ -47,9 +47,9 @@ var vault = require("./vault");
47
47
  var { sha3Hash, kdf } = require("./crypto");
48
48
  var { HASH_PREFIX, VAULT_PREFIX, TIME } = require("./constants");
49
49
 
50
- var complianceMod = lazyRequire(function () { return require("./compliance"); });
51
- var dbMod = lazyRequire(function () { return require("./db"); });
52
- var auditMod = lazyRequire(function () { return require("./audit"); });
50
+ var compliance = lazyRequire(function () { return require("./compliance"); });
51
+ var db = lazyRequire(function () { return require("./db"); });
52
+ var audit = lazyRequire(function () { return require("./audit"); });
53
53
 
54
54
  // F-POSTURE-1 cascade hook + F-RTBF-2 integration. Recording the
55
55
  // posture lets eraseRow call b.db.vacuumAfterErase({ mode: "full" })
@@ -88,7 +88,7 @@ function applyPosture(posture) {
88
88
  _activePosture = posture;
89
89
  var requireVacuum = false;
90
90
  try {
91
- requireVacuum = complianceMod().postureDefault(posture, "requireVacuumAfterErase") === true;
91
+ requireVacuum = compliance().postureDefault(posture, "requireVacuumAfterErase") === true;
92
92
  } catch (_e) { /* compliance not loaded — record posture only */ }
93
93
  return { posture: posture, requireVacuumAfterErase: requireVacuum };
94
94
  }
@@ -495,14 +495,14 @@ function eraseRow(table, row) {
495
495
  if (_activePosture) {
496
496
  var requireVacuum = false;
497
497
  try {
498
- requireVacuum = complianceMod().postureDefault(
498
+ requireVacuum = compliance().postureDefault(
499
499
  _activePosture, "requireVacuumAfterErase") === true;
500
500
  } catch (_e) { /* compliance lookup best-effort */ }
501
501
  if (requireVacuum) {
502
502
  try {
503
- var db = dbMod();
504
- if (db && typeof db.vacuumAfterErase === "function") {
505
- db.vacuumAfterErase({ mode: "full" });
503
+ var dbInst = db();
504
+ if (dbInst && typeof dbInst.vacuumAfterErase === "function") {
505
+ dbInst.vacuumAfterErase({ mode: "full" });
506
506
  }
507
507
  } catch (_vacErr) {
508
508
  // VACUUM is best-effort at the eraseRow seam — DB might not be
@@ -510,7 +510,7 @@ function eraseRow(table, row) {
510
510
  // captures the skip; operators on regulated postures wire the
511
511
  // sweep through b.retention which gates erasure on db.init().
512
512
  try {
513
- auditMod().safeEmit({
513
+ audit().safeEmit({
514
514
  action: "cryptofield.vacuum.skipped",
515
515
  outcome: "failure",
516
516
  metadata: {
package/lib/db.js CHANGED
@@ -1479,7 +1479,7 @@ function stream(sql) {
1479
1479
  this.destroy(new DbError("db/stream-limit-exceeded",
1480
1480
  "db.stream: emitted " + emitted + " rows, exceeding streamLimit " +
1481
1481
  perCallLimit + ". Pass opts.streamLimit higher OR raise via " +
1482
- "db.init({ streamLimit }) after auditing the export nodePath."));
1482
+ "db.init({ streamLimit }) after auditing the export path."));
1483
1483
  return;
1484
1484
  }
1485
1485
  var step = iter.next();
@@ -64,7 +64,7 @@ var ExternalDbMigrateError = defineClass("ExternalDbMigrateError", { alwaysPerma
64
64
 
65
65
  // Lazy require — external-db imports back into this module via its
66
66
  // public `migrate` namespace; load-order would cycle without lazy.
67
- var externalDbModule = lazyRequire(function () { return require("./external-db"); });
67
+ var externalDb = lazyRequire(function () { return require("./external-db"); });
68
68
 
69
69
  var TRACKING_TABLE = "_blamejs_externaldb_migrations";
70
70
  var LOCK_TABLE = "_blamejs_externaldb_migrations_lock";
@@ -327,7 +327,7 @@ function _resolveBackendName(opts) {
327
327
  }
328
328
  // Default to the externalDb's defaultBackend; throw clear if not initialized.
329
329
  var listed;
330
- try { listed = externalDbModule().listBackends(); }
330
+ try { listed = externalDb().listBackends(); }
331
331
  catch (_e) {
332
332
  throw _err("externaldb-migrate/not-initialized",
333
333
  "externalDb is not initialized — call b.externalDb.init({ backends }) first");
@@ -363,14 +363,14 @@ function create(opts) {
363
363
 
364
364
  function _ctx(backendName) {
365
365
  return {
366
- externalDb: externalDbModule(),
366
+ externalDb: externalDb(),
367
367
  backendName: backendName,
368
368
  };
369
369
  }
370
370
 
371
371
  async function status() {
372
372
  var backendName = _resolveBackendName(opts);
373
- return await externalDbModule().transaction(async function (xdb) {
373
+ return await externalDb().transaction(async function (xdb) {
374
374
  await _ensureTrackingTable(xdb);
375
375
  var res = await xdb.query(
376
376
  "SELECT name, description, appliedAt FROM " + Q_TRACKING +
@@ -394,7 +394,7 @@ function create(opts) {
394
394
  var backendName = _resolveBackendName(opts);
395
395
  var ctx = _ctx(backendName);
396
396
 
397
- return await externalDbModule().transaction(async function (xdb) {
397
+ return await externalDb().transaction(async function (xdb) {
398
398
  await _ensureTrackingTable(xdb);
399
399
  await _ensureLockTable(xdb);
400
400
  await _ensureHistoryTable(xdb);
@@ -404,7 +404,7 @@ function create(opts) {
404
404
  // pool acquisition for the lock connection — the migrate runner
405
405
  // serializes apply order, so this single-connection lock is
406
406
  // sufficient.
407
- var lockResult = await externalDbModule().transaction(async function (xdb) {
407
+ var lockResult = await externalDb().transaction(async function (xdb) {
408
408
  return await _acquireLock(xdb, opts);
409
409
  }, { backend: backendName });
410
410
  var lockHolder = lockResult.holder;
@@ -421,7 +421,7 @@ function create(opts) {
421
421
  }
422
422
 
423
423
  try {
424
- var appliedRes = await externalDbModule().query(
424
+ var appliedRes = await externalDb().query(
425
425
  "SELECT name FROM " + Q_TRACKING, [], { backend: backendName }
426
426
  );
427
427
  var appliedSet = new Set(((appliedRes && appliedRes.rows) || []).map(function (r) { return r.name; }));
@@ -435,7 +435,7 @@ function create(opts) {
435
435
  var mod = _loadMigration(file, dir);
436
436
  var t0 = Date.now();
437
437
  try {
438
- await externalDbModule().transaction(async function (xdb) {
438
+ await externalDb().transaction(async function (xdb) {
439
439
  await mod.up(xdb, ctx);
440
440
  var ranAt = new Date().toISOString();
441
441
  await xdb.query(
@@ -489,7 +489,7 @@ function create(opts) {
489
489
  return { applied: applied, skipped: skipped, backend: backendName };
490
490
  } finally {
491
491
  try {
492
- await externalDbModule().transaction(async function (xdb) {
492
+ await externalDb().transaction(async function (xdb) {
493
493
  await _releaseLock(xdb, lockHolder);
494
494
  }, { backend: backendName });
495
495
  _emit(audit, "externaldb.migrate.lock.released", "success",
@@ -509,12 +509,12 @@ function create(opts) {
509
509
  var backendName = _resolveBackendName(opts);
510
510
  var ctx = _ctx(backendName);
511
511
 
512
- await externalDbModule().transaction(async function (xdb) {
512
+ await externalDb().transaction(async function (xdb) {
513
513
  await _ensureTrackingTable(xdb);
514
514
  await _ensureLockTable(xdb);
515
515
  }, { backend: backendName });
516
516
 
517
- var lockResultDown = await externalDbModule().transaction(async function (xdb) {
517
+ var lockResultDown = await externalDb().transaction(async function (xdb) {
518
518
  return await _acquireLock(xdb, opts);
519
519
  }, { backend: backendName });
520
520
  var lockHolder = lockResultDown.holder;
@@ -528,7 +528,7 @@ function create(opts) {
528
528
  }
529
529
 
530
530
  try {
531
- var appliedRes = await externalDbModule().query(
531
+ var appliedRes = await externalDb().query(
532
532
  "SELECT name FROM " + Q_TRACKING + " ORDER BY appliedAt DESC, name DESC LIMIT $1",
533
533
  [steps], { backend: backendName }
534
534
  );
@@ -543,7 +543,7 @@ function create(opts) {
543
543
  }
544
544
  var t0 = Date.now();
545
545
  try {
546
- await externalDbModule().transaction(async function (xdb) {
546
+ await externalDb().transaction(async function (xdb) {
547
547
  await mod.down(xdb, ctx);
548
548
  await xdb.query(
549
549
  "DELETE FROM " + Q_TRACKING + " WHERE name = $1",
@@ -564,7 +564,7 @@ function create(opts) {
564
564
  return { reverted: reverted, backend: backendName };
565
565
  } finally {
566
566
  try {
567
- await externalDbModule().transaction(async function (xdb) {
567
+ await externalDb().transaction(async function (xdb) {
568
568
  await _releaseLock(xdb, lockHolder);
569
569
  }, { backend: backendName });
570
570
  _emit(audit, "externaldb.migrate.lock.released", "success",
@@ -588,7 +588,7 @@ function create(opts) {
588
588
  async function history(historyOpts) {
589
589
  historyOpts = historyOpts || {};
590
590
  var backendName = _resolveBackendName(opts);
591
- return await externalDbModule().transaction(async function (xdb) {
591
+ return await externalDb().transaction(async function (xdb) {
592
592
  await _ensureHistoryTable(xdb);
593
593
  var res = await xdb.query(
594
594
  "SELECT version, ranAt, ranBy, schemaIntrospectionHash, signature, publicKeyFingerprint " +
@@ -22,7 +22,7 @@ var lazyRequire = require("./lazy-require");
22
22
  var { defineClass } = require("./framework-error");
23
23
  var FlagError = defineClass("FlagError", { alwaysPermanent: true });
24
24
 
25
- var fwCrypto = lazyRequire(function () { return require("./crypto"); });
25
+ var bCrypto = lazyRequire(function () { return require("./crypto"); });
26
26
 
27
27
  function _normalize(input, label) {
28
28
  if (input == null) return {};
@@ -96,7 +96,7 @@ function fromRequest(req, opts) {
96
96
  headers["x-forwarded-for"].split(",")[0].trim()) ||
97
97
  (req.connection && req.connection.remoteAddress) || "";
98
98
  var ua = headers["user-agent"] || "";
99
- tk = "anon:" + fwCrypto().sha3Hash(ip + ":" + ua).slice(0, 16); // allow:raw-byte-literal — base16 prefix len
99
+ tk = "anon:" + bCrypto().sha3Hash(ip + ":" + ua).slice(0, 16); // allow:raw-byte-literal — base16 prefix len
100
100
  }
101
101
  ctx.targetingKey = tk;
102
102
 
package/lib/keychain.js CHANGED
@@ -161,7 +161,7 @@ function _validateFallbackFile(filepath, primitive) {
161
161
  KeychainError, "keychain/bad-fallback-file");
162
162
  if (!nodePath.isAbsolute(filepath)) {
163
163
  throw new KeychainError("keychain/relative-fallback-file",
164
- primitive + ": fallbackFile must be an absolute nodePath; got " + filepath);
164
+ primitive + ": fallbackFile must be an absolute path; got " + filepath);
165
165
  }
166
166
  }
167
167
 
@@ -613,7 +613,7 @@ function _isFallbackError(e) {
613
613
  * service: string, // required, no NUL/CR/LF bytes
614
614
  * account: string, // required, no NUL/CR/LF bytes
615
615
  * password: string, // required, non-empty
616
- * fallbackFile?: string, // absolute nodePath; required if file fallback may engage
616
+ * fallbackFile?: string, // absolute path; required if file fallback may engage
617
617
  * passphrase?: string, // required when fallbackFile engages (Argon2id-derived KEK)
618
618
  * preferFile?: boolean, // default: false
619
619
  * audit?: boolean, // default: true (emits keychain.stored)
@@ -685,7 +685,7 @@ async function store(opts) {
685
685
  * {
686
686
  * service: string, // required
687
687
  * account: string, // required
688
- * fallbackFile?: string, // absolute nodePath; required for file-backend lookup
688
+ * fallbackFile?: string, // absolute path; required for file-backend lookup
689
689
  * passphrase?: string, // required when fallbackFile engages
690
690
  * preferFile?: boolean, // default: false
691
691
  * audit?: boolean, // default: true (emits keychain.retrieved)
@@ -781,7 +781,7 @@ async function retrieve(opts) {
781
781
  * {
782
782
  * service: string, // required
783
783
  * account: string, // required
784
- * fallbackFile?: string, // absolute nodePath; required for file-backend cleanup
784
+ * fallbackFile?: string, // absolute path; required for file-backend cleanup
785
785
  * passphrase?: string, // required when fallbackFile engages
786
786
  * preferFile?: boolean, // default: false
787
787
  * audit?: boolean, // default: true (emits keychain.removed)
package/lib/log.js CHANGED
@@ -72,7 +72,7 @@ var { FrameworkError } = require("./framework-error");
72
72
  // pulling the whole crypto bundle into the framework's earliest
73
73
  // boot path (request-id middleware needs only generateToken).
74
74
  var safeEnv = lazyRequire(function () { return require("./parsers/safe-env"); });
75
- var crypto = lazyRequire(function () { return require("./crypto"); });
75
+ var bCrypto = lazyRequire(function () { return require("./crypto"); });
76
76
 
77
77
  // Request-id correlation token — 8 bytes hex-encoded (16 chars). Short
78
78
  // enough to read in a log line, long enough to keep collisions far below
@@ -384,7 +384,7 @@ function create(opts) {
384
384
  // 16 random hex chars — short, sufficient correlation entropy.
385
385
  // Routes through the framework token primitive so the entropy
386
386
  // source matches the rest of the codebase.
387
- return crypto().generateToken(REQUEST_ID_BYTES);
387
+ return bCrypto().generateToken(REQUEST_ID_BYTES);
388
388
  };
389
389
  return function logRequestIdMiddleware(req, res, next) {
390
390
  var inbound = req.headers && req.headers[headerName];
package/lib/mail.js CHANGED
@@ -72,7 +72,7 @@ var net = lazyRequire(function () { return require("net"); });
72
72
  var networkDns = lazyRequire(function () { return require("./network-dns"); });
73
73
  var nodeUrl = require("url");
74
74
  var numericBounds = require("./numeric-bounds");
75
- var tls = lazyRequire(function () { return require("tls"); });
75
+ var nodeTls = lazyRequire(function () { return require("tls"); });
76
76
  var safeJson = require("./safe-json");
77
77
  var safeSchema = require("./safe-schema");
78
78
  var validateOpts = require("./validate-opts");
@@ -1142,7 +1142,7 @@ function _smtpSend(message, cfg) {
1142
1142
  tlsConnectOpts.host = cfg.host;
1143
1143
  tlsConnectOpts.port = cfg.port;
1144
1144
  if (family === 4 || family === 6) tlsConnectOpts.family = family;
1145
- attachSocket(tls().connect(tlsConnectOpts));
1145
+ attachSocket(nodeTls().connect(tlsConnectOpts));
1146
1146
  } else {
1147
1147
  var netOpts = { host: cfg.host, port: cfg.port };
1148
1148
  if (family === 4 || family === 6) netOpts.family = family;
@@ -1211,7 +1211,7 @@ function _smtpSend(message, cfg) {
1211
1211
  if (code !== 220) { fail("starttls-rejected (code " + code + ")"); return; }
1212
1212
  var tlsConnectOpts = Object.assign({ socket: socket }, cfg.tlsOpts);
1213
1213
  if (cfg.servername) tlsConnectOpts.servername = cfg.servername;
1214
- var tlsSocket = tls().connect(tlsConnectOpts, function () {
1214
+ var tlsSocket = nodeTls().connect(tlsConnectOpts, function () {
1215
1215
  upgradedToTLS = true;
1216
1216
  try { socket.removeAllListeners("data"); } catch (_e) { /* listeners migrate to upgraded socket */ }
1217
1217
  attachSocket(tlsSocket);
@@ -64,7 +64,7 @@ var lazyRequire = require("./lazy-require");
64
64
  var validateOpts = require("./validate-opts");
65
65
  var { McpError } = require("./framework-error");
66
66
 
67
- var crypto = lazyRequire(function () { return require("./crypto"); });
67
+ var bCrypto = lazyRequire(function () { return require("./crypto"); });
68
68
  var audit = lazyRequire(function () { return require("./audit"); });
69
69
  var C = require("./constants");
70
70
 
@@ -202,7 +202,7 @@ function create(opts) {
202
202
  outputSchema: tool.outputSchema || null,
203
203
  alg: alg,
204
204
  });
205
- var sig = crypto().sign(Buffer.from(payload, "utf8"), signingKey);
205
+ var sig = bCrypto().sign(Buffer.from(payload, "utf8"), signingKey);
206
206
  return {
207
207
  tool: tool.name,
208
208
  description: tool.description || "",
@@ -254,7 +254,7 @@ function create(opts) {
254
254
  }),
255
255
  issuedAt: new Date().toISOString(),
256
256
  });
257
- var sig = crypto().sign(Buffer.from(manifestBody, "utf8"), signingKey);
257
+ var sig = bCrypto().sign(Buffer.from(manifestBody, "utf8"), signingKey);
258
258
  return {
259
259
  body: manifestBody,
260
260
  signature: sig.toString("base64"),
@@ -309,7 +309,7 @@ function create(opts) {
309
309
  }
310
310
  var nonce = typeof callOpts.nonce === "string" && callOpts.nonce.length > 0
311
311
  ? callOpts.nonce
312
- : crypto().generateToken(16); // allow:raw-byte-literal — 128-bit nonce, not byte arithmetic on a payload
312
+ : bCrypto().generateToken(16); // allow:raw-byte-literal — 128-bit nonce, not byte arithmetic on a payload
313
313
  var iat = new Date();
314
314
  var exp = new Date(iat.getTime() + ttlMs);
315
315
  var envelope = {
@@ -320,7 +320,7 @@ function create(opts) {
320
320
  exp: exp.toISOString(),
321
321
  };
322
322
  var payload = Buffer.from(canonicalJson.stringify(envelope), "utf8");
323
- var sig = crypto().sign(payload, signingKey);
323
+ var sig = bCrypto().sign(payload, signingKey);
324
324
  _emitAudit("mcp.tool_registry.call_signed",
325
325
  { tool: envelope.tool, nonce: nonce, alg: alg });
326
326
  return {
@@ -438,7 +438,7 @@ function create(opts) {
438
438
  "verifyCall: signature not valid base64");
439
439
  }
440
440
  var ok;
441
- try { ok = crypto().verify(payload, sigBuf, verifyingKey); }
441
+ try { ok = bCrypto().verify(payload, sigBuf, verifyingKey); }
442
442
  catch (verifyErr) {
443
443
  _emitAudit("mcp.tool_registry.call_verify_error",
444
444
  { tool: env.tool, nonce: env.nonce, error: String(verifyErr.message || verifyErr) }, "denied");
@@ -123,7 +123,7 @@ var validateOpts = require("../validate-opts");
123
123
  var C = require("../constants");
124
124
  var { defineClass } = require("../framework-error");
125
125
 
126
- var auditFwk = lazyRequire(function () { return require("../audit"); });
126
+ var audit = lazyRequire(function () { return require("../audit"); });
127
127
 
128
128
  // Node's HTTP parser surfaces malformed chunked-transfer-encoding via a
129
129
  // stable family of HPE_* codes. RFC 9112 §7.1 — when a server rejects a
@@ -1294,7 +1294,7 @@ function create(opts) {
1294
1294
  ? "http.chunked.extension.refused"
1295
1295
  : "http.chunked.malformed.refused";
1296
1296
  try {
1297
- auditFwk().safeEmit({
1297
+ audit().safeEmit({
1298
1298
  action: chunkAction,
1299
1299
  outcome: "denied",
1300
1300
  metadata: {
@@ -52,7 +52,7 @@ var defineClass = require("../framework-error").defineClass;
52
52
  var lazyRequire = require("../lazy-require");
53
53
  var validateOpts = require("../validate-opts");
54
54
 
55
- var crypto = lazyRequire(function () { return require("../crypto"); });
55
+ var bCrypto = lazyRequire(function () { return require("../crypto"); });
56
56
  var audit = lazyRequire(function () { return require("../audit"); });
57
57
 
58
58
  var RequireBoundKeyError = defineClass("RequireBoundKeyError", { alwaysPermanent: true });
@@ -67,7 +67,7 @@ function _parseBearer(req) {
67
67
  function _timingSafeStringEqual(a, b) {
68
68
  if (typeof a !== "string" || typeof b !== "string") return false;
69
69
  if (a.length !== b.length) return false;
70
- return crypto().timingSafeEqual(Buffer.from(a), Buffer.from(b));
70
+ return bCrypto().timingSafeEqual(Buffer.from(a), Buffer.from(b));
71
71
  }
72
72
 
73
73
  /**
@@ -243,7 +243,7 @@ function create(opts) {
243
243
  var fpColon = req.peerFingerprint && req.peerFingerprint.colon;
244
244
  if (!fpHex && req.peerCert && req.peerCert.raw) {
245
245
  try {
246
- var fp = crypto().hashCertFingerprint(req.peerCert.raw);
246
+ var fp = bCrypto().hashCertFingerprint(req.peerCert.raw);
247
247
  fpHex = fp.hex; fpColon = fp.colon;
248
248
  } catch (_e) { /* fall through to refused below */ }
249
249
  }
@@ -256,7 +256,7 @@ function create(opts) {
256
256
  keyId: record.id || null,
257
257
  });
258
258
  }
259
- } else if (!crypto().isCertRevoked(req.peerCert.raw, pinned)) {
259
+ } else if (!bCrypto().isCertRevoked(req.peerCert.raw, pinned)) {
260
260
  // isCertRevoked returns true on MATCH against the deny-list
261
261
  // shape; we use it here as a fingerprint-set membership test
262
262
  // because it does the same constant-time hex/colon comparison
@@ -49,7 +49,7 @@ var defineClass = require("../framework-error").defineClass;
49
49
  var lazyRequire = require("../lazy-require");
50
50
  var validateOpts = require("../validate-opts");
51
51
 
52
- var crypto = lazyRequire(function () { return require("../crypto"); });
52
+ var bCrypto = lazyRequire(function () { return require("../crypto"); });
53
53
  var audit = lazyRequire(function () { return require("../audit"); });
54
54
 
55
55
  var RequireMtlsError = defineClass("RequireMtlsError", { alwaysPermanent: true });
@@ -169,18 +169,18 @@ function create(opts) {
169
169
  // allow/deny matching.
170
170
  var fp;
171
171
  try {
172
- fp = crypto().hashCertFingerprint(peerCert.raw);
172
+ fp = bCrypto().hashCertFingerprint(peerCert.raw);
173
173
  } catch (e) {
174
174
  return _refuse(res, "fingerprint-failed", { error: (e && e.message) || String(e) });
175
175
  }
176
176
 
177
- if (denyList.length > 0 && crypto().isCertRevoked(peerCert.raw, denyList)) {
177
+ if (denyList.length > 0 && bCrypto().isCertRevoked(peerCert.raw, denyList)) {
178
178
  return _refuse(res, "fingerprint-on-deny-list", {
179
179
  fingerprint: fp.colon,
180
180
  subject: (peerCert.subject && peerCert.subject.CN) || null,
181
181
  });
182
182
  }
183
- if (allowList && allowList.length > 0 && !crypto().isCertRevoked(peerCert.raw, allowList)) {
183
+ if (allowList && allowList.length > 0 && !bCrypto().isCertRevoked(peerCert.raw, allowList)) {
184
184
  return _refuse(res, "fingerprint-not-allowed", {
185
185
  fingerprint: fp.colon,
186
186
  subject: (peerCert.subject && peerCert.subject.CN) || null,
package/lib/migrations.js CHANGED
@@ -45,7 +45,7 @@ var lazyRequire = require("./lazy-require");
45
45
  var { boot } = require("./log");
46
46
  var migrationFiles = require("./migration-files");
47
47
  var numericBounds = require("./numeric-bounds");
48
- var dbModule = lazyRequire(function () { return require("./db"); });
48
+ var db = lazyRequire(function () { return require("./db"); });
49
49
  var validateOpts = require("./validate-opts");
50
50
  var { FrameworkError } = require("./framework-error");
51
51
 
@@ -224,7 +224,7 @@ function _resolveDb(opts) {
224
224
  if (opts && opts.db && typeof opts.db.prepare === "function") return opts.db;
225
225
  // Fall back to the framework's singleton db when one isn't passed —
226
226
  // operator-side wiring usually does `b.migrations.create({ dir })`.
227
- var d = dbModule();
227
+ var d = db();
228
228
  if (typeof d.prepare !== "function") {
229
229
  throw new MigrationError("migrations/no-db",
230
230
  "no db handle: pass opts.db or initialize b.db before create()",
@@ -43,7 +43,7 @@ var defineClass = require("./framework-error").defineClass;
43
43
  var lazyRequire = require("./lazy-require");
44
44
  var validateOpts = require("./validate-opts");
45
45
 
46
- var auditFwk = lazyRequire(function () { return require("./audit"); });
46
+ var audit = lazyRequire(function () { return require("./audit"); });
47
47
  var observability = lazyRequire(function () { return require("./observability"); });
48
48
 
49
49
  var ByteQuotaError = defineClass("ByteQuotaError", { alwaysPermanent: true });
@@ -181,7 +181,7 @@ function create(opts) {
181
181
  function _emitAudit(action, outcome, metadata) {
182
182
  if (!auditOn) return;
183
183
  try {
184
- auditFwk().safeEmit({
184
+ audit().safeEmit({
185
185
  action: "network.byte_quota." + action,
186
186
  outcome: outcome,
187
187
  metadata: metadata || {},
package/lib/network.js CHANGED
@@ -33,7 +33,7 @@
33
33
  var byteQuota = require("./network-byte-quota");
34
34
  var ntpCheck = require("./ntp-check");
35
35
  var nts = require("./network-nts");
36
- var dns = require("./network-dns");
36
+ var networkDns = require("./network-dns");
37
37
  var networkProxy = require("./network-proxy");
38
38
  var networkTls = require("./network-tls");
39
39
  var heartbeat = require("./network-heartbeat");
@@ -211,15 +211,15 @@ function bootFromEnv(opts) {
211
211
  var dnsServers = env.BLAMEJS_DNS_SERVERS;
212
212
  if (dnsServers) {
213
213
  var dl = String(dnsServers).split(",").map(function (s) { return s.trim(); }).filter(Boolean);
214
- if (dl.length > 0) { dns.setServers(dl); applied.dns.servers = dl.length; }
214
+ if (dl.length > 0) { networkDns.setServers(dl); applied.dns.servers = dl.length; }
215
215
  }
216
- if (env.BLAMEJS_DNS_RESULT_ORDER) { dns.setResultOrder(env.BLAMEJS_DNS_RESULT_ORDER); applied.dns.resultOrder = env.BLAMEJS_DNS_RESULT_ORDER; }
217
- if (env.BLAMEJS_DNS_FAMILY) { dns.setFamily(parseInt(env.BLAMEJS_DNS_FAMILY, 10)); applied.dns.family = parseInt(env.BLAMEJS_DNS_FAMILY, 10); }
218
- if (env.BLAMEJS_DNS_LOOKUP_TIMEOUT_MS) { dns.setLookupTimeoutMs(parseInt(env.BLAMEJS_DNS_LOOKUP_TIMEOUT_MS, 10)); applied.dns.lookupTimeoutMs = parseInt(env.BLAMEJS_DNS_LOOKUP_TIMEOUT_MS, 10); }
219
- if (env.BLAMEJS_DNS_CACHE_TTL_MS) { dns.setCacheTtlMs(parseInt(env.BLAMEJS_DNS_CACHE_TTL_MS, 10)); applied.dns.cacheTtlMs = parseInt(env.BLAMEJS_DNS_CACHE_TTL_MS, 10); }
220
- if (env.BLAMEJS_DOH_URL) { dns.useDnsOverHttps({ url: env.BLAMEJS_DOH_URL }); applied.dns.doh = env.BLAMEJS_DOH_URL; }
221
- else if (env.BLAMEJS_DOH_PROVIDER) { dns.useDnsOverHttps({ provider: env.BLAMEJS_DOH_PROVIDER }); applied.dns.dohProvider = env.BLAMEJS_DOH_PROVIDER; }
222
- if (env.BLAMEJS_DOT_HOST) { dns.useDnsOverTls({ host: env.BLAMEJS_DOT_HOST, port: env.BLAMEJS_DOT_PORT ? parseInt(env.BLAMEJS_DOT_PORT, 10) : 853 }); applied.dns.dot = env.BLAMEJS_DOT_HOST; }
216
+ if (env.BLAMEJS_DNS_RESULT_ORDER) { networkDns.setResultOrder(env.BLAMEJS_DNS_RESULT_ORDER); applied.dns.resultOrder = env.BLAMEJS_DNS_RESULT_ORDER; }
217
+ if (env.BLAMEJS_DNS_FAMILY) { networkDns.setFamily(parseInt(env.BLAMEJS_DNS_FAMILY, 10)); applied.dns.family = parseInt(env.BLAMEJS_DNS_FAMILY, 10); }
218
+ if (env.BLAMEJS_DNS_LOOKUP_TIMEOUT_MS) { networkDns.setLookupTimeoutMs(parseInt(env.BLAMEJS_DNS_LOOKUP_TIMEOUT_MS, 10)); applied.dns.lookupTimeoutMs = parseInt(env.BLAMEJS_DNS_LOOKUP_TIMEOUT_MS, 10); }
219
+ if (env.BLAMEJS_DNS_CACHE_TTL_MS) { networkDns.setCacheTtlMs(parseInt(env.BLAMEJS_DNS_CACHE_TTL_MS, 10)); applied.dns.cacheTtlMs = parseInt(env.BLAMEJS_DNS_CACHE_TTL_MS, 10); }
220
+ if (env.BLAMEJS_DOH_URL) { networkDns.useDnsOverHttps({ url: env.BLAMEJS_DOH_URL }); applied.dns.doh = env.BLAMEJS_DOH_URL; }
221
+ else if (env.BLAMEJS_DOH_PROVIDER) { networkDns.useDnsOverHttps({ provider: env.BLAMEJS_DOH_PROVIDER }); applied.dns.dohProvider = env.BLAMEJS_DOH_PROVIDER; }
222
+ if (env.BLAMEJS_DOT_HOST) { networkDns.useDnsOverTls({ host: env.BLAMEJS_DOT_HOST, port: env.BLAMEJS_DOT_PORT ? parseInt(env.BLAMEJS_DOT_PORT, 10) : 853 }); applied.dns.dot = env.BLAMEJS_DOT_HOST; }
223
223
 
224
224
  if (env.HTTP_PROXY || env.http_proxy || env.HTTPS_PROXY || env.https_proxy ||
225
225
  env.NO_PROXY || env.no_proxy || env.ALL_PROXY || env.all_proxy) {
@@ -286,7 +286,7 @@ function snapshot() {
286
286
  servers: ntpFacade.getServers(),
287
287
  thresholds: ntpCheck.getThresholds(),
288
288
  },
289
- dns: dns._stateForTest(),
289
+ dns: networkDns._stateForTest(),
290
290
  proxy: networkProxy.snapshot(),
291
291
  tls: {
292
292
  systemTrust: networkTls.isSystemTrustEnabled(),
@@ -305,7 +305,7 @@ function _resetForTest() {
305
305
  ntpFacade._defaultServers = null;
306
306
  ntpFacade._defaultTimeoutMs = null;
307
307
  if (typeof ntpCheck._resetThresholdsForTest === "function") ntpCheck._resetThresholdsForTest();
308
- dns._resetForTest();
308
+ networkDns._resetForTest();
309
309
  networkProxy._resetForTest();
310
310
  networkTls._resetForTest();
311
311
  heartbeat._resetForTest();
@@ -316,7 +316,7 @@ function _resetForTest() {
316
316
 
317
317
  module.exports = {
318
318
  ntp: ntpFacade,
319
- dns: dns,
319
+ dns: networkDns,
320
320
  proxy: networkProxy,
321
321
  tls: networkTls,
322
322
  heartbeat: heartbeat,
package/lib/notify.js CHANGED
@@ -53,10 +53,10 @@ var { NotifyError } = require("./framework-error");
53
53
  // Lazy-required modules to avoid load-order cycles. retry / observability /
54
54
  // redact / httpClient don't currently import notify, but treating them
55
55
  // the same way every primitive does keeps the load-order story uniform.
56
- var retryModule = lazyRequire(function () { return require("./retry"); });
56
+ var retryHelper = lazyRequire(function () { return require("./retry"); });
57
57
  var observability = lazyRequire(function () { return require("./observability"); });
58
- var redactModule = lazyRequire(function () { return require("./redact"); });
59
- var httpClientModule = lazyRequire(function () { return require("./http-client"); });
58
+ var redact = lazyRequire(function () { return require("./redact"); });
59
+ var httpClient = lazyRequire(function () { return require("./http-client"); });
60
60
 
61
61
  var _err = NotifyError.factory;
62
62
 
@@ -222,7 +222,7 @@ function httpJson(opts) {
222
222
  return {
223
223
  name: name,
224
224
  send: async function (message, sendOpts) {
225
- var client = customClient || httpClientModule();
225
+ var client = customClient || httpClient();
226
226
  var body;
227
227
  var contentType;
228
228
  if (bodyFormat === "form") {
@@ -380,7 +380,7 @@ function create(opts) {
380
380
  var redactFn = (typeof opts.redact === "function")
381
381
  ? opts.redact
382
382
  // Default: b.redact.redact — the framework's PII detector chain.
383
- : function (m) { return redactModule().redact(m); };
383
+ : function (m) { return redact().redact(m); };
384
384
  var defaultTimeoutMs = cfg.defaultTimeoutMs;
385
385
  var defaultRetry = opts.defaultRetry || null;
386
386
  var defaultBreaker = opts.defaultBreaker || null;
@@ -402,7 +402,7 @@ function create(opts) {
402
402
  };
403
403
  var breakerOpts = entry.breaker || defaultBreaker;
404
404
  if (breakerOpts) {
405
- registry.breaker = new (retryModule().CircuitBreaker)(n, breakerOpts);
405
+ registry.breaker = new (retryHelper().CircuitBreaker)(n, breakerOpts);
406
406
  }
407
407
  if (entry.serialize) registry.mutex = new safeAsync.Mutex();
408
408
  channels[n] = registry;
@@ -519,7 +519,7 @@ function create(opts) {
519
519
  try {
520
520
  // b.retry.withRetry IS the retry loop. Notify never hand-rolls
521
521
  // backoff/jitter/classification — the framework owns it.
522
- var result = await retryModule().withRetry(function (attempt) {
522
+ var result = await retryHelper().withRetry(function (attempt) {
523
523
  return _attemptSerialized(attempt);
524
524
  }, perCallRetry);
525
525
 
@@ -647,7 +647,7 @@ function create(opts) {
647
647
  mutex: null,
648
648
  };
649
649
  var breakerOpts = entry.breaker || defaultBreaker;
650
- if (breakerOpts) registry.breaker = new (retryModule().CircuitBreaker)(name, breakerOpts);
650
+ if (breakerOpts) registry.breaker = new (retryHelper().CircuitBreaker)(name, breakerOpts);
651
651
  if (entry.serialize) registry.mutex = new safeAsync.Mutex();
652
652
  channels[name] = registry;
653
653
  }
@@ -68,7 +68,7 @@ var { boot } = require("../log");
68
68
  // (transitively) vault, which leaves safe-env's module.exports
69
69
  // half-built when vault first reaches readVar. Defer audit resolution
70
70
  // until the first emit-driven call.
71
- var auditModule = lazyRequire(function () { return require("../audit"); });
71
+ var audit = lazyRequire(function () { return require("../audit"); });
72
72
 
73
73
  var log = boot("env");
74
74
 
@@ -519,11 +519,11 @@ function _writeAuditRows(filepath, diff) {
519
519
  // we're a follower, audit.record will throw NotLeaderError. Catch
520
520
  // explicitly: a follower's local config-load shouldn't crash because
521
521
  // the cluster's audit chain belongs to the leader.
522
- var audit = auditModule(); // resolve the lazy-required audit module
522
+ var auditInst = audit(); // resolve the lazy-required audit module
523
523
 
524
524
  function _safeRecord(action, metadata) {
525
525
  try {
526
- audit.emit({
526
+ auditInst.emit({
527
527
  actor: { kind: "system", id: "config-loader" },
528
528
  action: action,
529
529
  outcome: "success",
@@ -131,7 +131,7 @@ async function extract(opts) {
131
131
  if (nodeFs.existsSync(opts.stagingDir)) {
132
132
  throw new RestoreBundleError("restore-bundle/staging-exists",
133
133
  "extract: stagingDir already exists: " + opts.stagingDir +
134
- " (refusing to merge into existing directory — pick a fresh nodePath)");
134
+ " (refusing to merge into existing directory — pick a fresh path)");
135
135
  }
136
136
  if (!Buffer.isBuffer(opts.passphrase) && typeof opts.passphrase !== "string") {
137
137
  throw new RestoreBundleError("restore-bundle/no-passphrase",
package/lib/router.js CHANGED
@@ -46,11 +46,11 @@ var websocket = require("./websocket");
46
46
  var { boot } = require("./log");
47
47
  var { RouterError } = require("./framework-error");
48
48
 
49
- var auditFwk = lazyRequire(function () { return require("./audit"); });
49
+ var audit = lazyRequire(function () { return require("./audit"); });
50
50
  // compliance — lazy because router.js is required during boot before
51
51
  // the operator's `b.compliance.set(...)` runs; the posture lookup only
52
52
  // matters at listen() time, well after boot finishes.
53
- var complianceLazy = lazyRequire(function () { return require("./compliance"); });
53
+ var compliance = lazyRequire(function () { return require("./compliance"); });
54
54
 
55
55
  var log = boot("router");
56
56
  var HTTP_STATUS = requestHelpers.HTTP_STATUS;
@@ -733,12 +733,12 @@ class Router {
733
733
  if (declared !== "replay-cache") return declared;
734
734
  var active = null;
735
735
  try {
736
- var compliance = complianceLazy();
737
- if (compliance && typeof compliance.current === "function") active = compliance.current();
736
+ var complianceInst = compliance();
737
+ if (complianceInst && typeof complianceInst.current === "function") active = complianceInst.current();
738
738
  } catch (_e) { /* compliance not initialized */ }
739
739
  if (active && TLS_0RTT_FAILCLOSED_POSTURES.indexOf(active) !== -1) {
740
740
  try {
741
- auditFwk().safeEmit({
741
+ audit().safeEmit({
742
742
  action: "tls.0rtt.refused",
743
743
  outcome: "denied",
744
744
  metadata: { reason: "posture-failclosed", posture: active, declared: declared },
@@ -759,7 +759,7 @@ class Router {
759
759
  if (String(earlyDataHeader).trim() !== "1") return null; // RFC 8470: only "1" means early data
760
760
  if (posture === "refuse") {
761
761
  try {
762
- auditFwk().safeEmit({
762
+ audit().safeEmit({
763
763
  action: "tls.0rtt.refused",
764
764
  outcome: "denied",
765
765
  metadata: { reason: "posture-refuse", method: req.method, url: req.url },
@@ -783,7 +783,7 @@ class Router {
783
783
  var key = hash.digest("hex");
784
784
  if (this._tls0RttReplayCache.has(key)) {
785
785
  try {
786
- auditFwk().safeEmit({
786
+ audit().safeEmit({
787
787
  action: "tls.0rtt.replayed",
788
788
  outcome: "denied",
789
789
  metadata: { reason: "cache-hit", method: req.method, url: req.url,
@@ -805,7 +805,7 @@ class Router {
805
805
  }
806
806
  this._tls0RttReplayCache.set(key, nowMs + TLS_0RTT_REPLAY_WINDOW_MS);
807
807
  try {
808
- auditFwk().safeEmit({
808
+ audit().safeEmit({
809
809
  action: "tls.0rtt.accepted",
810
810
  outcome: "success",
811
811
  metadata: { method: req.method, url: req.url, windowMs: TLS_0RTT_REPLAY_WINDOW_MS },
@@ -889,7 +889,7 @@ class Router {
889
889
  });
890
890
  } catch (parseErr) {
891
891
  try {
892
- auditFwk().safeEmit({
892
+ audit().safeEmit({
893
893
  action: "router.redirect.cross_origin.refused",
894
894
  outcome: "denied",
895
895
  metadata: {
@@ -913,7 +913,7 @@ class Router {
913
913
  }
914
914
  if (!match) {
915
915
  try {
916
- auditFwk().safeEmit({
916
+ audit().safeEmit({
917
917
  action: "router.redirect.cross_origin.refused",
918
918
  outcome: "denied",
919
919
  metadata: {
@@ -930,7 +930,7 @@ class Router {
930
930
  );
931
931
  }
932
932
  try {
933
- auditFwk().safeEmit({
933
+ audit().safeEmit({
934
934
  action: "router.redirect.cross_origin.allowed",
935
935
  outcome: "success",
936
936
  metadata: { target: url, origin: targetOrigin },
@@ -1064,7 +1064,7 @@ class Router {
1064
1064
  // (a clean peer would not initiate after GOAWAY).
1065
1065
  h2session.on("stream", function (stream) {
1066
1066
  if (h2session._blamejsGoawaySent) {
1067
- try { auditFwk().safeEmit({
1067
+ try { audit().safeEmit({
1068
1068
  action: "http2.window_update.refused",
1069
1069
  outcome: "denied",
1070
1070
  metadata: { reason: "post-goaway-stream", streamId: stream.id || null,
package/lib/seeders.js CHANGED
@@ -67,7 +67,7 @@ var { SeederError } = require("./framework-error");
67
67
 
68
68
  var log = boot("seeders");
69
69
 
70
- var dbModule = lazyRequire(function () { return require("./db"); });
70
+ var db = lazyRequire(function () { return require("./db"); });
71
71
  var observability = lazyRequire(function () { return require("./observability"); });
72
72
 
73
73
  var _err = SeederError.factory;
@@ -151,7 +151,7 @@ function _validateCreateOpts(opts) {
151
151
 
152
152
  function _resolveDb(opts) {
153
153
  if (opts && opts.db && typeof opts.db.prepare === "function") return opts.db;
154
- var d = dbModule();
154
+ var d = db();
155
155
  if (typeof d.prepare !== "function") {
156
156
  throw _err("NO_DB", "seeders: no db handle: pass opts.db or initialize b.db before create()");
157
157
  }
package/lib/testing.js CHANGED
@@ -62,7 +62,7 @@ var { TestingError } = require("./framework-error");
62
62
  // metrics is the only place that exposes the global `tap` slot the
63
63
  // captureMetricsTap helper swaps; pulling it lazily keeps testing.js
64
64
  // safe to require at any framework load order.
65
- var metricsModule = lazyRequire(function () { return require("./metrics"); });
65
+ var metrics = lazyRequire(function () { return require("./metrics"); });
66
66
 
67
67
  var _err = TestingError.factory;
68
68
 
@@ -563,7 +563,7 @@ function captureObservability() {
563
563
  * }
564
564
  */
565
565
  function captureMetricsTap() {
566
- var m = metricsModule();
566
+ var m = metrics();
567
567
  var original = m.tap;
568
568
  var captured = [];
569
569
  m.tap = function (name, value, labels) {
package/lib/vault-aad.js CHANGED
@@ -52,7 +52,7 @@ var C = require("./constants");
52
52
  var { defineClass } = require("./framework-error");
53
53
  var VaultAadError = defineClass("VaultAadError", { alwaysPermanent: true });
54
54
 
55
- var crypto = lazyRequire(function () { return require("./crypto"); });
55
+ var bCrypto = lazyRequire(function () { return require("./crypto"); });
56
56
  var vault = lazyRequire(function () { return require("./vault"); });
57
57
  var audit = lazyRequire(function () { return require("./audit"); });
58
58
 
@@ -154,11 +154,11 @@ function _deriveKey(aadBytes) {
154
154
  // this is a deterministic derivation; rotating vault keys produces
155
155
  // a different root and breaks all prior AAD-sealed values (operator
156
156
  // intent: rotation = re-seal).
157
- var rootHash = crypto().sha3Hash(keysJson);
157
+ var rootHash = bCrypto().sha3Hash(keysJson);
158
158
  var prefix = Buffer.from("vault.aad/v1/", "utf8");
159
159
  var rootBuf = Buffer.from(rootHash, "hex");
160
160
  var input = Buffer.concat([prefix, rootBuf, aadBytes]);
161
- return crypto().kdf(input, C.BYTES.bytes(32));
161
+ return bCrypto().kdf(input, C.BYTES.bytes(32));
162
162
  }
163
163
 
164
164
  function seal(plaintext, aadParts) {
@@ -178,7 +178,7 @@ function seal(plaintext, aadParts) {
178
178
  var aadBytes = _canonicalize(aadParts);
179
179
  var key = _deriveKey(aadBytes);
180
180
  var ptBuf = Buffer.from(plaintext, "utf8");
181
- var packed = crypto().encryptPacked(ptBuf, key, aadBytes);
181
+ var packed = bCrypto().encryptPacked(ptBuf, key, aadBytes);
182
182
 
183
183
  try {
184
184
  audit().safeEmit({
@@ -213,7 +213,7 @@ function unseal(value, aadParts) {
213
213
  "unseal: base64 decode failed - " + e.message);
214
214
  }
215
215
  var pt;
216
- try { pt = crypto().decryptPacked(packed, key, aadBytes); }
216
+ try { pt = bCrypto().decryptPacked(packed, key, aadBytes); }
217
217
  catch (e) {
218
218
  try {
219
219
  audit().safeEmit({
package/lib/watcher.js CHANGED
@@ -434,7 +434,7 @@ function create(opts) {
434
434
  ((e && e.message) || String(e)) + " — pass mode: \"poll\" to fall back to interval polling");
435
435
  }
436
436
  throw new WatcherError("watcher/start-failed",
437
- "watcher.create: nodeFs.watch failed: " + ((e && e.message) || String(e)));
437
+ "watcher.create: fs.watch failed: " + ((e && e.message) || String(e)));
438
438
  }
439
439
  }
440
440
 
package/lib/ws-client.js CHANGED
@@ -54,7 +54,7 @@ var lazyRequire = require("./lazy-require");
54
54
  var validateOpts = require("./validate-opts");
55
55
  var safeAsync = require("./safe-async");
56
56
  var safeBuffer = require("./safe-buffer");
57
- var fwCrypto = lazyRequire(function () { return require("./crypto"); });
57
+ var bCrypto = lazyRequire(function () { return require("./crypto"); });
58
58
  var websocket = lazyRequire(function () { return require("./websocket"); });
59
59
  var audit = lazyRequire(function () { return require("./audit"); });
60
60
  var networkTls = lazyRequire(function () { return require("./network-tls"); });
@@ -137,7 +137,7 @@ function _inflateRawCappedSync(zlib, compressed, maxBytes, windowBits) {
137
137
  }
138
138
 
139
139
  function _generateKey() {
140
- return fwCrypto().generateBytes(C.BYTES.bytes(16)).toString("base64");
140
+ return bCrypto().generateBytes(C.BYTES.bytes(16)).toString("base64");
141
141
  }
142
142
 
143
143
  function _expectedAccept(secKey, handshakeGuid) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blamejs/core",
3
- "version": "0.9.15",
3
+ "version": "0.9.16",
4
4
  "description": "The Node framework that owns its stack.",
5
5
  "license": "Apache-2.0",
6
6
  "author": "blamejs contributors",
package/sbom.cdx.json CHANGED
@@ -2,10 +2,10 @@
2
2
  "$schema": "http://cyclonedx.org/schema/bom-1.5.schema.json",
3
3
  "bomFormat": "CycloneDX",
4
4
  "specVersion": "1.6",
5
- "serialNumber": "urn:uuid:40df0b28-c547-4f48-9bbf-f005b59cbd1b",
5
+ "serialNumber": "urn:uuid:8e662af8-d254-46ec-8625-aa19174598d2",
6
6
  "version": 1,
7
7
  "metadata": {
8
- "timestamp": "2026-05-14T00:04:25.956Z",
8
+ "timestamp": "2026-05-14T04:47:34.904Z",
9
9
  "lifecycles": [
10
10
  {
11
11
  "phase": "build"
@@ -19,14 +19,14 @@
19
19
  }
20
20
  ],
21
21
  "component": {
22
- "bom-ref": "@blamejs/core@0.9.15",
22
+ "bom-ref": "@blamejs/core@0.9.16",
23
23
  "type": "library",
24
24
  "name": "blamejs",
25
- "version": "0.9.15",
25
+ "version": "0.9.16",
26
26
  "scope": "required",
27
27
  "author": "blamejs contributors",
28
28
  "description": "The Node framework that owns its stack.",
29
- "purl": "pkg:npm/%40blamejs/core@0.9.15",
29
+ "purl": "pkg:npm/%40blamejs/core@0.9.16",
30
30
  "properties": [],
31
31
  "externalReferences": [
32
32
  {
@@ -54,7 +54,7 @@
54
54
  "components": [],
55
55
  "dependencies": [
56
56
  {
57
- "ref": "@blamejs/core@0.9.15",
57
+ "ref": "@blamejs/core@0.9.16",
58
58
  "dependsOn": []
59
59
  }
60
60
  ]