@blamejs/blamejs-shop 0.3.39 → 0.3.41

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 (62) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/lib/admin.js +331 -0
  3. package/lib/asset-manifest.json +1 -1
  4. package/lib/storefront.js +244 -4
  5. package/lib/vendor/MANIFEST.json +2 -2
  6. package/lib/vendor/blamejs/CHANGELOG.md +8 -0
  7. package/lib/vendor/blamejs/README.md +8 -5
  8. package/lib/vendor/blamejs/SECURITY.md +7 -0
  9. package/lib/vendor/blamejs/api-snapshot.json +266 -2
  10. package/lib/vendor/blamejs/examples/wiki/lib/source-comment-block-validator.js +1 -0
  11. package/lib/vendor/blamejs/index.js +7 -1
  12. package/lib/vendor/blamejs/lib/agent-idempotency.js +113 -0
  13. package/lib/vendor/blamejs/lib/agent-orchestrator.js +108 -0
  14. package/lib/vendor/blamejs/lib/agent-snapshot.js +137 -0
  15. package/lib/vendor/blamejs/lib/agent-tenant.js +193 -17
  16. package/lib/vendor/blamejs/lib/ai-input.js +167 -3
  17. package/lib/vendor/blamejs/lib/ai-output.js +463 -0
  18. package/lib/vendor/blamejs/lib/ai-prompt.js +304 -0
  19. package/lib/vendor/blamejs/lib/archive-wrap.js +234 -1
  20. package/lib/vendor/blamejs/lib/archive.js +1 -0
  21. package/lib/vendor/blamejs/lib/audit.js +3 -0
  22. package/lib/vendor/blamejs/lib/auth/oid4vp.js +47 -28
  23. package/lib/vendor/blamejs/lib/cluster.js +186 -14
  24. package/lib/vendor/blamejs/lib/codepoint-class.js +18 -0
  25. package/lib/vendor/blamejs/lib/compliance-ai-act.js +446 -0
  26. package/lib/vendor/blamejs/lib/consent.js +104 -8
  27. package/lib/vendor/blamejs/lib/content-credentials.js +851 -41
  28. package/lib/vendor/blamejs/lib/crypto-field.js +5 -0
  29. package/lib/vendor/blamejs/lib/db.js +15 -0
  30. package/lib/vendor/blamejs/lib/framework-error.js +21 -0
  31. package/lib/vendor/blamejs/lib/mail-srs.js +122 -19
  32. package/lib/vendor/blamejs/lib/privacy.js +168 -0
  33. package/lib/vendor/blamejs/lib/safe-archive.js +196 -136
  34. package/lib/vendor/blamejs/lib/validate-opts.js +24 -0
  35. package/lib/vendor/blamejs/lib/vault/rotate.js +175 -15
  36. package/lib/vendor/blamejs/lib/vault-aad.js +84 -33
  37. package/lib/vendor/blamejs/package.json +1 -1
  38. package/lib/vendor/blamejs/release-notes/v0.14.11.json +72 -0
  39. package/lib/vendor/blamejs/release-notes/v0.14.12.json +95 -0
  40. package/lib/vendor/blamejs/release-notes/v0.14.13.json +52 -0
  41. package/lib/vendor/blamejs/release-notes/v0.14.14.json +31 -0
  42. package/lib/vendor/blamejs/test/00-primitives.js +9 -1
  43. package/lib/vendor/blamejs/test/layer-0-primitives/agent-idempotency.test.js +103 -0
  44. package/lib/vendor/blamejs/test/layer-0-primitives/agent-orchestrator.test.js +91 -0
  45. package/lib/vendor/blamejs/test/layer-0-primitives/agent-snapshot.test.js +186 -0
  46. package/lib/vendor/blamejs/test/layer-0-primitives/agent-tenant.test.js +140 -0
  47. package/lib/vendor/blamejs/test/layer-0-primitives/ai-input.test.js +59 -0
  48. package/lib/vendor/blamejs/test/layer-0-primitives/ai-output.test.js +125 -0
  49. package/lib/vendor/blamejs/test/layer-0-primitives/ai-prompt.test.js +133 -0
  50. package/lib/vendor/blamejs/test/layer-0-primitives/app-shutdown.test.js +6 -1
  51. package/lib/vendor/blamejs/test/layer-0-primitives/archive-read.test.js +94 -0
  52. package/lib/vendor/blamejs/test/layer-0-primitives/archive-wrap.test.js +176 -0
  53. package/lib/vendor/blamejs/test/layer-0-primitives/cluster-vault-rotation.test.js +243 -0
  54. package/lib/vendor/blamejs/test/layer-0-primitives/codebase-patterns.test.js +250 -0
  55. package/lib/vendor/blamejs/test/layer-0-primitives/compliance-ai-act.test.js +130 -0
  56. package/lib/vendor/blamejs/test/layer-0-primitives/consent-purposes.test.js +70 -0
  57. package/lib/vendor/blamejs/test/layer-0-primitives/content-credentials.test.js +289 -2
  58. package/lib/vendor/blamejs/test/layer-0-primitives/federation-vc-suite.test.js +22 -0
  59. package/lib/vendor/blamejs/test/layer-0-primitives/mail-srs.test.js +61 -0
  60. package/lib/vendor/blamejs/test/layer-0-primitives/privacy-vendor-review.test.js +69 -0
  61. package/lib/vendor/blamejs/test/layer-0-primitives/vault-rotate-aad.test.js +158 -0
  62. package/package.json +1 -1
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 1,
3
- "frameworkVersion": "0.14.10",
4
- "createdAt": "2026-05-31T10:40:06.680Z",
3
+ "frameworkVersion": "0.14.14",
4
+ "createdAt": "2026-05-31T19:48:38.125Z",
5
5
  "exports": {
6
6
  "a2a": {
7
7
  "type": "object",
@@ -271,6 +271,31 @@
271
271
  "idempotency": {
272
272
  "type": "object",
273
273
  "members": {
274
+ "AAD_ROTATION": {
275
+ "type": "object",
276
+ "members": {
277
+ "backend": {
278
+ "type": "primitive",
279
+ "valueType": "string"
280
+ },
281
+ "reseal": {
282
+ "type": "function",
283
+ "arity": 1
284
+ },
285
+ "rowIdField": {
286
+ "type": "primitive",
287
+ "valueType": "string"
288
+ },
289
+ "schemaVersion": {
290
+ "type": "primitive",
291
+ "valueType": "string"
292
+ },
293
+ "table": {
294
+ "type": "primitive",
295
+ "valueType": "string"
296
+ }
297
+ }
298
+ },
274
299
  "AgentIdempotencyError": {
275
300
  "type": "function",
276
301
  "arity": 4
@@ -373,12 +398,41 @@
373
398
  }
374
399
  }
375
400
  }
401
+ },
402
+ "reseal": {
403
+ "type": "function",
404
+ "arity": 1
376
405
  }
377
406
  }
378
407
  },
379
408
  "orchestrator": {
380
409
  "type": "object",
381
410
  "members": {
411
+ "AAD_ROTATION": {
412
+ "type": "object",
413
+ "members": {
414
+ "backend": {
415
+ "type": "primitive",
416
+ "valueType": "string"
417
+ },
418
+ "reseal": {
419
+ "type": "function",
420
+ "arity": 1
421
+ },
422
+ "rowIdField": {
423
+ "type": "primitive",
424
+ "valueType": "string"
425
+ },
426
+ "schemaVersion": {
427
+ "type": "primitive",
428
+ "valueType": "string"
429
+ },
430
+ "table": {
431
+ "type": "primitive",
432
+ "valueType": "string"
433
+ }
434
+ }
435
+ },
382
436
  "AgentOrchestratorError": {
383
437
  "type": "function",
384
438
  "arity": 4
@@ -503,6 +557,10 @@
503
557
  }
504
558
  }
505
559
  },
560
+ "reseal": {
561
+ "type": "function",
562
+ "arity": 1
563
+ },
506
564
  "shardFor": {
507
565
  "type": "function",
508
566
  "arity": 2
@@ -748,6 +806,31 @@
748
806
  "snapshot": {
749
807
  "type": "object",
750
808
  "members": {
809
+ "AAD_ROTATION": {
810
+ "type": "object",
811
+ "members": {
812
+ "backend": {
813
+ "type": "primitive",
814
+ "valueType": "string"
815
+ },
816
+ "reseal": {
817
+ "type": "function",
818
+ "arity": 1
819
+ },
820
+ "rowIdField": {
821
+ "type": "primitive",
822
+ "valueType": "string"
823
+ },
824
+ "schemaVersion": {
825
+ "type": "primitive",
826
+ "valueType": "string"
827
+ },
828
+ "table": {
829
+ "type": "primitive",
830
+ "valueType": "string"
831
+ }
832
+ }
833
+ },
751
834
  "AgentSnapshotError": {
752
835
  "type": "function",
753
836
  "arity": 4
@@ -756,6 +839,10 @@
756
839
  "type": "primitive",
757
840
  "valueType": "number"
758
841
  },
842
+ "SEALED_PREFIX": {
843
+ "type": "primitive",
844
+ "valueType": "string"
845
+ },
759
846
  "create": {
760
847
  "type": "function",
761
848
  "arity": 1
@@ -854,6 +941,10 @@
854
941
  }
855
942
  }
856
943
  }
944
+ },
945
+ "reseal": {
946
+ "type": "function",
947
+ "arity": 1
857
948
  }
858
949
  }
859
950
  },
@@ -980,6 +1071,10 @@
980
1071
  "tenant": {
981
1072
  "type": "object",
982
1073
  "members": {
1074
+ "AAD_ROTATION": {
1075
+ "type": "instance",
1076
+ "ctorName": "Array"
1077
+ },
983
1078
  "AgentTenantError": {
984
1079
  "type": "function",
985
1080
  "arity": 4
@@ -1592,10 +1687,18 @@
1592
1687
  "type": "instance",
1593
1688
  "ctorName": "Array"
1594
1689
  },
1690
+ "TRUST_TIERS": {
1691
+ "type": "instance",
1692
+ "ctorName": "Array"
1693
+ },
1595
1694
  "classify": {
1596
1695
  "type": "function",
1597
1696
  "arity": 2
1598
1697
  },
1698
+ "classifyWithSources": {
1699
+ "type": "function",
1700
+ "arity": 3
1701
+ },
1599
1702
  "refuseIfMalicious": {
1600
1703
  "type": "function",
1601
1704
  "arity": 2
@@ -1631,6 +1734,48 @@
1631
1734
  }
1632
1735
  }
1633
1736
  },
1737
+ "output": {
1738
+ "type": "object",
1739
+ "members": {
1740
+ "AiOutputError": {
1741
+ "type": "function",
1742
+ "arity": 4
1743
+ },
1744
+ "ENTITIES": {
1745
+ "type": "instance",
1746
+ "ctorName": "Array"
1747
+ },
1748
+ "redact": {
1749
+ "type": "function",
1750
+ "arity": 2
1751
+ },
1752
+ "sanitize": {
1753
+ "type": "function",
1754
+ "arity": 2
1755
+ }
1756
+ }
1757
+ },
1758
+ "prompt": {
1759
+ "type": "object",
1760
+ "members": {
1761
+ "AiPromptError": {
1762
+ "type": "function",
1763
+ "arity": 4
1764
+ },
1765
+ "ROLE_CONTROL_TOKENS": {
1766
+ "type": "instance",
1767
+ "ctorName": "Array"
1768
+ },
1769
+ "UNTRUSTED_ROLES": {
1770
+ "type": "instance",
1771
+ "ctorName": "Array"
1772
+ },
1773
+ "template": {
1774
+ "type": "function",
1775
+ "arity": 2
1776
+ }
1777
+ }
1778
+ },
1634
1779
  "quota": {
1635
1780
  "type": "object",
1636
1781
  "members": {
@@ -1938,6 +2083,10 @@
1938
2083
  }
1939
2084
  }
1940
2085
  },
2086
+ "rewrapTenant": {
2087
+ "type": "function",
2088
+ "arity": 1
2089
+ },
1941
2090
  "sniffEnvelope": {
1942
2091
  "type": "function",
1943
2092
  "arity": 1
@@ -12829,10 +12978,18 @@
12829
12978
  "type": "instance",
12830
12979
  "ctorName": "Array"
12831
12980
  },
12981
+ "adherenceForm": {
12982
+ "type": "function",
12983
+ "arity": 1
12984
+ },
12832
12985
  "classify": {
12833
12986
  "type": "function",
12834
12987
  "arity": 1
12835
12988
  },
12989
+ "declareAdherence": {
12990
+ "type": "function",
12991
+ "arity": 1
12992
+ },
12836
12993
  "listObligations": {
12837
12994
  "type": "function",
12838
12995
  "arity": 1
@@ -12840,6 +12997,10 @@
12840
12997
  "trainingDataSummary": {
12841
12998
  "type": "function",
12842
12999
  "arity": 1
13000
+ },
13001
+ "verifyAdherence": {
13002
+ "type": "function",
13003
+ "arity": 3
12843
13004
  }
12844
13005
  }
12845
13006
  },
@@ -13248,6 +13409,40 @@
13248
13409
  "type": "instance",
13249
13410
  "ctorName": "Array"
13250
13411
  },
13412
+ "PURPOSES": {
13413
+ "type": "object",
13414
+ "members": {
13415
+ "educational-only": {
13416
+ "type": "object",
13417
+ "members": {
13418
+ "citation": {
13419
+ "type": "primitive",
13420
+ "valueType": "string"
13421
+ },
13422
+ "commercialUseProhibited": {
13423
+ "type": "primitive",
13424
+ "valueType": "boolean"
13425
+ },
13426
+ "dataMinimization": {
13427
+ "type": "primitive",
13428
+ "valueType": "boolean"
13429
+ },
13430
+ "forbidsLawfulBasis": {
13431
+ "type": "instance",
13432
+ "ctorName": "Array"
13433
+ },
13434
+ "notes": {
13435
+ "type": "primitive",
13436
+ "valueType": "string"
13437
+ },
13438
+ "purpose": {
13439
+ "type": "primitive",
13440
+ "valueType": "string"
13441
+ }
13442
+ }
13443
+ }
13444
+ }
13445
+ },
13251
13446
  "grant": {
13252
13447
  "type": "function",
13253
13448
  "arity": 1
@@ -13260,6 +13455,14 @@
13260
13455
  "type": "function",
13261
13456
  "arity": 1
13262
13457
  },
13458
+ "listPurposes": {
13459
+ "type": "function",
13460
+ "arity": 0
13461
+ },
13462
+ "recognizedPurpose": {
13463
+ "type": "function",
13464
+ "arity": 1
13465
+ },
13263
13466
  "verify": {
13264
13467
  "type": "function",
13265
13468
  "arity": 1
@@ -13509,6 +13712,10 @@
13509
13712
  "type": "instance",
13510
13713
  "ctorName": "Array"
13511
13714
  },
13715
+ "attachIdentityAssertion": {
13716
+ "type": "function",
13717
+ "arity": 1
13718
+ },
13512
13719
  "build": {
13513
13720
  "type": "function",
13514
13721
  "arity": 1
@@ -13536,6 +13743,14 @@
13536
13743
  "verify": {
13537
13744
  "type": "function",
13538
13745
  "arity": 3
13746
+ },
13747
+ "verifyCose": {
13748
+ "type": "function",
13749
+ "arity": 3
13750
+ },
13751
+ "verifyIdentityAssertion": {
13752
+ "type": "function",
13753
+ "arity": 3
13539
13754
  }
13540
13755
  }
13541
13756
  },
@@ -15857,6 +16072,14 @@
15857
16072
  "type": "function",
15858
16073
  "arity": 4
15859
16074
  },
16075
+ "AiOutputError": {
16076
+ "type": "function",
16077
+ "arity": 4
16078
+ },
16079
+ "AiPromptError": {
16080
+ "type": "function",
16081
+ "arity": 4
16082
+ },
15860
16083
  "ApiKeyError": {
15861
16084
  "type": "function",
15862
16085
  "arity": 4
@@ -16133,6 +16356,10 @@
16133
16356
  "type": "function",
16134
16357
  "arity": 4
16135
16358
  },
16359
+ "PrivacyError": {
16360
+ "type": "function",
16361
+ "arity": 4
16362
+ },
16136
16363
  "ProblemDetailsError": {
16137
16364
  "type": "function",
16138
16365
  "arity": 4
@@ -45509,6 +45736,27 @@
45509
45736
  }
45510
45737
  }
45511
45738
  },
45739
+ "privacy": {
45740
+ "type": "object",
45741
+ "members": {
45742
+ "PrivacyError": {
45743
+ "type": "function",
45744
+ "arity": 4
45745
+ },
45746
+ "VENDOR_REVIEW_CLAUSES": {
45747
+ "type": "instance",
45748
+ "ctorName": "Array"
45749
+ },
45750
+ "listVendorReviewClauses": {
45751
+ "type": "function",
45752
+ "arity": 0
45753
+ },
45754
+ "vendorReview": {
45755
+ "type": "function",
45756
+ "arity": 1
45757
+ }
45758
+ }
45759
+ },
45512
45760
  "privacyPass": {
45513
45761
  "type": "object",
45514
45762
  "members": {
@@ -46379,6 +46627,10 @@
46379
46627
  "type": "function",
46380
46628
  "arity": 1
46381
46629
  },
46630
+ "extractToMemory": {
46631
+ "type": "function",
46632
+ "arity": 1
46633
+ },
46382
46634
  "inspect": {
46383
46635
  "type": "function",
46384
46636
  "arity": 1
@@ -49738,13 +49990,25 @@
49738
49990
  "type": "function",
49739
49991
  "arity": 3
49740
49992
  },
49993
+ "resealRoot": {
49994
+ "type": "function",
49995
+ "arity": 4
49996
+ },
49741
49997
  "seal": {
49742
49998
  "type": "function",
49743
49999
  "arity": 2
49744
50000
  },
50001
+ "sealRoot": {
50002
+ "type": "function",
50003
+ "arity": 3
50004
+ },
49745
50005
  "unseal": {
49746
50006
  "type": "function",
49747
50007
  "arity": 2
50008
+ },
50009
+ "unsealRoot": {
50010
+ "type": "function",
50011
+ "arity": 3
49748
50012
  }
49749
50013
  }
49750
50014
  },
@@ -51,6 +51,7 @@ var KNOWN_POSTURES = {
51
51
  hipaa: 1, "pci-dss": 1, gdpr: 1, soc2: 1, dora: 1, nis2: 1, cra: 1,
52
52
  fapi2: 1, "21-cfr-11": 1, fdx: 1, "tcpa-10dlc": 1, "iab-tcf": 1, "iab-mspa": 1,
53
53
  "sox-404": 1, "sec-cyber": 1, ferpa: 1, glba: 1, ccpa: 1, "modpa": 1,
54
+ "ca-sopipa": 1, coppa: 1, "coppa-2025": 1,
54
55
  "nydfs-500": 1, "eu-data-act": 1, "eu-ai-act": 1,
55
56
  // v0.10.8 — EU AI Act Art. 50 + Art. 11 + AB-853 + CAC + AI governance
56
57
  "eu-ai-act-art-50": 1, "eu-ai-act-art-11": 1,
@@ -26,7 +26,7 @@ _tls.DEFAULT_MIN_VERSION = "TLSv1.3";
26
26
  * frameworkSchema, clusterStorage, session, atomicFile,
27
27
  * cookies
28
28
  * Audit: audit, auditChain, auditSign, auditTools, consent,
29
- * subject, events, redact
29
+ * subject, events, redact, privacy
30
30
  * HTTP: router, middleware (csrf, cors, rate-limit, request-id,
31
31
  * security-headers, bot-guard, attach-user, require-auth,
32
32
  * error-handler, body-parser, csp-nonce, compression,
@@ -88,6 +88,7 @@ audit.export = function (opts) {
88
88
  };
89
89
  var auditChain = require("./lib/audit-chain");
90
90
  var consent = require("./lib/consent");
91
+ var privacy = require("./lib/privacy");
91
92
  var subject = require("./lib/subject");
92
93
  var session = require("./lib/session");
93
94
  var storage = require("./lib/storage");
@@ -139,6 +140,8 @@ var sse = require("./lib/sse");
139
140
  var mcp = require("./lib/mcp");
140
141
  var graphqlFederation = require("./lib/graphql-federation");
141
142
  var aiInput = require("./lib/ai-input");
143
+ var aiOutput = require("./lib/ai-output");
144
+ var aiPrompt = require("./lib/ai-prompt");
142
145
  var a2a = require("./lib/a2a");
143
146
  var darkPatterns = require("./lib/dark-patterns");
144
147
  var budr = require("./lib/budr");
@@ -457,6 +460,7 @@ module.exports = {
457
460
  auditTools: auditTools,
458
461
  events: events,
459
462
  consent: consent,
463
+ privacy: privacy,
460
464
  subject: subject,
461
465
  session: session,
462
466
  storage: storage,
@@ -471,6 +475,8 @@ module.exports = {
471
475
  ai: {
472
476
  adverseDecision: require("./lib/ai-adverse-decision"),
473
477
  input: aiInput,
478
+ output: aiOutput,
479
+ prompt: aiPrompt,
474
480
  aiContentDetect: require("./lib/ai-content-detect"),
475
481
  modelManifest: require("./lib/ai-model-manifest"),
476
482
  disclosure: require("./lib/ai-disclosure"),
@@ -69,6 +69,8 @@ var safeJson = require("./safe-json");
69
69
  var guardIdempotencyKey = require("./guard-idempotency-key");
70
70
  var agentAudit = require("./agent-audit");
71
71
  var { boundedMap } = require("./bounded-map");
72
+ var vaultAad = require("./vault-aad");
73
+ var validateOpts = require("./validate-opts");
72
74
 
73
75
  // The default in-memory backend is keyed on (method, actorId, keyHash) —
74
76
  // the key hash comes from request-supplied idempotency keys, so a flood of
@@ -540,10 +542,121 @@ function _safeAudit(auditImpl, action, actor, metadata) {
540
542
  agentAudit.safeAudit(auditImpl, action, actor, metadata);
541
543
  }
542
544
 
545
+ // ---- Vault-key rotation: out-of-band reseal hook -------------------------
546
+ //
547
+ // The cached-result column is AAD-sealed on an OPERATOR-SUPPLIED backing
548
+ // store (opts.store / the in-memory default), NOT in the framework's db.enc.
549
+ // The vault-key rotation pipeline (b.vaultRotate.rotate) only walks tables
550
+ // that live inside db.enc, so it cannot reach this store — the rows would be
551
+ // ORPHANED under the old vault root after a rotation (CWE-320 cryptographic-
552
+ // key-management failure: ciphertext stranded under a retired key, then
553
+ // unreadable once the old keypair is destroyed). This reseal hook lets an
554
+ // operator rotate the store out-of-band, composing the SAME explicit-root
555
+ // primitive the in-tree pipeline uses (vaultAad.resealRoot) and the SAME
556
+ // AAD builder the seal path used (cryptoField._aadParts) so the re-sealed
557
+ // AAD tuple is byte-identical — one source of truth, no drift.
558
+ //
559
+ // Reseal store contract (the durable SQL / Redis backend the operator
560
+ // already wired for opts.store also exposes):
561
+ // - listAll() → array of every stored row (each row carries the
562
+ // sealed `resultBlob` column + its keyHash identity).
563
+ // - putResealed(row) → write the row back, addressed by its own stored
564
+ // identity (keyHash). Distinct from the per-request
565
+ // put(method, actorId, key) because reseal addresses
566
+ // a row by the row identity already on disk, not by
567
+ // the raw idempotency key (which is never stored —
568
+ // only its namespaced keyHash is).
569
+ /**
570
+ * @primitive b.agent.idempotency.reseal
571
+ * @signature b.agent.idempotency.reseal(opts)
572
+ * @since 0.14.12
573
+ * @status stable
574
+ * @compliance gdpr, soc2
575
+ * @related b.vault.getKeysJson, b.cryptoField.sealRow
576
+ *
577
+ * Re-seals every AAD-bound cached-result cell on an operator-supplied
578
+ * store from the OLD vault keypair to the NEW one, out-of-band. The
579
+ * in-tree vault-key rotation pipeline only walks tables inside `db.enc`,
580
+ * so an operator-supplied idempotency store is unreachable to it — after a
581
+ * keypair rotation its cells would otherwise be orphaned under the retired
582
+ * root (CWE-320). Composes the same AAD-cell re-seal the rotation pipeline
583
+ * uses, rebuilding each cell's AAD from the registered schema (one source
584
+ * of truth). Only AAD-sealed cells are touched; plain rows pass through.
585
+ *
586
+ * @opts
587
+ * store: Object, // { listAll(): rows[], putResealed(row) } (sync or async)
588
+ * oldRootJson: string, // b.vault.getKeysJson() of the retired keypair
589
+ * newRootJson: string, // b.vault.getKeysJson() of the new keypair
590
+ *
591
+ * @example
592
+ * await b.agent.idempotency.reseal({ store: durableStore, oldRootJson: oldKeys, newRootJson: newKeys });
593
+ * // → { table: "agent_idempotency", resealed: 12 }
594
+ */
595
+ function reseal(args) {
596
+ args = args || {};
597
+ validateOpts.requireNonEmptyString(args.oldRootJson,
598
+ "reseal: oldRootJson (b.vault.getKeysJson() of the OLD keypair)",
599
+ AgentIdempotencyError, "agent-idempotency/bad-root");
600
+ validateOpts.requireNonEmptyString(args.newRootJson,
601
+ "reseal: newRootJson (b.vault.getKeysJson() of the NEW keypair)",
602
+ AgentIdempotencyError, "agent-idempotency/bad-root");
603
+ var store = args.store;
604
+ validateOpts.requireMethods(store, ["listAll", "putResealed"],
605
+ "reseal: operator store (so every persisted row can be re-sealed out-of-band)",
606
+ AgentIdempotencyError, "agent-idempotency/bad-reseal-store");
607
+ _ensureSealTable();
608
+ var schema = cryptoField().getSchema(SEAL_TABLE);
609
+ // listAll / putResealed may be sync (in-memory) or async (durable SQL /
610
+ // Redis). Thread both through Promise.resolve so either shape works.
611
+ return Promise.resolve(store.listAll()).then(function (rows) {
612
+ if (!Array.isArray(rows)) {
613
+ throw new AgentIdempotencyError("agent-idempotency/bad-reseal-store",
614
+ "reseal: store.listAll() must resolve to an array of rows");
615
+ }
616
+ var chain = Promise.resolve();
617
+ var resealed = 0;
618
+ rows.forEach(function (row) {
619
+ if (!row || typeof row !== "object") return;
620
+ var changed = false;
621
+ for (var f = 0; f < schema.sealedFields.length; f += 1) {
622
+ var column = schema.sealedFields[f];
623
+ var value = row[column];
624
+ // Only AAD-sealed cells need rotating. Vault-less / pre-sealing rows
625
+ // carry plain JSON; a plain `vault:` cell would have been written by
626
+ // a non-AAD path that doesn't exist for this table — leave both
627
+ // untouched (resealRoot would throw not-sealed on a plain value).
628
+ if (typeof value !== "string" || !vaultAad.isAadSealed(value)) continue;
629
+ var aadParts = cryptoField()._aadParts(schema, SEAL_TABLE, column, row);
630
+ row[column] = vaultAad.resealRoot(value, aadParts, args.oldRootJson, args.newRootJson);
631
+ changed = true;
632
+ }
633
+ if (changed) {
634
+ resealed += 1;
635
+ chain = chain.then(function () { return store.putResealed(row); });
636
+ }
637
+ });
638
+ return chain.then(function () { return { table: SEAL_TABLE, resealed: resealed }; });
639
+ });
640
+ }
641
+
543
642
  module.exports = {
544
643
  create: create,
644
+ reseal: reseal,
545
645
  AgentIdempotencyError: AgentIdempotencyError,
546
646
  guards: {
547
647
  key: guardIdempotencyKey,
548
648
  },
649
+ // AAD_ROTATION — the vault-key rotation descriptor every framework module
650
+ // that seals an {aad:true} table on an OPERATOR-SUPPLIED store (outside
651
+ // db.enc) exports, so an operator can register it with a rotation eager-
652
+ // sweep and the codebase-patterns detect-and-refuse gate can confirm no
653
+ // such external-store table is silently orphaned. `backend: "external"`
654
+ // flags that the in-tree b.vaultRotate.rotate pipeline cannot reach it.
655
+ AAD_ROTATION: {
656
+ table: SEAL_TABLE,
657
+ rowIdField: "keyHash",
658
+ schemaVersion: "1",
659
+ backend: "external",
660
+ reseal: reseal,
661
+ },
549
662
  };