@blamejs/core 0.14.26 → 0.15.0

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 (150) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/README.md +2 -2
  3. package/index.js +4 -0
  4. package/lib/agent-envelope-mac.js +104 -0
  5. package/lib/agent-event-bus.js +105 -4
  6. package/lib/agent-posture-chain.js +8 -42
  7. package/lib/ai-content-detect.js +9 -10
  8. package/lib/api-key.js +107 -74
  9. package/lib/atomic-file.js +62 -4
  10. package/lib/audit-chain.js +47 -11
  11. package/lib/audit-sign.js +77 -2
  12. package/lib/audit-tools.js +79 -51
  13. package/lib/audit.js +249 -123
  14. package/lib/auth/openid-federation.js +108 -47
  15. package/lib/backup/index.js +13 -10
  16. package/lib/break-glass.js +202 -144
  17. package/lib/cache.js +174 -105
  18. package/lib/chain-writer.js +38 -16
  19. package/lib/cli.js +19 -14
  20. package/lib/cluster-provider-db.js +130 -104
  21. package/lib/cluster-storage.js +119 -22
  22. package/lib/cluster.js +119 -71
  23. package/lib/compliance.js +169 -4
  24. package/lib/consent.js +73 -24
  25. package/lib/constants.js +16 -11
  26. package/lib/crypto-field.js +474 -92
  27. package/lib/db-declare-row-policy.js +35 -22
  28. package/lib/db-file-lifecycle.js +3 -2
  29. package/lib/db-query.js +497 -255
  30. package/lib/db-schema.js +209 -44
  31. package/lib/db.js +176 -95
  32. package/lib/error-page.js +14 -1
  33. package/lib/external-db-migrate.js +229 -139
  34. package/lib/external-db.js +25 -15
  35. package/lib/file-upload.js +52 -7
  36. package/lib/framework-error.js +14 -1
  37. package/lib/framework-files.js +73 -0
  38. package/lib/framework-schema.js +695 -394
  39. package/lib/gate-contract.js +649 -1
  40. package/lib/guard-agent-registry.js +26 -44
  41. package/lib/guard-all.js +1 -0
  42. package/lib/guard-auth.js +42 -112
  43. package/lib/guard-cidr.js +33 -154
  44. package/lib/guard-csv.js +46 -113
  45. package/lib/guard-domain.js +34 -157
  46. package/lib/guard-dsn.js +27 -43
  47. package/lib/guard-email.js +47 -69
  48. package/lib/guard-envelope.js +19 -32
  49. package/lib/guard-event-bus-payload.js +24 -42
  50. package/lib/guard-event-bus-topic.js +25 -43
  51. package/lib/guard-filename.js +42 -106
  52. package/lib/guard-graphql.js +42 -123
  53. package/lib/guard-html.js +53 -108
  54. package/lib/guard-idempotency-key.js +24 -42
  55. package/lib/guard-image.js +46 -103
  56. package/lib/guard-imap-command.js +18 -32
  57. package/lib/guard-jmap.js +16 -30
  58. package/lib/guard-json.js +38 -108
  59. package/lib/guard-jsonpath.js +38 -171
  60. package/lib/guard-jwt.js +49 -179
  61. package/lib/guard-list-id.js +25 -41
  62. package/lib/guard-list-unsubscribe.js +27 -43
  63. package/lib/guard-mail-compose.js +24 -42
  64. package/lib/guard-mail-move.js +26 -44
  65. package/lib/guard-mail-query.js +28 -46
  66. package/lib/guard-mail-reply.js +24 -42
  67. package/lib/guard-mail-sieve.js +24 -42
  68. package/lib/guard-managesieve-command.js +17 -31
  69. package/lib/guard-markdown.js +37 -104
  70. package/lib/guard-message-id.js +26 -45
  71. package/lib/guard-mime.js +39 -151
  72. package/lib/guard-oauth.js +54 -135
  73. package/lib/guard-pdf.js +45 -101
  74. package/lib/guard-pop3-command.js +21 -31
  75. package/lib/guard-posture-chain.js +24 -42
  76. package/lib/guard-regex.js +33 -107
  77. package/lib/guard-saga-config.js +24 -42
  78. package/lib/guard-shell.js +42 -172
  79. package/lib/guard-smtp-command.js +48 -54
  80. package/lib/guard-snapshot-envelope.js +24 -42
  81. package/lib/guard-sql.js +1491 -0
  82. package/lib/guard-stream-args.js +24 -43
  83. package/lib/guard-svg.js +47 -65
  84. package/lib/guard-template.js +35 -172
  85. package/lib/guard-tenant-id.js +26 -45
  86. package/lib/guard-time.js +32 -154
  87. package/lib/guard-trace-context.js +25 -44
  88. package/lib/guard-uuid.js +32 -153
  89. package/lib/guard-xml.js +38 -113
  90. package/lib/guard-yaml.js +51 -163
  91. package/lib/http-client.js +37 -9
  92. package/lib/inbox.js +120 -107
  93. package/lib/legal-hold.js +107 -50
  94. package/lib/log-stream-cloudwatch.js +47 -31
  95. package/lib/log-stream-otlp.js +32 -18
  96. package/lib/mail-crypto-smime.js +2 -6
  97. package/lib/mail-greylist.js +2 -6
  98. package/lib/mail-helo.js +2 -6
  99. package/lib/mail-journal.js +85 -64
  100. package/lib/mail-rbl.js +2 -6
  101. package/lib/mail-scan.js +2 -6
  102. package/lib/mail-server-jmap.js +117 -12
  103. package/lib/mail-spam-score.js +2 -6
  104. package/lib/mail-store.js +287 -154
  105. package/lib/middleware/body-parser.js +71 -25
  106. package/lib/middleware/csrf-protect.js +19 -8
  107. package/lib/middleware/fetch-metadata.js +17 -7
  108. package/lib/middleware/idempotency-key.js +54 -38
  109. package/lib/middleware/rate-limit.js +102 -32
  110. package/lib/middleware/security-headers.js +21 -5
  111. package/lib/migrations.js +108 -66
  112. package/lib/network-heartbeat.js +7 -0
  113. package/lib/nonce-store.js +31 -9
  114. package/lib/object-store/azure-blob-bucket-ops.js +9 -4
  115. package/lib/object-store/azure-blob.js +57 -3
  116. package/lib/object-store/sigv4.js +10 -0
  117. package/lib/observability.js +87 -0
  118. package/lib/otel-export.js +25 -1
  119. package/lib/outbox.js +136 -82
  120. package/lib/parsers/safe-xml.js +47 -7
  121. package/lib/pqc-agent.js +44 -0
  122. package/lib/pubsub-cluster.js +42 -20
  123. package/lib/queue-local.js +202 -139
  124. package/lib/queue-redis.js +9 -1
  125. package/lib/queue-sqs.js +6 -0
  126. package/lib/redact.js +68 -11
  127. package/lib/redis-client.js +160 -31
  128. package/lib/retention.js +82 -39
  129. package/lib/router.js +212 -5
  130. package/lib/safe-dns.js +29 -45
  131. package/lib/safe-ical.js +18 -33
  132. package/lib/safe-icap.js +27 -43
  133. package/lib/safe-sieve.js +21 -40
  134. package/lib/safe-sql.js +124 -3
  135. package/lib/safe-vcard.js +18 -33
  136. package/lib/scheduler.js +35 -12
  137. package/lib/seeders.js +122 -74
  138. package/lib/session-stores.js +42 -14
  139. package/lib/session.js +109 -72
  140. package/lib/sql.js +3885 -0
  141. package/lib/ssrf-guard.js +51 -4
  142. package/lib/static.js +177 -34
  143. package/lib/subject.js +55 -17
  144. package/lib/vault/index.js +3 -2
  145. package/lib/vault/passphrase-ops.js +3 -2
  146. package/lib/vault/rotate.js +104 -64
  147. package/lib/vendor-data.js +2 -0
  148. package/lib/websocket.js +35 -5
  149. package/package.json +1 -1
  150. package/sbom.cdx.json +6 -6
@@ -30,6 +30,7 @@
30
30
  */
31
31
 
32
32
  var { defineClass } = require("./framework-error");
33
+ var gateContract = require("./gate-contract");
33
34
 
34
35
  var GuardIdempotencyKeyError = defineClass("GuardIdempotencyKeyError", { alwaysPermanent: true });
35
36
 
@@ -41,12 +42,7 @@ var PROFILES = Object.freeze({
41
42
  permissive: { maxBytes: 2048, asciiOnly: false },
42
43
  });
43
44
 
44
- var COMPLIANCE_POSTURES = Object.freeze({
45
- hipaa: "strict",
46
- "pci-dss": "strict",
47
- gdpr: "strict",
48
- soc2: "strict",
49
- });
45
+ var COMPLIANCE_POSTURES = gateContract.ALL_STRICT_POSTURES;
50
46
 
51
47
  /**
52
48
  * @primitive b.guardIdempotencyKey.validate
@@ -111,41 +107,27 @@ function validate(value, opts) {
111
107
  return value;
112
108
  }
113
109
 
114
- /**
115
- * @primitive b.guardIdempotencyKey.compliancePosture
116
- * @signature b.guardIdempotencyKey.compliancePosture(posture)
117
- * @since 0.9.22
118
- * @status stable
119
- *
120
- * Return the effective profile for a given compliance posture name.
121
- * Returns `null` for unknown posture names so operator typos surface
122
- * here instead of silently falling through to the default profile.
123
- *
124
- * @example
125
- * b.guardIdempotencyKey.compliancePosture("hipaa"); // → "strict"
126
- */
127
- function compliancePosture(posture) {
128
- return COMPLIANCE_POSTURES[posture] || null;
129
- }
110
+ // compliancePosture is assembled by gateContract.defineParser below; its
111
+ // wiki section renders from the single-sourced @abiTemplate (defineParser)
112
+ // block in gate-contract.js, instantiated for this guard by the page
113
+ // generator.
130
114
 
131
- function _resolveProfile(opts) {
132
- if (opts.posture && COMPLIANCE_POSTURES[opts.posture]) {
133
- return COMPLIANCE_POSTURES[opts.posture];
134
- }
135
- var p = opts.profile || DEFAULT_PROFILE;
136
- if (!PROFILES[p]) {
137
- throw new GuardIdempotencyKeyError("idempotency-key/bad-profile",
138
- "guardIdempotencyKey: unknown profile '" + p + "'");
139
- }
140
- return p;
141
- }
115
+ var _resolveProfile = gateContract.makeProfileResolver({
116
+ profiles: PROFILES,
117
+ postures: COMPLIANCE_POSTURES,
118
+ defaults: DEFAULT_PROFILE,
119
+ errorClass: GuardIdempotencyKeyError,
120
+ codePrefix: "idempotency-key",
121
+ });
142
122
 
143
- module.exports = {
144
- validate: validate,
145
- compliancePosture: compliancePosture,
146
- PROFILES: PROFILES,
147
- COMPLIANCE_POSTURES: COMPLIANCE_POSTURES,
148
- GuardIdempotencyKeyError: GuardIdempotencyKeyError,
149
- NAME: "idempotencyKey",
150
- KIND: "idempotency-key",
151
- };
123
+ module.exports = gateContract.defineParser({
124
+ name: "idempotency-key",
125
+ entry: validate,
126
+ errorClass: GuardIdempotencyKeyError,
127
+ profiles: PROFILES,
128
+ postures: COMPLIANCE_POSTURES,
129
+ extra: {
130
+ NAME: "idempotencyKey",
131
+ KIND: "idempotency-key",
132
+ },
133
+ });
@@ -394,12 +394,7 @@ function sanitize(input, opts) {
394
394
  throw _err("image.bad-input", "sanitize requires metadata object");
395
395
  }
396
396
  var issues = _detectIssues(input, opts);
397
- for (var i = 0; i < issues.length; i += 1) {
398
- if (issues[i].severity === "critical" || issues[i].severity === "high") {
399
- throw _err(issues[i].ruleId || "image.refused",
400
- "guardImage.sanitize: " + issues[i].snippet);
401
- }
402
- }
397
+ gateContract.throwOnRefusalSeverity(issues, { errorClass: GuardImageError, codePrefix: "image" });
403
398
  return input;
404
399
  }
405
400
 
@@ -461,70 +456,11 @@ function gate(opts) {
461
456
  });
462
457
  }
463
458
 
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
- */
483
- var buildProfile = gateContract.makeProfileBuilder(PROFILES);
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
- */
502
- function compliancePosture(name) {
503
- return gateContract.lookupCompliancePosture(name, COMPLIANCE_POSTURES,
504
- _err, "image");
505
- }
506
-
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
- */
527
- var loadRulePack = _imgRulePacks.load;
459
+ // buildProfile / compliancePosture / loadRulePack are assembled by
460
+ // gateContract.defineGuard below (makeProfileBuilder(PROFILES) /
461
+ // lookupCompliancePosture(_, COMPLIANCE_POSTURES) / makeRulePackLoader).
462
+ // Their wiki sections render from the single-sourced @abiTemplate blocks
463
+ // in gate-contract.js, instantiated per guard by the page generator.
528
464
 
529
465
  /**
530
466
  * @primitive b.guardImage.inspectMagic
@@ -549,36 +485,43 @@ function inspectMagic(bytes) {
549
485
  return _detectMagicMimes(bytes);
550
486
  }
551
487
 
552
- module.exports = {
553
- // ---- guard-* family registry exports ----
554
- NAME: "image",
555
- KIND: "metadata",
556
- INTEGRATION_FIXTURES: Object.freeze({
557
- kind: "metadata",
558
- benignBytes: Buffer.from([0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A]),
559
- // Hostile: declared image/png but bytes are JPEG (mime-mismatch class —
560
- // drive-by content-type confusion / decoder-mux).
561
- hostileBytes: Buffer.from([0xFF, 0xD8, 0xFF]),
562
- benignMetadata: {
563
- bytes: Buffer.from([0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A]),
564
- declaredMime: "image/png",
565
- width: 100, height: 100, frames: 1, // pixel + frame count fixture
566
- },
567
- hostileMetadata: {
568
- bytes: Buffer.from([0xFF, 0xD8, 0xFF]),
569
- declaredMime: "image/png",
570
- },
571
- }),
572
- // ---- primitive surface ----
573
- validate: validate,
574
- sanitize: sanitize,
575
- gate: gate,
576
- inspectMagic: inspectMagic,
577
- buildProfile: buildProfile,
578
- compliancePosture: compliancePosture,
579
- loadRulePack: loadRulePack,
580
- PROFILES: PROFILES,
581
- DEFAULTS: DEFAULTS,
582
- COMPLIANCE_POSTURES: COMPLIANCE_POSTURES,
583
- GuardImageError: GuardImageError,
584
- };
488
+ // ---- adaptive integration-test fixtures (consumed by layer-5 host harness) ----
489
+ var INTEGRATION_FIXTURES = Object.freeze({
490
+ kind: "metadata",
491
+ benignBytes: Buffer.from([0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A]),
492
+ // Hostile: declared image/png but bytes are JPEG (mime-mismatch class —
493
+ // drive-by content-type confusion / decoder-mux).
494
+ hostileBytes: Buffer.from([0xFF, 0xD8, 0xFF]),
495
+ benignMetadata: {
496
+ bytes: Buffer.from([0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A]),
497
+ declaredMime: "image/png",
498
+ width: 100, height: 100, frames: 1, // pixel + frame count fixture
499
+ },
500
+ hostileMetadata: {
501
+ bytes: Buffer.from([0xFF, 0xD8, 0xFF]),
502
+ declaredMime: "image/png",
503
+ },
504
+ });
505
+
506
+ // Assembled from the gate-contract guard factory: error class, registry
507
+ // exports (NAME / KIND / INTEGRATION_FIXTURES), buildProfile /
508
+ // compliancePosture / loadRulePack wiring, plus the per-guard inspection
509
+ // surface (validate / sanitize / gate) and the image extra (inspectMagic)
510
+ // passed through verbatim. KIND="metadata" is a custom kind, so the bespoke
511
+ // `gate` (operator-feeds-metadata ctx.metadata reader) is REQUIRED and
512
+ // carries the magic-byte / polyglot / dimension chain unchanged.
513
+ module.exports = gateContract.defineGuard({
514
+ name: "image",
515
+ kind: "metadata",
516
+ errorClass: GuardImageError,
517
+ profiles: PROFILES,
518
+ defaults: DEFAULTS,
519
+ postures: COMPLIANCE_POSTURES,
520
+ integrationFixtures: INTEGRATION_FIXTURES,
521
+ validate: validate,
522
+ sanitize: sanitize,
523
+ gate: gate,
524
+ extra: {
525
+ inspectMagic: inspectMagic,
526
+ },
527
+ });
@@ -82,6 +82,7 @@
82
82
  */
83
83
 
84
84
  var { defineClass } = require("./framework-error");
85
+ var gateContract = require("./gate-contract");
85
86
 
86
87
  var GuardImapCommandError = defineClass("GuardImapCommandError", { alwaysPermanent: true });
87
88
 
@@ -120,12 +121,7 @@ var PROFILES = Object.freeze({
120
121
  },
121
122
  });
122
123
 
123
- var COMPLIANCE_POSTURES = Object.freeze({
124
- hipaa: "strict",
125
- "pci-dss": "strict",
126
- gdpr: "strict",
127
- soc2: "strict",
128
- });
124
+ var COMPLIANCE_POSTURES = gateContract.ALL_STRICT_POSTURES;
129
125
 
130
126
  // IMAP4rev2 commands per RFC 9051 §6.
131
127
  var KNOWN_VERBS = Object.freeze({
@@ -309,29 +305,19 @@ function detectLiteralSmuggling(line) {
309
305
  return LITERAL_SMUGGLE_RE.test(line); // allow:regex-no-length-cap — caller's input is already length-capped upstream by the listener's per-line cap
310
306
  }
311
307
 
312
- /**
313
- * @primitive b.guardImapCommand.compliancePosture
314
- * @signature b.guardImapCommand.compliancePosture(posture)
315
- * @since 0.9.49
316
- * @status stable
317
- *
318
- * Return the effective profile for a compliance posture, or `null`
319
- * for unknown names.
320
- *
321
- * @example
322
- * b.guardImapCommand.compliancePosture("hipaa"); // → "strict"
323
- */
324
- function compliancePosture(posture) {
325
- return COMPLIANCE_POSTURES[posture] || null;
326
- }
327
-
328
- module.exports = {
329
- validate: validate,
330
- detectLiteralSmuggling: detectLiteralSmuggling,
331
- compliancePosture: compliancePosture,
332
- PROFILES: PROFILES,
333
- COMPLIANCE_POSTURES: COMPLIANCE_POSTURES,
334
- KNOWN_VERBS: KNOWN_VERBS,
335
- ZERO_ARG_VERBS: ZERO_ARG_VERBS,
336
- GuardImapCommandError: GuardImapCommandError,
337
- };
308
+ // compliancePosture is assembled by gateContract.defineParser below; its
309
+ // wiki section renders from the single-sourced @abiTemplate (defineParser)
310
+ // block in gate-contract.js, instantiated for this guard by the page
311
+ // generator.
312
+ module.exports = gateContract.defineParser({
313
+ name: "imap-command",
314
+ entry: validate,
315
+ errorClass: GuardImapCommandError,
316
+ profiles: PROFILES,
317
+ postures: COMPLIANCE_POSTURES,
318
+ extra: {
319
+ detectLiteralSmuggling: detectLiteralSmuggling,
320
+ KNOWN_VERBS: KNOWN_VERBS,
321
+ ZERO_ARG_VERBS: ZERO_ARG_VERBS,
322
+ },
323
+ });
package/lib/guard-jmap.js CHANGED
@@ -59,6 +59,7 @@
59
59
  var { defineClass } = require("./framework-error");
60
60
  var safeJson = require("./safe-json");
61
61
  var validateOpts = require("./validate-opts");
62
+ var gateContract = require("./gate-contract");
62
63
 
63
64
  var GuardJmapError = defineClass("GuardJmapError", { alwaysPermanent: true });
64
65
 
@@ -91,12 +92,7 @@ var PROFILES = Object.freeze({
91
92
  },
92
93
  });
93
94
 
94
- var COMPLIANCE_POSTURES = Object.freeze({
95
- hipaa: "strict",
96
- "pci-dss": "strict",
97
- gdpr: "strict",
98
- soc2: "strict",
99
- });
95
+ var COMPLIANCE_POSTURES = gateContract.ALL_STRICT_POSTURES;
100
96
 
101
97
  // Capability URIs the server's core JMAP implementation always supports.
102
98
  // Additional capabilities (mail / contacts / calendars / submission)
@@ -295,27 +291,17 @@ function _countBackRefs(node, depth, maxDepth) {
295
291
  return maxO;
296
292
  }
297
293
 
298
- /**
299
- * @primitive b.guardJmap.compliancePosture
300
- * @signature b.guardJmap.compliancePosture(posture)
301
- * @since 0.9.50
302
- * @status stable
303
- *
304
- * Return the effective profile for a compliance posture, or `null`
305
- * for unknown names.
306
- *
307
- * @example
308
- * b.guardJmap.compliancePosture("hipaa"); // → "strict"
309
- */
310
- function compliancePosture(posture) {
311
- return COMPLIANCE_POSTURES[posture] || null;
312
- }
313
-
314
- module.exports = {
315
- validate: validate,
316
- compliancePosture: compliancePosture,
317
- PROFILES: PROFILES,
318
- COMPLIANCE_POSTURES: COMPLIANCE_POSTURES,
319
- CORE_CAPABILITIES: CORE_CAPABILITIES,
320
- GuardJmapError: GuardJmapError,
321
- };
294
+ // compliancePosture is assembled by gateContract.defineParser below; its
295
+ // wiki section renders from the single-sourced @abiTemplate (defineParser)
296
+ // block in gate-contract.js, instantiated for this guard by the page
297
+ // generator.
298
+ module.exports = gateContract.defineParser({
299
+ name: "jmap",
300
+ entry: validate,
301
+ errorClass: GuardJmapError,
302
+ profiles: PROFILES,
303
+ postures: COMPLIANCE_POSTURES,
304
+ extra: {
305
+ CORE_CAPABILITIES: CORE_CAPABILITIES,
306
+ },
307
+ });
package/lib/guard-json.js CHANGED
@@ -820,115 +820,45 @@ function gate(opts) {
820
820
  });
821
821
  }
822
822
 
823
- /**
824
- * @primitive b.guardJson.buildProfile
825
- * @signature b.guardJson.buildProfile(opts)
826
- * @since 0.7.13
827
- * @status stable
828
- * @related b.guardJson.gate, b.guardJson.compliancePosture
829
- *
830
- * Compose a derived profile from one or more named bases plus
831
- * inline overrides. `opts.extends` is a profile name (`"strict"` /
832
- * `"balanced"` / `"permissive"`) or an array of names; later entries
833
- * shadow earlier ones. Inline `opts` keys win last. Used to keep
834
- * operator-defined profiles traceable to a baseline rather than re-
835
- * typing every key.
836
- *
837
- * @opts
838
- * extends: string|string[], // base profile name(s) to compose
839
- * ...: any guard-json key, // inline override of resolved keys
840
- *
841
- * @example
842
- * var custom = b.guardJson.buildProfile({
843
- * extends: "balanced",
844
- * pollutionPolicy: "reject",
845
- * maxDepth: 16,
846
- * });
847
- * custom.pollutionPolicy; // → "reject"
848
- * custom.maxDepth; // → 16
849
- */
850
- var buildProfile = gateContract.makeProfileBuilder(PROFILES);
851
-
852
- /**
853
- * @primitive b.guardJson.compliancePosture
854
- * @signature b.guardJson.compliancePosture(name)
855
- * @since 0.7.13
856
- * @status stable
857
- * @compliance hipaa, pci-dss, gdpr, soc2
858
- * @related b.guardJson.gate, b.guardJson.buildProfile
859
- *
860
- * Look up a compliance-posture overlay by name (`"hipaa"` /
861
- * `"pci-dss"` / `"gdpr"` / `"soc2"`). Returns a shallow clone of the
862
- * posture object — the caller may mutate freely. Throws
863
- * `GuardJsonError("json.bad-posture")` on unknown name.
864
- *
865
- * @example
866
- * var posture = b.guardJson.compliancePosture("hipaa");
867
- * posture.pollutionPolicy; // → "reject"
868
- * posture.forensicSnippetBytes; // → 256
869
- */
870
- function compliancePosture(name) {
871
- return gateContract.lookupCompliancePosture(name, COMPLIANCE_POSTURES, _err, "json");
872
- }
823
+ // buildProfile / compliancePosture / loadRulePack are assembled by
824
+ // gateContract.defineGuard below (makeProfileBuilder(PROFILES) /
825
+ // lookupCompliancePosture(_, COMPLIANCE_POSTURES) / makeRulePackLoader).
826
+ // Their wiki sections render from the single-sourced @abiTemplate blocks
827
+ // in gate-contract.js, instantiated per guard by the page generator.
828
+
829
+ var INTEGRATION_FIXTURES = Object.freeze({
830
+ kind: "content",
831
+ contentType: "application/json",
832
+ extension: ".json",
833
+ benignBytes: Buffer.from('{"name":"alice","age":30}', "utf8"),
834
+ // Hostile: prototype-pollution payload (CVE-2025-55182 React Server
835
+ // Functions class; CVE-2025-57820 Svelte devalue class).
836
+ hostileBytes: Buffer.from('{"__proto__":{"polluted":true}}', "utf8"),
837
+ });
873
838
 
874
- var _jsonRulePacks = gateContract.makeRulePackLoader(GuardJsonError, "json");
875
- /**
876
- * @primitive b.guardJson.loadRulePack
877
- * @signature b.guardJson.loadRulePack(pack)
878
- * @since 0.7.13
879
- * @status stable
880
- * @related b.guardJson.gate
881
- *
882
- * Register an operator-supplied rule pack with the guard-json
883
- * registry. The pack is identified by `pack.id` (non-empty string)
884
- * and stored for later inspection / dispatch by gates that opt in
885
- * via `opts.rulePackId`. Returns the pack object unchanged on
886
- * success; throws `GuardJsonError("json.bad-opt")` when `pack` is
887
- * missing or `pack.id` is not a non-empty string.
888
- *
889
- * @example
890
- * var pack = b.guardJson.loadRulePack({
891
- * id: "tenant-keys",
892
- * rules: [
893
- * { id: "tenant-id-shape", severity: "high",
894
- * detect: function (tree) { return !tree || typeof tree.tenantId !== "string"; },
895
- * reason: "tenantId must be a string at top level" },
896
- * ],
897
- * });
898
- * pack.id; // → "tenant-keys"
899
- */
900
- var loadRulePack = _jsonRulePacks.load;
901
-
902
- module.exports = {
903
- // ---- guard-* family registry exports ----
904
- NAME: "json",
905
- KIND: "content",
906
- MIME_TYPES: Object.freeze([
907
- "application/json", "application/ld+json", "application/vnd.api+json",
908
- ]),
909
- EXTENSIONS: Object.freeze([".json", ".jsonld"]),
910
- INTEGRATION_FIXTURES: Object.freeze({
911
- kind: "content",
912
- contentType: "application/json",
913
- extension: ".json",
914
- benignBytes: Buffer.from('{"name":"alice","age":30}', "utf8"),
915
- // Hostile: prototype-pollution payload (CVE-2025-55182 React Server
916
- // Functions class; CVE-2025-57820 Svelte devalue class).
917
- hostileBytes: Buffer.from('{"__proto__":{"polluted":true}}', "utf8"),
918
- }),
919
- // ---- primitive surface ----
920
- validate: validate,
921
- parse: parse,
922
- gate: gate,
923
- buildProfile: buildProfile,
924
- compliancePosture: compliancePosture,
925
- loadRulePack: loadRulePack,
926
- PROFILES: PROFILES,
927
- DEFAULTS: DEFAULTS,
928
- COMPLIANCE_POSTURES: COMPLIANCE_POSTURES,
929
- POLLUTION_KEYS: POLLUTION_KEYS,
930
- GuardJsonError: GuardJsonError,
931
- };
839
+ // Assembled from the gate-contract guard factory: error class, registry
840
+ // exports (NAME / KIND / MIME_TYPES / EXTENSIONS / INTEGRATION_FIXTURES),
841
+ // buildProfile / compliancePosture / loadRulePack wiring, plus the
842
+ // per-guard inspection surface (validate / parse) and JSON extras
843
+ // (POLLUTION_KEYS) passed through verbatim. The bespoke `gate` carries
844
+ // JSON's sanitize-reparse-reserialize chain unchanged.
845
+ module.exports = gateContract.defineGuard({
846
+ name: "json",
847
+ kind: "content",
848
+ errorClass: GuardJsonError,
849
+ profiles: PROFILES,
850
+ defaults: DEFAULTS,
851
+ postures: COMPLIANCE_POSTURES,
852
+ mimeTypes: ["application/json", "application/ld+json", "application/vnd.api+json"],
853
+ extensions: [".json", ".jsonld"],
854
+ integrationFixtures: INTEGRATION_FIXTURES,
855
+ validate: validate,
856
+ gate: gate,
857
+ extra: {
858
+ parse: parse,
859
+ POLLUTION_KEYS: POLLUTION_KEYS,
860
+ },
861
+ });
932
862
 
933
863
  void BIDI_RE; // referenced via codepointClass.detectCharThreats; binding kept for clarity
934
864
  void C0_CTRL_RE;