@blamejs/core 0.13.22 → 0.13.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,10 @@ upgrading across more than a few patches at a time.
8
8
 
9
9
  ## v0.13.x
10
10
 
11
+ - v0.13.24 (2026-05-28) — **`b.guard*` docs corrected: the compliance-posture opt key, the gate API, and validate return shapes.** Documentation corrections across the b.guard* family. The most consequential: the posture-selection option was documented as `compliance:` in many guards' @opts, but the working key is `compliancePosture:` — passing the documented `{ compliance: "hipaa" }` was silently ignored, so a compliance posture (e.g. HIPAA PII redaction) never activated. If you select a posture via the gate/validate/sanitize options, use `compliancePosture:`; `compliance:` had no effect. The guard docs now name the correct key uniformly. Also corrected: gate examples and prose that invoked the gate as a callable or via `.run` / `.inspect` (the gate is an object whose method is `.check(ctx)`), and validate() return shapes that listed `severities` / `summary` / `refusal` fields the function never returned (it returns `{ ok, issues }`). **Fixed:** *guard posture option is `compliancePosture:`, not `compliance:`* — Many `b.guard*` primitives documented the compliance-posture selector as `compliance: "hipaa"|"pci-dss"|"gdpr"|"soc2"` in their `@opts`, but the family resolver reads `compliancePosture:`. Passing `{ compliance: "hipaa" }` was accepted and silently ignored — the posture overlay (e.g. CSV `piiPolicy: "redact"` under HIPAA) never applied, leaving the default policy in force. The docs across the guard family now name `compliancePosture:` consistently (the key the resolver and `b.guardX.compliancePosture(name)` already used). Action: if you selected a posture with `compliance:`, switch to `compliancePosture:` — the posture was not taking effect before. · *guard gate is an object with `.check(ctx)`, not a callable* — Several guards' gate `@example`s and prose invoked the gate as a function (`g({...})`), via `.run(...)`, or via `.inspect(...)`, and a few described it as "an async function". `b.guardX.gate(opts)` returns an object whose async method is `.check(ctx)`; the examples and prose now use `.check`, so they run as written. · *guard validate() returns `{ ok, issues }`* — Several guards documented `validate()` as returning `{ ok, issues, severities }`, `{ ok, issues, summary }`, or `{ ok, issues, refusal? }`. The function returns `{ ok, issues }` (each issue carries its own `severity` / `kind`); the documented extra top-level fields were never present. The docs now state the actual shape.
12
+
13
+ - v0.13.23 (2026-05-28) — **Documentation corrected to match actual behavior across several primitives.** A set of JSDoc / doc-comment corrections where the documented contract had drifted from what the code does. No behavior changes — the implementations already behaved as now documented; only the docs were wrong. The most operator-relevant is the JWT signer doc: an expiring token signed without an explicit jti receives an auto-minted 128-bit jti (so the replay-defense path has the jti it needs), which the sign-opts doc previously denied. Also corrected: did.resolve's unsupported-method error now names did:jwk (always supported); b.cose.verify is marked stable to match its stable sign sibling and the CWT / EAT / SCITT / mdoc verifiers built on it; b.linkHeader.serialize's doc now states every parameter value is double-quoted; b.auth.saml verifyResponse's documented return shape now lists inResponseTo and issuer (both always returned); and the rate-limit custom-backend contract drops a gc member the middleware never invoked. **Fixed:** *JWT signer doc now describes the auto-minted jti on expiring tokens* — `b.auth.jwt.sign`'s opts doc claimed that omitting `jti` adds no jti. In fact, when a token carries an `exp` and no operator-supplied `jti`, the signer auto-mints a random 128-bit `jti` so a replay-protected token always carries the identifier `verify`'s replay store requires. The doc now describes this; pass an explicit `jti` for a deterministic value. Behavior is unchanged. · *`b.did.resolve` unsupported-method error now names did:jwk* — The thrown error for an unsupported DID method listed only `did:key` and `did:web`, omitting `did:jwk`, which `resolve` fully supports. The message now reads `(did:key, did:jwk, and did:web only)`. · *`b.cose.verify` marked stable* — `b.cose.verify` carried `@status experimental` while its `b.cose.sign` sibling is stable and the CWT / EAT / SCITT / mdoc verifiers that depend on it are stable and shipped. The verifier is the same maturity as the rest of the COSE_Sign1 round-trip; its status now reflects that. · *`b.linkHeader.serialize` doc matches its quoting behavior* — The doc said parameters are token-encoded when they fit RFC 7230 token grammar and double-quoted otherwise. The serializer always double-quotes every value (valid under RFC 8288, and required for space-separated multi-rel and media-type values). The doc now states that. · *`b.auth.saml` verifyResponse documented return shape lists all fields* — The prose and the example each omitted a different field that `verifyResponse` always returns. The documented shape now lists all of `nameId`, `nameIdFormat`, `sessionIndex`, `attributes`, `audience`, `inResponseTo`, and `issuer`. · *rate-limit custom-backend contract is `{ take, reset }`* — The custom-backend opts doc listed a `gc` member that the middleware never reads or invokes (the runtime contract is `take` / `reset` / `close`, and the error message already said `{ take, reset }`). The documented shape now matches; an operator-supplied `gc` was always silently ignored. · *`b.mail.agent.create` doc no longer lists consumer as a method* — The created agent's method list named `consumer`, which is not a method on the returned object — the queue consumer is the sibling export `b.mail.agent.consumer`. The doc now says so.
14
+
11
15
  - v0.13.22 (2026-05-27) — **`b.archive.read.zip.fromTrustedStream` reads a ZIP from a Readable — no longer an experimental stub.** fromTrustedStream was an experimental stub whose inspect / entries / extract methods threw, forcing callers to buffer the stream themselves and use the random-access reader. It now works, with the same shape as the tar trusted-stream reader: pass b.archive.adapters.trustedStream(readable) and the bytes are collected into a size-capped buffer (1 GiB hard ceiling) and read through the same bomb-cap, path-traversal, and entry-type decode as the random-access reader — so bombPolicy, guardProfile, entryTypePolicy, and audit all apply, and inspect / entries / extract / extractEntries all return data. This is a bounded-memory reader (the archive is held in memory under the ceiling), not zero-buffer streaming; a future forward-inflate walker shared with the tar reader would lift the ceiling. **Added:** *`b.archive.read.zip.fromTrustedStream` now reads — `inspect` / `entries` / `extract` / `extractEntries`* — The ZIP trusted-stream reader is implemented (was an experimental stub that threw). Pass `b.archive.adapters.trustedStream(readable)` to read a ZIP straight from a Node Readable without buffering it yourself. The stream is collected into a size-capped buffer (1 GiB ceiling, matching `b.archive.read.tar`'s trusted-stream reader) and decoded through the same adversarial-safe path as the random-access reader, so `bombPolicy` / `guardProfile` / `entryTypePolicy` / `audit` are honored on decode. Adversarial archives remain fully bomb-capped; "trusted" refers only to the source-size bound. A non-trusted-stream adapter is refused with `archive-read/bad-adapter`.
12
16
 
13
17
  - v0.13.21 (2026-05-27) — **`b.cose.exportKey` — serialize a public key as a COSE_Key, the inverse of `b.cose.importKey`.** b.cose could import a COSE_Key (RFC 9052 §7) into a node:crypto key for verification, but had no way to produce one — so a key used with b.cose.sign could not be shipped to a verifier in COSE form without hand-building the CBOR map. b.cose.exportKey(keyObject, opts?) closes the round-trip: it serializes an EC2 (P-256 / P-384 / P-521) or OKP (Ed25519) public key as the CBOR-encoded COSE_Key map, with optional alg and kid common parameters. A private key has its public half exported; unsupported curves / key types are refused rather than emitting a COSE_Key no verifier here would accept. The bytes round-trip through b.cose.importKey, and feed the mdoc MSO / COSE_Key header / SCITT / C2PA verification-key paths. **Added:** *`b.cose.exportKey(keyObject, { alg?, kid? })` — KeyObject → COSE_Key (RFC 9052 §7)* — Serialize a `node:crypto` public key as the CBOR-encoded COSE_Key map — the inverse of `b.cose.importKey`. Supports EC2 (P-256 / P-384 / P-521) and OKP (Ed25519), the same key types `b.cose.verify` accepts; `opts.alg` (e.g. `"ES256"`) and `opts.kid` populate the COSE_Key alg (label 3) and kid (label 2) common parameters. A private key exports its public half; unsupported curves / key types throw rather than producing a COSE_Key no verifier would accept. `b.cose.importKey(b.cbor.decode(exportKey(k)))` round-trips, so a key signed with `b.cose.sign` can be shipped to a verifier as bytes — the mdoc MSO / COSE_Key header / SCITT / C2PA verification-key paths.
@@ -370,7 +370,7 @@ function sniffEnvelope(bytes) {
370
370
  * @signature b.archive.wrapWithPassphrase(bytes, opts)
371
371
  * @since 0.12.11
372
372
  * @status stable
373
- * @related b.archive.unwrapWithPassphrase, b.archive.wrap, b.backupCrypto
373
+ * @related b.archive.unwrapWithPassphrase, b.archive.wrap
374
374
  *
375
375
  * Wrap archive bytes in a passphrase-derived envelope. The envelope
376
376
  * wire format is the framework's standard Argon2id (RFC 9106) +
package/lib/auth/jwt.js CHANGED
@@ -48,10 +48,13 @@
48
48
  * subject: claims.sub override
49
49
  * expiresInSec: relative exp (claims.exp = now + expiresInSec)
50
50
  * notBeforeSec: relative nbf (claims.nbf = now + notBeforeSec)
51
- * jti: claims.jti override (string; if missing, no jti is added —
52
- * the framework doesn't auto-mint without an operator request
53
- * since jti has uniqueness/replay-tracking semantics that
54
- * belong at the application layer)
51
+ * jti: claims.jti override (string). When omitted, a random
52
+ * 128-bit jti is auto-minted if (and only if) the token
53
+ * carries an exp — so a replay-protected token always
54
+ * has the jti the verifier's replay store requires,
55
+ * closing the silent hole where a sign without jti would
56
+ * never replay-protect. Pass an explicit jti for a
57
+ * deterministic value.
55
58
  * now: test-time clock injection (epoch milliseconds)
56
59
  *
57
60
  * Verify opts:
package/lib/auth/saml.js CHANGED
@@ -415,7 +415,7 @@ function create(opts) {
415
415
  * (Response-level OR Assertion-level signature), the assertion's
416
416
  * SubjectConfirmation Bearer constraints, and Conditions audience
417
417
  * + time bounds. Returns `{ nameId, nameIdFormat, sessionIndex,
418
- * attributes, audience, inResponseTo }`.
418
+ * attributes, audience, inResponseTo, issuer }`.
419
419
  *
420
420
  * @opts
421
421
  * {
@@ -428,7 +428,7 @@ function create(opts) {
428
428
  * var info = sp.verifyResponse(req.body.SAMLResponse, {
429
429
  * expectedInResponseTo: req.session.samlRequestId,
430
430
  * });
431
- * // → { nameId, nameIdFormat, sessionIndex, attributes, audience, issuer }
431
+ * // → { nameId, nameIdFormat, sessionIndex, attributes, audience, inResponseTo, issuer }
432
432
  * });
433
433
  */
434
434
  function verifyResponse(samlResponseB64, vopts) {
package/lib/cose.js CHANGED
@@ -227,7 +227,7 @@ async function sign(payload, opts) {
227
227
  * @primitive b.cose.verify
228
228
  * @signature b.cose.verify(coseSign1, opts)
229
229
  * @since 0.12.33
230
- * @status experimental
230
+ * @status stable
231
231
  * @related b.cose.sign, b.cbor.decode
232
232
  *
233
233
  * Verify a COSE_Sign1 (RFC 9052) and return its payload + headers.
package/lib/did.js CHANGED
@@ -365,7 +365,7 @@ function resolve(did, opts) {
365
365
  return { didDocument: docW, verificationMethods: _extractVerificationMethods(docW) };
366
366
  }
367
367
 
368
- throw new DidError("did/unsupported-method", "did.resolve: unsupported DID method '" + parsed.method + "' (did:key and did:web only)");
368
+ throw new DidError("did/unsupported-method", "did.resolve: unsupported DID method '" + parsed.method + "' (did:key, did:jwk, and did:web only)");
369
369
  }
370
370
 
371
371
  // Import a publicKeyJwk after allowlisting its kty/crv — a DID document
@@ -650,7 +650,7 @@ function _detectIssues(entries, opts) {
650
650
  *
651
651
  * @opts
652
652
  * profile: "strict"|"balanced"|"permissive",
653
- * compliance: "hipaa"|"pci-dss"|"gdpr"|"soc2",
653
+ * compliancePosture: "hipaa"|"pci-dss"|"gdpr"|"soc2",
654
654
  * traversalPolicy: "reject"|"audit"|"allow",
655
655
  * absolutePathPolicy: "reject"|"audit"|"allow",
656
656
  * symlinkPolicy: "reject"|"audit"|"allow",
@@ -723,7 +723,7 @@ function validateEntries(entries, opts) {
723
723
  *
724
724
  * @opts
725
725
  * profile: "strict"|"balanced"|"permissive",
726
- * compliance: "hipaa"|"pci-dss"|"gdpr"|"soc2",
726
+ * compliancePosture: "hipaa"|"pci-dss"|"gdpr"|"soc2",
727
727
  * name: string,
728
728
  * ...: any validateEntries opt
729
729
  *
package/lib/guard-auth.js CHANGED
@@ -34,7 +34,7 @@
34
34
  *
35
35
  * Profiles: `strict` / `balanced` / `permissive`. Compliance postures:
36
36
  * `hipaa` / `pci-dss` / `gdpr` / `soc2`. Operators select via
37
- * `{ profile: "strict" }` or `{ compliance: "hipaa" }`; postures
37
+ * `{ profile: "strict" }` or `{ compliancePosture: "hipaa" }`; postures
38
38
  * overlay on the profile baseline.
39
39
  *
40
40
  * @card
@@ -205,7 +205,7 @@ function _detectIssues(bundle, opts) {
205
205
  * @compliance hipaa, pci-dss, gdpr, soc2
206
206
  * @related b.guardAuth.sanitize, b.guardAuth.gate, b.guardJwt.validate, b.guardOauth.validate
207
207
  *
208
- * Inspect an auth-bundle object and return `{ ok, issues, summary }`.
208
+ * Inspect an auth-bundle object and return `{ ok, issues }`.
209
209
  * Each issue carries `{ kind, severity, ruleId, source, snippet }`
210
210
  * with severity in `"warn"|"high"|"critical"` and `source` tagging
211
211
  * the sub-guard that raised it (`"jwt"` / `"oauth"` / `"cookies"` /
@@ -219,7 +219,7 @@ function _detectIssues(bundle, opts) {
219
219
  *
220
220
  * @opts
221
221
  * profile: "strict"|"balanced"|"permissive",
222
- * compliance: "hipaa"|"pci-dss"|"gdpr"|"soc2",
222
+ * compliancePosture: "hipaa"|"pci-dss"|"gdpr"|"soc2",
223
223
  * childProfile: "strict"|"balanced"|"permissive", // forwarded to guardJwt / guardOauth
224
224
  * requireAtLeastOne: boolean,
225
225
  * allowedRedirectUris: string[], // forwarded to guardOauth
@@ -256,7 +256,7 @@ function validate(input, opts) {
256
256
  *
257
257
  * @opts
258
258
  * profile: "strict"|"balanced"|"permissive",
259
- * compliance: "hipaa"|"pci-dss"|"gdpr"|"soc2",
259
+ * compliancePosture: "hipaa"|"pci-dss"|"gdpr"|"soc2",
260
260
  *
261
261
  * @example
262
262
  * var clean = b.guardAuth.sanitize({
@@ -300,7 +300,7 @@ function sanitize(input, opts) {
300
300
  *
301
301
  * @opts
302
302
  * profile: "strict"|"balanced"|"permissive",
303
- * compliance: "hipaa"|"pci-dss"|"gdpr"|"soc2",
303
+ * compliancePosture: "hipaa"|"pci-dss"|"gdpr"|"soc2",
304
304
  * name: string, // gate identity for audit / observability
305
305
  * childProfile: "strict"|"balanced"|"permissive",
306
306
  * allowedRedirectUris: string[],
package/lib/guard-cidr.js CHANGED
@@ -437,7 +437,7 @@ function _detectIssues(input, opts) {
437
437
  * @compliance hipaa, pci-dss, gdpr, soc2
438
438
  * @related b.guardCidr.sanitize, b.guardCidr.gate
439
439
  *
440
- * Inspect a CIDR notation string and return `{ ok, issues, summary }`.
440
+ * Inspect a CIDR notation string and return `{ ok, issues }`.
441
441
  * Each issue carries `{ kind, severity, ruleId, snippet }` with
442
442
  * severity in `"warn"|"high"|"critical"`. Detected: malformed address
443
443
  * shape, octet-out-of-range, mask-out-of-range, network-address
@@ -448,7 +448,7 @@ function _detectIssues(input, opts) {
448
448
  *
449
449
  * @opts
450
450
  * profile: "strict"|"balanced"|"permissive",
451
- * compliance: "hipaa"|"pci-dss"|"gdpr"|"soc2",
451
+ * compliancePosture: "hipaa"|"pci-dss"|"gdpr"|"soc2",
452
452
  * family: "either"|"ipv4-only"|"ipv6-only",
453
453
  * networkAlignmentPolicy: "reject"|"audit"|"allow",
454
454
  * reservedRangesPolicy: "reject"|"audit"|"allow",
@@ -496,7 +496,7 @@ function validate(input, opts) {
496
496
  *
497
497
  * @opts
498
498
  * profile: "strict"|"balanced"|"permissive",
499
- * compliance: "hipaa"|"pci-dss"|"gdpr"|"soc2",
499
+ * compliancePosture: "hipaa"|"pci-dss"|"gdpr"|"soc2",
500
500
  *
501
501
  * @example
502
502
  * var safe = b.guardCidr.sanitize("2001:DB8::/32", { profile: "permissive" });
@@ -542,7 +542,7 @@ function sanitize(input, opts) {
542
542
  *
543
543
  * @opts
544
544
  * profile: "strict"|"balanced"|"permissive",
545
- * compliance: "hipaa"|"pci-dss"|"gdpr"|"soc2",
545
+ * compliancePosture: "hipaa"|"pci-dss"|"gdpr"|"soc2",
546
546
  * name: string, // gate identity for audit / observability
547
547
  * family: "either"|"ipv4-only"|"ipv6-only",
548
548
  *
package/lib/guard-csv.js CHANGED
@@ -43,7 +43,7 @@
43
43
  * Profiles: `strict` / `balanced` / `permissive` /
44
44
  * `email-attachment`. Compliance postures: `hipaa` / `pci-dss` /
45
45
  * `gdpr` / `soc2`. Operators select via `{ profile: "strict" }` or
46
- * `{ compliance: "hipaa" }`; postures overlay on top of the
46
+ * `{ compliancePosture: "hipaa" }`; postures overlay on top of the
47
47
  * profile baseline.
48
48
  *
49
49
  * Threat-detection regex literals are composed programmatically
@@ -696,7 +696,7 @@ function schema(spec) {
696
696
  *
697
697
  * @opts
698
698
  * profile: "strict"|"balanced"|"permissive"|"email-attachment",
699
- * compliance: "hipaa"|"pci-dss"|"gdpr"|"soc2",
699
+ * compliancePosture: "hipaa"|"pci-dss"|"gdpr"|"soc2",
700
700
  * headers: string[]|false, // explicit column order; false suppresses header row
701
701
  * delimiter: string, // default ","
702
702
  * lineEnding: string, // default "\r\n"
@@ -802,7 +802,7 @@ function serialize(rows, opts) {
802
802
  * @related b.guardCsv.sanitize, b.guardCsv.gate
803
803
  *
804
804
  * Inspect `input` (string or Buffer of CSV text) and return
805
- * `{ ok, issues, summary }`. Each issue carries `{ kind, severity,
805
+ * `{ ok, issues }`. Each issue carries `{ kind, severity,
806
806
  * ruleId, location, snippet }` with severity in
807
807
  * `"warn"|"high"|"critical"`. Detected: BOM mid-stream, Unicode
808
808
  * bidi override (CVE-2021-42574), C0 control char, null byte,
@@ -813,7 +813,7 @@ function serialize(rows, opts) {
813
813
  *
814
814
  * @opts
815
815
  * profile: "strict"|"balanced"|"permissive"|"email-attachment",
816
- * compliance: "hipaa"|"pci-dss"|"gdpr"|"soc2",
816
+ * compliancePosture: "hipaa"|"pci-dss"|"gdpr"|"soc2",
817
817
  * bidiCharPolicy: "reject"|"strip"|"audit"|"allow",
818
818
  * controlCharPolicy: "reject"|"strip"|"allow",
819
819
  * nullByteHandling: "reject"|"strip"|"allow",
@@ -860,7 +860,7 @@ function validate(input, opts) {
860
860
  *
861
861
  * @opts
862
862
  * profile: "strict"|"balanced"|"permissive"|"email-attachment",
863
- * compliance: "hipaa"|"pci-dss"|"gdpr"|"soc2",
863
+ * compliancePosture: "hipaa"|"pci-dss"|"gdpr"|"soc2",
864
864
  * bidiCharPolicy: "reject"|"strip"|"audit"|"allow",
865
865
  * controlCharPolicy: "reject"|"strip"|"allow",
866
866
  * nullByteHandling: "reject"|"strip"|"allow",
@@ -981,7 +981,7 @@ function detect(input) {
981
981
  *
982
982
  * @opts
983
983
  * profile: "strict"|"balanced"|"permissive"|"email-attachment",
984
- * compliance: "hipaa"|"pci-dss"|"gdpr"|"soc2",
984
+ * compliancePosture: "hipaa"|"pci-dss"|"gdpr"|"soc2",
985
985
  * name: string, // gate identity for audit / observability
986
986
  * operatorRules: [{ id: string, severity: "warn"|"high"|"critical",
987
987
  * detect: function, reason: string }],
@@ -563,7 +563,7 @@ function _detectIssues(input, opts) {
563
563
  * @compliance hipaa, pci-dss, gdpr, soc2
564
564
  * @related b.guardDomain.sanitize, b.guardDomain.gate
565
565
  *
566
- * Inspect a domain-name string and return `{ ok, issues, summary }`.
566
+ * Inspect a domain-name string and return `{ ok, issues }`.
567
567
  * Each issue carries `{ kind, severity, ruleId, snippet }` with
568
568
  * severity in `"warn"|"high"|"critical"`. Detected: domain/label
569
569
  * length cap (RFC 1035 §2.3.4), LDH violation, IDN A-label
@@ -575,7 +575,7 @@ function _detectIssues(input, opts) {
575
575
  *
576
576
  * @opts
577
577
  * profile: "strict"|"balanced"|"permissive",
578
- * compliance: "hipaa"|"pci-dss"|"gdpr"|"soc2",
578
+ * compliancePosture: "hipaa"|"pci-dss"|"gdpr"|"soc2",
579
579
  * ldhPolicy: "reject"|"audit"|"allow",
580
580
  * punycodePolicy: "reject"|"audit"|"allow",
581
581
  * mixedScriptPolicy: "reject"|"audit"|"allow",
@@ -635,7 +635,7 @@ function validate(input, opts) {
635
635
  *
636
636
  * @opts
637
637
  * profile: "strict"|"balanced"|"permissive",
638
- * compliance: "hipaa"|"pci-dss"|"gdpr"|"soc2",
638
+ * compliancePosture: "hipaa"|"pci-dss"|"gdpr"|"soc2",
639
639
  *
640
640
  * @example
641
641
  * var safe = b.guardDomain.sanitize("Example.Com.", { profile: "balanced" });
@@ -677,7 +677,7 @@ function sanitize(input, opts) {
677
677
  *
678
678
  * @opts
679
679
  * profile: "strict"|"balanced"|"permissive",
680
- * compliance: "hipaa"|"pci-dss"|"gdpr"|"soc2",
680
+ * compliancePosture: "hipaa"|"pci-dss"|"gdpr"|"soc2",
681
681
  * name: string, // gate identity for audit / observability
682
682
  *
683
683
  * @example
@@ -840,9 +840,10 @@ function sanitize(input, opts) {
840
840
  * @status stable
841
841
  * @related b.guardEmail.validateMessage, b.guardEmail.sanitize, b.guardAll.gate
842
842
  *
843
- * Build a guard gate function compatible with the `b.guardAll` family
844
- * dispatch. The returned async gate accepts a request-shaped context,
845
- * runs `validateMessage` against the extracted bytes, and returns
843
+ * Build a guard gate compatible with the `b.guardAll` family
844
+ * dispatch. The returned gate's async `check(ctx)` method accepts a
845
+ * request-shaped context, runs `validateMessage` against the extracted
846
+ * bytes, and returns
846
847
  * `{ ok, action, issues? }` where `action` is `serve` (no issues),
847
848
  * `audit-only` (warn-level), or `refuse` (high / critical severity).
848
849
  *
@@ -854,11 +855,11 @@ function sanitize(input, opts) {
854
855
  * @example
855
856
  * var guardEmail = require("./lib/guard-email");
856
857
  * var g = guardEmail.gate({ profile: "strict" });
857
- * typeof g; // → "function"
858
+ * typeof g.check; // → "function"
858
859
  *
859
860
  * var msg = "From: alice@example.com\r\nTo: bob@example.com\r\n" +
860
861
  * "Subject: hi\r\nDate: Mon, 5 May 2026 10:00:00 +0000\r\n\r\nbody\r\n";
861
- * g({ body: Buffer.from(msg, "utf8") }).then(function (rv) {
862
+ * g.check({ body: Buffer.from(msg, "utf8") }).then(function (rv) {
862
863
  * rv.action; // → "serve"
863
864
  * });
864
865
  */
@@ -634,7 +634,7 @@ function _sanitize(input, opts) {
634
634
  * @related b.guardFilename.sanitize, b.guardFilename.gate
635
635
  *
636
636
  * Inspect a filename (string or Buffer) and return
637
- * `{ ok, issues, summary }`. Each issue carries
637
+ * `{ ok, issues }`. Each issue carries
638
638
  * `{ kind, severity, ruleId, location, snippet }` with severity in
639
639
  * `"warn"|"high"|"critical"`. Detected: path-traversal raw and
640
640
  * percent-encoded, null-byte truncation, NTFS ADS, UNC path,
@@ -647,7 +647,7 @@ function _sanitize(input, opts) {
647
647
  *
648
648
  * @opts
649
649
  * profile: "strict"|"balanced"|"permissive",
650
- * compliance: "hipaa"|"pci-dss"|"gdpr"|"soc2",
650
+ * compliancePosture: "hipaa"|"pci-dss"|"gdpr"|"soc2",
651
651
  * bidiPolicy: "reject"|"strip"|"allow",
652
652
  * controlPolicy: "reject"|"strip"|"allow",
653
653
  * nullBytePolicy: "reject", // always reject
@@ -759,7 +759,7 @@ function _sanitizeStripMode(input, opts) {
759
759
  *
760
760
  * @opts
761
761
  * profile: "strict"|"balanced"|"permissive",
762
- * compliance: "hipaa"|"pci-dss"|"gdpr"|"soc2",
762
+ * compliancePosture: "hipaa"|"pci-dss"|"gdpr"|"soc2",
763
763
  * mode: "enforce"|"strip",
764
764
  * audit: { safeEmit: function }, // optional sink for strip mode
765
765
  * unicodeNormalization: "NFC"|null,
@@ -820,7 +820,7 @@ function sanitize(input, opts) {
820
820
  *
821
821
  * @opts
822
822
  * profile: "strict"|"balanced"|"permissive",
823
- * compliance: "hipaa"|"pci-dss"|"gdpr"|"soc2",
823
+ * compliancePosture: "hipaa"|"pci-dss"|"gdpr"|"soc2",
824
824
  * name: string, // gate identity for audit / observability
825
825
  *
826
826
  * @example
@@ -458,7 +458,7 @@ function _detectIssues(req, opts) {
458
458
  * @related b.guardGraphql.sanitize, b.guardGraphql.gate
459
459
  *
460
460
  * Apply the full guard-graphql threat catalog to a request bundle
461
- * (or batch array). Returns `{ ok, issues, refusal? }` per
461
+ * (or batch array). Returns `{ ok, issues }` per
462
462
  * `gateContract.aggregateIssues`. Detected classes include
463
463
  * `query-missing`, `query-cap`, `variables-cap`, `request-cap`,
464
464
  * `batch-size`, `introspection`, `persisted-query-missing`,
@@ -469,7 +469,7 @@ function _detectIssues(req, opts) {
469
469
  *
470
470
  * @opts
471
471
  * profile: "strict"|"balanced"|"permissive",
472
- * compliance: "hipaa"|"pci-dss"|"gdpr"|"soc2",
472
+ * compliancePosture: "hipaa"|"pci-dss"|"gdpr"|"soc2",
473
473
  * introspectionPolicy: "reject"|"audit"|"allow",
474
474
  * persistedQueryPolicy: "require"|"audit"|"allow",
475
475
  * operationNamePolicy: "reject"|"audit"|"allow",
@@ -528,7 +528,7 @@ function validate(input, opts) {
528
528
  *
529
529
  * @opts
530
530
  * profile: "strict"|"balanced"|"permissive",
531
- * compliance: "hipaa"|"pci-dss"|"gdpr"|"soc2",
531
+ * compliancePosture: "hipaa"|"pci-dss"|"gdpr"|"soc2",
532
532
  * ...: every guardGraphql.validate opt is honored,
533
533
  *
534
534
  * @example
@@ -573,13 +573,13 @@ function sanitize(input, opts) {
573
573
  *
574
574
  * @opts
575
575
  * profile: "strict"|"balanced"|"permissive",
576
- * compliance: "hipaa"|"pci-dss"|"gdpr"|"soc2",
576
+ * compliancePosture: "hipaa"|"pci-dss"|"gdpr"|"soc2",
577
577
  * name: string, // gate label for audit trails
578
578
  * ...: every guardGraphql.validate opt is honored,
579
579
  *
580
580
  * @example
581
581
  * var gqlGate = b.guardGraphql.gate({ profile: "strict" });
582
- * var rv = await gqlGate.run({
582
+ * var rv = await gqlGate.check({
583
583
  * graphqlRequest: {
584
584
  * query: "{ a:me { id } b:me { id } c:me { id } d:me { id } " +
585
585
  * "e:me { id } f:me { id } g:me { id } h:me { id } " +
package/lib/guard-html.js CHANGED
@@ -1030,7 +1030,7 @@ function sanitize(input, opts) {
1030
1030
  * Returns a guard descriptor that plugs into the framework's
1031
1031
  * content-safety wiring (`b.fileUpload.contentSafety` /
1032
1032
  * `b.staticServe.contentSafety` / `b.guardAll`). The descriptor's
1033
- * `inspect(ctx)` resolves to one of four actions: `serve` (no
1033
+ * `check(ctx)` resolves to one of four actions: `serve` (no
1034
1034
  * issues), `audit-only` (low-severity issues observed), `sanitize`
1035
1035
  * (sanitized buffer attached when no policy is "reject"), or
1036
1036
  * `refuse` (critical issue with at least one reject-policy active).
@@ -1057,7 +1057,7 @@ function sanitize(input, opts) {
1057
1057
  *
1058
1058
  * // Refuse on tag-budget exceeded — strict profile rejects <script>.
1059
1059
  * var hostileBuf = Buffer.from("<p>hi</p><script>alert(1)</script>", "utf8");
1060
- * var rv = await g.inspect({ bytes: hostileBuf, contentType: "text/html" });
1060
+ * var rv = await g.check({ bytes: hostileBuf, contentType: "text/html" });
1061
1061
  * rv.ok; // → false
1062
1062
  * rv.action; // → "refuse"
1063
1063
  */
@@ -421,7 +421,7 @@ function sanitize(input, opts) {
421
421
  *
422
422
  * @opts
423
423
  * profile: "strict"|"balanced"|"permissive",
424
- * compliance: "hipaa"|"pci-dss"|"gdpr"|"soc2",
424
+ * compliancePosture: "hipaa"|"pci-dss"|"gdpr"|"soc2",
425
425
  * name: string,
426
426
  * ...: any validate opt
427
427
  *
package/lib/guard-json.js CHANGED
@@ -59,7 +59,7 @@
59
59
  *
60
60
  * Profiles: `strict` / `balanced` / `permissive`. Compliance
61
61
  * postures: `hipaa` / `pci-dss` / `gdpr` / `soc2`. Operators select
62
- * via `{ profile: "strict" }` or `{ compliance: "hipaa" }`;
62
+ * via `{ profile: "strict" }` or `{ compliancePosture: "hipaa" }`;
63
63
  * postures overlay on top of the profile baseline.
64
64
  *
65
65
  * Source files MUST be pure ASCII; threat-detection regexes
@@ -571,7 +571,7 @@ function _stripPollutionTree(value, opts, depth) {
571
571
  *
572
572
  * Inspect `input` (string of JSON source) for the full guard-json
573
573
  * threat catalog without committing to a parsed value. Returns
574
- * `{ ok, issues, severities }` where `issues` is the aggregated
574
+ * `{ ok, issues }` where `issues` is the aggregated
575
575
  * detector output — every prototype-pollution key, depth/breadth
576
576
  * cap hit, duplicate-key smuggle, JSON5-quirk match, BOM placement,
577
577
  * unicode threat, and numeric-precision-loss candidate is reported
@@ -587,7 +587,7 @@ function _stripPollutionTree(value, opts, depth) {
587
587
  *
588
588
  * @opts
589
589
  * profile: "strict"|"balanced"|"permissive",
590
- * compliance: "hipaa"|"pci-dss"|"gdpr"|"soc2",
590
+ * compliancePosture: "hipaa"|"pci-dss"|"gdpr"|"soc2",
591
591
  * pollutionPolicy: "reject"|"strip"|"audit"|"allow",
592
592
  * duplicateKeyPolicy: "reject"|"audit"|"allow",
593
593
  * nanInfinityPolicy: "reject"|"audit"|"allow",
@@ -660,7 +660,7 @@ function validate(input, opts) {
660
660
  *
661
661
  * @opts
662
662
  * profile: "strict"|"balanced"|"permissive",
663
- * compliance: "hipaa"|"pci-dss"|"gdpr"|"soc2",
663
+ * compliancePosture: "hipaa"|"pci-dss"|"gdpr"|"soc2",
664
664
  * pollutionPolicy: "reject"|"strip"|"audit"|"allow",
665
665
  * bomPolicy: "reject"|"strip"|"allow",
666
666
  * controlPolicy: "reject"|"strip"|"allow",
@@ -770,7 +770,7 @@ function _policyKeyForRuleId(ruleId) {
770
770
  *
771
771
  * @opts
772
772
  * profile: "strict"|"balanced"|"permissive",
773
- * compliance: "hipaa"|"pci-dss"|"gdpr"|"soc2",
773
+ * compliancePosture: "hipaa"|"pci-dss"|"gdpr"|"soc2",
774
774
  * name: string, // gate identity for audit / observability
775
775
  *
776
776
  * @example
@@ -34,7 +34,7 @@
34
34
  * Profiles: `strict` / `balanced` / `permissive`. Compliance
35
35
  * postures: `hipaa` / `pci-dss` / `gdpr` / `soc2`. Operators
36
36
  * select via `{ profile: "strict" }` or
37
- * `{ compliance: "hipaa" }`; postures overlay on top of the
37
+ * `{ compliancePosture: "hipaa" }`; postures overlay on top of the
38
38
  * profile baseline. Filter / script / dynamic-hint refusal holds
39
39
  * at every profile — the RCE class is never an operator opt-in.
40
40
  *
@@ -257,7 +257,7 @@ function _detectIssues(input, opts) {
257
257
  *
258
258
  * @opts
259
259
  * profile: "strict"|"balanced"|"permissive",
260
- * compliance: "hipaa"|"pci-dss"|"gdpr"|"soc2",
260
+ * compliancePosture: "hipaa"|"pci-dss"|"gdpr"|"soc2",
261
261
  * bidiPolicy: "reject"|"audit"|"allow",
262
262
  * controlPolicy: "reject"|"audit"|"allow",
263
263
  * nullBytePolicy: "reject"|"audit"|"allow",
@@ -308,7 +308,7 @@ function validate(input, opts) {
308
308
  *
309
309
  * @opts
310
310
  * profile: "strict"|"balanced"|"permissive",
311
- * compliance: "hipaa"|"pci-dss"|"gdpr"|"soc2",
311
+ * compliancePosture: "hipaa"|"pci-dss"|"gdpr"|"soc2",
312
312
  * filterExprPolicy: "reject"|"audit"|"allow",
313
313
  * scriptExprPolicy: "reject"|"audit"|"allow",
314
314
  * dynamicHintPolicy: "reject"|"audit"|"allow",
@@ -360,7 +360,7 @@ function sanitize(input, opts) {
360
360
  *
361
361
  * @opts
362
362
  * profile: "strict"|"balanced"|"permissive",
363
- * compliance: "hipaa"|"pci-dss"|"gdpr"|"soc2",
363
+ * compliancePosture: "hipaa"|"pci-dss"|"gdpr"|"soc2",
364
364
  * name: string, // override gate name in audit emissions
365
365
  * filterExprPolicy: "reject"|"audit"|"allow",
366
366
  * scriptExprPolicy: "reject"|"audit"|"allow",
package/lib/guard-jwt.js CHANGED
@@ -441,7 +441,7 @@ function _detectIssues(input, opts) {
441
441
  * @related b.guardJwt.sanitize, b.guardJwt.gate
442
442
  *
443
443
  * Apply the full guard-jwt threat catalog to a JWT compact-
444
- * serialization string. Returns `{ ok, issues, refusal? }` per
444
+ * serialization string. Returns `{ ok, issues }` per
445
445
  * `gateContract.aggregateIssues`. Detected classes include
446
446
  * `alg-none` (always critical), `kid-traversal` (always critical),
447
447
  * `alg-not-allowed`, `typ-confusion`, `crit-unknown`, `exp-past`,
@@ -456,7 +456,7 @@ function _detectIssues(input, opts) {
456
456
  *
457
457
  * @opts
458
458
  * profile: "strict"|"balanced"|"permissive",
459
- * compliance: "hipaa"|"pci-dss"|"gdpr"|"soc2",
459
+ * compliancePosture: "hipaa"|"pci-dss"|"gdpr"|"soc2",
460
460
  * allowedAlgs: string[],
461
461
  * requiredClaims: string[],
462
462
  * knownCrit: string[],
@@ -524,7 +524,7 @@ function validate(input, opts) {
524
524
  *
525
525
  * @opts
526
526
  * profile: "strict"|"balanced"|"permissive",
527
- * compliance: "hipaa"|"pci-dss"|"gdpr"|"soc2",
527
+ * compliancePosture: "hipaa"|"pci-dss"|"gdpr"|"soc2",
528
528
  * ...: every guardJwt.validate opt is honored,
529
529
  *
530
530
  * @example
@@ -573,13 +573,13 @@ function sanitize(input, opts) {
573
573
  *
574
574
  * @opts
575
575
  * profile: "strict"|"balanced"|"permissive",
576
- * compliance: "hipaa"|"pci-dss"|"gdpr"|"soc2",
576
+ * compliancePosture: "hipaa"|"pci-dss"|"gdpr"|"soc2",
577
577
  * name: string, // gate label for audit trails
578
578
  * ...: every guardJwt.validate opt is honored,
579
579
  *
580
580
  * @example
581
581
  * var jwtGate = b.guardJwt.gate({ profile: "strict" });
582
- * var rv = await jwtGate.run({
582
+ * var rv = await jwtGate.check({
583
583
  * identifier:
584
584
  * "eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0." +
585
585
  * "eyJzdWIiOiJhdHRhY2tlciJ9.",
@@ -505,7 +505,7 @@ function _detectIssues(input, opts) {
505
505
  *
506
506
  * @opts
507
507
  * profile: "strict"|"balanced"|"permissive",
508
- * compliance: "hipaa"|"pci-dss"|"gdpr"|"soc2",
508
+ * compliancePosture: "hipaa"|"pci-dss"|"gdpr"|"soc2",
509
509
  * bidiPolicy: "reject"|"strip"|"audit"|"allow",
510
510
  * controlPolicy: "reject"|"strip"|"allow",
511
511
  * nullBytePolicy: "reject"|"strip"|"allow",
@@ -568,7 +568,7 @@ function validate(input, opts) {
568
568
  *
569
569
  * @opts
570
570
  * profile: "strict"|"balanced"|"permissive",
571
- * compliance: "hipaa"|"pci-dss"|"gdpr"|"soc2",
571
+ * compliancePosture: "hipaa"|"pci-dss"|"gdpr"|"soc2",
572
572
  * ...: same shape as b.guardMarkdown.validate opts,
573
573
  *
574
574
  * @example
@@ -606,7 +606,7 @@ function sanitize(input, opts) {
606
606
  * @compliance hipaa, pci-dss, gdpr, soc2
607
607
  * @related b.guardMarkdown.validate, b.guardMarkdown.sanitize, b.guardAll.gate, b.staticServe.create
608
608
  *
609
- * Build an async gate `(ctx) -> { ok, action, issues }` consumable
609
+ * Build a guard gate whose async `check(ctx)` returns `{ ok, action, issues }`, consumable
610
610
  * by `b.guardAll`, `b.staticServe`, `b.fileUpload`, and any host
611
611
  * that ingests user-supplied markdown. The gate decodes
612
612
  * `ctx.bytes` / `ctx.bodyText`, runs `validate`, and maps
@@ -617,15 +617,15 @@ function sanitize(input, opts) {
617
617
  * @opts
618
618
  * name: string, // gate label for audit / observability
619
619
  * profile: "strict"|"balanced"|"permissive",
620
- * compliance: "hipaa"|"pci-dss"|"gdpr"|"soc2",
620
+ * compliancePosture: "hipaa"|"pci-dss"|"gdpr"|"soc2",
621
621
  * ...: same shape as b.guardMarkdown.validate opts,
622
622
  *
623
623
  * @example
624
624
  * var g = b.guardMarkdown.gate({ profile: "strict" });
625
- * var rv = await g({ bytes: Buffer.from("# hello\n", "utf8") });
625
+ * var rv = await g.check({ bytes: Buffer.from("# hello\n", "utf8") });
626
626
  * rv.action; // → "serve"
627
627
  *
628
- * var bad = await g({ bytes: Buffer.from("[x](javascript:1)", "utf8") });
628
+ * var bad = await g.check({ bytes: Buffer.from("[x](javascript:1)", "utf8") });
629
629
  * bad.action; // → "refuse"
630
630
  */
631
631
  function gate(opts) {
package/lib/guard-mime.js CHANGED
@@ -369,7 +369,7 @@ function _detectIssues(input, opts) {
369
369
  *
370
370
  * @opts
371
371
  * profile: "strict"|"balanced"|"permissive",
372
- * compliance: "hipaa"|"pci-dss"|"gdpr"|"soc2",
372
+ * compliancePosture: "hipaa"|"pci-dss"|"gdpr"|"soc2",
373
373
  * bidiPolicy: "reject"|"strip"|"audit"|"allow",
374
374
  * controlPolicy: "reject"|"strip"|"allow",
375
375
  * nullBytePolicy: "reject"|"strip"|"allow",
@@ -423,7 +423,7 @@ function validate(input, opts) {
423
423
  *
424
424
  * @opts
425
425
  * profile: "strict"|"balanced"|"permissive",
426
- * compliance: "hipaa"|"pci-dss"|"gdpr"|"soc2",
426
+ * compliancePosture: "hipaa"|"pci-dss"|"gdpr"|"soc2",
427
427
  * ...: same shape as b.guardMime.validate opts,
428
428
  *
429
429
  * @example
@@ -467,7 +467,7 @@ function sanitize(input, opts) {
467
467
  * @compliance hipaa, pci-dss, gdpr, soc2
468
468
  * @related b.guardMime.validate, b.guardMime.sanitize, b.guardAll.gate
469
469
  *
470
- * Build an async gate `(ctx) -> { ok, action, issues }` consumable
470
+ * Build a guard gate whose async `check(ctx)` returns `{ ok, action, issues }`, consumable
471
471
  * by `b.guardAll`, `b.staticServe`, `b.fileUpload`, and any other
472
472
  * host that integrates the guard contract. The gate reads
473
473
  * `ctx.identifier` (or `ctx.mime`), runs `validate`, and maps
@@ -477,15 +477,15 @@ function sanitize(input, opts) {
477
477
  * @opts
478
478
  * name: string, // gate label for audit / observability
479
479
  * profile: "strict"|"balanced"|"permissive",
480
- * compliance: "hipaa"|"pci-dss"|"gdpr"|"soc2",
480
+ * compliancePosture: "hipaa"|"pci-dss"|"gdpr"|"soc2",
481
481
  * ...: same shape as b.guardMime.validate opts,
482
482
  *
483
483
  * @example
484
484
  * var g = b.guardMime.gate({ profile: "strict" });
485
- * var rv = await g({ identifier: "application/json" });
485
+ * var rv = await g.check({ identifier: "application/json" });
486
486
  * rv.action; // → "serve"
487
487
  *
488
- * var bad = await g({ identifier: "application/x-msdownload" });
488
+ * var bad = await g.check({ identifier: "application/x-msdownload" });
489
489
  * bad.action; // → "refuse"
490
490
  */
491
491
  function gate(opts) {
@@ -352,7 +352,7 @@ function _detectIssues(flow, opts) {
352
352
  * @related b.guardOauth.sanitize, b.guardOauth.gate
353
353
  *
354
354
  * Apply the full guard-oauth threat catalog to a flow bundle.
355
- * Returns `{ ok, issues, refusal? }` per
355
+ * Returns `{ ok, issues }` per
356
356
  * `gateContract.aggregateIssues`. Detected classes include
357
357
  * `pkce-missing`, `pkce-method` (e.g. plain under require-s256),
358
358
  * `state-missing`, `redirect-uri-not-allowed`,
@@ -365,7 +365,7 @@ function _detectIssues(flow, opts) {
365
365
  *
366
366
  * @opts
367
367
  * profile: "strict"|"balanced"|"permissive",
368
- * compliance: "hipaa"|"pci-dss"|"gdpr"|"soc2",
368
+ * compliancePosture: "hipaa"|"pci-dss"|"gdpr"|"soc2",
369
369
  * pkcePolicy: "require-s256"|"require-any"|"audit"|"allow",
370
370
  * statePolicy: "require"|"audit"|"allow",
371
371
  * redirectUriPolicy: "require-exact-allowlist"|"audit"|"allow",
@@ -427,7 +427,7 @@ function validate(input, opts) {
427
427
  *
428
428
  * @opts
429
429
  * profile: "strict"|"balanced"|"permissive",
430
- * compliance: "hipaa"|"pci-dss"|"gdpr"|"soc2",
430
+ * compliancePosture: "hipaa"|"pci-dss"|"gdpr"|"soc2",
431
431
  * ...: every guardOauth.validate opt is honored,
432
432
  *
433
433
  * @example
@@ -475,7 +475,7 @@ function sanitize(input, opts) {
475
475
  *
476
476
  * @opts
477
477
  * profile: "strict"|"balanced"|"permissive",
478
- * compliance: "hipaa"|"pci-dss"|"gdpr"|"soc2",
478
+ * compliancePosture: "hipaa"|"pci-dss"|"gdpr"|"soc2",
479
479
  * name: string, // gate label for audit trails
480
480
  * ...: every guardOauth.validate opt is honored,
481
481
  *
@@ -484,7 +484,7 @@ function sanitize(input, opts) {
484
484
  * profile: "strict",
485
485
  * allowedRedirectUris: ["https://app.example.com/callback"],
486
486
  * });
487
- * var rv = await oauthGate.run({
487
+ * var rv = await oauthGate.check({
488
488
  * oauthFlow: {
489
489
  * response_type: "code",
490
490
  * redirect_uri: "https://attacker.example/callback",
package/lib/guard-pdf.js CHANGED
@@ -410,7 +410,7 @@ function sanitize(input, opts) {
410
410
  *
411
411
  * @opts
412
412
  * profile: "strict"|"balanced"|"permissive",
413
- * compliance: "hipaa"|"pci-dss"|"gdpr"|"soc2",
413
+ * compliancePosture: "hipaa"|"pci-dss"|"gdpr"|"soc2",
414
414
  * name: string,
415
415
  * ...: any validate opt
416
416
  *
@@ -30,7 +30,7 @@
30
30
  * Profiles: `strict` / `balanced` / `permissive`. Compliance
31
31
  * postures: `hipaa` / `pci-dss` / `gdpr` / `soc2`. Operators
32
32
  * select via `{ profile: "strict" }` or
33
- * `{ compliance: "hipaa" }`; postures overlay on top of the
33
+ * `{ compliancePosture: "hipaa" }`; postures overlay on top of the
34
34
  * profile baseline. Nested-quantifier rejection holds at every
35
35
  * profile — the catastrophic class is never an operator opt-in.
36
36
  *
@@ -368,7 +368,7 @@ function _detectNestedExtglob(input, opts, issues) {
368
368
  *
369
369
  * @opts
370
370
  * profile: "strict"|"balanced"|"permissive",
371
- * compliance: "hipaa"|"pci-dss"|"gdpr"|"soc2",
371
+ * compliancePosture: "hipaa"|"pci-dss"|"gdpr"|"soc2",
372
372
  * bidiPolicy: "reject"|"audit"|"allow",
373
373
  * controlPolicy: "reject"|"audit"|"allow",
374
374
  * nullBytePolicy: "reject"|"audit"|"allow",
@@ -422,7 +422,7 @@ function validate(input, opts) {
422
422
  *
423
423
  * @opts
424
424
  * profile: "strict"|"balanced"|"permissive",
425
- * compliance: "hipaa"|"pci-dss"|"gdpr"|"soc2",
425
+ * compliancePosture: "hipaa"|"pci-dss"|"gdpr"|"soc2",
426
426
  * nestedQuantPolicy: "reject"|"audit"|"allow",
427
427
  * alternationQuantPolicy: "reject"|"audit"|"allow",
428
428
  * boundedRepeatPolicy: "reject"|"audit"|"allow",
@@ -477,7 +477,7 @@ function sanitize(input, opts) {
477
477
  *
478
478
  * @opts
479
479
  * profile: "strict"|"balanced"|"permissive",
480
- * compliance: "hipaa"|"pci-dss"|"gdpr"|"soc2",
480
+ * compliancePosture: "hipaa"|"pci-dss"|"gdpr"|"soc2",
481
481
  * name: string, // override gate name in audit emissions
482
482
  * nestedQuantPolicy: "reject"|"audit"|"allow",
483
483
  * alternationQuantPolicy: "reject"|"audit"|"allow",
@@ -28,7 +28,7 @@
28
28
  *
29
29
  * Profiles: `strict` / `balanced` / `permissive`. Compliance
30
30
  * postures: `hipaa` / `pci-dss` / `gdpr` / `soc2`. Operators select
31
- * via `{ profile: "strict" }` or `{ compliance: "hipaa" }`;
31
+ * via `{ profile: "strict" }` or `{ compliancePosture: "hipaa" }`;
32
32
  * postures overlay on top of the profile baseline.
33
33
  *
34
34
  * Shell args cannot be repaired safely — `sanitize` either passes
@@ -262,7 +262,7 @@ function _detectIssues(input, opts) {
262
262
  *
263
263
  * @opts
264
264
  * profile: "strict"|"balanced"|"permissive",
265
- * compliance: "hipaa"|"pci-dss"|"gdpr"|"soc2",
265
+ * compliancePosture: "hipaa"|"pci-dss"|"gdpr"|"soc2",
266
266
  * bidiPolicy: "reject"|"audit"|"allow",
267
267
  * controlPolicy: "reject"|"audit"|"allow",
268
268
  * nullBytePolicy: "reject"|"audit"|"allow",
@@ -314,7 +314,7 @@ function validate(input, opts) {
314
314
  *
315
315
  * @opts
316
316
  * profile: "strict"|"balanced"|"permissive",
317
- * compliance: "hipaa"|"pci-dss"|"gdpr"|"soc2",
317
+ * compliancePosture: "hipaa"|"pci-dss"|"gdpr"|"soc2",
318
318
  * posixMetaPolicy: "reject"|"audit"|"allow",
319
319
  * cmdMetaPolicy: "reject"|"audit"|"allow",
320
320
  * dollarSubstPolicy: "reject"|"audit"|"allow",
@@ -369,7 +369,7 @@ function sanitize(input, opts) {
369
369
  *
370
370
  * @opts
371
371
  * profile: "strict"|"balanced"|"permissive",
372
- * compliance: "hipaa"|"pci-dss"|"gdpr"|"soc2",
372
+ * compliancePosture: "hipaa"|"pci-dss"|"gdpr"|"soc2",
373
373
  * name: string, // override gate name in audit emissions
374
374
  * posixMetaPolicy: "reject"|"audit"|"allow",
375
375
  * cmdMetaPolicy: "reject"|"audit"|"allow",
package/lib/guard-svg.js CHANGED
@@ -1017,9 +1017,9 @@ function sanitize(input, opts) {
1017
1017
  * @status stable
1018
1018
  * @related b.guardSvg.validate, b.guardSvg.sanitize, b.fileUpload, b.staticServe
1019
1019
  *
1020
- * Build a uniform gate over guard-* family contract. Returns an
1021
- * async function whose verdict is `{ ok, action, issues?,
1022
- * sanitized? }` where `action` is `serve` / `audit-only` /
1020
+ * Build a uniform gate over the guard-* family contract. Returns a
1021
+ * gate whose async `check(ctx)` produces a verdict `{ ok, action,
1022
+ * issues?, sanitized? }` where `action` is `serve` / `audit-only` /
1023
1023
  * `sanitize` / `refuse`. SVGZ inputs always refuse — operators
1024
1024
  * ungzip and re-gate the inner SVG. External `xlink:href` on
1025
1025
  * `<use>` / `<feImage>` refuses under `strict` (SSRF + XSS chain).
@@ -1042,13 +1042,13 @@ function sanitize(input, opts) {
1042
1042
  *
1043
1043
  * @example
1044
1044
  * var g = b.guardSvg.gate({ profile: "strict" });
1045
- * var verdict = await g({
1045
+ * var verdict = await g.check({
1046
1046
  * bytes: Buffer.from('<svg><circle r="10"/></svg>', "utf8"),
1047
1047
  * });
1048
1048
  * verdict.action; // → "serve"
1049
1049
  *
1050
1050
  * // Refuses external xlink:href under strict:
1051
- * var refuse = await g({
1051
+ * var refuse = await g.check({
1052
1052
  * bytes: Buffer.from(
1053
1053
  * '<svg><use xlink:href="https://evil.example/x.svg#a"/></svg>',
1054
1054
  * "utf8"),
@@ -34,7 +34,7 @@
34
34
  * Profiles: `strict` / `balanced` / `permissive`. Compliance
35
35
  * postures: `hipaa` / `pci-dss` / `gdpr` / `soc2`. Operators
36
36
  * select via `{ profile: "strict" }` or
37
- * `{ compliance: "hipaa" }`; postures overlay on top of the
37
+ * `{ compliancePosture: "hipaa" }`; postures overlay on top of the
38
38
  * profile baseline. Jinja / ERB / Pug shape rejection holds at
39
39
  * every profile — the SSTI class is never an operator opt-in.
40
40
  *
@@ -237,7 +237,7 @@ function _detectIssues(input, opts) {
237
237
  *
238
238
  * @opts
239
239
  * profile: "strict"|"balanced"|"permissive",
240
- * compliance: "hipaa"|"pci-dss"|"gdpr"|"soc2",
240
+ * compliancePosture: "hipaa"|"pci-dss"|"gdpr"|"soc2",
241
241
  * bidiPolicy: "reject"|"audit"|"allow",
242
242
  * controlPolicy: "reject"|"audit"|"allow",
243
243
  * nullBytePolicy: "reject"|"audit"|"allow",
@@ -287,7 +287,7 @@ function validate(input, opts) {
287
287
  *
288
288
  * @opts
289
289
  * profile: "strict"|"balanced"|"permissive",
290
- * compliance: "hipaa"|"pci-dss"|"gdpr"|"soc2",
290
+ * compliancePosture: "hipaa"|"pci-dss"|"gdpr"|"soc2",
291
291
  * jinjaPolicy: "reject"|"audit"|"allow",
292
292
  * erbPolicy: "reject"|"audit"|"allow",
293
293
  * pugPolicy: "reject"|"audit"|"allow",
@@ -339,7 +339,7 @@ function sanitize(input, opts) {
339
339
  *
340
340
  * @opts
341
341
  * profile: "strict"|"balanced"|"permissive",
342
- * compliance: "hipaa"|"pci-dss"|"gdpr"|"soc2",
342
+ * compliancePosture: "hipaa"|"pci-dss"|"gdpr"|"soc2",
343
343
  * name: string, // override gate name in audit emissions
344
344
  * jinjaPolicy: "reject"|"audit"|"allow",
345
345
  * erbPolicy: "reject"|"audit"|"allow",
package/lib/guard-time.js CHANGED
@@ -347,7 +347,7 @@ function _detectIssues(input, opts) {
347
347
  *
348
348
  * @opts
349
349
  * profile: "strict"|"balanced"|"permissive",
350
- * compliance: "hipaa"|"pci-dss"|"gdpr"|"soc2",
350
+ * compliancePosture: "hipaa"|"pci-dss"|"gdpr"|"soc2",
351
351
  * bidiPolicy: "reject"|"strip"|"audit"|"allow",
352
352
  * controlPolicy: "reject"|"strip"|"allow",
353
353
  * nullBytePolicy: "reject"|"strip"|"allow",
@@ -403,7 +403,7 @@ function validate(input, opts) {
403
403
  *
404
404
  * @opts
405
405
  * profile: "strict"|"balanced"|"permissive",
406
- * compliance: "hipaa"|"pci-dss"|"gdpr"|"soc2",
406
+ * compliancePosture: "hipaa"|"pci-dss"|"gdpr"|"soc2",
407
407
  * ...: same shape as b.guardTime.validate opts,
408
408
  *
409
409
  * @example
@@ -442,7 +442,7 @@ function sanitize(input, opts) {
442
442
  * @compliance hipaa, pci-dss, gdpr, soc2
443
443
  * @related b.guardTime.validate, b.guardTime.sanitize, b.guardAll.gate
444
444
  *
445
- * Build an async gate `(ctx) -> { ok, action, issues }` consumable
445
+ * Build a guard gate whose async `check(ctx)` returns `{ ok, action, issues }`, consumable
446
446
  * by `b.guardAll`, audit pipelines, scheduling primitives, and
447
447
  * retention readers. The gate reads `ctx.identifier` (or
448
448
  * `ctx.timestamp` / `ctx.time`), runs `validate`, and maps
@@ -452,15 +452,15 @@ function sanitize(input, opts) {
452
452
  * @opts
453
453
  * name: string, // gate label for audit / observability
454
454
  * profile: "strict"|"balanced"|"permissive",
455
- * compliance: "hipaa"|"pci-dss"|"gdpr"|"soc2",
455
+ * compliancePosture: "hipaa"|"pci-dss"|"gdpr"|"soc2",
456
456
  * ...: same shape as b.guardTime.validate opts,
457
457
  *
458
458
  * @example
459
459
  * var g = b.guardTime.gate({ profile: "strict" });
460
- * var rv = await g({ identifier: "2026-05-05T12:34:56Z" });
460
+ * var rv = await g.check({ identifier: "2026-05-05T12:34:56Z" });
461
461
  * rv.action; // → "serve"
462
462
  *
463
- * var bad = await g({ identifier: "2026-05-05 12:34:56" });
463
+ * var bad = await g.check({ identifier: "2026-05-05 12:34:56" });
464
464
  * bad.action; // → "refuse"
465
465
  */
466
466
  function gate(opts) {
package/lib/guard-uuid.js CHANGED
@@ -307,7 +307,7 @@ function _detectIssues(input, opts) {
307
307
  *
308
308
  * @opts
309
309
  * profile: "strict"|"balanced"|"permissive",
310
- * compliance: "hipaa"|"pci-dss"|"gdpr"|"soc2",
310
+ * compliancePosture: "hipaa"|"pci-dss"|"gdpr"|"soc2",
311
311
  * bidiPolicy: "reject"|"strip"|"audit"|"allow",
312
312
  * controlPolicy: "reject"|"strip"|"allow",
313
313
  * nullBytePolicy: "reject"|"strip"|"allow",
@@ -361,7 +361,7 @@ function validate(input, opts) {
361
361
  *
362
362
  * @opts
363
363
  * profile: "strict"|"balanced"|"permissive",
364
- * compliance: "hipaa"|"pci-dss"|"gdpr"|"soc2",
364
+ * compliancePosture: "hipaa"|"pci-dss"|"gdpr"|"soc2",
365
365
  * ...: same shape as b.guardUuid.validate opts,
366
366
  *
367
367
  * @example
@@ -406,7 +406,7 @@ function sanitize(input, opts) {
406
406
  * @compliance hipaa, pci-dss, gdpr, soc2
407
407
  * @related b.guardUuid.validate, b.guardUuid.sanitize, b.guardAll.gate
408
408
  *
409
- * Build an async gate `(ctx) -> { ok, action, issues }` consumable
409
+ * Build a guard gate whose async `check(ctx)` returns `{ ok, action, issues }`, consumable
410
410
  * by `b.guardAll`, ID validators, and any host that handles
411
411
  * UUID-shaped tokens. The gate reads `ctx.identifier` (or
412
412
  * `ctx.uuid`), runs `validate`, and maps severity to action: zero
@@ -416,15 +416,15 @@ function sanitize(input, opts) {
416
416
  * @opts
417
417
  * name: string, // gate label for audit / observability
418
418
  * profile: "strict"|"balanced"|"permissive",
419
- * compliance: "hipaa"|"pci-dss"|"gdpr"|"soc2",
419
+ * compliancePosture: "hipaa"|"pci-dss"|"gdpr"|"soc2",
420
420
  * ...: same shape as b.guardUuid.validate opts,
421
421
  *
422
422
  * @example
423
423
  * var g = b.guardUuid.gate({ profile: "strict" });
424
- * var rv = await g({ identifier: "550e8400-e29b-41d4-a716-446655440000" });
424
+ * var rv = await g.check({ identifier: "550e8400-e29b-41d4-a716-446655440000" });
425
425
  * rv.action; // → "serve"
426
426
  *
427
- * var bad = await g({ identifier: "{550e8400-e29b-41d4-a716-446655440000}" });
427
+ * var bad = await g.check({ identifier: "{550e8400-e29b-41d4-a716-446655440000}" });
428
428
  * bad.action; // → "refuse"
429
429
  */
430
430
  function gate(opts) {
package/lib/guard-xml.js CHANGED
@@ -371,7 +371,7 @@ function _detectIssues(input, opts) {
371
371
  *
372
372
  * Inspect `input` (string of XML source) for the full guard-xml
373
373
  * threat catalog without invoking a parser. Returns
374
- * `{ ok, issues, severities }` where `issues` enumerates every
374
+ * `{ ok, issues }` where `issues` enumerates every
375
375
  * DOCTYPE declaration, `<!ENTITY>` definition (including parameter
376
376
  * entities), SYSTEM/PUBLIC external-entity reference, XInclude
377
377
  * directive, xsi:schemaLocation hint, processing instruction (after
@@ -388,7 +388,7 @@ function _detectIssues(input, opts) {
388
388
  *
389
389
  * @opts
390
390
  * profile: "strict"|"balanced"|"permissive",
391
- * compliance: "hipaa"|"pci-dss"|"gdpr"|"soc2",
391
+ * compliancePosture: "hipaa"|"pci-dss"|"gdpr"|"soc2",
392
392
  * doctypePolicy: "reject"|"audit"|"allow",
393
393
  * entityPolicy: "reject"|"audit"|"allow",
394
394
  * externalEntityPolicy: "reject"|"audit"|"allow",
@@ -455,7 +455,7 @@ function validate(input, opts) {
455
455
  *
456
456
  * @opts
457
457
  * profile: "strict"|"balanced"|"permissive",
458
- * compliance: "hipaa"|"pci-dss"|"gdpr"|"soc2",
458
+ * compliancePosture: "hipaa"|"pci-dss"|"gdpr"|"soc2",
459
459
  * bidiPolicy: "reject"|"strip"|"audit"|"allow",
460
460
  * controlPolicy: "reject"|"strip"|"allow",
461
461
  * nullBytePolicy: "reject"|"strip"|"allow",
@@ -514,7 +514,7 @@ function sanitize(input, opts) {
514
514
  *
515
515
  * @opts
516
516
  * profile: "strict"|"balanced"|"permissive",
517
- * compliance: "hipaa"|"pci-dss"|"gdpr"|"soc2",
517
+ * compliancePosture: "hipaa"|"pci-dss"|"gdpr"|"soc2",
518
518
  * name: string, // gate identity for audit / observability
519
519
  *
520
520
  * @example
package/lib/guard-yaml.js CHANGED
@@ -58,7 +58,7 @@
58
58
  *
59
59
  * Profiles: `strict` / `balanced` / `permissive`. Compliance
60
60
  * postures: `hipaa` / `pci-dss` / `gdpr` / `soc2`. Operators select
61
- * via `{ profile: "strict" }` or `{ compliance: "hipaa" }`;
61
+ * via `{ profile: "strict" }` or `{ compliancePosture: "hipaa" }`;
62
62
  * postures overlay on top of the profile baseline.
63
63
  *
64
64
  * @card
@@ -452,7 +452,7 @@ function _detectDuplicateKeysYaml(text) {
452
452
  *
453
453
  * Inspect `input` (string of YAML source) for the full guard-yaml
454
454
  * threat catalog without committing to a parsed value. Returns
455
- * `{ ok, issues, severities }` where `issues` is the aggregated
455
+ * `{ ok, issues }` where `issues` is the aggregated
456
456
  * detector output — every dangerous-tag prefix, custom-tag use,
457
457
  * anchor / alias amplification, multi-document split, Norway-
458
458
  * problem implicit boolean, leading-zero octal, merge-key chain,
@@ -468,7 +468,7 @@ function _detectDuplicateKeysYaml(text) {
468
468
  *
469
469
  * @opts
470
470
  * profile: "strict"|"balanced"|"permissive",
471
- * compliance: "hipaa"|"pci-dss"|"gdpr"|"soc2",
471
+ * compliancePosture: "hipaa"|"pci-dss"|"gdpr"|"soc2",
472
472
  * tagPolicy: "reject"|"audit"|"allow",
473
473
  * aliasPolicy: "reject"|"audit"|"allow",
474
474
  * multiDocPolicy: "reject"|"audit"|"allow",
@@ -535,7 +535,7 @@ function validate(input, opts) {
535
535
  *
536
536
  * @opts
537
537
  * profile: "strict"|"balanced"|"permissive",
538
- * compliance: "hipaa"|"pci-dss"|"gdpr"|"soc2",
538
+ * compliancePosture: "hipaa"|"pci-dss"|"gdpr"|"soc2",
539
539
  * tagPolicy: "reject"|"audit"|"allow",
540
540
  * aliasPolicy: "reject"|"audit"|"allow",
541
541
  * maxBytes: number, maxDepth: number, maxNodes: number,
@@ -586,7 +586,7 @@ function parse(input, opts) {
586
586
  *
587
587
  * @opts
588
588
  * profile: "strict"|"balanced"|"permissive",
589
- * compliance: "hipaa"|"pci-dss"|"gdpr"|"soc2",
589
+ * compliancePosture: "hipaa"|"pci-dss"|"gdpr"|"soc2",
590
590
  * name: string, // gate identity for audit / observability
591
591
  *
592
592
  * @example
@@ -125,8 +125,9 @@ function _serParam(name, value) {
125
125
  * Build an HTTP <code>Link</code> header value from an array of
126
126
  * <code>{ uri, rel, params? }</code> (or a single such object). The URI
127
127
  * is angle-bracketed, <code>rel</code> (string or array) is emitted
128
- * first, and parameters are token-valued when they fit RFC 7230 token
129
- * grammar or double-quoted otherwise. Useful for emitting standard REST
128
+ * first, and every parameter value is double-quoted (always valid under
129
+ * RFC 8288, and required for space-separated multi-rel and media-type
130
+ * values like <code>text/html</code>). Useful for emitting standard REST
130
131
  * pagination links.
131
132
  *
132
133
  * @example
package/lib/mail-agent.js CHANGED
@@ -156,8 +156,10 @@ var COMPOSE_HINT = Object.freeze({
156
156
  * @related b.mailStore, b.mail.agent.consumer
157
157
  *
158
158
  * Create the agent facade. Returns an object with read / write / sieve
159
- * / identity / mdn / export / import / consumer methods. Reads stay
160
- * synchronous-shaped via promises; writes audit on completion.
159
+ * / identity / mdn / export / import methods. Reads stay
160
+ * synchronous-shaped via promises; writes audit on completion. (The
161
+ * queue consumer is the sibling export <code>b.mail.agent.consumer</code>,
162
+ * not a method on this object.)
161
163
  *
162
164
  * @opts
163
165
  * store: b.mailStore instance, // required
@@ -36,7 +36,7 @@
36
36
  * header: true // set X-RateLimit-* response headers
37
37
  * skipPaths: [] // string-prefix or regex matchers
38
38
  * scope: 'global' | 'per-route' (default 'global')
39
- * backend: 'memory' (default) | 'cluster' | { take, reset, gc? }
39
+ * backend: 'memory' (default) | 'cluster' | { take, reset }
40
40
  * algorithm: 'token-bucket' (default) | 'fixed-window'
41
41
  * // memory backend only; ignored
42
42
  * // for cluster backend (which is
@@ -366,7 +366,7 @@ function _resolveBackend(opts) {
366
366
  * header: boolean, // default true
367
367
  * skipPaths: Array<string|RegExp>,
368
368
  * scope: "global"|"per-route",
369
- * backend: "memory"|"cluster"|{ take, reset, gc },
369
+ * backend: "memory"|"cluster"|{ take, reset },
370
370
  * algorithm: "token-bucket"|"fixed-window",
371
371
  * burst: number,
372
372
  * refillPerSecond: number,
package/lib/tsa.js CHANGED
@@ -183,7 +183,8 @@ function buildRequest(data, opts) {
183
183
  nonce = Buffer.isBuffer(opts.nonce) ? opts.nonce : nodeCrypto.randomBytes(8); // allow:raw-byte-literal — RFC 3161 nonce: 64-bit random
184
184
  children.push(asn1.writeInteger(nonce));
185
185
  }
186
- // certReq DEFAULT FALSE only encode when true (the default we want).
186
+ // certReq DEFAULTS TRUE (RFC 3161 §2.4.1) encode the boolean unless
187
+ // the caller explicitly opts out with certReq:false.
187
188
  var certReq = opts.certReq !== false;
188
189
  if (certReq) children.push(asn1.writeBoolean(true));
189
190
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blamejs/core",
3
- "version": "0.13.22",
3
+ "version": "0.13.24",
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.5",
5
- "serialNumber": "urn:uuid:81d23e48-6a96-4d2b-ac47-bada0b15cf1f",
5
+ "serialNumber": "urn:uuid:be8cbd49-821e-4e0e-92d5-ea42e8aff583",
6
6
  "version": 1,
7
7
  "metadata": {
8
- "timestamp": "2026-05-28T00:00:09.259Z",
8
+ "timestamp": "2026-05-28T11:47:50.484Z",
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.13.22",
22
+ "bom-ref": "@blamejs/core@0.13.24",
23
23
  "type": "application",
24
24
  "name": "blamejs",
25
- "version": "0.13.22",
25
+ "version": "0.13.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.13.22",
29
+ "purl": "pkg:npm/%40blamejs/core@0.13.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.13.22",
57
+ "ref": "@blamejs/core@0.13.24",
58
58
  "dependsOn": []
59
59
  }
60
60
  ]