@blamejs/core 0.14.27 → 0.15.1

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 (134) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/README.md +2 -2
  3. package/index.js +4 -0
  4. package/lib/ai-content-detect.js +9 -10
  5. package/lib/api-key.js +158 -77
  6. package/lib/atomic-file.js +29 -1
  7. package/lib/audit-chain.js +47 -11
  8. package/lib/audit-sign.js +77 -2
  9. package/lib/audit-tools.js +79 -51
  10. package/lib/audit.js +228 -100
  11. package/lib/backup/index.js +13 -10
  12. package/lib/break-glass.js +202 -144
  13. package/lib/cache.js +174 -105
  14. package/lib/chain-writer.js +38 -16
  15. package/lib/cli.js +19 -14
  16. package/lib/cluster-provider-db.js +130 -104
  17. package/lib/cluster-storage.js +119 -22
  18. package/lib/cluster.js +119 -71
  19. package/lib/compliance.js +22 -0
  20. package/lib/consent.js +82 -29
  21. package/lib/constants.js +16 -11
  22. package/lib/crypto-field.js +387 -91
  23. package/lib/db-declare-row-policy.js +35 -22
  24. package/lib/db-file-lifecycle.js +3 -2
  25. package/lib/db-query.js +517 -256
  26. package/lib/db-schema.js +209 -44
  27. package/lib/db.js +202 -95
  28. package/lib/external-db-migrate.js +229 -139
  29. package/lib/external-db.js +25 -15
  30. package/lib/framework-error.js +11 -0
  31. package/lib/framework-files.js +73 -0
  32. package/lib/framework-schema.js +695 -394
  33. package/lib/gate-contract.js +596 -1
  34. package/lib/guard-agent-registry.js +26 -44
  35. package/lib/guard-all.js +1 -0
  36. package/lib/guard-auth.js +42 -112
  37. package/lib/guard-cidr.js +33 -154
  38. package/lib/guard-csv.js +46 -113
  39. package/lib/guard-domain.js +34 -157
  40. package/lib/guard-dsn.js +27 -43
  41. package/lib/guard-email.js +47 -69
  42. package/lib/guard-envelope.js +19 -32
  43. package/lib/guard-event-bus-payload.js +24 -42
  44. package/lib/guard-event-bus-topic.js +25 -43
  45. package/lib/guard-filename.js +42 -106
  46. package/lib/guard-graphql.js +42 -123
  47. package/lib/guard-html.js +53 -108
  48. package/lib/guard-idempotency-key.js +24 -42
  49. package/lib/guard-image.js +46 -103
  50. package/lib/guard-imap-command.js +18 -32
  51. package/lib/guard-jmap.js +16 -30
  52. package/lib/guard-json.js +38 -108
  53. package/lib/guard-jsonpath.js +38 -171
  54. package/lib/guard-jwt.js +49 -179
  55. package/lib/guard-list-id.js +25 -41
  56. package/lib/guard-list-unsubscribe.js +27 -43
  57. package/lib/guard-mail-compose.js +24 -42
  58. package/lib/guard-mail-move.js +26 -44
  59. package/lib/guard-mail-query.js +28 -46
  60. package/lib/guard-mail-reply.js +24 -42
  61. package/lib/guard-mail-sieve.js +24 -42
  62. package/lib/guard-managesieve-command.js +17 -31
  63. package/lib/guard-markdown.js +37 -104
  64. package/lib/guard-message-id.js +26 -45
  65. package/lib/guard-mime.js +39 -151
  66. package/lib/guard-oauth.js +54 -135
  67. package/lib/guard-pdf.js +45 -101
  68. package/lib/guard-pop3-command.js +21 -31
  69. package/lib/guard-posture-chain.js +24 -42
  70. package/lib/guard-regex.js +33 -107
  71. package/lib/guard-saga-config.js +24 -42
  72. package/lib/guard-shell.js +42 -172
  73. package/lib/guard-smtp-command.js +48 -54
  74. package/lib/guard-snapshot-envelope.js +24 -42
  75. package/lib/guard-sql.js +1491 -0
  76. package/lib/guard-stream-args.js +24 -43
  77. package/lib/guard-svg.js +47 -65
  78. package/lib/guard-template.js +35 -172
  79. package/lib/guard-tenant-id.js +26 -45
  80. package/lib/guard-time.js +32 -154
  81. package/lib/guard-trace-context.js +25 -44
  82. package/lib/guard-uuid.js +32 -153
  83. package/lib/guard-xml.js +38 -113
  84. package/lib/guard-yaml.js +51 -163
  85. package/lib/http-client.js +14 -0
  86. package/lib/inbox.js +120 -107
  87. package/lib/legal-hold.js +107 -50
  88. package/lib/log-stream-cloudwatch.js +47 -31
  89. package/lib/log-stream-otlp.js +32 -18
  90. package/lib/mail-crypto-smime.js +2 -6
  91. package/lib/mail-greylist.js +2 -6
  92. package/lib/mail-helo.js +2 -6
  93. package/lib/mail-journal.js +85 -64
  94. package/lib/mail-rbl.js +2 -6
  95. package/lib/mail-scan.js +2 -6
  96. package/lib/mail-spam-score.js +2 -6
  97. package/lib/mail-store.js +293 -154
  98. package/lib/middleware/fetch-metadata.js +17 -7
  99. package/lib/middleware/idempotency-key.js +54 -38
  100. package/lib/middleware/rate-limit.js +102 -32
  101. package/lib/middleware/security-headers.js +21 -5
  102. package/lib/migrations.js +108 -66
  103. package/lib/network-heartbeat.js +7 -0
  104. package/lib/nonce-store.js +31 -9
  105. package/lib/object-store/azure-blob-bucket-ops.js +9 -4
  106. package/lib/object-store/azure-blob.js +31 -3
  107. package/lib/object-store/sigv4.js +10 -0
  108. package/lib/outbox.js +136 -82
  109. package/lib/pqc-agent.js +44 -0
  110. package/lib/pubsub-cluster.js +42 -20
  111. package/lib/queue-local.js +202 -139
  112. package/lib/queue-redis.js +9 -1
  113. package/lib/queue-sqs.js +6 -0
  114. package/lib/retention.js +82 -39
  115. package/lib/safe-dns.js +29 -45
  116. package/lib/safe-ical.js +18 -33
  117. package/lib/safe-icap.js +27 -43
  118. package/lib/safe-sieve.js +21 -40
  119. package/lib/safe-sql.js +124 -3
  120. package/lib/safe-vcard.js +18 -33
  121. package/lib/scheduler.js +35 -12
  122. package/lib/seeders.js +122 -74
  123. package/lib/session-stores.js +42 -14
  124. package/lib/session.js +116 -72
  125. package/lib/sql.js +3885 -0
  126. package/lib/static.js +45 -7
  127. package/lib/subject.js +89 -49
  128. package/lib/vault/index.js +3 -2
  129. package/lib/vault/passphrase-ops.js +3 -2
  130. package/lib/vault/rotate.js +104 -64
  131. package/lib/vendor-data.js +2 -0
  132. package/lib/websocket.js +16 -0
  133. package/package.json +1 -1
  134. 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;