@blamejs/core 0.8.43 → 0.8.49

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (222) hide show
  1. package/CHANGELOG.md +92 -0
  2. package/README.md +10 -10
  3. package/index.js +52 -0
  4. package/lib/a2a.js +159 -34
  5. package/lib/acme.js +762 -0
  6. package/lib/ai-pref.js +166 -43
  7. package/lib/api-key.js +108 -47
  8. package/lib/api-snapshot.js +157 -40
  9. package/lib/app-shutdown.js +113 -77
  10. package/lib/archive.js +337 -40
  11. package/lib/arg-parser.js +697 -0
  12. package/lib/asyncapi.js +99 -55
  13. package/lib/atomic-file.js +465 -104
  14. package/lib/audit-chain.js +123 -34
  15. package/lib/audit-daily-review.js +389 -0
  16. package/lib/audit-sign.js +302 -56
  17. package/lib/audit-tools.js +412 -63
  18. package/lib/audit.js +656 -35
  19. package/lib/auth/jwt-external.js +17 -0
  20. package/lib/auth/oauth.js +7 -0
  21. package/lib/auth-bot-challenge.js +505 -0
  22. package/lib/auth-header.js +92 -25
  23. package/lib/backup/bundle.js +26 -0
  24. package/lib/backup/index.js +512 -89
  25. package/lib/backup/manifest.js +168 -7
  26. package/lib/break-glass.js +415 -39
  27. package/lib/budr.js +103 -30
  28. package/lib/bundler.js +86 -66
  29. package/lib/cache.js +192 -72
  30. package/lib/chain-writer.js +65 -40
  31. package/lib/circuit-breaker.js +56 -33
  32. package/lib/cli-helpers.js +106 -75
  33. package/lib/cli.js +6 -30
  34. package/lib/cloud-events.js +99 -32
  35. package/lib/cluster-storage.js +162 -37
  36. package/lib/cluster.js +340 -49
  37. package/lib/codepoint-class.js +66 -0
  38. package/lib/compliance.js +424 -24
  39. package/lib/config-drift.js +111 -46
  40. package/lib/config.js +94 -40
  41. package/lib/consent.js +165 -18
  42. package/lib/constants.js +1 -0
  43. package/lib/content-credentials.js +153 -48
  44. package/lib/cookies.js +154 -62
  45. package/lib/credential-hash.js +133 -61
  46. package/lib/crypto-field.js +702 -18
  47. package/lib/crypto-hpke.js +256 -0
  48. package/lib/crypto.js +744 -22
  49. package/lib/csv.js +178 -35
  50. package/lib/daemon.js +456 -0
  51. package/lib/dark-patterns.js +186 -55
  52. package/lib/db-query.js +79 -2
  53. package/lib/db.js +1431 -60
  54. package/lib/ddl-change-control.js +523 -0
  55. package/lib/deprecate.js +195 -40
  56. package/lib/dev.js +82 -39
  57. package/lib/dora.js +67 -48
  58. package/lib/dr-runbook.js +368 -0
  59. package/lib/dsr.js +142 -11
  60. package/lib/dual-control.js +91 -56
  61. package/lib/events.js +120 -41
  62. package/lib/external-db-migrate.js +192 -2
  63. package/lib/external-db.js +795 -50
  64. package/lib/fapi2.js +122 -1
  65. package/lib/fda-21cfr11.js +395 -0
  66. package/lib/fdx.js +132 -2
  67. package/lib/file-type.js +87 -0
  68. package/lib/file-upload.js +93 -0
  69. package/lib/flag.js +82 -20
  70. package/lib/forms.js +132 -29
  71. package/lib/framework-error.js +169 -0
  72. package/lib/framework-schema.js +163 -35
  73. package/lib/gate-contract.js +849 -175
  74. package/lib/graphql-federation.js +68 -7
  75. package/lib/guard-all.js +172 -55
  76. package/lib/guard-archive.js +286 -124
  77. package/lib/guard-auth.js +194 -21
  78. package/lib/guard-cidr.js +190 -28
  79. package/lib/guard-csv.js +397 -51
  80. package/lib/guard-domain.js +213 -91
  81. package/lib/guard-email.js +236 -29
  82. package/lib/guard-filename.js +307 -75
  83. package/lib/guard-graphql.js +263 -30
  84. package/lib/guard-html.js +310 -116
  85. package/lib/guard-image.js +243 -30
  86. package/lib/guard-json.js +260 -54
  87. package/lib/guard-jsonpath.js +235 -23
  88. package/lib/guard-jwt.js +284 -30
  89. package/lib/guard-markdown.js +204 -22
  90. package/lib/guard-mime.js +190 -26
  91. package/lib/guard-oauth.js +277 -28
  92. package/lib/guard-pdf.js +251 -27
  93. package/lib/guard-regex.js +226 -18
  94. package/lib/guard-shell.js +229 -26
  95. package/lib/guard-svg.js +177 -10
  96. package/lib/guard-template.js +232 -21
  97. package/lib/guard-time.js +195 -29
  98. package/lib/guard-uuid.js +189 -30
  99. package/lib/guard-xml.js +259 -36
  100. package/lib/guard-yaml.js +241 -44
  101. package/lib/honeytoken.js +63 -27
  102. package/lib/html-balance.js +83 -0
  103. package/lib/http-client.js +486 -59
  104. package/lib/http-message-signature.js +582 -0
  105. package/lib/i18n.js +102 -49
  106. package/lib/iab-mspa.js +112 -32
  107. package/lib/iab-tcf.js +107 -2
  108. package/lib/inbox.js +90 -52
  109. package/lib/keychain.js +865 -0
  110. package/lib/legal-hold.js +374 -0
  111. package/lib/local-db-thin.js +320 -0
  112. package/lib/log-stream.js +281 -51
  113. package/lib/log.js +184 -86
  114. package/lib/mail-bounce.js +107 -62
  115. package/lib/mail.js +295 -58
  116. package/lib/mcp.js +108 -27
  117. package/lib/metrics.js +98 -89
  118. package/lib/middleware/age-gate.js +36 -0
  119. package/lib/middleware/ai-act-disclosure.js +37 -0
  120. package/lib/middleware/api-encrypt.js +45 -0
  121. package/lib/middleware/assetlinks.js +40 -0
  122. package/lib/middleware/asyncapi-serve.js +35 -0
  123. package/lib/middleware/attach-user.js +40 -0
  124. package/lib/middleware/bearer-auth.js +40 -0
  125. package/lib/middleware/body-parser.js +230 -0
  126. package/lib/middleware/bot-disclose.js +34 -0
  127. package/lib/middleware/bot-guard.js +39 -0
  128. package/lib/middleware/compression.js +37 -0
  129. package/lib/middleware/cookies.js +32 -0
  130. package/lib/middleware/cors.js +40 -0
  131. package/lib/middleware/csp-nonce.js +40 -0
  132. package/lib/middleware/csp-report.js +34 -0
  133. package/lib/middleware/csrf-protect.js +43 -0
  134. package/lib/middleware/daily-byte-quota.js +53 -85
  135. package/lib/middleware/db-role-for.js +40 -0
  136. package/lib/middleware/dpop.js +40 -0
  137. package/lib/middleware/error-handler.js +37 -14
  138. package/lib/middleware/fetch-metadata.js +39 -0
  139. package/lib/middleware/flag-context.js +34 -0
  140. package/lib/middleware/gpc.js +33 -0
  141. package/lib/middleware/headers.js +35 -0
  142. package/lib/middleware/health.js +46 -0
  143. package/lib/middleware/host-allowlist.js +30 -0
  144. package/lib/middleware/network-allowlist.js +38 -0
  145. package/lib/middleware/openapi-serve.js +34 -0
  146. package/lib/middleware/rate-limit.js +160 -18
  147. package/lib/middleware/request-id.js +36 -18
  148. package/lib/middleware/request-log.js +37 -0
  149. package/lib/middleware/require-aal.js +29 -0
  150. package/lib/middleware/require-auth.js +32 -0
  151. package/lib/middleware/require-bound-key.js +41 -0
  152. package/lib/middleware/require-content-type.js +32 -0
  153. package/lib/middleware/require-methods.js +27 -0
  154. package/lib/middleware/require-mtls.js +33 -0
  155. package/lib/middleware/require-step-up.js +37 -0
  156. package/lib/middleware/security-headers.js +44 -0
  157. package/lib/middleware/security-txt.js +38 -0
  158. package/lib/middleware/span-http-server.js +37 -0
  159. package/lib/middleware/sse.js +36 -0
  160. package/lib/middleware/trace-log-correlation.js +33 -0
  161. package/lib/middleware/trace-propagate.js +32 -0
  162. package/lib/middleware/tus-upload.js +90 -0
  163. package/lib/middleware/web-app-manifest.js +53 -0
  164. package/lib/mtls-ca.js +100 -70
  165. package/lib/network-byte-quota.js +308 -0
  166. package/lib/network-heartbeat.js +135 -0
  167. package/lib/network-tls.js +534 -4
  168. package/lib/network.js +103 -0
  169. package/lib/notify.js +114 -43
  170. package/lib/ntp-check.js +192 -51
  171. package/lib/observability.js +145 -47
  172. package/lib/openapi.js +90 -44
  173. package/lib/outbox.js +99 -1
  174. package/lib/pagination.js +168 -86
  175. package/lib/parsers/index.js +16 -5
  176. package/lib/permissions.js +93 -40
  177. package/lib/pqc-agent.js +84 -8
  178. package/lib/pqc-software.js +94 -60
  179. package/lib/process-spawn.js +95 -21
  180. package/lib/pubsub.js +96 -66
  181. package/lib/queue.js +375 -54
  182. package/lib/redact.js +793 -21
  183. package/lib/render.js +139 -47
  184. package/lib/request-helpers.js +485 -121
  185. package/lib/restore-bundle.js +142 -39
  186. package/lib/restore-rollback.js +136 -45
  187. package/lib/retention.js +178 -50
  188. package/lib/retry.js +116 -33
  189. package/lib/router.js +475 -23
  190. package/lib/safe-async.js +543 -94
  191. package/lib/safe-buffer.js +337 -41
  192. package/lib/safe-json.js +467 -62
  193. package/lib/safe-jsonpath.js +285 -0
  194. package/lib/safe-schema.js +631 -87
  195. package/lib/safe-sql.js +221 -59
  196. package/lib/safe-url.js +278 -46
  197. package/lib/sandbox-worker.js +135 -0
  198. package/lib/sandbox.js +358 -0
  199. package/lib/scheduler.js +135 -70
  200. package/lib/self-update.js +647 -0
  201. package/lib/session-device-binding.js +431 -0
  202. package/lib/session.js +259 -49
  203. package/lib/slug.js +138 -26
  204. package/lib/ssrf-guard.js +316 -56
  205. package/lib/storage.js +433 -70
  206. package/lib/subject.js +405 -23
  207. package/lib/template.js +148 -8
  208. package/lib/tenant-quota.js +545 -0
  209. package/lib/testing.js +440 -53
  210. package/lib/time.js +291 -23
  211. package/lib/tls-exporter.js +239 -0
  212. package/lib/tracing.js +90 -74
  213. package/lib/uuid.js +97 -22
  214. package/lib/vault/index.js +284 -22
  215. package/lib/vault/seal-pem-file.js +66 -0
  216. package/lib/watcher.js +368 -0
  217. package/lib/webhook.js +196 -63
  218. package/lib/websocket.js +393 -68
  219. package/lib/wiki-concepts.js +338 -0
  220. package/lib/worker-pool.js +464 -0
  221. package/package.json +3 -3
  222. package/sbom.cyclonedx.json +7 -7
@@ -1,36 +1,62 @@
1
1
  "use strict";
2
2
  /**
3
- * guard-image — Image identifier-safety primitive (b.guardImage).
3
+ * @module b.guardImage
4
+ * @nav Guards
5
+ * @title Guard Image
4
6
  *
5
- * Validates image-format inputs without vendoring a full decoder.
6
- * The framework's stance: operators bring their own decoder (sharp,
7
- * jimp, libvips wrappers, etc.). guardImage closes the magic-byte
8
- * vs declared-Content-Type mismatch class, the polyglot file class,
9
- * and operator-supplied metadata bounds (oversized dimensions, frame
10
- * count, color depth). KIND="metadata" — consumes
11
- * `ctx.metadata` shape: `{ bytes?, declaredMime?, width?, height?,
12
- * frames?, colorDepth?, hasAlpha? }`.
7
+ * @intro
8
+ * Image content-safety guard closes the magic-byte / declared-MIME
9
+ * mismatch class and the polyglot-file class without vendoring a
10
+ * raster decoder. Operators bring their own decoder (sharp, jimp,
11
+ * libvips bindings) and feed structural metadata to the guard.
12
+ * `KIND="metadata"` — consumes `ctx.metadata` shape `{ bytes?,
13
+ * declaredMime?, width?, height?, frames?, colorDepth?, hasAlpha? }`.
13
14
  *
14
- * Threat catalog:
15
- * - Magic-byte vs declared-MIME mismatch `Content-Type:
16
- * image/png` with JPEG bytes (drive-by content-type confusion;
17
- * downstream decoder picks wrong path).
18
- * - Polyglot file multiple format magic bytes detected in the
19
- * same buffer (PHP-in-JPEG, JS-in-PNG class).
20
- * - Oversized dimensions — operator passes width / height; the
21
- * guard refuses against maxWidth / maxHeight.
22
- * - Excessive frame count (animated GIF / WebP / APNG / AVIF
23
- * image sequences) — operator passes frames; refused against
24
- * maxFrames.
25
- * - SVG content — delegates to b.guardSvg (this guard refuses
26
- * SVG bytes directly so operators don't bypass the SVG guard
27
- * by routing through guardImage).
28
- * - Unknown / no magic-byte match.
15
+ * Magic-byte dispatch: `inspectMagic(bytes)` walks a signature table
16
+ * covering PNG (`89 50 4E 47 0D 0A 1A 0A`), JPEG (`FF D8 FF`),
17
+ * GIF87a / GIF89a, WebP (RIFF + WEBP at offset 8), BMP, ICO, TIFF
18
+ * (II / MM), AVIF / HEIC (`ftyp` boxes at offset 4), and SVG (`<?xml`
19
+ * / `<svg`). Returns the list of distinct MIMEs that match. Multiple
20
+ * matches signals a polyglot file (PHP-in-JPEG / JS-in-PNG class)
21
+ * refused under every profile.
29
22
  *
30
- * var rv = b.guardImage.validate({ bytes, declaredMime: "image/png",
31
- * width: 1024, height: 768 },
32
- * { profile: "strict" });
33
- * var g = b.guardImage.gate({ profile: "strict" });
23
+ * Dimension caps: oversized width / height refused against
24
+ * `maxWidth` / `maxHeight` (strict 8 192 px, balanced 16 384 px,
25
+ * permissive 65 536 px). Frame caps for animated GIF / WebP / APNG /
26
+ * AVIF image sequences refused against `maxFrames` (strict 60,
27
+ * balanced 200, permissive 1000). Operator-supplied — the guard
28
+ * does not decode bytes itself; the operator's decoder reports the
29
+ * metadata before passing it to the gate.
30
+ *
31
+ * Polyglot rejection: when `_detectMagicMimes` returns more than one
32
+ * distinct format, the buffer carries multiple magic-byte signatures
33
+ * (e.g. JPEG marker followed by an embedded ZIP central directory) —
34
+ * refused at every profile.
35
+ *
36
+ * EXIF / XMP metadata strip: handled by the operator's decoder
37
+ * (sharp's `withMetadata: false`, libvips `metadata-strip`). The
38
+ * guard does not parse byte streams; it enforces the policy boundary
39
+ * and refuses the upload when the decoder's reported metadata
40
+ * violates a cap.
41
+ *
42
+ * SVG routing: bytes that match the SVG magic are refused under every
43
+ * profile — operators must route SVG explicitly to `b.guardSvg`
44
+ * because the SVG threat catalog (XXE, billion-laughs, animation
45
+ * href injection, foreignObject namespace shift) is distinct from
46
+ * raster threats.
47
+ *
48
+ * Operator-feeds-metadata pattern: the gate trusts the metadata
49
+ * object the operator supplies. The operator's decoder is the
50
+ * ground truth for `width` / `height` / `frames`; the guard refuses
51
+ * based on those values. This keeps the framework's no-deps stance
52
+ * intact while still closing the policy gaps.
53
+ *
54
+ * Profiles `strict` / `balanced` / `permissive` and compliance
55
+ * postures `hipaa` / `pci-dss` / `gdpr` / `soc2` overlay on the
56
+ * profile baseline.
57
+ *
58
+ * @card
59
+ * Image content-safety guard — closes the magic-byte / declared-MIME mismatch class and the polyglot-file class without vendoring a raster decoder.
34
60
  */
35
61
 
36
62
  var lazyRequire = require("./lazy-require");
@@ -274,6 +300,57 @@ function _detectIssues(metadata, opts) {
274
300
  return issues;
275
301
  }
276
302
 
303
+ /**
304
+ * @primitive b.guardImage.validate
305
+ * @signature b.guardImage.validate(input, opts)
306
+ * @since 0.7.13
307
+ * @status stable
308
+ * @compliance hipaa, pci-dss, gdpr, soc2
309
+ * @related b.guardImage.sanitize, b.guardImage.gate, b.guardImage.inspectMagic
310
+ *
311
+ * Inspect an image-metadata bag `{ bytes?, declaredMime?, width?,
312
+ * height?, frames? }` and return `{ ok, issues }`. Issues carry
313
+ * `{ kind, severity, ruleId, snippet }`. Detected: magic-byte / MIME
314
+ * mismatch (`mime-mismatch`), polyglot file (`polyglot`, refused
315
+ * under every profile), SVG bytes routed through guardImage
316
+ * (`svg-routing`, must go to `b.guardSvg`), unknown magic
317
+ * (`unknown-magic`), oversized width / height (`width-cap` /
318
+ * `height-cap`), excessive frame count (`frames-cap`), oversized
319
+ * byte length (`image-cap`). Pure inspection — never mutates input
320
+ * or throws on hostile metadata.
321
+ *
322
+ * @opts
323
+ * profile: "strict"|"balanced"|"permissive",
324
+ * compliancePosture: "hipaa"|"pci-dss"|"gdpr"|"soc2",
325
+ * mismatchPolicy: "reject"|"audit"|"allow",
326
+ * polyglotPolicy: "reject"|"audit"|"allow",
327
+ * unknownMagicPolicy: "reject"|"audit"|"allow",
328
+ * svgRoutingPolicy: "reject"|"audit"|"allow",
329
+ * dimensionsPolicy: "reject"|"audit"|"allow",
330
+ * framesPolicy: "reject"|"audit"|"allow",
331
+ * maxWidth: number, // strict 8192, balanced 16384, permissive 65536
332
+ * maxHeight: number, // strict 8192, balanced 16384, permissive 65536
333
+ * maxFrames: number, // strict 60, balanced 200, permissive 1000
334
+ * maxBytes: number, // strict 32 MiB, balanced 64 MiB, permissive 256 MiB
335
+ *
336
+ * @example
337
+ * // Mismatch — declared image/png but bytes are JPEG.
338
+ * var rv = b.guardImage.validate({
339
+ * bytes: Buffer.from([0xFF, 0xD8, 0xFF]),
340
+ * declaredMime: "image/png",
341
+ * }, { profile: "strict" });
342
+ * rv.ok; // → false
343
+ * rv.issues[0].kind; // → "mime-mismatch"
344
+ *
345
+ * // Oversized width refused under strict (8192 px cap).
346
+ * var big = b.guardImage.validate({
347
+ * bytes: Buffer.from([0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A]),
348
+ * declaredMime: "image/png",
349
+ * width: 16384, height: 16384,
350
+ * }, { profile: "strict" });
351
+ * big.issues.some(function (i) { return i.kind === "width-cap"; });
352
+ * // → true
353
+ */
277
354
  function validate(input, opts) {
278
355
  opts = _resolveOpts(opts);
279
356
  numericBounds.requireAllPositiveFiniteIntIfPresent(opts,
@@ -282,6 +359,35 @@ function validate(input, opts) {
282
359
  return gateContract.aggregateIssues(_detectIssues(input, opts));
283
360
  }
284
361
 
362
+ /**
363
+ * @primitive b.guardImage.sanitize
364
+ * @signature b.guardImage.sanitize(input, opts)
365
+ * @since 0.7.13
366
+ * @status stable
367
+ * @related b.guardImage.validate, b.guardImage.gate
368
+ *
369
+ * Best-effort metadata pass-through. Image-byte sanitization
370
+ * (transcoding, EXIF strip, dimension downscale) is the operator
371
+ * decoder's responsibility — the guard cannot rewrite raster bytes
372
+ * without a vendored decoder. `sanitize` validates the metadata
373
+ * against the active profile and re-throws `GuardImageError` when
374
+ * any issue is `critical` or `high`. Returns the input unchanged
375
+ * when every issue is `warn` or below.
376
+ *
377
+ * @opts
378
+ * profile: "strict"|"balanced"|"permissive",
379
+ * compliancePosture: "hipaa"|"pci-dss"|"gdpr"|"soc2",
380
+ *
381
+ * @example
382
+ * try {
383
+ * b.guardImage.sanitize({
384
+ * bytes: Buffer.from([0xFF, 0xD8, 0xFF]),
385
+ * declaredMime: "image/png",
386
+ * }, { profile: "strict" });
387
+ * } catch (e) {
388
+ * e.code; // → "image.mime-mismatch"
389
+ * }
390
+ */
285
391
  function sanitize(input, opts) {
286
392
  opts = _resolveOpts(opts);
287
393
  if (!input || typeof input !== "object") {
@@ -297,6 +403,41 @@ function sanitize(input, opts) {
297
403
  return input;
298
404
  }
299
405
 
406
+ /**
407
+ * @primitive b.guardImage.gate
408
+ * @signature b.guardImage.gate(opts)
409
+ * @since 0.7.13
410
+ * @status stable
411
+ * @compliance hipaa, pci-dss, gdpr, soc2
412
+ * @related b.guardImage.validate, b.guardImage.sanitize, b.fileUpload, b.staticServe
413
+ *
414
+ * Build a `b.gateContract` gate suitable for `b.fileUpload({ contentSafety:
415
+ * { "image/png": gate, "image/jpeg": gate } })` or `b.staticServe`.
416
+ * Operators pass `ctx.metadata` (the decoder's reported shape) plus
417
+ * the original `bytes`. Action chain: `serve` (no issues) →
418
+ * `audit-only` (warn-only) → `refuse` (any critical / high). No
419
+ * `sanitize` action — image bytes can't be transcoded without a
420
+ * vendored decoder.
421
+ *
422
+ * @opts
423
+ * profile: "strict"|"balanced"|"permissive",
424
+ * compliance: "hipaa"|"pci-dss"|"gdpr"|"soc2",
425
+ * name: string,
426
+ * ...: any validate opt
427
+ *
428
+ * @example
429
+ * var imgGate = b.guardImage.gate({ profile: "strict" });
430
+ *
431
+ * var verdict = await imgGate.check({
432
+ * metadata: {
433
+ * bytes: Buffer.from([0xFF, 0xD8, 0xFF]),
434
+ * declaredMime: "image/png",
435
+ * width: 1024, height: 768, frames: 1,
436
+ * },
437
+ * });
438
+ * verdict.action; // → "refuse"
439
+ * verdict.issues[0].kind; // → "mime-mismatch"
440
+ */
300
441
  function gate(opts) {
301
442
  opts = _resolveOpts(opts);
302
443
  return gateContract.buildGuardGate(
@@ -320,18 +461,90 @@ function gate(opts) {
320
461
  });
321
462
  }
322
463
 
464
+ /**
465
+ * @primitive b.guardImage.buildProfile
466
+ * @signature b.guardImage.buildProfile(opts)
467
+ * @since 0.7.13
468
+ * @status stable
469
+ * @related b.guardImage.compliancePosture, b.guardImage.gate
470
+ *
471
+ * Resolve a named profile against the guard's PROFILES catalog and
472
+ * return the merged options bag. Throws
473
+ * `GuardImageError("image.bad-profile")` on unknown name.
474
+ *
475
+ * @opts
476
+ * profile: "strict"|"balanced"|"permissive",
477
+ *
478
+ * @example
479
+ * var resolved = b.guardImage.buildProfile({ profile: "strict" });
480
+ * resolved.maxWidth; // → 8192
481
+ * resolved.polyglotPolicy; // → "reject"
482
+ */
323
483
  var buildProfile = gateContract.makeProfileBuilder(PROFILES);
324
484
 
485
+ /**
486
+ * @primitive b.guardImage.compliancePosture
487
+ * @signature b.guardImage.compliancePosture(name)
488
+ * @since 0.7.13
489
+ * @status stable
490
+ * @compliance hipaa, pci-dss, gdpr, soc2
491
+ * @related b.guardImage.gate, b.guardImage.buildProfile
492
+ *
493
+ * Return the option overlay for a named compliance posture
494
+ * (`"hipaa"` / `"pci-dss"` / `"gdpr"` / `"soc2"`). Throws
495
+ * `GuardImageError("image.bad-posture")` on unknown name.
496
+ *
497
+ * @example
498
+ * var posture = b.guardImage.compliancePosture("hipaa");
499
+ * posture.mismatchPolicy; // → "reject"
500
+ * posture.forensicSnippetBytes; // → 256
501
+ */
325
502
  function compliancePosture(name) {
326
503
  return gateContract.lookupCompliancePosture(name, COMPLIANCE_POSTURES,
327
504
  _err, "image");
328
505
  }
329
506
 
330
507
  var _imgRulePacks = gateContract.makeRulePackLoader(GuardImageError, "image");
508
+ /**
509
+ * @primitive b.guardImage.loadRulePack
510
+ * @signature b.guardImage.loadRulePack(pack)
511
+ * @since 0.7.13
512
+ * @status stable
513
+ * @related b.guardImage.gate
514
+ *
515
+ * Register an operator-supplied rule pack (extra MIME / dimension /
516
+ * polyglot overrides) into the guard's private store. Throws
517
+ * `GuardImageError("image.bad-opt")` when `pack` is missing or
518
+ * `pack.id` is not a non-empty string.
519
+ *
520
+ * @example
521
+ * var pack = b.guardImage.loadRulePack({
522
+ * id: "kb-2026-image",
523
+ * extraMaxFrames: 30,
524
+ * });
525
+ * pack.id; // → "kb-2026-image"
526
+ */
331
527
  var loadRulePack = _imgRulePacks.load;
332
528
 
333
- // Operator helper: surface the magic-byte detection result so callers
334
- // can run their own dispatch without re-implementing the table.
529
+ /**
530
+ * @primitive b.guardImage.inspectMagic
531
+ * @signature b.guardImage.inspectMagic(bytes)
532
+ * @since 0.7.13
533
+ * @status stable
534
+ * @related b.guardImage.validate, b.guardImage.gate
535
+ *
536
+ * Read the leading bytes of `bytes` and return an array of distinct
537
+ * MIMEs that match a known image-format magic-byte signature. Empty
538
+ * array on no match; multiple entries signals a polyglot file. Pure
539
+ * inspection — never mutates input or throws.
540
+ *
541
+ * @example
542
+ * var pngBytes = Buffer.from([0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A]);
543
+ * b.guardImage.inspectMagic(pngBytes); // → ["image/png"]
544
+ *
545
+ * b.guardImage.inspectMagic(Buffer.from([0xFF, 0xD8, 0xFF]));
546
+ * // → ["image/jpeg"]
547
+ */
335
548
  function inspectMagic(bytes) {
336
549
  return _detectMagicMimes(bytes);
337
550
  }