@blamejs/core 0.7.23 → 0.7.24

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,8 @@ upgrading across more than a few patches at a time.
8
8
 
9
9
  ## v0.7.x
10
10
 
11
+ - **0.7.24** (2026-05-05) — `b.retention.complianceFloor` accessor for regulatory minimum-retention windows. **Surface**: `b.retention.complianceFloor(posture, candidateTtlMs?)` returns the effective TTL that meets-or-exceeds the regulatory floor; throws `retention/unknown-posture` on unknown names. **`b.retention.COMPLIANCE_RETENTION_FLOOR_MS`** exposes the per-posture minimums for compliance audit visibility: `pci-dss` 365 days (PCI-DSS Req 10.7.1), `hipaa` 6 years (45 CFR §164.316(b)(2)), `sox` 7 years (Sarbanes-Oxley §802), `soc2` 1 year, `dora` 5 years (DORA Article 17). When `candidateTtlMs` exceeds the floor it wins; when it's below, the floor takes over. Smoke 8488 / wiki e2e 178 / Linux container smoke 8488 / Linux container wiki e2e 178 / eslint clean / api-snapshot baseline refreshed.
12
+
11
13
  - **0.7.23** (2026-05-05) — DNS-over-HTTPS default-on. **Default-on DoH for outbound DNS** — `lib/network-dns.js` now uses Cloudflare DoH (`https://cloudflare-dns.com/dns-query`) for hostname resolution by default when neither `useDnsOverHttps()` nor `useDnsOverTls()` has been called explicitly. Privacy-respecting (encrypted DNS over TLS to a non-ISP resolver), aligned with Core Rule §3 ("security defaults are not opt-in"). **Local-form hosts route through node:dns** — RFC 6761 / 6762 special-form names (`localhost`, `*.localhost`, `*.local`, `*.test`, `*.invalid`, `*.internal`, `*.intranet`, `*.lan`, `*.home`, `*.corp`) AND IP literals skip DoH and use node:dns directly so `/etc/hosts` lookups + dev workflows continue to resolve correctly. **Operator opt-out via `b.network.dns.useSystemResolver()`** — split-horizon / internal-DNS deployments call this once at boot and every lookup routes through the OS resolver thereafter. **Env override `BLAMEJS_DNS_TRANSPORT`** — operators set `system` (force OS resolver), `dot` (force Cloudflare DNS-over-TLS at 1.1.1.1:853), or leave unset (default DoH). Smoke 8478 / wiki e2e 178 / Linux container smoke 8478 / Linux container wiki e2e 178 / eslint clean / api-snapshot baseline refreshed.
12
14
 
13
15
  - **0.7.22** (2026-05-05) — DKIM dual-signer + soc2-cc7 → soc2 posture rename. **`b.mail.dkim.dualSigner`** — RFC 8463 §3 transition signer that produces messages with BOTH a legacy RSA-SHA-256 DKIM-Signature AND an Ed25519-SHA-256 DKIM-Signature header. Receivers without Ed25519 support validate the RSA signature; receivers that prefer Ed25519 validate the post-quantum-friendlier signature. Operators rolling off RSA-SHA-256 wire `b.mail.dkim.dualSigner({ domain, rsa: { selector, privateKey }, eddsa: { selector, privateKey } })` and pass the result anywhere a regular DKIM signer is accepted; `sign()` produces a wire with two `DKIM-Signature` headers. Both signers are constructed eagerly at create-time (configuration errors surface at boot, not at first send). **soc2-cc7 → soc2 posture rename** — every guard's compliance posture name changes from `"soc2-cc7"` to `"soc2"`. The CC7-specific scoping was misleading (SOC 2 controls span CC1–CC9; the existing posture wasn't CC7-specific). Operators with `compliancePosture: "soc2-cc7"` MUST update to `compliancePosture: "soc2"` — the old name now throws `unknown compliance posture`. Smoke 8478 / wiki e2e 178 / Linux container smoke 8478 / Linux container wiki e2e 178 / eslint clean / api-snapshot baseline refreshed.
package/lib/retention.js CHANGED
@@ -55,6 +55,7 @@
55
55
  * write. This is the escape hatch; the table+ageField+ttlMs shape
56
56
  * covers the common case.
57
57
  */
58
+ var C = require("./constants");
58
59
  var lazyRequire = require("./lazy-require");
59
60
  var validateOpts = require("./validate-opts");
60
61
  var { defineClass } = require("./framework-error");
@@ -433,7 +434,47 @@ function create(opts) {
433
434
  return { declare: declare, run: run, runAll: runAll, preview: preview, list: list };
434
435
  }
435
436
 
437
+ // Audit-log retention floors per regulatory posture. These are the
438
+ // MINIMUMS — operators may declare longer windows but cannot declare
439
+ // shorter ones. Operator-facing helper for compliance audit.
440
+ //
441
+ // PCI-DSS Requirement 10.7.1 — 12 months online (active accessible)
442
+ // HIPAA 45 CFR §164.316(b)(2) — 6 years from creation
443
+ // SOX (Sarbanes-Oxley) §802 — 7 years for audit-relevant records
444
+ // GDPR Art. 5(1)(e) — no fixed minimum; operator declares
445
+ // SOC 2 (CC1–CC9) — 1 year typical; auditor-driven
446
+ // DORA Art. 17 (incident logs) — 5 years
447
+ var COMPLIANCE_RETENTION_FLOOR_MS = Object.freeze({
448
+ "pci-dss": C.TIME.days(365), // 12 months
449
+ "hipaa": C.TIME.days(365 * 6), // 6 years
450
+ "sox": C.TIME.days(365 * 7), // 7 years
451
+ "soc2": C.TIME.days(365), // 1 year
452
+ "dora": C.TIME.days(365 * 5), // 5 years (Article 17 incident logs)
453
+ });
454
+
455
+ // Operator passes a posture name + a candidate ttlMs; returns the
456
+ // effective ttl that meets-or-exceeds the floor. Throws if posture is
457
+ // unknown so typos surface at config time.
458
+ function complianceFloor(posture, candidateTtlMs) {
459
+ if (typeof posture !== "string") {
460
+ throw new RetentionError("retention/bad-posture",
461
+ "complianceFloor: posture must be a string, got " + JSON.stringify(posture));
462
+ }
463
+ var floor = COMPLIANCE_RETENTION_FLOOR_MS[posture];
464
+ if (floor === undefined) {
465
+ throw new RetentionError("retention/unknown-posture",
466
+ "complianceFloor: unknown posture '" + posture + "'; expected one of " +
467
+ Object.keys(COMPLIANCE_RETENTION_FLOOR_MS).join(", "));
468
+ }
469
+ if (typeof candidateTtlMs !== "number" || !isFinite(candidateTtlMs) || candidateTtlMs <= 0) {
470
+ return floor;
471
+ }
472
+ return candidateTtlMs > floor ? candidateTtlMs : floor;
473
+ }
474
+
436
475
  module.exports = {
437
- create: create,
438
- RetentionError: RetentionError,
476
+ create: create,
477
+ complianceFloor: complianceFloor,
478
+ COMPLIANCE_RETENTION_FLOOR_MS: COMPLIANCE_RETENTION_FLOOR_MS,
479
+ RetentionError: RetentionError,
439
480
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blamejs/core",
3
- "version": "0.7.23",
3
+ "version": "0.7.24",
4
4
  "description": "The Node framework that owns its stack.",
5
5
  "license": "Apache-2.0",
6
6
  "author": "blamejs contributors",
@@ -2,10 +2,10 @@
2
2
  "$schema": "http://cyclonedx.org/schema/bom-1.5.schema.json",
3
3
  "bomFormat": "CycloneDX",
4
4
  "specVersion": "1.5",
5
- "serialNumber": "urn:uuid:2ed35351-9ec7-4e19-9471-f35604ba988a",
5
+ "serialNumber": "urn:uuid:942606f7-1484-4ac3-9332-63f73e25256f",
6
6
  "version": 1,
7
7
  "metadata": {
8
- "timestamp": "2026-05-05T06:39:17.238Z",
8
+ "timestamp": "2026-05-05T06:51:47.053Z",
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.7.23",
22
+ "bom-ref": "@blamejs/core@0.7.24",
23
23
  "type": "library",
24
24
  "name": "blamejs",
25
- "version": "0.7.23",
25
+ "version": "0.7.24",
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.7.23",
29
+ "purl": "pkg:npm/%40blamejs/core@0.7.24",
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.7.23",
57
+ "ref": "@blamejs/core@0.7.24",
58
58
  "dependsOn": []
59
59
  }
60
60
  ]