settld 0.1.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 (863) hide show
  1. package/Dockerfile +45 -0
  2. package/README.md +150 -0
  3. package/SETTLD_VERSION +1 -0
  4. package/bin/settld.js +212 -0
  5. package/conformance/README.md +14 -0
  6. package/conformance/kernel-v0/README.md +60 -0
  7. package/conformance/kernel-v0/cases.json +19 -0
  8. package/conformance/kernel-v0/run.mjs +830 -0
  9. package/conformance/v1/README.md +77 -0
  10. package/conformance/v1/bundles/closepack/nonstrict-pass-missing-sla-acceptance/attestation/bundle_head_attestation.json +1 -0
  11. package/conformance/v1/bundles/closepack/nonstrict-pass-missing-sla-acceptance/evidence/evidence_index.json +1 -0
  12. package/conformance/v1/bundles/closepack/nonstrict-pass-missing-sla-acceptance/governance/policy.json +1 -0
  13. package/conformance/v1/bundles/closepack/nonstrict-pass-missing-sla-acceptance/governance/revocations.json +1 -0
  14. package/conformance/v1/bundles/closepack/nonstrict-pass-missing-sla-acceptance/manifest.json +1 -0
  15. package/conformance/v1/bundles/closepack/nonstrict-pass-missing-sla-acceptance/payload/invoice_bundle/attestation/bundle_head_attestation.json +1 -0
  16. package/conformance/v1/bundles/closepack/nonstrict-pass-missing-sla-acceptance/payload/invoice_bundle/governance/policy.json +1 -0
  17. package/conformance/v1/bundles/closepack/nonstrict-pass-missing-sla-acceptance/payload/invoice_bundle/governance/revocations.json +1 -0
  18. package/conformance/v1/bundles/closepack/nonstrict-pass-missing-sla-acceptance/payload/invoice_bundle/invoice/invoice_claim.json +1 -0
  19. package/conformance/v1/bundles/closepack/nonstrict-pass-missing-sla-acceptance/payload/invoice_bundle/manifest.json +1 -0
  20. package/conformance/v1/bundles/closepack/nonstrict-pass-missing-sla-acceptance/payload/invoice_bundle/metering/metering_report.json +1 -0
  21. package/conformance/v1/bundles/closepack/nonstrict-pass-missing-sla-acceptance/payload/invoice_bundle/payload/job_proof_bundle/attestation/bundle_head_attestation.json +1 -0
  22. package/conformance/v1/bundles/closepack/nonstrict-pass-missing-sla-acceptance/payload/invoice_bundle/payload/job_proof_bundle/events/events.jsonl +1 -0
  23. package/conformance/v1/bundles/closepack/nonstrict-pass-missing-sla-acceptance/payload/invoice_bundle/payload/job_proof_bundle/events/payload_material.jsonl +1 -0
  24. package/conformance/v1/bundles/closepack/nonstrict-pass-missing-sla-acceptance/payload/invoice_bundle/payload/job_proof_bundle/governance/global/events/events.jsonl +1 -0
  25. package/conformance/v1/bundles/closepack/nonstrict-pass-missing-sla-acceptance/payload/invoice_bundle/payload/job_proof_bundle/governance/global/events/payload_material.jsonl +1 -0
  26. package/conformance/v1/bundles/closepack/nonstrict-pass-missing-sla-acceptance/payload/invoice_bundle/payload/job_proof_bundle/governance/global/snapshot.json +1 -0
  27. package/conformance/v1/bundles/closepack/nonstrict-pass-missing-sla-acceptance/payload/invoice_bundle/payload/job_proof_bundle/governance/policy.json +1 -0
  28. package/conformance/v1/bundles/closepack/nonstrict-pass-missing-sla-acceptance/payload/invoice_bundle/payload/job_proof_bundle/governance/revocations.json +1 -0
  29. package/conformance/v1/bundles/closepack/nonstrict-pass-missing-sla-acceptance/payload/invoice_bundle/payload/job_proof_bundle/governance/tenant/events/events.jsonl +0 -0
  30. package/conformance/v1/bundles/closepack/nonstrict-pass-missing-sla-acceptance/payload/invoice_bundle/payload/job_proof_bundle/governance/tenant/events/payload_material.jsonl +0 -0
  31. package/conformance/v1/bundles/closepack/nonstrict-pass-missing-sla-acceptance/payload/invoice_bundle/payload/job_proof_bundle/governance/tenant/snapshot.json +1 -0
  32. package/conformance/v1/bundles/closepack/nonstrict-pass-missing-sla-acceptance/payload/invoice_bundle/payload/job_proof_bundle/job/snapshot.json +1 -0
  33. package/conformance/v1/bundles/closepack/nonstrict-pass-missing-sla-acceptance/payload/invoice_bundle/payload/job_proof_bundle/keys/public_keys.json +1 -0
  34. package/conformance/v1/bundles/closepack/nonstrict-pass-missing-sla-acceptance/payload/invoice_bundle/payload/job_proof_bundle/manifest.json +1 -0
  35. package/conformance/v1/bundles/closepack/nonstrict-pass-missing-sla-acceptance/payload/invoice_bundle/payload/job_proof_bundle/verify/report.json +1 -0
  36. package/conformance/v1/bundles/closepack/nonstrict-pass-missing-sla-acceptance/payload/invoice_bundle/payload/job_proof_bundle/verify/verification_report.json +1 -0
  37. package/conformance/v1/bundles/closepack/nonstrict-pass-missing-sla-acceptance/payload/invoice_bundle/pricing/pricing_matrix.json +1 -0
  38. package/conformance/v1/bundles/closepack/nonstrict-pass-missing-sla-acceptance/payload/invoice_bundle/pricing/pricing_matrix_signatures.json +1 -0
  39. package/conformance/v1/bundles/closepack/nonstrict-pass-missing-sla-acceptance/payload/invoice_bundle/settld.json +1 -0
  40. package/conformance/v1/bundles/closepack/nonstrict-pass-missing-sla-acceptance/payload/invoice_bundle/verify/verification_report.json +1 -0
  41. package/conformance/v1/bundles/closepack/nonstrict-pass-missing-sla-acceptance/settld.json +1 -0
  42. package/conformance/v1/bundles/closepack/nonstrict-pass-missing-sla-acceptance/verify/verification_report.json +1 -0
  43. package/conformance/v1/bundles/closepack/strict-fail-embedded-invoice-fails/acceptance/acceptance_criteria.json +1 -0
  44. package/conformance/v1/bundles/closepack/strict-fail-embedded-invoice-fails/acceptance/acceptance_evaluation.json +1 -0
  45. package/conformance/v1/bundles/closepack/strict-fail-embedded-invoice-fails/attestation/bundle_head_attestation.json +1 -0
  46. package/conformance/v1/bundles/closepack/strict-fail-embedded-invoice-fails/evidence/evidence_index.json +1 -0
  47. package/conformance/v1/bundles/closepack/strict-fail-embedded-invoice-fails/governance/policy.json +1 -0
  48. package/conformance/v1/bundles/closepack/strict-fail-embedded-invoice-fails/governance/revocations.json +1 -0
  49. package/conformance/v1/bundles/closepack/strict-fail-embedded-invoice-fails/manifest.json +1 -0
  50. package/conformance/v1/bundles/closepack/strict-fail-embedded-invoice-fails/payload/invoice_bundle/attestation/bundle_head_attestation.json +1 -0
  51. package/conformance/v1/bundles/closepack/strict-fail-embedded-invoice-fails/payload/invoice_bundle/governance/policy.json +1 -0
  52. package/conformance/v1/bundles/closepack/strict-fail-embedded-invoice-fails/payload/invoice_bundle/governance/revocations.json +1 -0
  53. package/conformance/v1/bundles/closepack/strict-fail-embedded-invoice-fails/payload/invoice_bundle/invoice/invoice_claim.json +1 -0
  54. package/conformance/v1/bundles/closepack/strict-fail-embedded-invoice-fails/payload/invoice_bundle/manifest.json +1 -0
  55. package/conformance/v1/bundles/closepack/strict-fail-embedded-invoice-fails/payload/invoice_bundle/metering/metering_report.json +1 -0
  56. package/conformance/v1/bundles/closepack/strict-fail-embedded-invoice-fails/payload/invoice_bundle/payload/job_proof_bundle/attestation/bundle_head_attestation.json +1 -0
  57. package/conformance/v1/bundles/closepack/strict-fail-embedded-invoice-fails/payload/invoice_bundle/payload/job_proof_bundle/events/events.jsonl +1 -0
  58. package/conformance/v1/bundles/closepack/strict-fail-embedded-invoice-fails/payload/invoice_bundle/payload/job_proof_bundle/events/payload_material.jsonl +1 -0
  59. package/conformance/v1/bundles/closepack/strict-fail-embedded-invoice-fails/payload/invoice_bundle/payload/job_proof_bundle/governance/global/events/events.jsonl +1 -0
  60. package/conformance/v1/bundles/closepack/strict-fail-embedded-invoice-fails/payload/invoice_bundle/payload/job_proof_bundle/governance/global/events/payload_material.jsonl +1 -0
  61. package/conformance/v1/bundles/closepack/strict-fail-embedded-invoice-fails/payload/invoice_bundle/payload/job_proof_bundle/governance/global/snapshot.json +1 -0
  62. package/conformance/v1/bundles/closepack/strict-fail-embedded-invoice-fails/payload/invoice_bundle/payload/job_proof_bundle/governance/policy.json +1 -0
  63. package/conformance/v1/bundles/closepack/strict-fail-embedded-invoice-fails/payload/invoice_bundle/payload/job_proof_bundle/governance/revocations.json +1 -0
  64. package/conformance/v1/bundles/closepack/strict-fail-embedded-invoice-fails/payload/invoice_bundle/payload/job_proof_bundle/governance/tenant/events/events.jsonl +0 -0
  65. package/conformance/v1/bundles/closepack/strict-fail-embedded-invoice-fails/payload/invoice_bundle/payload/job_proof_bundle/governance/tenant/events/payload_material.jsonl +0 -0
  66. package/conformance/v1/bundles/closepack/strict-fail-embedded-invoice-fails/payload/invoice_bundle/payload/job_proof_bundle/governance/tenant/snapshot.json +1 -0
  67. package/conformance/v1/bundles/closepack/strict-fail-embedded-invoice-fails/payload/invoice_bundle/payload/job_proof_bundle/job/snapshot.json +1 -0
  68. package/conformance/v1/bundles/closepack/strict-fail-embedded-invoice-fails/payload/invoice_bundle/payload/job_proof_bundle/keys/public_keys.json +1 -0
  69. package/conformance/v1/bundles/closepack/strict-fail-embedded-invoice-fails/payload/invoice_bundle/payload/job_proof_bundle/manifest.json +1 -0
  70. package/conformance/v1/bundles/closepack/strict-fail-embedded-invoice-fails/payload/invoice_bundle/payload/job_proof_bundle/verify/report.json +1 -0
  71. package/conformance/v1/bundles/closepack/strict-fail-embedded-invoice-fails/payload/invoice_bundle/payload/job_proof_bundle/verify/verification_report.json +1 -0
  72. package/conformance/v1/bundles/closepack/strict-fail-embedded-invoice-fails/payload/invoice_bundle/pricing/pricing_matrix.json +1 -0
  73. package/conformance/v1/bundles/closepack/strict-fail-embedded-invoice-fails/payload/invoice_bundle/pricing/pricing_matrix_signatures.json +1 -0
  74. package/conformance/v1/bundles/closepack/strict-fail-embedded-invoice-fails/payload/invoice_bundle/settld.json +1 -0
  75. package/conformance/v1/bundles/closepack/strict-fail-embedded-invoice-fails/payload/invoice_bundle/verify/verification_report.json +1 -0
  76. package/conformance/v1/bundles/closepack/strict-fail-embedded-invoice-fails/settld.json +1 -0
  77. package/conformance/v1/bundles/closepack/strict-fail-embedded-invoice-fails/sla/sla_definition.json +1 -0
  78. package/conformance/v1/bundles/closepack/strict-fail-embedded-invoice-fails/sla/sla_evaluation.json +1 -0
  79. package/conformance/v1/bundles/closepack/strict-fail-embedded-invoice-fails/verify/verification_report.json +1 -0
  80. package/conformance/v1/bundles/closepack/strict-fail-evidence-index-mismatch/acceptance/acceptance_criteria.json +1 -0
  81. package/conformance/v1/bundles/closepack/strict-fail-evidence-index-mismatch/acceptance/acceptance_evaluation.json +1 -0
  82. package/conformance/v1/bundles/closepack/strict-fail-evidence-index-mismatch/attestation/bundle_head_attestation.json +1 -0
  83. package/conformance/v1/bundles/closepack/strict-fail-evidence-index-mismatch/evidence/evidence_index.json +1 -0
  84. package/conformance/v1/bundles/closepack/strict-fail-evidence-index-mismatch/governance/policy.json +1 -0
  85. package/conformance/v1/bundles/closepack/strict-fail-evidence-index-mismatch/governance/revocations.json +1 -0
  86. package/conformance/v1/bundles/closepack/strict-fail-evidence-index-mismatch/manifest.json +1 -0
  87. package/conformance/v1/bundles/closepack/strict-fail-evidence-index-mismatch/payload/invoice_bundle/attestation/bundle_head_attestation.json +1 -0
  88. package/conformance/v1/bundles/closepack/strict-fail-evidence-index-mismatch/payload/invoice_bundle/governance/policy.json +1 -0
  89. package/conformance/v1/bundles/closepack/strict-fail-evidence-index-mismatch/payload/invoice_bundle/governance/revocations.json +1 -0
  90. package/conformance/v1/bundles/closepack/strict-fail-evidence-index-mismatch/payload/invoice_bundle/invoice/invoice_claim.json +1 -0
  91. package/conformance/v1/bundles/closepack/strict-fail-evidence-index-mismatch/payload/invoice_bundle/manifest.json +1 -0
  92. package/conformance/v1/bundles/closepack/strict-fail-evidence-index-mismatch/payload/invoice_bundle/metering/metering_report.json +1 -0
  93. package/conformance/v1/bundles/closepack/strict-fail-evidence-index-mismatch/payload/invoice_bundle/payload/job_proof_bundle/attestation/bundle_head_attestation.json +1 -0
  94. package/conformance/v1/bundles/closepack/strict-fail-evidence-index-mismatch/payload/invoice_bundle/payload/job_proof_bundle/events/events.jsonl +1 -0
  95. package/conformance/v1/bundles/closepack/strict-fail-evidence-index-mismatch/payload/invoice_bundle/payload/job_proof_bundle/events/payload_material.jsonl +1 -0
  96. package/conformance/v1/bundles/closepack/strict-fail-evidence-index-mismatch/payload/invoice_bundle/payload/job_proof_bundle/governance/global/events/events.jsonl +1 -0
  97. package/conformance/v1/bundles/closepack/strict-fail-evidence-index-mismatch/payload/invoice_bundle/payload/job_proof_bundle/governance/global/events/payload_material.jsonl +1 -0
  98. package/conformance/v1/bundles/closepack/strict-fail-evidence-index-mismatch/payload/invoice_bundle/payload/job_proof_bundle/governance/global/snapshot.json +1 -0
  99. package/conformance/v1/bundles/closepack/strict-fail-evidence-index-mismatch/payload/invoice_bundle/payload/job_proof_bundle/governance/policy.json +1 -0
  100. package/conformance/v1/bundles/closepack/strict-fail-evidence-index-mismatch/payload/invoice_bundle/payload/job_proof_bundle/governance/revocations.json +1 -0
  101. package/conformance/v1/bundles/closepack/strict-fail-evidence-index-mismatch/payload/invoice_bundle/payload/job_proof_bundle/governance/tenant/events/events.jsonl +0 -0
  102. package/conformance/v1/bundles/closepack/strict-fail-evidence-index-mismatch/payload/invoice_bundle/payload/job_proof_bundle/governance/tenant/events/payload_material.jsonl +0 -0
  103. package/conformance/v1/bundles/closepack/strict-fail-evidence-index-mismatch/payload/invoice_bundle/payload/job_proof_bundle/governance/tenant/snapshot.json +1 -0
  104. package/conformance/v1/bundles/closepack/strict-fail-evidence-index-mismatch/payload/invoice_bundle/payload/job_proof_bundle/job/snapshot.json +1 -0
  105. package/conformance/v1/bundles/closepack/strict-fail-evidence-index-mismatch/payload/invoice_bundle/payload/job_proof_bundle/keys/public_keys.json +1 -0
  106. package/conformance/v1/bundles/closepack/strict-fail-evidence-index-mismatch/payload/invoice_bundle/payload/job_proof_bundle/manifest.json +1 -0
  107. package/conformance/v1/bundles/closepack/strict-fail-evidence-index-mismatch/payload/invoice_bundle/payload/job_proof_bundle/verify/report.json +1 -0
  108. package/conformance/v1/bundles/closepack/strict-fail-evidence-index-mismatch/payload/invoice_bundle/payload/job_proof_bundle/verify/verification_report.json +1 -0
  109. package/conformance/v1/bundles/closepack/strict-fail-evidence-index-mismatch/payload/invoice_bundle/pricing/pricing_matrix.json +1 -0
  110. package/conformance/v1/bundles/closepack/strict-fail-evidence-index-mismatch/payload/invoice_bundle/pricing/pricing_matrix_signatures.json +1 -0
  111. package/conformance/v1/bundles/closepack/strict-fail-evidence-index-mismatch/payload/invoice_bundle/settld.json +1 -0
  112. package/conformance/v1/bundles/closepack/strict-fail-evidence-index-mismatch/payload/invoice_bundle/verify/verification_report.json +1 -0
  113. package/conformance/v1/bundles/closepack/strict-fail-evidence-index-mismatch/settld.json +1 -0
  114. package/conformance/v1/bundles/closepack/strict-fail-evidence-index-mismatch/sla/sla_definition.json +1 -0
  115. package/conformance/v1/bundles/closepack/strict-fail-evidence-index-mismatch/sla/sla_evaluation.json +1 -0
  116. package/conformance/v1/bundles/closepack/strict-fail-evidence-index-mismatch/verify/verification_report.json +1 -0
  117. package/conformance/v1/bundles/closepack/strict-pass/acceptance/acceptance_criteria.json +1 -0
  118. package/conformance/v1/bundles/closepack/strict-pass/acceptance/acceptance_evaluation.json +1 -0
  119. package/conformance/v1/bundles/closepack/strict-pass/attestation/bundle_head_attestation.json +1 -0
  120. package/conformance/v1/bundles/closepack/strict-pass/evidence/evidence_index.json +1 -0
  121. package/conformance/v1/bundles/closepack/strict-pass/governance/policy.json +1 -0
  122. package/conformance/v1/bundles/closepack/strict-pass/governance/revocations.json +1 -0
  123. package/conformance/v1/bundles/closepack/strict-pass/manifest.json +1 -0
  124. package/conformance/v1/bundles/closepack/strict-pass/payload/invoice_bundle/attestation/bundle_head_attestation.json +1 -0
  125. package/conformance/v1/bundles/closepack/strict-pass/payload/invoice_bundle/governance/policy.json +1 -0
  126. package/conformance/v1/bundles/closepack/strict-pass/payload/invoice_bundle/governance/revocations.json +1 -0
  127. package/conformance/v1/bundles/closepack/strict-pass/payload/invoice_bundle/invoice/invoice_claim.json +1 -0
  128. package/conformance/v1/bundles/closepack/strict-pass/payload/invoice_bundle/manifest.json +1 -0
  129. package/conformance/v1/bundles/closepack/strict-pass/payload/invoice_bundle/metering/metering_report.json +1 -0
  130. package/conformance/v1/bundles/closepack/strict-pass/payload/invoice_bundle/payload/job_proof_bundle/attestation/bundle_head_attestation.json +1 -0
  131. package/conformance/v1/bundles/closepack/strict-pass/payload/invoice_bundle/payload/job_proof_bundle/events/events.jsonl +1 -0
  132. package/conformance/v1/bundles/closepack/strict-pass/payload/invoice_bundle/payload/job_proof_bundle/events/payload_material.jsonl +1 -0
  133. package/conformance/v1/bundles/closepack/strict-pass/payload/invoice_bundle/payload/job_proof_bundle/governance/global/events/events.jsonl +1 -0
  134. package/conformance/v1/bundles/closepack/strict-pass/payload/invoice_bundle/payload/job_proof_bundle/governance/global/events/payload_material.jsonl +1 -0
  135. package/conformance/v1/bundles/closepack/strict-pass/payload/invoice_bundle/payload/job_proof_bundle/governance/global/snapshot.json +1 -0
  136. package/conformance/v1/bundles/closepack/strict-pass/payload/invoice_bundle/payload/job_proof_bundle/governance/policy.json +1 -0
  137. package/conformance/v1/bundles/closepack/strict-pass/payload/invoice_bundle/payload/job_proof_bundle/governance/revocations.json +1 -0
  138. package/conformance/v1/bundles/closepack/strict-pass/payload/invoice_bundle/payload/job_proof_bundle/governance/tenant/events/events.jsonl +0 -0
  139. package/conformance/v1/bundles/closepack/strict-pass/payload/invoice_bundle/payload/job_proof_bundle/governance/tenant/events/payload_material.jsonl +0 -0
  140. package/conformance/v1/bundles/closepack/strict-pass/payload/invoice_bundle/payload/job_proof_bundle/governance/tenant/snapshot.json +1 -0
  141. package/conformance/v1/bundles/closepack/strict-pass/payload/invoice_bundle/payload/job_proof_bundle/job/snapshot.json +1 -0
  142. package/conformance/v1/bundles/closepack/strict-pass/payload/invoice_bundle/payload/job_proof_bundle/keys/public_keys.json +1 -0
  143. package/conformance/v1/bundles/closepack/strict-pass/payload/invoice_bundle/payload/job_proof_bundle/manifest.json +1 -0
  144. package/conformance/v1/bundles/closepack/strict-pass/payload/invoice_bundle/payload/job_proof_bundle/verify/report.json +1 -0
  145. package/conformance/v1/bundles/closepack/strict-pass/payload/invoice_bundle/payload/job_proof_bundle/verify/verification_report.json +1 -0
  146. package/conformance/v1/bundles/closepack/strict-pass/payload/invoice_bundle/pricing/pricing_matrix.json +1 -0
  147. package/conformance/v1/bundles/closepack/strict-pass/payload/invoice_bundle/pricing/pricing_matrix_signatures.json +1 -0
  148. package/conformance/v1/bundles/closepack/strict-pass/payload/invoice_bundle/settld.json +1 -0
  149. package/conformance/v1/bundles/closepack/strict-pass/payload/invoice_bundle/verify/verification_report.json +1 -0
  150. package/conformance/v1/bundles/closepack/strict-pass/settld.json +1 -0
  151. package/conformance/v1/bundles/closepack/strict-pass/sla/sla_definition.json +1 -0
  152. package/conformance/v1/bundles/closepack/strict-pass/sla/sla_evaluation.json +1 -0
  153. package/conformance/v1/bundles/closepack/strict-pass/verify/verification_report.json +1 -0
  154. package/conformance/v1/bundles/financepack/pass-with-tool-version-unknown-warning/attestation/bundle_head_attestation.json +1 -0
  155. package/conformance/v1/bundles/financepack/pass-with-tool-version-unknown-warning/finance/GLBatch.v1.json +1 -0
  156. package/conformance/v1/bundles/financepack/pass-with-tool-version-unknown-warning/finance/JournalCsv.v1.csv +2 -0
  157. package/conformance/v1/bundles/financepack/pass-with-tool-version-unknown-warning/finance/JournalCsv.v1.json +1 -0
  158. package/conformance/v1/bundles/financepack/pass-with-tool-version-unknown-warning/finance/reconcile.json +1 -0
  159. package/conformance/v1/bundles/financepack/pass-with-tool-version-unknown-warning/governance/policy.json +1 -0
  160. package/conformance/v1/bundles/financepack/pass-with-tool-version-unknown-warning/governance/revocations.json +1 -0
  161. package/conformance/v1/bundles/financepack/pass-with-tool-version-unknown-warning/manifest.json +1 -0
  162. package/conformance/v1/bundles/financepack/pass-with-tool-version-unknown-warning/month/attestation/bundle_head_attestation.json +1 -0
  163. package/conformance/v1/bundles/financepack/pass-with-tool-version-unknown-warning/month/events/events.jsonl +1 -0
  164. package/conformance/v1/bundles/financepack/pass-with-tool-version-unknown-warning/month/events/payload_material.jsonl +1 -0
  165. package/conformance/v1/bundles/financepack/pass-with-tool-version-unknown-warning/month/governance/global/events/events.jsonl +1 -0
  166. package/conformance/v1/bundles/financepack/pass-with-tool-version-unknown-warning/month/governance/global/events/payload_material.jsonl +1 -0
  167. package/conformance/v1/bundles/financepack/pass-with-tool-version-unknown-warning/month/governance/global/snapshot.json +1 -0
  168. package/conformance/v1/bundles/financepack/pass-with-tool-version-unknown-warning/month/governance/policy.json +1 -0
  169. package/conformance/v1/bundles/financepack/pass-with-tool-version-unknown-warning/month/governance/revocations.json +1 -0
  170. package/conformance/v1/bundles/financepack/pass-with-tool-version-unknown-warning/month/governance/tenant/events/events.jsonl +0 -0
  171. package/conformance/v1/bundles/financepack/pass-with-tool-version-unknown-warning/month/governance/tenant/events/payload_material.jsonl +0 -0
  172. package/conformance/v1/bundles/financepack/pass-with-tool-version-unknown-warning/month/governance/tenant/snapshot.json +1 -0
  173. package/conformance/v1/bundles/financepack/pass-with-tool-version-unknown-warning/month/keys/public_keys.json +1 -0
  174. package/conformance/v1/bundles/financepack/pass-with-tool-version-unknown-warning/month/manifest.json +1 -0
  175. package/conformance/v1/bundles/financepack/pass-with-tool-version-unknown-warning/month/verify/report.json +1 -0
  176. package/conformance/v1/bundles/financepack/pass-with-tool-version-unknown-warning/month/verify/verification_report.json +1 -0
  177. package/conformance/v1/bundles/financepack/pass-with-tool-version-unknown-warning/settld.json +1 -0
  178. package/conformance/v1/bundles/financepack/pass-with-tool-version-unknown-warning/verify/verification_report.json +1 -0
  179. package/conformance/v1/bundles/financepack/strict-fail-manifest-tamper/attestation/bundle_head_attestation.json +1 -0
  180. package/conformance/v1/bundles/financepack/strict-fail-manifest-tamper/finance/GLBatch.v1.json +1 -0
  181. package/conformance/v1/bundles/financepack/strict-fail-manifest-tamper/finance/JournalCsv.v1.csv +2 -0
  182. package/conformance/v1/bundles/financepack/strict-fail-manifest-tamper/finance/JournalCsv.v1.json +1 -0
  183. package/conformance/v1/bundles/financepack/strict-fail-manifest-tamper/finance/reconcile.json +2 -0
  184. package/conformance/v1/bundles/financepack/strict-fail-manifest-tamper/governance/policy.json +1 -0
  185. package/conformance/v1/bundles/financepack/strict-fail-manifest-tamper/governance/revocations.json +1 -0
  186. package/conformance/v1/bundles/financepack/strict-fail-manifest-tamper/manifest.json +1 -0
  187. package/conformance/v1/bundles/financepack/strict-fail-manifest-tamper/month/attestation/bundle_head_attestation.json +1 -0
  188. package/conformance/v1/bundles/financepack/strict-fail-manifest-tamper/month/events/events.jsonl +1 -0
  189. package/conformance/v1/bundles/financepack/strict-fail-manifest-tamper/month/events/payload_material.jsonl +1 -0
  190. package/conformance/v1/bundles/financepack/strict-fail-manifest-tamper/month/governance/global/events/events.jsonl +1 -0
  191. package/conformance/v1/bundles/financepack/strict-fail-manifest-tamper/month/governance/global/events/payload_material.jsonl +1 -0
  192. package/conformance/v1/bundles/financepack/strict-fail-manifest-tamper/month/governance/global/snapshot.json +1 -0
  193. package/conformance/v1/bundles/financepack/strict-fail-manifest-tamper/month/governance/policy.json +1 -0
  194. package/conformance/v1/bundles/financepack/strict-fail-manifest-tamper/month/governance/revocations.json +1 -0
  195. package/conformance/v1/bundles/financepack/strict-fail-manifest-tamper/month/governance/tenant/events/events.jsonl +0 -0
  196. package/conformance/v1/bundles/financepack/strict-fail-manifest-tamper/month/governance/tenant/events/payload_material.jsonl +0 -0
  197. package/conformance/v1/bundles/financepack/strict-fail-manifest-tamper/month/governance/tenant/snapshot.json +1 -0
  198. package/conformance/v1/bundles/financepack/strict-fail-manifest-tamper/month/keys/public_keys.json +1 -0
  199. package/conformance/v1/bundles/financepack/strict-fail-manifest-tamper/month/manifest.json +1 -0
  200. package/conformance/v1/bundles/financepack/strict-fail-manifest-tamper/month/verify/report.json +1 -0
  201. package/conformance/v1/bundles/financepack/strict-fail-manifest-tamper/month/verify/verification_report.json +1 -0
  202. package/conformance/v1/bundles/financepack/strict-fail-manifest-tamper/settld.json +1 -0
  203. package/conformance/v1/bundles/financepack/strict-fail-manifest-tamper/verify/verification_report.json +1 -0
  204. package/conformance/v1/bundles/financepack/strict-fail-missing-verification-report/attestation/bundle_head_attestation.json +1 -0
  205. package/conformance/v1/bundles/financepack/strict-fail-missing-verification-report/finance/GLBatch.v1.json +1 -0
  206. package/conformance/v1/bundles/financepack/strict-fail-missing-verification-report/finance/JournalCsv.v1.csv +2 -0
  207. package/conformance/v1/bundles/financepack/strict-fail-missing-verification-report/finance/JournalCsv.v1.json +1 -0
  208. package/conformance/v1/bundles/financepack/strict-fail-missing-verification-report/finance/reconcile.json +1 -0
  209. package/conformance/v1/bundles/financepack/strict-fail-missing-verification-report/governance/policy.json +1 -0
  210. package/conformance/v1/bundles/financepack/strict-fail-missing-verification-report/governance/revocations.json +1 -0
  211. package/conformance/v1/bundles/financepack/strict-fail-missing-verification-report/manifest.json +1 -0
  212. package/conformance/v1/bundles/financepack/strict-fail-missing-verification-report/month/attestation/bundle_head_attestation.json +1 -0
  213. package/conformance/v1/bundles/financepack/strict-fail-missing-verification-report/month/events/events.jsonl +1 -0
  214. package/conformance/v1/bundles/financepack/strict-fail-missing-verification-report/month/events/payload_material.jsonl +1 -0
  215. package/conformance/v1/bundles/financepack/strict-fail-missing-verification-report/month/governance/global/events/events.jsonl +1 -0
  216. package/conformance/v1/bundles/financepack/strict-fail-missing-verification-report/month/governance/global/events/payload_material.jsonl +1 -0
  217. package/conformance/v1/bundles/financepack/strict-fail-missing-verification-report/month/governance/global/snapshot.json +1 -0
  218. package/conformance/v1/bundles/financepack/strict-fail-missing-verification-report/month/governance/policy.json +1 -0
  219. package/conformance/v1/bundles/financepack/strict-fail-missing-verification-report/month/governance/revocations.json +1 -0
  220. package/conformance/v1/bundles/financepack/strict-fail-missing-verification-report/month/governance/tenant/events/events.jsonl +0 -0
  221. package/conformance/v1/bundles/financepack/strict-fail-missing-verification-report/month/governance/tenant/events/payload_material.jsonl +0 -0
  222. package/conformance/v1/bundles/financepack/strict-fail-missing-verification-report/month/governance/tenant/snapshot.json +1 -0
  223. package/conformance/v1/bundles/financepack/strict-fail-missing-verification-report/month/keys/public_keys.json +1 -0
  224. package/conformance/v1/bundles/financepack/strict-fail-missing-verification-report/month/manifest.json +1 -0
  225. package/conformance/v1/bundles/financepack/strict-fail-missing-verification-report/month/verify/report.json +1 -0
  226. package/conformance/v1/bundles/financepack/strict-fail-missing-verification-report/month/verify/verification_report.json +1 -0
  227. package/conformance/v1/bundles/financepack/strict-fail-missing-verification-report/settld.json +1 -0
  228. package/conformance/v1/bundles/financepack/strict-pass/attestation/bundle_head_attestation.json +1 -0
  229. package/conformance/v1/bundles/financepack/strict-pass/finance/GLBatch.v1.json +1 -0
  230. package/conformance/v1/bundles/financepack/strict-pass/finance/JournalCsv.v1.csv +2 -0
  231. package/conformance/v1/bundles/financepack/strict-pass/finance/JournalCsv.v1.json +1 -0
  232. package/conformance/v1/bundles/financepack/strict-pass/finance/reconcile.json +1 -0
  233. package/conformance/v1/bundles/financepack/strict-pass/governance/policy.json +1 -0
  234. package/conformance/v1/bundles/financepack/strict-pass/governance/revocations.json +1 -0
  235. package/conformance/v1/bundles/financepack/strict-pass/manifest.json +1 -0
  236. package/conformance/v1/bundles/financepack/strict-pass/month/attestation/bundle_head_attestation.json +1 -0
  237. package/conformance/v1/bundles/financepack/strict-pass/month/events/events.jsonl +1 -0
  238. package/conformance/v1/bundles/financepack/strict-pass/month/events/payload_material.jsonl +1 -0
  239. package/conformance/v1/bundles/financepack/strict-pass/month/governance/global/events/events.jsonl +1 -0
  240. package/conformance/v1/bundles/financepack/strict-pass/month/governance/global/events/payload_material.jsonl +1 -0
  241. package/conformance/v1/bundles/financepack/strict-pass/month/governance/global/snapshot.json +1 -0
  242. package/conformance/v1/bundles/financepack/strict-pass/month/governance/policy.json +1 -0
  243. package/conformance/v1/bundles/financepack/strict-pass/month/governance/revocations.json +1 -0
  244. package/conformance/v1/bundles/financepack/strict-pass/month/governance/tenant/events/events.jsonl +0 -0
  245. package/conformance/v1/bundles/financepack/strict-pass/month/governance/tenant/events/payload_material.jsonl +0 -0
  246. package/conformance/v1/bundles/financepack/strict-pass/month/governance/tenant/snapshot.json +1 -0
  247. package/conformance/v1/bundles/financepack/strict-pass/month/keys/public_keys.json +1 -0
  248. package/conformance/v1/bundles/financepack/strict-pass/month/manifest.json +1 -0
  249. package/conformance/v1/bundles/financepack/strict-pass/month/verify/report.json +1 -0
  250. package/conformance/v1/bundles/financepack/strict-pass/month/verify/verification_report.json +1 -0
  251. package/conformance/v1/bundles/financepack/strict-pass/settld.json +1 -0
  252. package/conformance/v1/bundles/financepack/strict-pass/verify/verification_report.json +1 -0
  253. package/conformance/v1/bundles/invoicebundle/nonstrict-pass-missing-verification-report/attestation/bundle_head_attestation.json +1 -0
  254. package/conformance/v1/bundles/invoicebundle/nonstrict-pass-missing-verification-report/governance/policy.json +1 -0
  255. package/conformance/v1/bundles/invoicebundle/nonstrict-pass-missing-verification-report/governance/revocations.json +1 -0
  256. package/conformance/v1/bundles/invoicebundle/nonstrict-pass-missing-verification-report/invoice/invoice_claim.json +1 -0
  257. package/conformance/v1/bundles/invoicebundle/nonstrict-pass-missing-verification-report/manifest.json +1 -0
  258. package/conformance/v1/bundles/invoicebundle/nonstrict-pass-missing-verification-report/metering/metering_report.json +1 -0
  259. package/conformance/v1/bundles/invoicebundle/nonstrict-pass-missing-verification-report/payload/job_proof_bundle/attestation/bundle_head_attestation.json +1 -0
  260. package/conformance/v1/bundles/invoicebundle/nonstrict-pass-missing-verification-report/payload/job_proof_bundle/events/events.jsonl +1 -0
  261. package/conformance/v1/bundles/invoicebundle/nonstrict-pass-missing-verification-report/payload/job_proof_bundle/events/payload_material.jsonl +1 -0
  262. package/conformance/v1/bundles/invoicebundle/nonstrict-pass-missing-verification-report/payload/job_proof_bundle/governance/global/events/events.jsonl +1 -0
  263. package/conformance/v1/bundles/invoicebundle/nonstrict-pass-missing-verification-report/payload/job_proof_bundle/governance/global/events/payload_material.jsonl +1 -0
  264. package/conformance/v1/bundles/invoicebundle/nonstrict-pass-missing-verification-report/payload/job_proof_bundle/governance/global/snapshot.json +1 -0
  265. package/conformance/v1/bundles/invoicebundle/nonstrict-pass-missing-verification-report/payload/job_proof_bundle/governance/policy.json +1 -0
  266. package/conformance/v1/bundles/invoicebundle/nonstrict-pass-missing-verification-report/payload/job_proof_bundle/governance/revocations.json +1 -0
  267. package/conformance/v1/bundles/invoicebundle/nonstrict-pass-missing-verification-report/payload/job_proof_bundle/governance/tenant/events/events.jsonl +0 -0
  268. package/conformance/v1/bundles/invoicebundle/nonstrict-pass-missing-verification-report/payload/job_proof_bundle/governance/tenant/events/payload_material.jsonl +0 -0
  269. package/conformance/v1/bundles/invoicebundle/nonstrict-pass-missing-verification-report/payload/job_proof_bundle/governance/tenant/snapshot.json +1 -0
  270. package/conformance/v1/bundles/invoicebundle/nonstrict-pass-missing-verification-report/payload/job_proof_bundle/job/snapshot.json +1 -0
  271. package/conformance/v1/bundles/invoicebundle/nonstrict-pass-missing-verification-report/payload/job_proof_bundle/keys/public_keys.json +1 -0
  272. package/conformance/v1/bundles/invoicebundle/nonstrict-pass-missing-verification-report/payload/job_proof_bundle/manifest.json +1 -0
  273. package/conformance/v1/bundles/invoicebundle/nonstrict-pass-missing-verification-report/payload/job_proof_bundle/verify/report.json +1 -0
  274. package/conformance/v1/bundles/invoicebundle/nonstrict-pass-missing-verification-report/payload/job_proof_bundle/verify/verification_report.json +1 -0
  275. package/conformance/v1/bundles/invoicebundle/nonstrict-pass-missing-verification-report/pricing/pricing_matrix.json +1 -0
  276. package/conformance/v1/bundles/invoicebundle/nonstrict-pass-missing-verification-report/pricing/pricing_matrix_signatures.json +1 -0
  277. package/conformance/v1/bundles/invoicebundle/nonstrict-pass-missing-verification-report/settld.json +1 -0
  278. package/conformance/v1/bundles/invoicebundle/nonstrict-pass-unsigned-pricing-matrix-warning/attestation/bundle_head_attestation.json +1 -0
  279. package/conformance/v1/bundles/invoicebundle/nonstrict-pass-unsigned-pricing-matrix-warning/governance/policy.json +1 -0
  280. package/conformance/v1/bundles/invoicebundle/nonstrict-pass-unsigned-pricing-matrix-warning/governance/revocations.json +1 -0
  281. package/conformance/v1/bundles/invoicebundle/nonstrict-pass-unsigned-pricing-matrix-warning/invoice/invoice_claim.json +1 -0
  282. package/conformance/v1/bundles/invoicebundle/nonstrict-pass-unsigned-pricing-matrix-warning/manifest.json +1 -0
  283. package/conformance/v1/bundles/invoicebundle/nonstrict-pass-unsigned-pricing-matrix-warning/metering/metering_report.json +1 -0
  284. package/conformance/v1/bundles/invoicebundle/nonstrict-pass-unsigned-pricing-matrix-warning/payload/job_proof_bundle/attestation/bundle_head_attestation.json +1 -0
  285. package/conformance/v1/bundles/invoicebundle/nonstrict-pass-unsigned-pricing-matrix-warning/payload/job_proof_bundle/events/events.jsonl +1 -0
  286. package/conformance/v1/bundles/invoicebundle/nonstrict-pass-unsigned-pricing-matrix-warning/payload/job_proof_bundle/events/payload_material.jsonl +1 -0
  287. package/conformance/v1/bundles/invoicebundle/nonstrict-pass-unsigned-pricing-matrix-warning/payload/job_proof_bundle/governance/global/events/events.jsonl +1 -0
  288. package/conformance/v1/bundles/invoicebundle/nonstrict-pass-unsigned-pricing-matrix-warning/payload/job_proof_bundle/governance/global/events/payload_material.jsonl +1 -0
  289. package/conformance/v1/bundles/invoicebundle/nonstrict-pass-unsigned-pricing-matrix-warning/payload/job_proof_bundle/governance/global/snapshot.json +1 -0
  290. package/conformance/v1/bundles/invoicebundle/nonstrict-pass-unsigned-pricing-matrix-warning/payload/job_proof_bundle/governance/policy.json +1 -0
  291. package/conformance/v1/bundles/invoicebundle/nonstrict-pass-unsigned-pricing-matrix-warning/payload/job_proof_bundle/governance/revocations.json +1 -0
  292. package/conformance/v1/bundles/invoicebundle/nonstrict-pass-unsigned-pricing-matrix-warning/payload/job_proof_bundle/governance/tenant/events/events.jsonl +0 -0
  293. package/conformance/v1/bundles/invoicebundle/nonstrict-pass-unsigned-pricing-matrix-warning/payload/job_proof_bundle/governance/tenant/events/payload_material.jsonl +0 -0
  294. package/conformance/v1/bundles/invoicebundle/nonstrict-pass-unsigned-pricing-matrix-warning/payload/job_proof_bundle/governance/tenant/snapshot.json +1 -0
  295. package/conformance/v1/bundles/invoicebundle/nonstrict-pass-unsigned-pricing-matrix-warning/payload/job_proof_bundle/job/snapshot.json +1 -0
  296. package/conformance/v1/bundles/invoicebundle/nonstrict-pass-unsigned-pricing-matrix-warning/payload/job_proof_bundle/keys/public_keys.json +1 -0
  297. package/conformance/v1/bundles/invoicebundle/nonstrict-pass-unsigned-pricing-matrix-warning/payload/job_proof_bundle/manifest.json +1 -0
  298. package/conformance/v1/bundles/invoicebundle/nonstrict-pass-unsigned-pricing-matrix-warning/payload/job_proof_bundle/verify/report.json +1 -0
  299. package/conformance/v1/bundles/invoicebundle/nonstrict-pass-unsigned-pricing-matrix-warning/payload/job_proof_bundle/verify/verification_report.json +1 -0
  300. package/conformance/v1/bundles/invoicebundle/nonstrict-pass-unsigned-pricing-matrix-warning/pricing/pricing_matrix.json +1 -0
  301. package/conformance/v1/bundles/invoicebundle/nonstrict-pass-unsigned-pricing-matrix-warning/settld.json +1 -0
  302. package/conformance/v1/bundles/invoicebundle/nonstrict-pass-unsigned-pricing-matrix-warning/verify/verification_report.json +1 -0
  303. package/conformance/v1/bundles/invoicebundle/strict-fail-evidence-sha-mismatch/attestation/bundle_head_attestation.json +1 -0
  304. package/conformance/v1/bundles/invoicebundle/strict-fail-evidence-sha-mismatch/governance/policy.json +1 -0
  305. package/conformance/v1/bundles/invoicebundle/strict-fail-evidence-sha-mismatch/governance/revocations.json +1 -0
  306. package/conformance/v1/bundles/invoicebundle/strict-fail-evidence-sha-mismatch/invoice/invoice_claim.json +1 -0
  307. package/conformance/v1/bundles/invoicebundle/strict-fail-evidence-sha-mismatch/manifest.json +1 -0
  308. package/conformance/v1/bundles/invoicebundle/strict-fail-evidence-sha-mismatch/metering/metering_report.json +1 -0
  309. package/conformance/v1/bundles/invoicebundle/strict-fail-evidence-sha-mismatch/payload/job_proof_bundle/attestation/bundle_head_attestation.json +1 -0
  310. package/conformance/v1/bundles/invoicebundle/strict-fail-evidence-sha-mismatch/payload/job_proof_bundle/events/events.jsonl +1 -0
  311. package/conformance/v1/bundles/invoicebundle/strict-fail-evidence-sha-mismatch/payload/job_proof_bundle/events/payload_material.jsonl +1 -0
  312. package/conformance/v1/bundles/invoicebundle/strict-fail-evidence-sha-mismatch/payload/job_proof_bundle/governance/global/events/events.jsonl +1 -0
  313. package/conformance/v1/bundles/invoicebundle/strict-fail-evidence-sha-mismatch/payload/job_proof_bundle/governance/global/events/payload_material.jsonl +1 -0
  314. package/conformance/v1/bundles/invoicebundle/strict-fail-evidence-sha-mismatch/payload/job_proof_bundle/governance/global/snapshot.json +1 -0
  315. package/conformance/v1/bundles/invoicebundle/strict-fail-evidence-sha-mismatch/payload/job_proof_bundle/governance/policy.json +1 -0
  316. package/conformance/v1/bundles/invoicebundle/strict-fail-evidence-sha-mismatch/payload/job_proof_bundle/governance/revocations.json +1 -0
  317. package/conformance/v1/bundles/invoicebundle/strict-fail-evidence-sha-mismatch/payload/job_proof_bundle/governance/tenant/events/events.jsonl +0 -0
  318. package/conformance/v1/bundles/invoicebundle/strict-fail-evidence-sha-mismatch/payload/job_proof_bundle/governance/tenant/events/payload_material.jsonl +0 -0
  319. package/conformance/v1/bundles/invoicebundle/strict-fail-evidence-sha-mismatch/payload/job_proof_bundle/governance/tenant/snapshot.json +1 -0
  320. package/conformance/v1/bundles/invoicebundle/strict-fail-evidence-sha-mismatch/payload/job_proof_bundle/job/snapshot.json +1 -0
  321. package/conformance/v1/bundles/invoicebundle/strict-fail-evidence-sha-mismatch/payload/job_proof_bundle/keys/public_keys.json +1 -0
  322. package/conformance/v1/bundles/invoicebundle/strict-fail-evidence-sha-mismatch/payload/job_proof_bundle/manifest.json +1 -0
  323. package/conformance/v1/bundles/invoicebundle/strict-fail-evidence-sha-mismatch/payload/job_proof_bundle/verify/report.json +1 -0
  324. package/conformance/v1/bundles/invoicebundle/strict-fail-evidence-sha-mismatch/payload/job_proof_bundle/verify/verification_report.json +1 -0
  325. package/conformance/v1/bundles/invoicebundle/strict-fail-evidence-sha-mismatch/pricing/pricing_matrix.json +1 -0
  326. package/conformance/v1/bundles/invoicebundle/strict-fail-evidence-sha-mismatch/pricing/pricing_matrix_signatures.json +1 -0
  327. package/conformance/v1/bundles/invoicebundle/strict-fail-evidence-sha-mismatch/settld.json +1 -0
  328. package/conformance/v1/bundles/invoicebundle/strict-fail-evidence-sha-mismatch/verify/verification_report.json +1 -0
  329. package/conformance/v1/bundles/invoicebundle/strict-fail-invalid-pricing-matrix-signature/attestation/bundle_head_attestation.json +1 -0
  330. package/conformance/v1/bundles/invoicebundle/strict-fail-invalid-pricing-matrix-signature/governance/policy.json +1 -0
  331. package/conformance/v1/bundles/invoicebundle/strict-fail-invalid-pricing-matrix-signature/governance/revocations.json +1 -0
  332. package/conformance/v1/bundles/invoicebundle/strict-fail-invalid-pricing-matrix-signature/invoice/invoice_claim.json +1 -0
  333. package/conformance/v1/bundles/invoicebundle/strict-fail-invalid-pricing-matrix-signature/manifest.json +1 -0
  334. package/conformance/v1/bundles/invoicebundle/strict-fail-invalid-pricing-matrix-signature/metering/metering_report.json +1 -0
  335. package/conformance/v1/bundles/invoicebundle/strict-fail-invalid-pricing-matrix-signature/payload/job_proof_bundle/attestation/bundle_head_attestation.json +1 -0
  336. package/conformance/v1/bundles/invoicebundle/strict-fail-invalid-pricing-matrix-signature/payload/job_proof_bundle/events/events.jsonl +1 -0
  337. package/conformance/v1/bundles/invoicebundle/strict-fail-invalid-pricing-matrix-signature/payload/job_proof_bundle/events/payload_material.jsonl +1 -0
  338. package/conformance/v1/bundles/invoicebundle/strict-fail-invalid-pricing-matrix-signature/payload/job_proof_bundle/governance/global/events/events.jsonl +1 -0
  339. package/conformance/v1/bundles/invoicebundle/strict-fail-invalid-pricing-matrix-signature/payload/job_proof_bundle/governance/global/events/payload_material.jsonl +1 -0
  340. package/conformance/v1/bundles/invoicebundle/strict-fail-invalid-pricing-matrix-signature/payload/job_proof_bundle/governance/global/snapshot.json +1 -0
  341. package/conformance/v1/bundles/invoicebundle/strict-fail-invalid-pricing-matrix-signature/payload/job_proof_bundle/governance/policy.json +1 -0
  342. package/conformance/v1/bundles/invoicebundle/strict-fail-invalid-pricing-matrix-signature/payload/job_proof_bundle/governance/revocations.json +1 -0
  343. package/conformance/v1/bundles/invoicebundle/strict-fail-invalid-pricing-matrix-signature/payload/job_proof_bundle/governance/tenant/events/events.jsonl +0 -0
  344. package/conformance/v1/bundles/invoicebundle/strict-fail-invalid-pricing-matrix-signature/payload/job_proof_bundle/governance/tenant/events/payload_material.jsonl +0 -0
  345. package/conformance/v1/bundles/invoicebundle/strict-fail-invalid-pricing-matrix-signature/payload/job_proof_bundle/governance/tenant/snapshot.json +1 -0
  346. package/conformance/v1/bundles/invoicebundle/strict-fail-invalid-pricing-matrix-signature/payload/job_proof_bundle/job/snapshot.json +1 -0
  347. package/conformance/v1/bundles/invoicebundle/strict-fail-invalid-pricing-matrix-signature/payload/job_proof_bundle/keys/public_keys.json +1 -0
  348. package/conformance/v1/bundles/invoicebundle/strict-fail-invalid-pricing-matrix-signature/payload/job_proof_bundle/manifest.json +1 -0
  349. package/conformance/v1/bundles/invoicebundle/strict-fail-invalid-pricing-matrix-signature/payload/job_proof_bundle/verify/report.json +1 -0
  350. package/conformance/v1/bundles/invoicebundle/strict-fail-invalid-pricing-matrix-signature/payload/job_proof_bundle/verify/verification_report.json +1 -0
  351. package/conformance/v1/bundles/invoicebundle/strict-fail-invalid-pricing-matrix-signature/pricing/pricing_matrix.json +1 -0
  352. package/conformance/v1/bundles/invoicebundle/strict-fail-invalid-pricing-matrix-signature/pricing/pricing_matrix_signatures.json +1 -0
  353. package/conformance/v1/bundles/invoicebundle/strict-fail-invalid-pricing-matrix-signature/settld.json +1 -0
  354. package/conformance/v1/bundles/invoicebundle/strict-fail-invalid-pricing-matrix-signature/verify/verification_report.json +1 -0
  355. package/conformance/v1/bundles/invoicebundle/strict-fail-invoice-total-mismatch/attestation/bundle_head_attestation.json +1 -0
  356. package/conformance/v1/bundles/invoicebundle/strict-fail-invoice-total-mismatch/governance/policy.json +1 -0
  357. package/conformance/v1/bundles/invoicebundle/strict-fail-invoice-total-mismatch/governance/revocations.json +1 -0
  358. package/conformance/v1/bundles/invoicebundle/strict-fail-invoice-total-mismatch/invoice/invoice_claim.json +1 -0
  359. package/conformance/v1/bundles/invoicebundle/strict-fail-invoice-total-mismatch/manifest.json +1 -0
  360. package/conformance/v1/bundles/invoicebundle/strict-fail-invoice-total-mismatch/metering/metering_report.json +1 -0
  361. package/conformance/v1/bundles/invoicebundle/strict-fail-invoice-total-mismatch/payload/job_proof_bundle/attestation/bundle_head_attestation.json +1 -0
  362. package/conformance/v1/bundles/invoicebundle/strict-fail-invoice-total-mismatch/payload/job_proof_bundle/events/events.jsonl +1 -0
  363. package/conformance/v1/bundles/invoicebundle/strict-fail-invoice-total-mismatch/payload/job_proof_bundle/events/payload_material.jsonl +1 -0
  364. package/conformance/v1/bundles/invoicebundle/strict-fail-invoice-total-mismatch/payload/job_proof_bundle/governance/global/events/events.jsonl +1 -0
  365. package/conformance/v1/bundles/invoicebundle/strict-fail-invoice-total-mismatch/payload/job_proof_bundle/governance/global/events/payload_material.jsonl +1 -0
  366. package/conformance/v1/bundles/invoicebundle/strict-fail-invoice-total-mismatch/payload/job_proof_bundle/governance/global/snapshot.json +1 -0
  367. package/conformance/v1/bundles/invoicebundle/strict-fail-invoice-total-mismatch/payload/job_proof_bundle/governance/policy.json +1 -0
  368. package/conformance/v1/bundles/invoicebundle/strict-fail-invoice-total-mismatch/payload/job_proof_bundle/governance/revocations.json +1 -0
  369. package/conformance/v1/bundles/invoicebundle/strict-fail-invoice-total-mismatch/payload/job_proof_bundle/governance/tenant/events/events.jsonl +0 -0
  370. package/conformance/v1/bundles/invoicebundle/strict-fail-invoice-total-mismatch/payload/job_proof_bundle/governance/tenant/events/payload_material.jsonl +0 -0
  371. package/conformance/v1/bundles/invoicebundle/strict-fail-invoice-total-mismatch/payload/job_proof_bundle/governance/tenant/snapshot.json +1 -0
  372. package/conformance/v1/bundles/invoicebundle/strict-fail-invoice-total-mismatch/payload/job_proof_bundle/job/snapshot.json +1 -0
  373. package/conformance/v1/bundles/invoicebundle/strict-fail-invoice-total-mismatch/payload/job_proof_bundle/keys/public_keys.json +1 -0
  374. package/conformance/v1/bundles/invoicebundle/strict-fail-invoice-total-mismatch/payload/job_proof_bundle/manifest.json +1 -0
  375. package/conformance/v1/bundles/invoicebundle/strict-fail-invoice-total-mismatch/payload/job_proof_bundle/verify/report.json +1 -0
  376. package/conformance/v1/bundles/invoicebundle/strict-fail-invoice-total-mismatch/payload/job_proof_bundle/verify/verification_report.json +1 -0
  377. package/conformance/v1/bundles/invoicebundle/strict-fail-invoice-total-mismatch/pricing/pricing_matrix.json +1 -0
  378. package/conformance/v1/bundles/invoicebundle/strict-fail-invoice-total-mismatch/pricing/pricing_matrix_signatures.json +1 -0
  379. package/conformance/v1/bundles/invoicebundle/strict-fail-invoice-total-mismatch/settld.json +1 -0
  380. package/conformance/v1/bundles/invoicebundle/strict-fail-invoice-total-mismatch/verify/verification_report.json +1 -0
  381. package/conformance/v1/bundles/invoicebundle/strict-fail-missing-pricing-matrix-signature/attestation/bundle_head_attestation.json +1 -0
  382. package/conformance/v1/bundles/invoicebundle/strict-fail-missing-pricing-matrix-signature/governance/policy.json +1 -0
  383. package/conformance/v1/bundles/invoicebundle/strict-fail-missing-pricing-matrix-signature/governance/revocations.json +1 -0
  384. package/conformance/v1/bundles/invoicebundle/strict-fail-missing-pricing-matrix-signature/invoice/invoice_claim.json +1 -0
  385. package/conformance/v1/bundles/invoicebundle/strict-fail-missing-pricing-matrix-signature/manifest.json +1 -0
  386. package/conformance/v1/bundles/invoicebundle/strict-fail-missing-pricing-matrix-signature/metering/metering_report.json +1 -0
  387. package/conformance/v1/bundles/invoicebundle/strict-fail-missing-pricing-matrix-signature/payload/job_proof_bundle/attestation/bundle_head_attestation.json +1 -0
  388. package/conformance/v1/bundles/invoicebundle/strict-fail-missing-pricing-matrix-signature/payload/job_proof_bundle/events/events.jsonl +1 -0
  389. package/conformance/v1/bundles/invoicebundle/strict-fail-missing-pricing-matrix-signature/payload/job_proof_bundle/events/payload_material.jsonl +1 -0
  390. package/conformance/v1/bundles/invoicebundle/strict-fail-missing-pricing-matrix-signature/payload/job_proof_bundle/governance/global/events/events.jsonl +1 -0
  391. package/conformance/v1/bundles/invoicebundle/strict-fail-missing-pricing-matrix-signature/payload/job_proof_bundle/governance/global/events/payload_material.jsonl +1 -0
  392. package/conformance/v1/bundles/invoicebundle/strict-fail-missing-pricing-matrix-signature/payload/job_proof_bundle/governance/global/snapshot.json +1 -0
  393. package/conformance/v1/bundles/invoicebundle/strict-fail-missing-pricing-matrix-signature/payload/job_proof_bundle/governance/policy.json +1 -0
  394. package/conformance/v1/bundles/invoicebundle/strict-fail-missing-pricing-matrix-signature/payload/job_proof_bundle/governance/revocations.json +1 -0
  395. package/conformance/v1/bundles/invoicebundle/strict-fail-missing-pricing-matrix-signature/payload/job_proof_bundle/governance/tenant/events/events.jsonl +0 -0
  396. package/conformance/v1/bundles/invoicebundle/strict-fail-missing-pricing-matrix-signature/payload/job_proof_bundle/governance/tenant/events/payload_material.jsonl +0 -0
  397. package/conformance/v1/bundles/invoicebundle/strict-fail-missing-pricing-matrix-signature/payload/job_proof_bundle/governance/tenant/snapshot.json +1 -0
  398. package/conformance/v1/bundles/invoicebundle/strict-fail-missing-pricing-matrix-signature/payload/job_proof_bundle/job/snapshot.json +1 -0
  399. package/conformance/v1/bundles/invoicebundle/strict-fail-missing-pricing-matrix-signature/payload/job_proof_bundle/keys/public_keys.json +1 -0
  400. package/conformance/v1/bundles/invoicebundle/strict-fail-missing-pricing-matrix-signature/payload/job_proof_bundle/manifest.json +1 -0
  401. package/conformance/v1/bundles/invoicebundle/strict-fail-missing-pricing-matrix-signature/payload/job_proof_bundle/verify/report.json +1 -0
  402. package/conformance/v1/bundles/invoicebundle/strict-fail-missing-pricing-matrix-signature/payload/job_proof_bundle/verify/verification_report.json +1 -0
  403. package/conformance/v1/bundles/invoicebundle/strict-fail-missing-pricing-matrix-signature/pricing/pricing_matrix.json +1 -0
  404. package/conformance/v1/bundles/invoicebundle/strict-fail-missing-pricing-matrix-signature/settld.json +1 -0
  405. package/conformance/v1/bundles/invoicebundle/strict-fail-missing-pricing-matrix-signature/verify/verification_report.json +1 -0
  406. package/conformance/v1/bundles/invoicebundle/strict-fail-missing-verification-report/attestation/bundle_head_attestation.json +1 -0
  407. package/conformance/v1/bundles/invoicebundle/strict-fail-missing-verification-report/governance/policy.json +1 -0
  408. package/conformance/v1/bundles/invoicebundle/strict-fail-missing-verification-report/governance/revocations.json +1 -0
  409. package/conformance/v1/bundles/invoicebundle/strict-fail-missing-verification-report/invoice/invoice_claim.json +1 -0
  410. package/conformance/v1/bundles/invoicebundle/strict-fail-missing-verification-report/manifest.json +1 -0
  411. package/conformance/v1/bundles/invoicebundle/strict-fail-missing-verification-report/metering/metering_report.json +1 -0
  412. package/conformance/v1/bundles/invoicebundle/strict-fail-missing-verification-report/payload/job_proof_bundle/attestation/bundle_head_attestation.json +1 -0
  413. package/conformance/v1/bundles/invoicebundle/strict-fail-missing-verification-report/payload/job_proof_bundle/events/events.jsonl +1 -0
  414. package/conformance/v1/bundles/invoicebundle/strict-fail-missing-verification-report/payload/job_proof_bundle/events/payload_material.jsonl +1 -0
  415. package/conformance/v1/bundles/invoicebundle/strict-fail-missing-verification-report/payload/job_proof_bundle/governance/global/events/events.jsonl +1 -0
  416. package/conformance/v1/bundles/invoicebundle/strict-fail-missing-verification-report/payload/job_proof_bundle/governance/global/events/payload_material.jsonl +1 -0
  417. package/conformance/v1/bundles/invoicebundle/strict-fail-missing-verification-report/payload/job_proof_bundle/governance/global/snapshot.json +1 -0
  418. package/conformance/v1/bundles/invoicebundle/strict-fail-missing-verification-report/payload/job_proof_bundle/governance/policy.json +1 -0
  419. package/conformance/v1/bundles/invoicebundle/strict-fail-missing-verification-report/payload/job_proof_bundle/governance/revocations.json +1 -0
  420. package/conformance/v1/bundles/invoicebundle/strict-fail-missing-verification-report/payload/job_proof_bundle/governance/tenant/events/events.jsonl +0 -0
  421. package/conformance/v1/bundles/invoicebundle/strict-fail-missing-verification-report/payload/job_proof_bundle/governance/tenant/events/payload_material.jsonl +0 -0
  422. package/conformance/v1/bundles/invoicebundle/strict-fail-missing-verification-report/payload/job_proof_bundle/governance/tenant/snapshot.json +1 -0
  423. package/conformance/v1/bundles/invoicebundle/strict-fail-missing-verification-report/payload/job_proof_bundle/job/snapshot.json +1 -0
  424. package/conformance/v1/bundles/invoicebundle/strict-fail-missing-verification-report/payload/job_proof_bundle/keys/public_keys.json +1 -0
  425. package/conformance/v1/bundles/invoicebundle/strict-fail-missing-verification-report/payload/job_proof_bundle/manifest.json +1 -0
  426. package/conformance/v1/bundles/invoicebundle/strict-fail-missing-verification-report/payload/job_proof_bundle/verify/report.json +1 -0
  427. package/conformance/v1/bundles/invoicebundle/strict-fail-missing-verification-report/payload/job_proof_bundle/verify/verification_report.json +1 -0
  428. package/conformance/v1/bundles/invoicebundle/strict-fail-missing-verification-report/pricing/pricing_matrix.json +1 -0
  429. package/conformance/v1/bundles/invoicebundle/strict-fail-missing-verification-report/pricing/pricing_matrix_signatures.json +1 -0
  430. package/conformance/v1/bundles/invoicebundle/strict-fail-missing-verification-report/settld.json +1 -0
  431. package/conformance/v1/bundles/invoicebundle/strict-fail-pricing-code-unknown/attestation/bundle_head_attestation.json +1 -0
  432. package/conformance/v1/bundles/invoicebundle/strict-fail-pricing-code-unknown/governance/policy.json +1 -0
  433. package/conformance/v1/bundles/invoicebundle/strict-fail-pricing-code-unknown/governance/revocations.json +1 -0
  434. package/conformance/v1/bundles/invoicebundle/strict-fail-pricing-code-unknown/invoice/invoice_claim.json +1 -0
  435. package/conformance/v1/bundles/invoicebundle/strict-fail-pricing-code-unknown/manifest.json +1 -0
  436. package/conformance/v1/bundles/invoicebundle/strict-fail-pricing-code-unknown/metering/metering_report.json +1 -0
  437. package/conformance/v1/bundles/invoicebundle/strict-fail-pricing-code-unknown/payload/job_proof_bundle/attestation/bundle_head_attestation.json +1 -0
  438. package/conformance/v1/bundles/invoicebundle/strict-fail-pricing-code-unknown/payload/job_proof_bundle/events/events.jsonl +1 -0
  439. package/conformance/v1/bundles/invoicebundle/strict-fail-pricing-code-unknown/payload/job_proof_bundle/events/payload_material.jsonl +1 -0
  440. package/conformance/v1/bundles/invoicebundle/strict-fail-pricing-code-unknown/payload/job_proof_bundle/governance/global/events/events.jsonl +1 -0
  441. package/conformance/v1/bundles/invoicebundle/strict-fail-pricing-code-unknown/payload/job_proof_bundle/governance/global/events/payload_material.jsonl +1 -0
  442. package/conformance/v1/bundles/invoicebundle/strict-fail-pricing-code-unknown/payload/job_proof_bundle/governance/global/snapshot.json +1 -0
  443. package/conformance/v1/bundles/invoicebundle/strict-fail-pricing-code-unknown/payload/job_proof_bundle/governance/policy.json +1 -0
  444. package/conformance/v1/bundles/invoicebundle/strict-fail-pricing-code-unknown/payload/job_proof_bundle/governance/revocations.json +1 -0
  445. package/conformance/v1/bundles/invoicebundle/strict-fail-pricing-code-unknown/payload/job_proof_bundle/governance/tenant/events/events.jsonl +0 -0
  446. package/conformance/v1/bundles/invoicebundle/strict-fail-pricing-code-unknown/payload/job_proof_bundle/governance/tenant/events/payload_material.jsonl +0 -0
  447. package/conformance/v1/bundles/invoicebundle/strict-fail-pricing-code-unknown/payload/job_proof_bundle/governance/tenant/snapshot.json +1 -0
  448. package/conformance/v1/bundles/invoicebundle/strict-fail-pricing-code-unknown/payload/job_proof_bundle/job/snapshot.json +1 -0
  449. package/conformance/v1/bundles/invoicebundle/strict-fail-pricing-code-unknown/payload/job_proof_bundle/keys/public_keys.json +1 -0
  450. package/conformance/v1/bundles/invoicebundle/strict-fail-pricing-code-unknown/payload/job_proof_bundle/manifest.json +1 -0
  451. package/conformance/v1/bundles/invoicebundle/strict-fail-pricing-code-unknown/payload/job_proof_bundle/verify/report.json +1 -0
  452. package/conformance/v1/bundles/invoicebundle/strict-fail-pricing-code-unknown/payload/job_proof_bundle/verify/verification_report.json +1 -0
  453. package/conformance/v1/bundles/invoicebundle/strict-fail-pricing-code-unknown/pricing/pricing_matrix.json +1 -0
  454. package/conformance/v1/bundles/invoicebundle/strict-fail-pricing-code-unknown/pricing/pricing_matrix_signatures.json +1 -0
  455. package/conformance/v1/bundles/invoicebundle/strict-fail-pricing-code-unknown/settld.json +1 -0
  456. package/conformance/v1/bundles/invoicebundle/strict-fail-pricing-code-unknown/verify/verification_report.json +1 -0
  457. package/conformance/v1/bundles/invoicebundle/strict-pass/attestation/bundle_head_attestation.json +1 -0
  458. package/conformance/v1/bundles/invoicebundle/strict-pass/governance/policy.json +1 -0
  459. package/conformance/v1/bundles/invoicebundle/strict-pass/governance/revocations.json +1 -0
  460. package/conformance/v1/bundles/invoicebundle/strict-pass/invoice/invoice_claim.json +1 -0
  461. package/conformance/v1/bundles/invoicebundle/strict-pass/manifest.json +1 -0
  462. package/conformance/v1/bundles/invoicebundle/strict-pass/metering/metering_report.json +1 -0
  463. package/conformance/v1/bundles/invoicebundle/strict-pass/payload/job_proof_bundle/attestation/bundle_head_attestation.json +1 -0
  464. package/conformance/v1/bundles/invoicebundle/strict-pass/payload/job_proof_bundle/events/events.jsonl +1 -0
  465. package/conformance/v1/bundles/invoicebundle/strict-pass/payload/job_proof_bundle/events/payload_material.jsonl +1 -0
  466. package/conformance/v1/bundles/invoicebundle/strict-pass/payload/job_proof_bundle/governance/global/events/events.jsonl +1 -0
  467. package/conformance/v1/bundles/invoicebundle/strict-pass/payload/job_proof_bundle/governance/global/events/payload_material.jsonl +1 -0
  468. package/conformance/v1/bundles/invoicebundle/strict-pass/payload/job_proof_bundle/governance/global/snapshot.json +1 -0
  469. package/conformance/v1/bundles/invoicebundle/strict-pass/payload/job_proof_bundle/governance/policy.json +1 -0
  470. package/conformance/v1/bundles/invoicebundle/strict-pass/payload/job_proof_bundle/governance/revocations.json +1 -0
  471. package/conformance/v1/bundles/invoicebundle/strict-pass/payload/job_proof_bundle/governance/tenant/events/events.jsonl +0 -0
  472. package/conformance/v1/bundles/invoicebundle/strict-pass/payload/job_proof_bundle/governance/tenant/events/payload_material.jsonl +0 -0
  473. package/conformance/v1/bundles/invoicebundle/strict-pass/payload/job_proof_bundle/governance/tenant/snapshot.json +1 -0
  474. package/conformance/v1/bundles/invoicebundle/strict-pass/payload/job_proof_bundle/job/snapshot.json +1 -0
  475. package/conformance/v1/bundles/invoicebundle/strict-pass/payload/job_proof_bundle/keys/public_keys.json +1 -0
  476. package/conformance/v1/bundles/invoicebundle/strict-pass/payload/job_proof_bundle/manifest.json +1 -0
  477. package/conformance/v1/bundles/invoicebundle/strict-pass/payload/job_proof_bundle/verify/report.json +1 -0
  478. package/conformance/v1/bundles/invoicebundle/strict-pass/payload/job_proof_bundle/verify/verification_report.json +1 -0
  479. package/conformance/v1/bundles/invoicebundle/strict-pass/pricing/pricing_matrix.json +1 -0
  480. package/conformance/v1/bundles/invoicebundle/strict-pass/pricing/pricing_matrix_signatures.json +1 -0
  481. package/conformance/v1/bundles/invoicebundle/strict-pass/settld.json +1 -0
  482. package/conformance/v1/bundles/invoicebundle/strict-pass/verify/verification_report.json +1 -0
  483. package/conformance/v1/bundles/jobproof/nonstrict-pass-missing-verification-report/attestation/bundle_head_attestation.json +1 -0
  484. package/conformance/v1/bundles/jobproof/nonstrict-pass-missing-verification-report/events/events.jsonl +1 -0
  485. package/conformance/v1/bundles/jobproof/nonstrict-pass-missing-verification-report/events/payload_material.jsonl +1 -0
  486. package/conformance/v1/bundles/jobproof/nonstrict-pass-missing-verification-report/governance/global/events/events.jsonl +1 -0
  487. package/conformance/v1/bundles/jobproof/nonstrict-pass-missing-verification-report/governance/global/events/payload_material.jsonl +1 -0
  488. package/conformance/v1/bundles/jobproof/nonstrict-pass-missing-verification-report/governance/global/snapshot.json +1 -0
  489. package/conformance/v1/bundles/jobproof/nonstrict-pass-missing-verification-report/governance/policy.json +1 -0
  490. package/conformance/v1/bundles/jobproof/nonstrict-pass-missing-verification-report/governance/revocations.json +1 -0
  491. package/conformance/v1/bundles/jobproof/nonstrict-pass-missing-verification-report/governance/tenant/events/events.jsonl +0 -0
  492. package/conformance/v1/bundles/jobproof/nonstrict-pass-missing-verification-report/governance/tenant/events/payload_material.jsonl +0 -0
  493. package/conformance/v1/bundles/jobproof/nonstrict-pass-missing-verification-report/governance/tenant/snapshot.json +1 -0
  494. package/conformance/v1/bundles/jobproof/nonstrict-pass-missing-verification-report/job/snapshot.json +1 -0
  495. package/conformance/v1/bundles/jobproof/nonstrict-pass-missing-verification-report/keys/public_keys.json +1 -0
  496. package/conformance/v1/bundles/jobproof/nonstrict-pass-missing-verification-report/manifest.json +1 -0
  497. package/conformance/v1/bundles/jobproof/nonstrict-pass-missing-verification-report/verify/report.json +1 -0
  498. package/conformance/v1/bundles/jobproof/strict-fail-manifest-tamper/attestation/bundle_head_attestation.json +1 -0
  499. package/conformance/v1/bundles/jobproof/strict-fail-manifest-tamper/events/events.jsonl +1 -0
  500. package/conformance/v1/bundles/jobproof/strict-fail-manifest-tamper/events/payload_material.jsonl +1 -0
  501. package/conformance/v1/bundles/jobproof/strict-fail-manifest-tamper/governance/global/events/events.jsonl +1 -0
  502. package/conformance/v1/bundles/jobproof/strict-fail-manifest-tamper/governance/global/events/payload_material.jsonl +1 -0
  503. package/conformance/v1/bundles/jobproof/strict-fail-manifest-tamper/governance/global/snapshot.json +1 -0
  504. package/conformance/v1/bundles/jobproof/strict-fail-manifest-tamper/governance/policy.json +1 -0
  505. package/conformance/v1/bundles/jobproof/strict-fail-manifest-tamper/governance/revocations.json +1 -0
  506. package/conformance/v1/bundles/jobproof/strict-fail-manifest-tamper/governance/tenant/events/events.jsonl +0 -0
  507. package/conformance/v1/bundles/jobproof/strict-fail-manifest-tamper/governance/tenant/events/payload_material.jsonl +0 -0
  508. package/conformance/v1/bundles/jobproof/strict-fail-manifest-tamper/governance/tenant/snapshot.json +1 -0
  509. package/conformance/v1/bundles/jobproof/strict-fail-manifest-tamper/job/snapshot.json +1 -0
  510. package/conformance/v1/bundles/jobproof/strict-fail-manifest-tamper/keys/public_keys.json +1 -0
  511. package/conformance/v1/bundles/jobproof/strict-fail-manifest-tamper/manifest.json +1 -0
  512. package/conformance/v1/bundles/jobproof/strict-fail-manifest-tamper/verify/report.json +1 -0
  513. package/conformance/v1/bundles/jobproof/strict-fail-manifest-tamper/verify/verification_report.json +1 -0
  514. package/conformance/v1/bundles/jobproof/strict-fail-unauthorized-signer/attestation/bundle_head_attestation.json +1 -0
  515. package/conformance/v1/bundles/jobproof/strict-fail-unauthorized-signer/events/events.jsonl +1 -0
  516. package/conformance/v1/bundles/jobproof/strict-fail-unauthorized-signer/events/payload_material.jsonl +1 -0
  517. package/conformance/v1/bundles/jobproof/strict-fail-unauthorized-signer/governance/global/events/events.jsonl +1 -0
  518. package/conformance/v1/bundles/jobproof/strict-fail-unauthorized-signer/governance/global/events/payload_material.jsonl +1 -0
  519. package/conformance/v1/bundles/jobproof/strict-fail-unauthorized-signer/governance/global/snapshot.json +1 -0
  520. package/conformance/v1/bundles/jobproof/strict-fail-unauthorized-signer/governance/policy.json +1 -0
  521. package/conformance/v1/bundles/jobproof/strict-fail-unauthorized-signer/governance/revocations.json +1 -0
  522. package/conformance/v1/bundles/jobproof/strict-fail-unauthorized-signer/governance/tenant/events/events.jsonl +0 -0
  523. package/conformance/v1/bundles/jobproof/strict-fail-unauthorized-signer/governance/tenant/events/payload_material.jsonl +0 -0
  524. package/conformance/v1/bundles/jobproof/strict-fail-unauthorized-signer/governance/tenant/snapshot.json +1 -0
  525. package/conformance/v1/bundles/jobproof/strict-fail-unauthorized-signer/job/snapshot.json +1 -0
  526. package/conformance/v1/bundles/jobproof/strict-fail-unauthorized-signer/keys/public_keys.json +1 -0
  527. package/conformance/v1/bundles/jobproof/strict-fail-unauthorized-signer/manifest.json +1 -0
  528. package/conformance/v1/bundles/jobproof/strict-fail-unauthorized-signer/verify/report.json +1 -0
  529. package/conformance/v1/bundles/jobproof/strict-fail-unauthorized-signer/verify/verification_report.json +1 -0
  530. package/conformance/v1/bundles/jobproof/strict-pass/attestation/bundle_head_attestation.json +1 -0
  531. package/conformance/v1/bundles/jobproof/strict-pass/events/events.jsonl +1 -0
  532. package/conformance/v1/bundles/jobproof/strict-pass/events/payload_material.jsonl +1 -0
  533. package/conformance/v1/bundles/jobproof/strict-pass/governance/global/events/events.jsonl +1 -0
  534. package/conformance/v1/bundles/jobproof/strict-pass/governance/global/events/payload_material.jsonl +1 -0
  535. package/conformance/v1/bundles/jobproof/strict-pass/governance/global/snapshot.json +1 -0
  536. package/conformance/v1/bundles/jobproof/strict-pass/governance/policy.json +1 -0
  537. package/conformance/v1/bundles/jobproof/strict-pass/governance/revocations.json +1 -0
  538. package/conformance/v1/bundles/jobproof/strict-pass/governance/tenant/events/events.jsonl +0 -0
  539. package/conformance/v1/bundles/jobproof/strict-pass/governance/tenant/events/payload_material.jsonl +0 -0
  540. package/conformance/v1/bundles/jobproof/strict-pass/governance/tenant/snapshot.json +1 -0
  541. package/conformance/v1/bundles/jobproof/strict-pass/job/snapshot.json +1 -0
  542. package/conformance/v1/bundles/jobproof/strict-pass/keys/public_keys.json +1 -0
  543. package/conformance/v1/bundles/jobproof/strict-pass/manifest.json +1 -0
  544. package/conformance/v1/bundles/jobproof/strict-pass/verify/report.json +1 -0
  545. package/conformance/v1/bundles/jobproof/strict-pass/verify/verification_report.json +1 -0
  546. package/conformance/v1/bundles/monthproof/nonstrict-pass-missing-verification-report/attestation/bundle_head_attestation.json +1 -0
  547. package/conformance/v1/bundles/monthproof/nonstrict-pass-missing-verification-report/events/events.jsonl +1 -0
  548. package/conformance/v1/bundles/monthproof/nonstrict-pass-missing-verification-report/events/payload_material.jsonl +1 -0
  549. package/conformance/v1/bundles/monthproof/nonstrict-pass-missing-verification-report/governance/global/events/events.jsonl +1 -0
  550. package/conformance/v1/bundles/monthproof/nonstrict-pass-missing-verification-report/governance/global/events/payload_material.jsonl +1 -0
  551. package/conformance/v1/bundles/monthproof/nonstrict-pass-missing-verification-report/governance/global/snapshot.json +1 -0
  552. package/conformance/v1/bundles/monthproof/nonstrict-pass-missing-verification-report/governance/policy.json +1 -0
  553. package/conformance/v1/bundles/monthproof/nonstrict-pass-missing-verification-report/governance/revocations.json +1 -0
  554. package/conformance/v1/bundles/monthproof/nonstrict-pass-missing-verification-report/governance/tenant/events/events.jsonl +0 -0
  555. package/conformance/v1/bundles/monthproof/nonstrict-pass-missing-verification-report/governance/tenant/events/payload_material.jsonl +0 -0
  556. package/conformance/v1/bundles/monthproof/nonstrict-pass-missing-verification-report/governance/tenant/snapshot.json +1 -0
  557. package/conformance/v1/bundles/monthproof/nonstrict-pass-missing-verification-report/keys/public_keys.json +1 -0
  558. package/conformance/v1/bundles/monthproof/nonstrict-pass-missing-verification-report/manifest.json +1 -0
  559. package/conformance/v1/bundles/monthproof/nonstrict-pass-missing-verification-report/verify/report.json +1 -0
  560. package/conformance/v1/bundles/monthproof/strict-fail-manifest-tamper/attestation/bundle_head_attestation.json +1 -0
  561. package/conformance/v1/bundles/monthproof/strict-fail-manifest-tamper/events/events.jsonl +2 -0
  562. package/conformance/v1/bundles/monthproof/strict-fail-manifest-tamper/events/payload_material.jsonl +1 -0
  563. package/conformance/v1/bundles/monthproof/strict-fail-manifest-tamper/governance/global/events/events.jsonl +1 -0
  564. package/conformance/v1/bundles/monthproof/strict-fail-manifest-tamper/governance/global/events/payload_material.jsonl +1 -0
  565. package/conformance/v1/bundles/monthproof/strict-fail-manifest-tamper/governance/global/snapshot.json +1 -0
  566. package/conformance/v1/bundles/monthproof/strict-fail-manifest-tamper/governance/policy.json +1 -0
  567. package/conformance/v1/bundles/monthproof/strict-fail-manifest-tamper/governance/revocations.json +1 -0
  568. package/conformance/v1/bundles/monthproof/strict-fail-manifest-tamper/governance/tenant/events/events.jsonl +0 -0
  569. package/conformance/v1/bundles/monthproof/strict-fail-manifest-tamper/governance/tenant/events/payload_material.jsonl +0 -0
  570. package/conformance/v1/bundles/monthproof/strict-fail-manifest-tamper/governance/tenant/snapshot.json +1 -0
  571. package/conformance/v1/bundles/monthproof/strict-fail-manifest-tamper/keys/public_keys.json +1 -0
  572. package/conformance/v1/bundles/monthproof/strict-fail-manifest-tamper/manifest.json +1 -0
  573. package/conformance/v1/bundles/monthproof/strict-fail-manifest-tamper/verify/report.json +1 -0
  574. package/conformance/v1/bundles/monthproof/strict-fail-manifest-tamper/verify/verification_report.json +1 -0
  575. package/conformance/v1/bundles/monthproof/strict-fail-unauthorized-signer/attestation/bundle_head_attestation.json +1 -0
  576. package/conformance/v1/bundles/monthproof/strict-fail-unauthorized-signer/events/events.jsonl +1 -0
  577. package/conformance/v1/bundles/monthproof/strict-fail-unauthorized-signer/events/payload_material.jsonl +1 -0
  578. package/conformance/v1/bundles/monthproof/strict-fail-unauthorized-signer/governance/global/events/events.jsonl +1 -0
  579. package/conformance/v1/bundles/monthproof/strict-fail-unauthorized-signer/governance/global/events/payload_material.jsonl +1 -0
  580. package/conformance/v1/bundles/monthproof/strict-fail-unauthorized-signer/governance/global/snapshot.json +1 -0
  581. package/conformance/v1/bundles/monthproof/strict-fail-unauthorized-signer/governance/policy.json +1 -0
  582. package/conformance/v1/bundles/monthproof/strict-fail-unauthorized-signer/governance/revocations.json +1 -0
  583. package/conformance/v1/bundles/monthproof/strict-fail-unauthorized-signer/governance/tenant/events/events.jsonl +0 -0
  584. package/conformance/v1/bundles/monthproof/strict-fail-unauthorized-signer/governance/tenant/events/payload_material.jsonl +0 -0
  585. package/conformance/v1/bundles/monthproof/strict-fail-unauthorized-signer/governance/tenant/snapshot.json +1 -0
  586. package/conformance/v1/bundles/monthproof/strict-fail-unauthorized-signer/keys/public_keys.json +1 -0
  587. package/conformance/v1/bundles/monthproof/strict-fail-unauthorized-signer/manifest.json +1 -0
  588. package/conformance/v1/bundles/monthproof/strict-fail-unauthorized-signer/verify/report.json +1 -0
  589. package/conformance/v1/bundles/monthproof/strict-fail-unauthorized-signer/verify/verification_report.json +1 -0
  590. package/conformance/v1/bundles/monthproof/strict-pass/attestation/bundle_head_attestation.json +1 -0
  591. package/conformance/v1/bundles/monthproof/strict-pass/events/events.jsonl +1 -0
  592. package/conformance/v1/bundles/monthproof/strict-pass/events/payload_material.jsonl +1 -0
  593. package/conformance/v1/bundles/monthproof/strict-pass/governance/global/events/events.jsonl +1 -0
  594. package/conformance/v1/bundles/monthproof/strict-pass/governance/global/events/payload_material.jsonl +1 -0
  595. package/conformance/v1/bundles/monthproof/strict-pass/governance/global/snapshot.json +1 -0
  596. package/conformance/v1/bundles/monthproof/strict-pass/governance/policy.json +1 -0
  597. package/conformance/v1/bundles/monthproof/strict-pass/governance/revocations.json +1 -0
  598. package/conformance/v1/bundles/monthproof/strict-pass/governance/tenant/events/events.jsonl +0 -0
  599. package/conformance/v1/bundles/monthproof/strict-pass/governance/tenant/events/payload_material.jsonl +0 -0
  600. package/conformance/v1/bundles/monthproof/strict-pass/governance/tenant/snapshot.json +1 -0
  601. package/conformance/v1/bundles/monthproof/strict-pass/keys/public_keys.json +1 -0
  602. package/conformance/v1/bundles/monthproof/strict-pass/manifest.json +1 -0
  603. package/conformance/v1/bundles/monthproof/strict-pass/verify/report.json +1 -0
  604. package/conformance/v1/bundles/monthproof/strict-pass/verify/verification_report.json +1 -0
  605. package/conformance/v1/cases.json +381 -0
  606. package/conformance/v1/expected/closepack_nonstrict_pass_missing_sla_acceptance.json +9 -0
  607. package/conformance/v1/expected/closepack_strict_fail_embedded_invoice_fails.json +9 -0
  608. package/conformance/v1/expected/closepack_strict_fail_evidence_index_mismatch.json +9 -0
  609. package/conformance/v1/expected/closepack_strict_pass.json +9 -0
  610. package/conformance/v1/expected/financepack_strict_fail_missing_verification_report.json +9 -0
  611. package/conformance/v1/expected/financepack_strict_fail_on_warnings_tool_version_unknown.json +9 -0
  612. package/conformance/v1/expected/financepack_strict_fail_trust_roots_missing.json +9 -0
  613. package/conformance/v1/expected/financepack_strict_fail_trust_roots_wrong.json +9 -0
  614. package/conformance/v1/expected/financepack_strict_pass.json +9 -0
  615. package/conformance/v1/expected/invoicebundle_nonstrict_pass_missing_verification_report.json +9 -0
  616. package/conformance/v1/expected/invoicebundle_nonstrict_pass_unsigned_pricing_matrix_warning.json +9 -0
  617. package/conformance/v1/expected/invoicebundle_strict_fail_evidence_sha_mismatch.json +9 -0
  618. package/conformance/v1/expected/invoicebundle_strict_fail_invalid_pricing_matrix_signature.json +9 -0
  619. package/conformance/v1/expected/invoicebundle_strict_fail_invoice_total_mismatch.json +9 -0
  620. package/conformance/v1/expected/invoicebundle_strict_fail_missing_pricing_matrix_signature.json +9 -0
  621. package/conformance/v1/expected/invoicebundle_strict_fail_missing_verification_report.json +9 -0
  622. package/conformance/v1/expected/invoicebundle_strict_fail_pricing_code_unknown.json +9 -0
  623. package/conformance/v1/expected/invoicebundle_strict_pass.json +9 -0
  624. package/conformance/v1/expected/jobproof_nonstrict_pass_missing_verification_report.json +9 -0
  625. package/conformance/v1/expected/jobproof_strict_fail_manifest_tamper.json +9 -0
  626. package/conformance/v1/expected/jobproof_strict_fail_unauthorized_signer.json +9 -0
  627. package/conformance/v1/expected/jobproof_strict_pass.json +9 -0
  628. package/conformance/v1/expected/monthproof_nonstrict_pass_missing_verification_report.json +9 -0
  629. package/conformance/v1/expected/monthproof_strict_fail_manifest_tamper.json +9 -0
  630. package/conformance/v1/expected/monthproof_strict_fail_unauthorized_signer.json +9 -0
  631. package/conformance/v1/expected/monthproof_strict_pass.json +9 -0
  632. package/conformance/v1/expected/security_bundle_symlink_outside.json +9 -0
  633. package/conformance/v1/expected/security_manifest_case_collision.json +8 -0
  634. package/conformance/v1/expected/security_manifest_duplicate_paths.json +9 -0
  635. package/conformance/v1/expected/security_manifest_path_traversal.json +9 -0
  636. package/conformance/v1/lib/harness.mjs +78 -0
  637. package/conformance/v1/lib/mutations.mjs +61 -0
  638. package/conformance/v1/produce-cases.json +75 -0
  639. package/conformance/v1/producer/bad-plugin-invalid-provider.mjs +4 -0
  640. package/conformance/v1/producer/bad-plugin-no-export.mjs +3 -0
  641. package/conformance/v1/producer/fixture_keypairs.json +18 -0
  642. package/conformance/v1/producer/inmemory-signer-plugin.mjs +47 -0
  643. package/conformance/v1/producer/signer-stdio-bad-json.mjs +54 -0
  644. package/conformance/v1/producer/signer-stdio-partial-stdout-exit1.mjs +51 -0
  645. package/conformance/v1/producer/signer-stdio-stderr-only-exit1.mjs +46 -0
  646. package/conformance/v1/producer/signer-stdio-stub.mjs +134 -0
  647. package/conformance/v1/protocol-vectors/v1.json +81 -0
  648. package/conformance/v1/release-cases.json +111 -0
  649. package/conformance/v1/release-trust-quorum.json +15 -0
  650. package/conformance/v1/release-trust-revoked.json +16 -0
  651. package/conformance/v1/release-trust.json +15 -0
  652. package/conformance/v1/releases/release_fail_asset_hash_mismatch/a.tgz +1 -0
  653. package/conformance/v1/releases/release_fail_asset_hash_mismatch/b.tar.gz +1 -0
  654. package/conformance/v1/releases/release_fail_asset_hash_mismatch/release_index_v1.json +1 -0
  655. package/conformance/v1/releases/release_fail_asset_hash_mismatch/release_index_v1.sig +1 -0
  656. package/conformance/v1/releases/release_fail_missing_asset/a.tgz +1 -0
  657. package/conformance/v1/releases/release_fail_missing_asset/release_index_v1.json +1 -0
  658. package/conformance/v1/releases/release_fail_missing_asset/release_index_v1.sig +1 -0
  659. package/conformance/v1/releases/release_fail_signature_invalid/a.tgz +1 -0
  660. package/conformance/v1/releases/release_fail_signature_invalid/b.tar.gz +1 -0
  661. package/conformance/v1/releases/release_fail_signature_invalid/release_index_v1.json +1 -0
  662. package/conformance/v1/releases/release_fail_signature_invalid/release_index_v1.sig +1 -0
  663. package/conformance/v1/releases/release_pass/a.tgz +1 -0
  664. package/conformance/v1/releases/release_pass/b.tar.gz +1 -0
  665. package/conformance/v1/releases/release_pass/release_index_v1.json +1 -0
  666. package/conformance/v1/releases/release_pass/release_index_v1.sig +1 -0
  667. package/conformance/v1/run-produce.mjs +507 -0
  668. package/conformance/v1/run-release.mjs +129 -0
  669. package/conformance/v1/run.mjs +229 -0
  670. package/conformance/v1/trust.json +11 -0
  671. package/docker-compose.yml +154 -0
  672. package/package.json +98 -0
  673. package/packages/artifact-verify/src/bundle-path.js +60 -0
  674. package/packages/artifact-verify/src/canonical-json.js +48 -0
  675. package/packages/artifact-verify/src/close-pack-bundle.js +914 -0
  676. package/packages/artifact-verify/src/crypto.js +18 -0
  677. package/packages/artifact-verify/src/finance-pack-bundle.js +750 -0
  678. package/packages/artifact-verify/src/governance-policy.js +312 -0
  679. package/packages/artifact-verify/src/hash-file.js +38 -0
  680. package/packages/artifact-verify/src/index.js +100 -0
  681. package/packages/artifact-verify/src/invoice-bundle.js +865 -0
  682. package/packages/artifact-verify/src/job-proof-bundle.js +1996 -0
  683. package/packages/artifact-verify/src/map-with-concurrency.js +32 -0
  684. package/packages/artifact-verify/src/reconcile.js +135 -0
  685. package/packages/artifact-verify/src/release/release-index-lib.js +190 -0
  686. package/packages/artifact-verify/src/release/verify-release.js +187 -0
  687. package/packages/artifact-verify/src/revocation-list.js +119 -0
  688. package/packages/artifact-verify/src/safe-unzip.js +335 -0
  689. package/packages/artifact-verify/src/settlement-decision-report.js +61 -0
  690. package/packages/artifact-verify/src/timestamp-proof.js +49 -0
  691. package/packages/artifact-verify/src/tool-provenance.js +49 -0
  692. package/packages/artifact-verify/src/trust.js +54 -0
  693. package/packages/artifact-verify/src/verification-warnings.js +34 -0
  694. package/scripts/closepack/export.mjs +101 -0
  695. package/scripts/closepack/lib.mjs +1068 -0
  696. package/scripts/closepack/verify.mjs +65 -0
  697. package/scripts/init/capability.mjs +556 -0
  698. package/scripts/init/postinstall-sanity.mjs +18 -0
  699. package/services/finance-sink/README.md +37 -0
  700. package/services/finance-sink/package.json +6 -0
  701. package/services/finance-sink/src/ack-worker.js +152 -0
  702. package/services/finance-sink/src/config.js +176 -0
  703. package/services/finance-sink/src/dedupe-store.js +232 -0
  704. package/services/finance-sink/src/s3-store.js +139 -0
  705. package/services/finance-sink/src/server.js +391 -0
  706. package/services/receiver/README.md +49 -0
  707. package/services/receiver/package.json +6 -0
  708. package/services/receiver/src/ack-worker.js +166 -0
  709. package/services/receiver/src/config.js +178 -0
  710. package/services/receiver/src/dedupe-store.js +232 -0
  711. package/services/receiver/src/s3-store.js +111 -0
  712. package/services/receiver/src/server.js +304 -0
  713. package/src/agent/agent-sim.js +167 -0
  714. package/src/api/app.js +31794 -0
  715. package/src/api/http.js +124 -0
  716. package/src/api/maintenance.js +174 -0
  717. package/src/api/middleware/auth.js +105 -0
  718. package/src/api/middleware/authz.js +19 -0
  719. package/src/api/openapi.js +5684 -0
  720. package/src/api/outbox.js +93 -0
  721. package/src/api/persistence.js +628 -0
  722. package/src/api/server.js +100 -0
  723. package/src/api/store.js +2088 -0
  724. package/src/api/workers/artifacts.js +574 -0
  725. package/src/api/workers/deliveries.js +628 -0
  726. package/src/api/workers/proof.js +374 -0
  727. package/src/core/acceptance-criteria.js +78 -0
  728. package/src/core/access.js +130 -0
  729. package/src/core/agent-reputation.js +311 -0
  730. package/src/core/agent-runs.js +253 -0
  731. package/src/core/agent-wallets.js +883 -0
  732. package/src/core/allocations.js +160 -0
  733. package/src/core/artifact-verification-status.js +216 -0
  734. package/src/core/artifacts.js +938 -0
  735. package/src/core/assist.js +106 -0
  736. package/src/core/audit-export.js +68 -0
  737. package/src/core/auth.js +189 -0
  738. package/src/core/billing-plans.js +187 -0
  739. package/src/core/booking.js +268 -0
  740. package/src/core/cancellation.js +34 -0
  741. package/src/core/canonical-json.js +104 -0
  742. package/src/core/claims.js +152 -0
  743. package/src/core/close-pack-bundle.js +527 -0
  744. package/src/core/config.js +272 -0
  745. package/src/core/contract-compiler.js +68 -0
  746. package/src/core/contract-document.js +226 -0
  747. package/src/core/contract-selection.js +152 -0
  748. package/src/core/contracts.js +439 -0
  749. package/src/core/crypto.js +30 -0
  750. package/src/core/deterministic-zip.js +169 -0
  751. package/src/core/dispatch-events.js +113 -0
  752. package/src/core/dispatch.js +26 -0
  753. package/src/core/dispute-open-envelope.js +163 -0
  754. package/src/core/escrow-ledger.js +329 -0
  755. package/src/core/event-chain.js +114 -0
  756. package/src/core/event-policy.js +120 -0
  757. package/src/core/evidence-linker.js +93 -0
  758. package/src/core/evidence-store.js +286 -0
  759. package/src/core/evidence.js +119 -0
  760. package/src/core/failpoints.js +30 -0
  761. package/src/core/finance-account-map.js +59 -0
  762. package/src/core/finance-pack-bundle.js +554 -0
  763. package/src/core/funding-hold.js +185 -0
  764. package/src/core/gl-batch.js +107 -0
  765. package/src/core/governance-policy.js +174 -0
  766. package/src/core/governance.js +92 -0
  767. package/src/core/hold-exposure.js +74 -0
  768. package/src/core/idempotency.js +51 -0
  769. package/src/core/ids.js +21 -0
  770. package/src/core/incidents.js +75 -0
  771. package/src/core/insurer-reimbursements.js +58 -0
  772. package/src/core/interaction-directions.js +170 -0
  773. package/src/core/invoice-bundle.js +564 -0
  774. package/src/core/job-reducer.js +702 -0
  775. package/src/core/job-state-machine.js +266 -0
  776. package/src/core/journal-csv.js +94 -0
  777. package/src/core/ledger-postings-finance.js +31 -0
  778. package/src/core/ledger-postings.js +476 -0
  779. package/src/core/ledger.js +59 -0
  780. package/src/core/liveness.js +154 -0
  781. package/src/core/log.js +156 -0
  782. package/src/core/maintenance-locks.js +3 -0
  783. package/src/core/marketplace-kernel.js +243 -0
  784. package/src/core/metrics.js +133 -0
  785. package/src/core/money-rail-adapters.js +735 -0
  786. package/src/core/month-close-hold-policy.js +19 -0
  787. package/src/core/month-close.js +159 -0
  788. package/src/core/operator-cost.js +79 -0
  789. package/src/core/operator-coverage.js +46 -0
  790. package/src/core/operator-reducer.js +73 -0
  791. package/src/core/operators.js +52 -0
  792. package/src/core/ops-audit.js +45 -0
  793. package/src/core/party-statements.js +145 -0
  794. package/src/core/pilot-templates.js +26 -0
  795. package/src/core/policy.js +76 -0
  796. package/src/core/pricing.js +71 -0
  797. package/src/core/proof-bundle.js +1153 -0
  798. package/src/core/proof-events.js +88 -0
  799. package/src/core/proof-verifier.js +261 -0
  800. package/src/core/proof.js +46 -0
  801. package/src/core/protocol.js +105 -0
  802. package/src/core/quotas.js +32 -0
  803. package/src/core/reputation-event.js +203 -0
  804. package/src/core/rescheduling.js +51 -0
  805. package/src/core/retention.js +32 -0
  806. package/src/core/revocation-list.js +70 -0
  807. package/src/core/risk.js +383 -0
  808. package/src/core/robot-health.js +111 -0
  809. package/src/core/robot-reducer.js +198 -0
  810. package/src/core/robots.js +152 -0
  811. package/src/core/s3-presign.js +111 -0
  812. package/src/core/secrets.js +128 -0
  813. package/src/core/settlement-adjustment.js +151 -0
  814. package/src/core/settlement-kernel.js +405 -0
  815. package/src/core/settlement-policy.js +206 -0
  816. package/src/core/settlement-splits.js +46 -0
  817. package/src/core/signer-keys.js +33 -0
  818. package/src/core/skills.js +86 -0
  819. package/src/core/sla-events.js +229 -0
  820. package/src/core/sla-metering.js +169 -0
  821. package/src/core/sla-policy-templates.js +340 -0
  822. package/src/core/sla.js +29 -0
  823. package/src/core/statements.js +426 -0
  824. package/src/core/tenancy.js +55 -0
  825. package/src/core/timestamp-proof.js +36 -0
  826. package/src/core/tool-manifest.js +116 -0
  827. package/src/core/tool-provenance.js +36 -0
  828. package/src/core/url-safety.js +263 -0
  829. package/src/core/verification-warnings.js +53 -0
  830. package/src/core/zone-coverage.js +59 -0
  831. package/src/core/zones.js +8 -0
  832. package/src/core/zoneset.js +67 -0
  833. package/src/db/migrate.js +61 -0
  834. package/src/db/migrations/001_init.sql +92 -0
  835. package/src/db/migrations/002_robot_reservations.sql +23 -0
  836. package/src/db/migrations/003_idempotency_v2.sql +32 -0
  837. package/src/db/migrations/004_notifications.sql +12 -0
  838. package/src/db/migrations/005_multi_tenant.sql +106 -0
  839. package/src/db/migrations/006_contracts.sql +27 -0
  840. package/src/db/migrations/007_artifacts_deliveries_correlations.sql +53 -0
  841. package/src/db/migrations/008_delivery_ingest_hardening.sql +52 -0
  842. package/src/db/migrations/009_auth_keys.sql +21 -0
  843. package/src/db/migrations/010_signer_keys.sql +25 -0
  844. package/src/db/migrations/011_ops_audit.sql +33 -0
  845. package/src/db/migrations/012_retention.sql +16 -0
  846. package/src/db/migrations/013_perf_indexes.sql +18 -0
  847. package/src/db/migrations/014_contracts_v2.sql +68 -0
  848. package/src/db/migrations/015_parties.sql +16 -0
  849. package/src/db/migrations/016_ledger_allocations.sql +18 -0
  850. package/src/db/migrations/017_party_statements.sql +31 -0
  851. package/src/db/migrations/018_finance_account_map.sql +12 -0
  852. package/src/db/migrations/019_ledger_allocations_account_id.sql +7 -0
  853. package/src/db/migrations/020_artifacts_source_event_unique.sql +10 -0
  854. package/src/db/migrations/021_artifacts_by_job_created_at_id.sql +6 -0
  855. package/src/db/migrations/022_governance_uniqueness.sql +28 -0
  856. package/src/db/migrations/023_marketplace_tasks.sql +45 -0
  857. package/src/db/migrations/024_agent_runtime_state.sql +70 -0
  858. package/src/db/migrations/025_tenant_settlement_policies.sql +19 -0
  859. package/src/db/migrations/026_money_rails_billable_events.sql +82 -0
  860. package/src/db/migrations/027_tenant_billing_config.sql +10 -0
  861. package/src/db/migrations/028_marketplace_rfq_storage.sql +121 -0
  862. package/src/db/pg.js +123 -0
  863. package/src/db/store-pg.js +6465 -0
@@ -0,0 +1,2088 @@
1
+ import { createLedger, addAccount, createAccount } from "../core/ledger.js";
2
+ import { createEd25519Keypair, keyIdFromPublicKeyPem } from "../core/crypto.js";
3
+ import { createId } from "../core/ids.js";
4
+ import { createDefaultContract } from "../core/contracts.js";
5
+ import { DEFAULT_TENANT_ID, makeScopedKey, normalizeTenantId } from "../core/tenancy.js";
6
+ import { GOVERNANCE_STREAM_ID, validateServerSignerKeyRegisteredPayload } from "../core/governance.js";
7
+ import os from "node:os";
8
+ import fs from "node:fs";
9
+ import path from "node:path";
10
+ import { applyTxRecord, createFileTxLog, TX_LOG_VERSION } from "./persistence.js";
11
+ import { processOutbox } from "./outbox.js";
12
+ import { createFsEvidenceStore, createInMemoryEvidenceStore, createS3EvidenceStore } from "../core/evidence-store.js";
13
+ import { normalizeScopes } from "../core/auth.js";
14
+ import { normalizeSignerKeyPurpose, normalizeSignerKeyStatus } from "../core/signer-keys.js";
15
+ import { MONTH_CLOSE_HOLD_POLICY, normalizeMonthCloseHoldPolicy } from "../core/month-close-hold-policy.js";
16
+ import { clampQuota } from "../core/quotas.js";
17
+ import { computeFinanceAccountMapHash, validateFinanceAccountMapV1 } from "../core/finance-account-map.js";
18
+ import { appendChainedEvent, createChainedEvent } from "../core/event-chain.js";
19
+ import { normalizeBillingPlanId } from "../core/billing-plans.js";
20
+
21
+ function loadOrCreateServerSigner({ persistenceDir }) {
22
+ if (!persistenceDir) {
23
+ const { publicKeyPem, privateKeyPem } = createEd25519Keypair();
24
+ return { publicKeyPem, privateKeyPem };
25
+ }
26
+
27
+ fs.mkdirSync(persistenceDir, { recursive: true });
28
+ const signerPath = path.join(persistenceDir, "server-signer.json");
29
+ if (fs.existsSync(signerPath)) {
30
+ const parsed = JSON.parse(fs.readFileSync(signerPath, "utf8"));
31
+ if (!parsed?.publicKeyPem || !parsed?.privateKeyPem) throw new Error("invalid server-signer.json");
32
+ return { publicKeyPem: parsed.publicKeyPem, privateKeyPem: parsed.privateKeyPem };
33
+ }
34
+
35
+ const { publicKeyPem, privateKeyPem } = createEd25519Keypair();
36
+ fs.writeFileSync(signerPath, JSON.stringify({ publicKeyPem, privateKeyPem }, null, 2), "utf8");
37
+ return { publicKeyPem, privateKeyPem };
38
+ }
39
+
40
+ export function createStore({ persistenceDir = null, serverSignerKeypair = null } = {}) {
41
+ const resolvedServerSignerKeypair =
42
+ serverSignerKeypair && typeof serverSignerKeypair === "object"
43
+ ? {
44
+ publicKeyPem: serverSignerKeypair.publicKeyPem,
45
+ privateKeyPem: serverSignerKeypair.privateKeyPem
46
+ }
47
+ : null;
48
+ if (serverSignerKeypair && (!resolvedServerSignerKeypair?.publicKeyPem || !resolvedServerSignerKeypair?.privateKeyPem)) {
49
+ throw new Error("invalid serverSignerKeypair");
50
+ }
51
+
52
+ const { publicKeyPem: serverPublicKeyPem, privateKeyPem: serverPrivateKeyPem } =
53
+ resolvedServerSignerKeypair ?? loadOrCreateServerSigner({ persistenceDir });
54
+ const serverKeyId = keyIdFromPublicKeyPem(serverPublicKeyPem);
55
+
56
+ function parseEvidenceRetentionMaxDaysByTenant() {
57
+ if (typeof process === "undefined") return new Map();
58
+ const raw = process.env.PROXY_EVIDENCE_RETENTION_MAX_DAYS_BY_TENANT;
59
+ if (!raw || String(raw).trim() === "") return new Map();
60
+ let parsed;
61
+ try {
62
+ parsed = JSON.parse(String(raw));
63
+ } catch (err) {
64
+ throw new Error(`invalid PROXY_EVIDENCE_RETENTION_MAX_DAYS_BY_TENANT JSON: ${err?.message}`);
65
+ }
66
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
67
+ throw new Error("PROXY_EVIDENCE_RETENTION_MAX_DAYS_BY_TENANT must be a JSON object");
68
+ }
69
+ const map = new Map();
70
+ for (const [tenantIdRaw, maxRaw] of Object.entries(parsed)) {
71
+ const tenantId = normalizeTenantId(tenantIdRaw);
72
+ const maxDays = Number(maxRaw);
73
+ if (!Number.isSafeInteger(maxDays) || maxDays <= 0) {
74
+ throw new Error(`PROXY_EVIDENCE_RETENTION_MAX_DAYS_BY_TENANT.${tenantId} must be a positive integer`);
75
+ }
76
+ map.set(tenantId, maxDays);
77
+ }
78
+ return map;
79
+ }
80
+
81
+ const evidenceRetentionMaxDaysByTenant = parseEvidenceRetentionMaxDaysByTenant();
82
+
83
+ function parseMonthCloseHoldPolicyByTenant() {
84
+ if (typeof process === "undefined") return new Map();
85
+ const raw = process.env.PROXY_MONTH_CLOSE_HOLD_POLICY_BY_TENANT;
86
+ if (!raw || String(raw).trim() === "") return new Map();
87
+ let parsed;
88
+ try {
89
+ parsed = JSON.parse(String(raw));
90
+ } catch (err) {
91
+ throw new Error(`invalid PROXY_MONTH_CLOSE_HOLD_POLICY_BY_TENANT JSON: ${err?.message}`);
92
+ }
93
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
94
+ throw new Error("PROXY_MONTH_CLOSE_HOLD_POLICY_BY_TENANT must be a JSON object of tenantId -> policy");
95
+ }
96
+ const map = new Map();
97
+ for (const [tenantIdRaw, policyRaw] of Object.entries(parsed)) {
98
+ if (!tenantIdRaw) continue;
99
+ map.set(normalizeTenantId(tenantIdRaw), normalizeMonthCloseHoldPolicy(policyRaw));
100
+ }
101
+ return map;
102
+ }
103
+
104
+ const monthCloseHoldPolicyByTenant = parseMonthCloseHoldPolicyByTenant();
105
+
106
+ const defaultMonthCloseHoldPolicy = (() => {
107
+ if (typeof process === "undefined") return MONTH_CLOSE_HOLD_POLICY.BLOCK_HOLDS_ORIGINATED_IN_PERIOD;
108
+ try {
109
+ return normalizeMonthCloseHoldPolicy(process.env.PROXY_MONTH_CLOSE_HOLD_POLICY ?? null);
110
+ } catch {
111
+ return MONTH_CLOSE_HOLD_POLICY.BLOCK_HOLDS_ORIGINATED_IN_PERIOD;
112
+ }
113
+ })();
114
+ const defaultEvidenceRetentionMaxDaysRaw = typeof process !== "undefined" ? process.env.PROXY_EVIDENCE_RETENTION_MAX_DAYS : null;
115
+ const defaultEvidenceRetentionMaxDays = defaultEvidenceRetentionMaxDaysRaw ? Number(defaultEvidenceRetentionMaxDaysRaw) : 365;
116
+ if (!Number.isSafeInteger(defaultEvidenceRetentionMaxDays) || defaultEvidenceRetentionMaxDays <= 0) {
117
+ throw new Error("PROXY_EVIDENCE_RETENTION_MAX_DAYS must be a positive integer");
118
+ }
119
+
120
+ function parseNonNegativeIntEnv(name, fallback) {
121
+ const raw = typeof process !== "undefined" ? process.env[name] : null;
122
+ if (raw === null || raw === undefined || String(raw).trim() === "") return fallback;
123
+ const n = Number(raw);
124
+ if (!Number.isSafeInteger(n) || n < 0) throw new Error(`${name} must be a non-negative safe integer`);
125
+ return n;
126
+ }
127
+
128
+ const ingestRecordsRetentionDays = parseNonNegativeIntEnv("PROXY_RETENTION_INGEST_RECORDS_DAYS", 0);
129
+ const deliveriesRetentionDays = parseNonNegativeIntEnv("PROXY_RETENTION_DELIVERIES_DAYS", 0);
130
+ const deliveryDlqRetentionDays = parseNonNegativeIntEnv("PROXY_RETENTION_DELIVERY_DLQ_DAYS", deliveriesRetentionDays);
131
+
132
+ const maxOpenJobs = parseNonNegativeIntEnv("PROXY_QUOTA_MAX_OPEN_JOBS", 0);
133
+ const maxPendingDeliveries = parseNonNegativeIntEnv("PROXY_QUOTA_MAX_PENDING_DELIVERIES", 0);
134
+ const maxIngestDlqDepth = parseNonNegativeIntEnv("PROXY_QUOTA_MAX_INGEST_DLQ_DEPTH", 0);
135
+ const maxEvidenceRefsPerJob = parseNonNegativeIntEnv("PROXY_QUOTA_MAX_EVIDENCE_REFS_PER_JOB", 0);
136
+ const maxArtifactsPerJobType = parseNonNegativeIntEnv("PROXY_QUOTA_MAX_ARTIFACTS_PER_JOB_TYPE", 0);
137
+ const platformMaxPendingDeliveries = parseNonNegativeIntEnv("PROXY_QUOTA_PLATFORM_MAX_PENDING_DELIVERIES", 0);
138
+ const defaultBillingPlan = (() => {
139
+ const raw = typeof process !== "undefined" ? process.env.PROXY_BILLING_DEFAULT_PLAN : null;
140
+ if (raw === null || raw === undefined || String(raw).trim() === "") return "free";
141
+ return normalizeBillingPlanId(raw, { allowNull: false, defaultPlan: "free" });
142
+ })();
143
+
144
+ function createTenantLedger() {
145
+ const ledger = createLedger();
146
+ addAccount(ledger, createAccount({ id: "acct_cash", name: "Cash (Payment Processor Clearing)", type: "asset" }));
147
+ addAccount(ledger, createAccount({ id: "acct_customer_escrow", name: "Customer Escrow", type: "liability" }));
148
+ addAccount(ledger, createAccount({ id: "acct_platform_revenue", name: "Platform Revenue", type: "revenue" }));
149
+ addAccount(ledger, createAccount({ id: "acct_owner_payable", name: "Owner Payable", type: "liability" }));
150
+ addAccount(ledger, createAccount({ id: "acct_operator_payable", name: "Operator Payable", type: "liability" }));
151
+ addAccount(ledger, createAccount({ id: "acct_developer_royalty_payable", name: "Developer Royalties Payable", type: "liability" }));
152
+ addAccount(ledger, createAccount({ id: "acct_insurance_reserve", name: "Insurance Reserve", type: "reserve" }));
153
+ addAccount(ledger, createAccount({ id: "acct_coverage_reserve", name: "Coverage Reserve", type: "reserve" }));
154
+ addAccount(ledger, createAccount({ id: "acct_coverage_unearned", name: "Coverage Unearned (Deferred)", type: "liability" }));
155
+ addAccount(ledger, createAccount({ id: "acct_coverage_revenue", name: "Coverage Revenue", type: "revenue" }));
156
+ addAccount(ledger, createAccount({ id: "acct_coverage_payout_expense", name: "Coverage Payout Expense", type: "expense" }));
157
+ addAccount(ledger, createAccount({ id: "acct_insurer_receivable", name: "Insurer Receivable", type: "asset" }));
158
+ addAccount(ledger, createAccount({ id: "acct_operator_chargeback_receivable", name: "Operator Chargeback Receivable", type: "asset" }));
159
+ addAccount(ledger, createAccount({ id: "acct_claims_expense", name: "Claims Expense", type: "expense" }));
160
+ addAccount(ledger, createAccount({ id: "acct_claims_payable", name: "Claims Payable", type: "liability" }));
161
+ addAccount(ledger, createAccount({ id: "acct_operator_labor_expense", name: "Operator Labor Expense", type: "expense" }));
162
+ addAccount(ledger, createAccount({ id: "acct_operator_cost_accrued", name: "Operator Cost Accrued", type: "liability" }));
163
+ addAccount(ledger, createAccount({ id: "acct_sla_credits_expense", name: "SLA Credits Expense", type: "expense" }));
164
+ addAccount(ledger, createAccount({ id: "acct_customer_credits_payable", name: "Customer Credits Payable", type: "liability" }));
165
+ return ledger;
166
+ }
167
+
168
+ const ledgerByTenant = new Map();
169
+ ledgerByTenant.set(DEFAULT_TENANT_ID, createTenantLedger());
170
+
171
+ const configByTenant = new Map();
172
+ configByTenant.set(DEFAULT_TENANT_ID, {
173
+ operatorCost: {
174
+ basis: "SHIFT_RATE",
175
+ rateCentsPerMinuteByZone: { default: 0 }
176
+ },
177
+ slaCredits: {
178
+ enabled: false,
179
+ defaultAmountCents: 0,
180
+ maxAmountCents: 0
181
+ },
182
+ evidenceRetentionMaxDays: evidenceRetentionMaxDaysByTenant.get(DEFAULT_TENANT_ID) ?? defaultEvidenceRetentionMaxDays,
183
+ retention: {
184
+ ingestRecordsDays: ingestRecordsRetentionDays,
185
+ deliveriesDays: deliveriesRetentionDays,
186
+ deliveryDlqDays: deliveryDlqRetentionDays
187
+ },
188
+ quotas: {
189
+ maxOpenJobs,
190
+ maxPendingDeliveries,
191
+ maxIngestDlqDepth,
192
+ maxEvidenceRefsPerJob,
193
+ maxArtifactsPerJobType
194
+ },
195
+ finance: {
196
+ accountMap: null,
197
+ monthCloseHoldPolicy: defaultMonthCloseHoldPolicy
198
+ },
199
+ billing: {
200
+ plan: defaultBillingPlan,
201
+ planOverrides: null,
202
+ hardLimitEnforced: true
203
+ }
204
+ });
205
+
206
+ const publicKeyByKeyId = new Map();
207
+ publicKeyByKeyId.set(serverKeyId, serverPublicKeyPem);
208
+
209
+ const store = {
210
+ kind: "memory",
211
+ jobs: new Map(), // `${tenantId}\n${jobId}` -> snapshot
212
+ jobEvents: new Map(), // `${tenantId}\n${jobId}` -> chained events
213
+ months: new Map(), // `${tenantId}\n${monthStreamId}` -> snapshot
214
+ monthEvents: new Map(), // `${tenantId}\n${monthStreamId}` -> chained events
215
+ robots: new Map(), // `${tenantId}\n${robotId}` -> snapshot
216
+ robotEvents: new Map(), // `${tenantId}\n${robotId}` -> chained events
217
+ operators: new Map(), // `${tenantId}\n${operatorId}` -> snapshot
218
+ operatorEvents: new Map(), // `${tenantId}\n${operatorId}` -> chained events
219
+ agentIdentities: new Map(), // `${tenantId}\n${agentId}` -> AgentIdentity.v1 record
220
+ agentWallets: new Map(), // `${tenantId}\n${agentId}` -> AgentWallet.v1 record
221
+ agentRuns: new Map(), // `${tenantId}\n${runId}` -> AgentRun.v1 snapshot
222
+ agentRunEvents: new Map(), // `${tenantId}\n${runId}` -> AgentEvent.v1[]
223
+ agentRunSettlements: new Map(), // `${tenantId}\n${runId}` -> AgentRunSettlement.v1
224
+ arbitrationCases: new Map(), // `${tenantId}\n${caseId}` -> ArbitrationCase.v1 snapshot
225
+ toolCallHolds: new Map(), // `${tenantId}\n${holdHash}` -> FundingHold.v1 snapshot
226
+ settlementAdjustments: new Map(), // `${tenantId}\n${adjustmentId}` -> SettlementAdjustment.v1 snapshot
227
+ moneyRailOperations: new Map(), // `${tenantId}\n${providerId}\n${operationId}` -> MoneyRailOperation.v1
228
+ moneyRailProviderEvents: new Map(), // `${tenantId}\n${providerId}\n${operationId}\n${eventType}\n${eventDedupeKey}` -> MoneyRailProviderEvent.v1
229
+ billableUsageEvents: new Map(), // `${tenantId}\n${eventKey}` -> BillableUsageEvent.v1
230
+ financeReconciliationTriages: new Map(), // `${tenantId}\n${triageKey}` -> FinanceReconciliationTriage.v1
231
+ marketplaceRfqs: new Map(), // `${tenantId}\n${rfqId}` -> MarketplaceRfq.v1
232
+ marketplaceRfqBids: new Map(), // `${tenantId}\n${rfqId}` -> MarketplaceBid.v1[]
233
+ tenantSettlementPolicies: new Map(), // `${tenantId}\n${policyId}\n${policyVersion}` -> TenantSettlementPolicy.v1
234
+ tenantSettlementPolicyRollouts: new Map(), // `${tenantId}\nrollout` -> TenantSettlementPolicyRollout.v1
235
+ contracts: new Map(), // `${tenantId}\n${contractId}` -> contract
236
+ idempotency: new Map(),
237
+ publicKeyByKeyId,
238
+ serverSigner: { keyId: serverKeyId, publicKeyPem: serverPublicKeyPem, privateKeyPem: serverPrivateKeyPem },
239
+ ledgerByTenant,
240
+ // Back-compat: keep store.ledger and store.config as the default tenant's objects.
241
+ ledger: ledgerByTenant.get(DEFAULT_TENANT_ID),
242
+ configByTenant,
243
+ config: configByTenant.get(DEFAULT_TENANT_ID),
244
+ parties: new Map(), // `${tenantId}\n${partyId}` -> party record
245
+ partyStatements: new Map(), // `${tenantId}\n${partyId}\n${period}` -> party statement record
246
+ ledgerAllocations: new Map(), // `${tenantId}\n${entryId}\n${postingId}\n${partyId}` -> allocation
247
+ notifications: [],
248
+ outbox: [],
249
+ outboxCursor: 0,
250
+ dispatchCursor: 0,
251
+ operatorQueueCursor: 0,
252
+ robotHealthCursor: 0,
253
+ jobAccountingCursor: 0,
254
+ monthCloseCursor: 0,
255
+ artifactCursor: 0,
256
+ deliveryCursor: 0,
257
+ persistence: persistenceDir ? createFileTxLog({ dir: persistenceDir }) : null
258
+ };
259
+
260
+ // Allow createApi to inject a deterministic clock for tests/workers.
261
+ store.nowIso = () => new Date().toISOString();
262
+
263
+ const evidenceStoreKind =
264
+ typeof process !== "undefined" && process.env.PROXY_EVIDENCE_STORE ? String(process.env.PROXY_EVIDENCE_STORE) : "fs";
265
+ const evidenceDir =
266
+ typeof process !== "undefined" && process.env.PROXY_EVIDENCE_DIR
267
+ ? String(process.env.PROXY_EVIDENCE_DIR)
268
+ : persistenceDir
269
+ ? path.join(persistenceDir, "evidence")
270
+ : path.join(os.tmpdir(), createId("proxy_evidence"));
271
+ if (evidenceStoreKind === "memory") {
272
+ store.evidenceStore = createInMemoryEvidenceStore();
273
+ } else if (evidenceStoreKind === "s3" || evidenceStoreKind === "minio") {
274
+ if (typeof process === "undefined") throw new Error("s3 evidence store requires process.env configuration");
275
+ const endpoint = process.env.PROXY_EVIDENCE_S3_ENDPOINT;
276
+ const region = process.env.PROXY_EVIDENCE_S3_REGION ?? "us-east-1";
277
+ const bucket = process.env.PROXY_EVIDENCE_S3_BUCKET;
278
+ const accessKeyId = process.env.PROXY_EVIDENCE_S3_ACCESS_KEY_ID ?? process.env.AWS_ACCESS_KEY_ID;
279
+ const secretAccessKey = process.env.PROXY_EVIDENCE_S3_SECRET_ACCESS_KEY ?? process.env.AWS_SECRET_ACCESS_KEY;
280
+ const forcePathStyle = (process.env.PROXY_EVIDENCE_S3_FORCE_PATH_STYLE ?? "1") !== "0";
281
+ store.evidenceStore = createS3EvidenceStore({
282
+ endpoint,
283
+ region,
284
+ bucket,
285
+ accessKeyId,
286
+ secretAccessKey,
287
+ forcePathStyle
288
+ });
289
+ } else {
290
+ store.evidenceStore = createFsEvidenceStore({ rootDir: evidenceDir });
291
+ }
292
+
293
+ store.ensureTenant = function ensureTenant(tenantId) {
294
+ tenantId = normalizeTenantId(tenantId);
295
+ if (!store.ledgerByTenant.has(tenantId)) store.ledgerByTenant.set(tenantId, createTenantLedger());
296
+ if (!store.configByTenant.has(tenantId)) {
297
+ const base = store.configByTenant.get(DEFAULT_TENANT_ID);
298
+ store.configByTenant.set(tenantId, JSON.parse(JSON.stringify(base)));
299
+ }
300
+ const cfg = store.configByTenant.get(tenantId);
301
+ if (cfg && typeof cfg === "object") {
302
+ const override = evidenceRetentionMaxDaysByTenant.get(tenantId);
303
+ if (override) cfg.evidenceRetentionMaxDays = override;
304
+ const policyOverride = monthCloseHoldPolicyByTenant.get(tenantId);
305
+ if (policyOverride) {
306
+ if (!cfg.finance) cfg.finance = {};
307
+ cfg.finance.monthCloseHoldPolicy = policyOverride;
308
+ }
309
+ }
310
+ if (store.contracts instanceof Map) {
311
+ const defaultKey = makeScopedKey({ tenantId, id: "contract_default" });
312
+ if (!store.contracts.has(defaultKey)) store.contracts.set(defaultKey, createDefaultContract({ tenantId }));
313
+ }
314
+ };
315
+
316
+ store.getLedger = function getLedger(tenantId) {
317
+ tenantId = normalizeTenantId(tenantId);
318
+ store.ensureTenant(tenantId);
319
+ return store.ledgerByTenant.get(tenantId);
320
+ };
321
+
322
+ store.getConfig = function getConfig(tenantId) {
323
+ tenantId = normalizeTenantId(tenantId);
324
+ store.ensureTenant(tenantId);
325
+ return store.configByTenant.get(tenantId);
326
+ };
327
+
328
+ store.getTenantBillingConfig = async function getTenantBillingConfig({ tenantId = DEFAULT_TENANT_ID } = {}) {
329
+ tenantId = normalizeTenantId(tenantId);
330
+ store.ensureTenant(tenantId);
331
+ const cfg = store.configByTenant.get(tenantId);
332
+ const billing = cfg?.billing ?? null;
333
+ return billing && typeof billing === "object" && !Array.isArray(billing) ? JSON.parse(JSON.stringify(billing)) : null;
334
+ };
335
+
336
+ store.putTenantBillingConfig = async function putTenantBillingConfig({ tenantId = DEFAULT_TENANT_ID, billing, audit = null } = {}) {
337
+ tenantId = normalizeTenantId(tenantId);
338
+ store.ensureTenant(tenantId);
339
+ if (!billing || typeof billing !== "object" || Array.isArray(billing)) {
340
+ throw new TypeError("billing config is required");
341
+ }
342
+ const normalizedBilling = JSON.parse(JSON.stringify(billing));
343
+ const cfg = store.configByTenant.get(tenantId);
344
+ cfg.billing = normalizedBilling;
345
+ if (audit) {
346
+ await store.appendOpsAudit({ tenantId, audit });
347
+ }
348
+ return normalizedBilling;
349
+ };
350
+
351
+ store.getFinanceAccountMap = async function getFinanceAccountMap({ tenantId = DEFAULT_TENANT_ID } = {}) {
352
+ tenantId = normalizeTenantId(tenantId);
353
+ store.ensureTenant(tenantId);
354
+ const cfg = store.configByTenant.get(tenantId);
355
+ const map = cfg?.finance?.accountMap ?? null;
356
+ return map && typeof map === "object" ? map : null;
357
+ };
358
+
359
+ store.putFinanceAccountMap = async function putFinanceAccountMap({ tenantId = DEFAULT_TENANT_ID, mapping, audit = null } = {}) {
360
+ tenantId = normalizeTenantId(tenantId);
361
+ store.ensureTenant(tenantId);
362
+ validateFinanceAccountMapV1(mapping);
363
+
364
+ const cfg = store.configByTenant.get(tenantId);
365
+ if (!cfg.finance) cfg.finance = {};
366
+ cfg.finance.accountMap = mapping;
367
+
368
+ if (audit) {
369
+ await store.appendOpsAudit({ tenantId, audit });
370
+ }
371
+
372
+ return { tenantId, mappingHash: computeFinanceAccountMapHash(mapping), mapping };
373
+ };
374
+
375
+ // Ensure the default tenant is initialized (ledger/config/contract).
376
+ store.ensureTenant(DEFAULT_TENANT_ID);
377
+
378
+ store.commitTx = function commitTx({ at = new Date().toISOString(), ops, audit = null }) {
379
+ if (!Array.isArray(ops) || ops.length === 0) throw new TypeError("commitTx requires non-empty ops[]");
380
+ const nextOps = [...ops];
381
+ if (audit) {
382
+ const tenantId = normalizeTenantId(audit?.tenantId ?? DEFAULT_TENANT_ID);
383
+ store.ensureTenant(tenantId);
384
+ store.opsAuditSeq = Number.isSafeInteger(store.opsAuditSeq) ? store.opsAuditSeq : 0;
385
+ store.opsAuditSeq += 1;
386
+ const id = store.opsAuditSeq;
387
+ const recordAudit = { ...(audit ?? {}), id, tenantId, at: audit?.at ?? at };
388
+ nextOps.push({ kind: "OPS_AUDIT_APPEND", tenantId, audit: recordAudit });
389
+ }
390
+ const record = { v: TX_LOG_VERSION, at, txId: createId("tx"), ops: nextOps };
391
+ if (store.persistence) store.persistence.append(record);
392
+ applyTxRecord(store, record);
393
+ processOutbox(store);
394
+ };
395
+
396
+ store.processOutbox = function processOutboxInStore({ maxMessages = Number.MAX_SAFE_INTEGER } = {}) {
397
+ processOutbox(store, { maxMessages });
398
+ };
399
+
400
+ store.listNotifications = function listNotifications({ tenantId = null, topic = null, limit = 200, offset = 0 } = {}) {
401
+ if (tenantId !== null) tenantId = normalizeTenantId(tenantId);
402
+ if (topic !== null && (typeof topic !== "string" || topic.trim() === "")) throw new TypeError("topic must be null or a non-empty string");
403
+ if (!Number.isSafeInteger(limit) || limit <= 0) throw new TypeError("limit must be a positive safe integer");
404
+ if (!Number.isSafeInteger(offset) || offset < 0) throw new TypeError("offset must be a non-negative safe integer");
405
+ const safeLimit = Math.min(1000, limit);
406
+ const safeOffset = offset;
407
+ const all = Array.isArray(store.notifications) ? store.notifications : [];
408
+ const filteredByTenant = tenantId === null ? all : all.filter((n) => normalizeTenantId(n?.tenantId) === tenantId);
409
+ const filtered = topic ? filteredByTenant.filter((n) => n?.topic === topic) : filteredByTenant;
410
+ // Most recent first (highest outbox index).
411
+ const sorted = [...filtered].sort((a, b) => (Number(b?.outboxIndex) || 0) - (Number(a?.outboxIndex) || 0));
412
+ return sorted.slice(safeOffset, safeOffset + safeLimit);
413
+ };
414
+
415
+ store.listLedgerEntries = function listLedgerEntries({ tenantId = DEFAULT_TENANT_ID, memoPrefix = null, limit = 200, offset = 0 } = {}) {
416
+ tenantId = normalizeTenantId(tenantId);
417
+ if (memoPrefix !== null && (typeof memoPrefix !== "string" || memoPrefix.trim() === "")) throw new TypeError("memoPrefix must be null or a non-empty string");
418
+ if (!Number.isSafeInteger(limit) || limit <= 0) throw new TypeError("limit must be a positive safe integer");
419
+ if (!Number.isSafeInteger(offset) || offset < 0) throw new TypeError("offset must be a non-negative safe integer");
420
+
421
+ const safeLimit = Math.min(5000, limit);
422
+ const safeOffset = offset;
423
+ const ledger = typeof store.getLedger === "function" ? store.getLedger(tenantId) : store.ledger;
424
+ const all = Array.isArray(ledger?.entries) ? ledger.entries : [];
425
+ const filtered = memoPrefix ? all.filter((e) => typeof e?.memo === "string" && e.memo.startsWith(memoPrefix)) : all;
426
+ return filtered.slice(safeOffset, safeOffset + safeLimit);
427
+ };
428
+
429
+ store.upsertParty = async function upsertParty({ tenantId = DEFAULT_TENANT_ID, party, audit = null } = {}) {
430
+ tenantId = normalizeTenantId(tenantId);
431
+ if (!party || typeof party !== "object") throw new TypeError("party is required");
432
+ const partyId = party.partyId ?? party.id ?? null;
433
+ if (typeof partyId !== "string" || partyId.trim() === "") throw new TypeError("party.partyId is required");
434
+ const partyRole = party.partyRole ?? party.role ?? null;
435
+ if (typeof partyRole !== "string" || partyRole.trim() === "") throw new TypeError("party.partyRole is required");
436
+ const displayName = party.displayName ?? null;
437
+ if (typeof displayName !== "string" || displayName.trim() === "") throw new TypeError("party.displayName is required");
438
+ const status = party.status ?? "active";
439
+ if (typeof status !== "string" || status.trim() === "") throw new TypeError("party.status is required");
440
+
441
+ const nowAt = typeof store.nowIso === "function" ? store.nowIso() : new Date().toISOString();
442
+ const key = makeScopedKey({ tenantId, id: String(partyId) });
443
+ const existing = store.parties.get(key) ?? null;
444
+ const record = {
445
+ tenantId,
446
+ partyId: String(partyId),
447
+ partyRole: String(partyRole),
448
+ displayName: String(displayName),
449
+ status: String(status),
450
+ createdAt: existing?.createdAt ?? nowAt,
451
+ updatedAt: nowAt
452
+ };
453
+ store.parties.set(key, record);
454
+ if (audit && typeof store.appendOpsAudit === "function") {
455
+ await store.appendOpsAudit({ tenantId, audit });
456
+ }
457
+ return record;
458
+ };
459
+
460
+ store.getParty = async function getParty({ tenantId = DEFAULT_TENANT_ID, partyId } = {}) {
461
+ tenantId = normalizeTenantId(tenantId);
462
+ if (typeof partyId !== "string" || partyId.trim() === "") throw new TypeError("partyId is required");
463
+ return store.parties.get(makeScopedKey({ tenantId, id: String(partyId) })) ?? null;
464
+ };
465
+
466
+ store.listParties = async function listParties({ tenantId = DEFAULT_TENANT_ID, role = null, status = null, limit = 200, offset = 0 } = {}) {
467
+ tenantId = normalizeTenantId(tenantId);
468
+ if (role !== null && (typeof role !== "string" || role.trim() === "")) throw new TypeError("role must be null or a non-empty string");
469
+ if (status !== null && (typeof status !== "string" || status.trim() === "")) throw new TypeError("status must be null or a non-empty string");
470
+ if (!Number.isSafeInteger(limit) || limit <= 0) throw new TypeError("limit must be a positive safe integer");
471
+ if (!Number.isSafeInteger(offset) || offset < 0) throw new TypeError("offset must be a non-negative safe integer");
472
+ const safeLimit = Math.min(1000, limit);
473
+ const safeOffset = offset;
474
+ const out = [];
475
+ for (const p of store.parties.values()) {
476
+ if (!p || typeof p !== "object") continue;
477
+ if (normalizeTenantId(p.tenantId ?? DEFAULT_TENANT_ID) !== tenantId) continue;
478
+ if (role !== null && String(p.partyRole ?? "") !== String(role)) continue;
479
+ if (status !== null && String(p.status ?? "") !== String(status)) continue;
480
+ out.push(p);
481
+ }
482
+ out.sort((a, b) => String(a.partyId ?? "").localeCompare(String(b.partyId ?? "")));
483
+ return out.slice(safeOffset, safeOffset + safeLimit);
484
+ };
485
+
486
+ store.listLedgerAllocations = async function listLedgerAllocations({ tenantId = DEFAULT_TENANT_ID, entryId = null, partyId = null, limit = 5000, offset = 0 } = {}) {
487
+ tenantId = normalizeTenantId(tenantId);
488
+ if (entryId !== null && (typeof entryId !== "string" || entryId.trim() === "")) throw new TypeError("entryId must be null or a non-empty string");
489
+ if (partyId !== null && (typeof partyId !== "string" || partyId.trim() === "")) throw new TypeError("partyId must be null or a non-empty string");
490
+ if (!Number.isSafeInteger(limit) || limit <= 0) throw new TypeError("limit must be a positive safe integer");
491
+ if (!Number.isSafeInteger(offset) || offset < 0) throw new TypeError("offset must be a non-negative safe integer");
492
+ const safeLimit = Math.min(5000, limit);
493
+ const safeOffset = offset;
494
+ const out = [];
495
+ for (const a of store.ledgerAllocations.values()) {
496
+ if (!a || typeof a !== "object") continue;
497
+ if (normalizeTenantId(a.tenantId ?? DEFAULT_TENANT_ID) !== tenantId) continue;
498
+ if (entryId !== null && String(a.entryId ?? "") !== String(entryId)) continue;
499
+ if (partyId !== null && String(a.partyId ?? "") !== String(partyId)) continue;
500
+ out.push(a);
501
+ }
502
+ out.sort((a, b) => String(a.entryId ?? "").localeCompare(String(b.entryId ?? "")) || String(a.postingId ?? "").localeCompare(String(b.postingId ?? "")));
503
+ return out.slice(safeOffset, safeOffset + safeLimit);
504
+ };
505
+
506
+ store.putPartyStatement = async function putPartyStatement({ tenantId = DEFAULT_TENANT_ID, statement, audit = null } = {}) {
507
+ tenantId = normalizeTenantId(tenantId);
508
+ if (!statement || typeof statement !== "object") throw new TypeError("statement is required");
509
+ const partyId = statement.partyId ?? null;
510
+ const period = statement.period ?? null;
511
+ if (typeof partyId !== "string" || partyId.trim() === "") throw new TypeError("statement.partyId is required");
512
+ if (typeof period !== "string" || period.trim() === "") throw new TypeError("statement.period is required");
513
+ const status = statement.status ?? "OPEN";
514
+ if (typeof status !== "string" || status.trim() === "") throw new TypeError("statement.status is required");
515
+ const statementHash = statement.statementHash ?? null;
516
+ const artifactId = statement.artifactId ?? null;
517
+ const artifactHash = statement.artifactHash ?? null;
518
+ if (typeof statementHash !== "string" || statementHash.trim() === "") throw new TypeError("statement.statementHash is required");
519
+ if (typeof artifactId !== "string" || artifactId.trim() === "") throw new TypeError("statement.artifactId is required");
520
+ if (typeof artifactHash !== "string" || artifactHash.trim() === "") throw new TypeError("statement.artifactHash is required");
521
+
522
+ const key = `${tenantId}\n${String(partyId)}\n${String(period)}`;
523
+ const existing = store.partyStatements.get(key) ?? null;
524
+ if (existing && String(existing.status ?? "") === "CLOSED") {
525
+ if (String(existing.artifactHash ?? "") !== String(artifactHash)) {
526
+ const err = new Error("party statement is closed and cannot be changed");
527
+ err.code = "PARTY_STATEMENT_IMMUTABLE";
528
+ throw err;
529
+ }
530
+ return existing;
531
+ }
532
+
533
+ const now = new Date().toISOString();
534
+ const createdAt = existing?.createdAt ?? now;
535
+ const record = {
536
+ tenantId,
537
+ partyId: String(partyId),
538
+ period: String(period),
539
+ basis: statement.basis ?? "settledAt",
540
+ status: String(status),
541
+ statementHash: String(statementHash),
542
+ artifactId: String(artifactId),
543
+ artifactHash: String(artifactHash),
544
+ closedAt: statement.closedAt ?? null,
545
+ createdAt,
546
+ updatedAt: now
547
+ };
548
+ store.partyStatements.set(key, record);
549
+ if (audit && typeof store.appendOpsAudit === "function") {
550
+ await store.appendOpsAudit({ tenantId, audit });
551
+ }
552
+ return record;
553
+ };
554
+
555
+ store.getPartyStatement = async function getPartyStatement({ tenantId = DEFAULT_TENANT_ID, partyId, period } = {}) {
556
+ tenantId = normalizeTenantId(tenantId);
557
+ if (typeof partyId !== "string" || partyId.trim() === "") throw new TypeError("partyId is required");
558
+ if (typeof period !== "string" || period.trim() === "") throw new TypeError("period is required");
559
+ const key = `${tenantId}\n${String(partyId)}\n${String(period)}`;
560
+ return store.partyStatements.get(key) ?? null;
561
+ };
562
+
563
+ store.listPartyStatements = async function listPartyStatements({
564
+ tenantId = DEFAULT_TENANT_ID,
565
+ period = null,
566
+ partyId = null,
567
+ status = null,
568
+ limit = 200,
569
+ offset = 0
570
+ } = {}) {
571
+ tenantId = normalizeTenantId(tenantId);
572
+ if (period !== null && (typeof period !== "string" || period.trim() === "")) throw new TypeError("period must be null or a non-empty string");
573
+ if (partyId !== null && (typeof partyId !== "string" || partyId.trim() === "")) throw new TypeError("partyId must be null or a non-empty string");
574
+ if (status !== null && (typeof status !== "string" || status.trim() === "")) throw new TypeError("status must be null or a non-empty string");
575
+ if (!Number.isSafeInteger(limit) || limit <= 0) throw new TypeError("limit must be a positive safe integer");
576
+ if (!Number.isSafeInteger(offset) || offset < 0) throw new TypeError("offset must be a non-negative safe integer");
577
+ const safeLimit = Math.min(1000, limit);
578
+ const safeOffset = offset;
579
+ const out = [];
580
+ for (const s of store.partyStatements.values()) {
581
+ if (!s || typeof s !== "object") continue;
582
+ if (normalizeTenantId(s.tenantId ?? DEFAULT_TENANT_ID) !== tenantId) continue;
583
+ if (period !== null && String(s.period ?? "") !== String(period)) continue;
584
+ if (partyId !== null && String(s.partyId ?? "") !== String(partyId)) continue;
585
+ if (status !== null && String(s.status ?? "") !== String(status)) continue;
586
+ out.push(s);
587
+ }
588
+ out.sort((a, b) => String(a.period ?? "").localeCompare(String(b.period ?? "")) || String(a.partyId ?? "").localeCompare(String(b.partyId ?? "")));
589
+ return out.slice(safeOffset, safeOffset + safeLimit);
590
+ };
591
+
592
+ store.putAgentIdentity = async function putAgentIdentity({ tenantId = DEFAULT_TENANT_ID, agentIdentity, audit = null } = {}) {
593
+ tenantId = normalizeTenantId(tenantId);
594
+ if (!agentIdentity || typeof agentIdentity !== "object" || Array.isArray(agentIdentity)) throw new TypeError("agentIdentity is required");
595
+
596
+ const agentId = agentIdentity.agentId ?? agentIdentity.id ?? null;
597
+ if (typeof agentId !== "string" || agentId.trim() === "") throw new TypeError("agentIdentity.agentId is required");
598
+
599
+ const owner = agentIdentity.owner ?? null;
600
+ if (!owner || typeof owner !== "object" || Array.isArray(owner)) throw new TypeError("agentIdentity.owner is required");
601
+ const ownerType = owner.ownerType ?? null;
602
+ const ownerId = owner.ownerId ?? null;
603
+ if (ownerType !== "human" && ownerType !== "business" && ownerType !== "service") {
604
+ throw new TypeError("agentIdentity.owner.ownerType must be human|business|service");
605
+ }
606
+ if (typeof ownerId !== "string" || ownerId.trim() === "") throw new TypeError("agentIdentity.owner.ownerId is required");
607
+
608
+ const keys = agentIdentity.keys ?? null;
609
+ if (!keys || typeof keys !== "object" || Array.isArray(keys)) throw new TypeError("agentIdentity.keys is required");
610
+ const keyId = keys.keyId ?? null;
611
+ const algorithm = keys.algorithm ?? null;
612
+ const publicKeyPem = keys.publicKeyPem ?? null;
613
+ if (typeof keyId !== "string" || keyId.trim() === "") throw new TypeError("agentIdentity.keys.keyId is required");
614
+ if (String(algorithm ?? "").toLowerCase() !== "ed25519") throw new TypeError("agentIdentity.keys.algorithm must be ed25519");
615
+ if (typeof publicKeyPem !== "string" || publicKeyPem.trim() === "") throw new TypeError("agentIdentity.keys.publicKeyPem is required");
616
+
617
+ const displayName = agentIdentity.displayName ?? null;
618
+ if (typeof displayName !== "string" || displayName.trim() === "") throw new TypeError("agentIdentity.displayName is required");
619
+
620
+ const status = String(agentIdentity.status ?? "active").trim().toLowerCase();
621
+ if (status !== "active" && status !== "suspended" && status !== "revoked") {
622
+ throw new TypeError("agentIdentity.status must be active|suspended|revoked");
623
+ }
624
+
625
+ const capabilitiesIn = Array.isArray(agentIdentity.capabilities) ? agentIdentity.capabilities : [];
626
+ const capabilities = [...new Set(capabilitiesIn.map((value) => String(value ?? "").trim()).filter(Boolean))].sort((left, right) =>
627
+ left.localeCompare(right)
628
+ );
629
+
630
+ const walletPolicyIn = agentIdentity.walletPolicy;
631
+ if (walletPolicyIn !== undefined && walletPolicyIn !== null && (typeof walletPolicyIn !== "object" || Array.isArray(walletPolicyIn))) {
632
+ throw new TypeError("agentIdentity.walletPolicy must be an object or null");
633
+ }
634
+ let walletPolicy = null;
635
+ if (walletPolicyIn && typeof walletPolicyIn === "object" && !Array.isArray(walletPolicyIn)) {
636
+ const allowedWalletPolicyFields = new Set(["maxPerTransactionCents", "maxDailyCents", "requireApprovalAboveCents"]);
637
+ for (const key of Object.keys(walletPolicyIn)) {
638
+ if (!allowedWalletPolicyFields.has(key)) throw new TypeError(`agentIdentity.walletPolicy contains unknown field: ${key}`);
639
+ }
640
+ walletPolicy = {};
641
+ for (const field of allowedWalletPolicyFields) {
642
+ const raw = walletPolicyIn[field];
643
+ if (raw === undefined || raw === null) continue;
644
+ const amount = Number(raw);
645
+ if (!Number.isSafeInteger(amount) || amount < 0) throw new TypeError(`agentIdentity.walletPolicy.${field} must be a non-negative integer`);
646
+ walletPolicy[field] = amount;
647
+ }
648
+ }
649
+
650
+ const metadataIn = agentIdentity.metadata;
651
+ if (metadataIn !== undefined && metadataIn !== null && (typeof metadataIn !== "object" || Array.isArray(metadataIn))) {
652
+ throw new TypeError("agentIdentity.metadata must be an object or null");
653
+ }
654
+
655
+ const nowAt = typeof store.nowIso === "function" ? store.nowIso() : new Date().toISOString();
656
+ const key = makeScopedKey({ tenantId, id: String(agentId) });
657
+ const existing = store.agentIdentities.get(key) ?? null;
658
+ if (existing) {
659
+ const err = new Error("agent identity already exists");
660
+ err.code = "AGENT_IDENTITY_EXISTS";
661
+ throw err;
662
+ }
663
+ const createdAt = typeof existing?.createdAt === "string" && existing.createdAt.trim() !== "" ? existing.createdAt : nowAt;
664
+
665
+ const record = {
666
+ schemaVersion: "AgentIdentity.v1",
667
+ agentId: String(agentId),
668
+ tenantId,
669
+ displayName: String(displayName),
670
+ description: typeof agentIdentity.description === "string" && agentIdentity.description.trim() !== "" ? agentIdentity.description : null,
671
+ status,
672
+ owner: {
673
+ ownerType: String(ownerType),
674
+ ownerId: String(ownerId)
675
+ },
676
+ keys: {
677
+ keyId: String(keyId),
678
+ algorithm: "ed25519",
679
+ publicKeyPem: String(publicKeyPem)
680
+ },
681
+ capabilities,
682
+ walletPolicy,
683
+ metadata:
684
+ metadataIn && typeof metadataIn === "object" && !Array.isArray(metadataIn)
685
+ ? { ...metadataIn }
686
+ : null,
687
+ revision:
688
+ Number.isSafeInteger(agentIdentity.revision) && agentIdentity.revision >= 0
689
+ ? Number(agentIdentity.revision)
690
+ : 0,
691
+ createdAt,
692
+ updatedAt: nowAt
693
+ };
694
+
695
+ const ops = [
696
+ { kind: "AGENT_IDENTITY_UPSERT", tenantId, agentIdentity: record },
697
+ { kind: "PUBLIC_KEY_PUT", keyId: String(keyId), publicKeyPem: String(publicKeyPem) }
698
+ ];
699
+ await store.commitTx({ at: nowAt, ops, audit });
700
+ return store.getAgentIdentity({ tenantId, agentId: String(agentId) });
701
+ };
702
+
703
+ store.getAgentIdentity = async function getAgentIdentity({ tenantId = DEFAULT_TENANT_ID, agentId } = {}) {
704
+ tenantId = normalizeTenantId(tenantId);
705
+ if (typeof agentId !== "string" || agentId.trim() === "") throw new TypeError("agentId is required");
706
+ const key = makeScopedKey({ tenantId, id: String(agentId) });
707
+ return store.agentIdentities.get(key) ?? null;
708
+ };
709
+
710
+ store.listAgentIdentities = async function listAgentIdentities({ tenantId = DEFAULT_TENANT_ID, status = null, limit = 200, offset = 0 } = {}) {
711
+ tenantId = normalizeTenantId(tenantId);
712
+ if (status !== null && (typeof status !== "string" || status.trim() === "")) throw new TypeError("status must be null or a non-empty string");
713
+ if (!Number.isSafeInteger(limit) || limit <= 0) throw new TypeError("limit must be a positive safe integer");
714
+ if (!Number.isSafeInteger(offset) || offset < 0) throw new TypeError("offset must be a non-negative safe integer");
715
+ const statusFilter = status ? String(status).trim().toLowerCase() : null;
716
+ const safeLimit = Math.min(1000, limit);
717
+ const safeOffset = offset;
718
+ const out = [];
719
+ for (const row of store.agentIdentities.values()) {
720
+ if (!row || typeof row !== "object") continue;
721
+ if (normalizeTenantId(row.tenantId ?? DEFAULT_TENANT_ID) !== tenantId) continue;
722
+ if (statusFilter !== null && String(row.status ?? "").toLowerCase() !== statusFilter) continue;
723
+ out.push(row);
724
+ }
725
+ out.sort((left, right) => String(left.agentId ?? "").localeCompare(String(right.agentId ?? "")));
726
+ return out.slice(safeOffset, safeOffset + safeLimit);
727
+ };
728
+
729
+ store.getAgentWallet = async function getAgentWallet({ tenantId = DEFAULT_TENANT_ID, agentId } = {}) {
730
+ tenantId = normalizeTenantId(tenantId);
731
+ if (typeof agentId !== "string" || agentId.trim() === "") throw new TypeError("agentId is required");
732
+ return store.agentWallets.get(makeScopedKey({ tenantId, id: String(agentId) })) ?? null;
733
+ };
734
+
735
+ store.putAgentWallet = async function putAgentWallet({ tenantId = DEFAULT_TENANT_ID, wallet } = {}) {
736
+ tenantId = normalizeTenantId(tenantId);
737
+ if (!wallet || typeof wallet !== "object" || Array.isArray(wallet)) throw new TypeError("wallet is required");
738
+ const agentId = wallet.agentId ?? null;
739
+ if (typeof agentId !== "string" || agentId.trim() === "") throw new TypeError("wallet.agentId is required");
740
+ const key = makeScopedKey({ tenantId, id: String(agentId) });
741
+ await store.commitTx({ at: wallet.updatedAt ?? new Date().toISOString(), ops: [{ kind: "AGENT_WALLET_UPSERT", tenantId, wallet: { ...wallet, tenantId, agentId } }] });
742
+ return store.agentWallets.get(key) ?? null;
743
+ };
744
+
745
+ store.getAgentRun = async function getAgentRun({ tenantId = DEFAULT_TENANT_ID, runId } = {}) {
746
+ tenantId = normalizeTenantId(tenantId);
747
+ if (typeof runId !== "string" || runId.trim() === "") throw new TypeError("runId is required");
748
+ return store.agentRuns.get(makeScopedKey({ tenantId, id: String(runId) })) ?? null;
749
+ };
750
+
751
+ store.listAgentRuns = async function listAgentRuns({ tenantId = DEFAULT_TENANT_ID, agentId = null, status = null, limit = 200, offset = 0 } = {}) {
752
+ tenantId = normalizeTenantId(tenantId);
753
+ if (agentId !== null && (typeof agentId !== "string" || agentId.trim() === "")) throw new TypeError("agentId must be null or a non-empty string");
754
+ if (status !== null && (typeof status !== "string" || status.trim() === "")) throw new TypeError("status must be null or a non-empty string");
755
+ if (!Number.isSafeInteger(limit) || limit <= 0) throw new TypeError("limit must be a positive safe integer");
756
+ if (!Number.isSafeInteger(offset) || offset < 0) throw new TypeError("offset must be a non-negative safe integer");
757
+
758
+ const statusFilter = status ? String(status).trim().toLowerCase() : null;
759
+ const safeLimit = Math.min(1000, limit);
760
+ const safeOffset = offset;
761
+ const out = [];
762
+ for (const row of store.agentRuns.values()) {
763
+ if (!row || typeof row !== "object") continue;
764
+ if (normalizeTenantId(row.tenantId ?? DEFAULT_TENANT_ID) !== tenantId) continue;
765
+ if (agentId !== null && String(row.agentId ?? "") !== String(agentId)) continue;
766
+ if (statusFilter !== null && String(row.status ?? "").toLowerCase() !== statusFilter) continue;
767
+ out.push(row);
768
+ }
769
+ out.sort((left, right) => String(left.runId ?? "").localeCompare(String(right.runId ?? "")));
770
+ return out.slice(safeOffset, safeOffset + safeLimit);
771
+ };
772
+
773
+ store.getAgentRunEvents = async function getAgentRunEvents({ tenantId = DEFAULT_TENANT_ID, runId } = {}) {
774
+ tenantId = normalizeTenantId(tenantId);
775
+ if (typeof runId !== "string" || runId.trim() === "") throw new TypeError("runId is required");
776
+ return store.agentRunEvents.get(makeScopedKey({ tenantId, id: String(runId) })) ?? [];
777
+ };
778
+
779
+ store.getAgentRunSettlement = async function getAgentRunSettlement({ tenantId = DEFAULT_TENANT_ID, runId } = {}) {
780
+ tenantId = normalizeTenantId(tenantId);
781
+ if (typeof runId !== "string" || runId.trim() === "") throw new TypeError("runId is required");
782
+ return store.agentRunSettlements.get(makeScopedKey({ tenantId, id: String(runId) })) ?? null;
783
+ };
784
+
785
+ store.getArbitrationCase = async function getArbitrationCase({ tenantId = DEFAULT_TENANT_ID, caseId } = {}) {
786
+ tenantId = normalizeTenantId(tenantId);
787
+ if (typeof caseId !== "string" || caseId.trim() === "") throw new TypeError("caseId is required");
788
+ return store.arbitrationCases.get(makeScopedKey({ tenantId, id: String(caseId) })) ?? null;
789
+ };
790
+
791
+ store.listArbitrationCases = async function listArbitrationCases({
792
+ tenantId = DEFAULT_TENANT_ID,
793
+ runId = null,
794
+ disputeId = null,
795
+ status = null,
796
+ limit = 200,
797
+ offset = 0
798
+ } = {}) {
799
+ tenantId = normalizeTenantId(tenantId);
800
+ if (runId !== null && (typeof runId !== "string" || runId.trim() === "")) throw new TypeError("runId must be null or a non-empty string");
801
+ if (disputeId !== null && (typeof disputeId !== "string" || disputeId.trim() === "")) throw new TypeError("disputeId must be null or a non-empty string");
802
+ if (status !== null && (typeof status !== "string" || status.trim() === "")) throw new TypeError("status must be null or a non-empty string");
803
+ if (!Number.isSafeInteger(limit) || limit <= 0) throw new TypeError("limit must be a positive safe integer");
804
+ if (!Number.isSafeInteger(offset) || offset < 0) throw new TypeError("offset must be a non-negative safe integer");
805
+
806
+ const statusFilter = status ? String(status).trim().toLowerCase() : null;
807
+ const safeLimit = Math.min(1000, limit);
808
+ const safeOffset = offset;
809
+ const out = [];
810
+ for (const row of store.arbitrationCases.values()) {
811
+ if (!row || typeof row !== "object") continue;
812
+ if (normalizeTenantId(row.tenantId ?? DEFAULT_TENANT_ID) !== tenantId) continue;
813
+ if (runId !== null && String(row.runId ?? "") !== String(runId)) continue;
814
+ if (disputeId !== null && String(row.disputeId ?? "") !== String(disputeId)) continue;
815
+ if (statusFilter !== null && String(row.status ?? "").toLowerCase() !== statusFilter) continue;
816
+ out.push(row);
817
+ }
818
+ out.sort((left, right) => String(left.caseId ?? "").localeCompare(String(right.caseId ?? "")));
819
+ return out.slice(safeOffset, safeOffset + safeLimit);
820
+ };
821
+
822
+ function assertNonEmptyString(value, name) {
823
+ if (typeof value !== "string" || value.trim() === "") throw new TypeError(`${name} is required`);
824
+ return value.trim();
825
+ }
826
+
827
+ function normalizeOptionalIso(value) {
828
+ if (value === null || value === undefined) return null;
829
+ const text = String(value).trim();
830
+ if (!text) return null;
831
+ if (!Number.isFinite(Date.parse(text))) throw new TypeError("invalid ISO date-time");
832
+ return new Date(text).toISOString();
833
+ }
834
+
835
+ function moneyRailOperationStoreKey({ tenantId, providerId, operationId }) {
836
+ return `${normalizeTenantId(tenantId)}\n${assertNonEmptyString(providerId, "providerId")}\n${assertNonEmptyString(operationId, "operationId")}`;
837
+ }
838
+
839
+ function moneyRailProviderEventStoreKey({ tenantId, providerId, operationId, eventType, eventDedupeKey }) {
840
+ return `${normalizeTenantId(tenantId)}\n${assertNonEmptyString(providerId, "providerId")}\n${assertNonEmptyString(operationId, "operationId")}\n${assertNonEmptyString(eventType, "eventType")}\n${assertNonEmptyString(eventDedupeKey, "eventDedupeKey")}`;
841
+ }
842
+
843
+ function billableUsageEventStoreKey({ tenantId, eventKey }) {
844
+ return `${normalizeTenantId(tenantId)}\n${assertNonEmptyString(eventKey, "eventKey")}`;
845
+ }
846
+
847
+ function financeReconciliationTriageStoreKey({ tenantId, triageKey }) {
848
+ return `${normalizeTenantId(tenantId)}\n${assertNonEmptyString(triageKey, "triageKey")}`;
849
+ }
850
+
851
+ store.getMoneyRailOperation = async function getMoneyRailOperation({ tenantId = DEFAULT_TENANT_ID, providerId, operationId } = {}) {
852
+ const key = moneyRailOperationStoreKey({ tenantId, providerId, operationId });
853
+ return store.moneyRailOperations.get(key) ?? null;
854
+ };
855
+
856
+ store.findMoneyRailOperationByIdempotency = async function findMoneyRailOperationByIdempotency({
857
+ tenantId = DEFAULT_TENANT_ID,
858
+ providerId,
859
+ direction,
860
+ idempotencyKey
861
+ } = {}) {
862
+ tenantId = normalizeTenantId(tenantId);
863
+ providerId = assertNonEmptyString(providerId, "providerId");
864
+ direction = assertNonEmptyString(direction, "direction").toLowerCase();
865
+ idempotencyKey = assertNonEmptyString(idempotencyKey, "idempotencyKey");
866
+ for (const operation of store.moneyRailOperations.values()) {
867
+ if (!operation || typeof operation !== "object") continue;
868
+ if (normalizeTenantId(operation.tenantId ?? DEFAULT_TENANT_ID) !== tenantId) continue;
869
+ if (String(operation.providerId ?? "") !== providerId) continue;
870
+ if (String(operation.direction ?? "").toLowerCase() !== direction) continue;
871
+ if (String(operation.idempotencyKey ?? "") !== idempotencyKey) continue;
872
+ return operation;
873
+ }
874
+ return null;
875
+ };
876
+
877
+ store.listMoneyRailOperations = async function listMoneyRailOperations({
878
+ tenantId = DEFAULT_TENANT_ID,
879
+ providerId = null,
880
+ direction = null,
881
+ state = null,
882
+ limit = 200,
883
+ offset = 0
884
+ } = {}) {
885
+ tenantId = normalizeTenantId(tenantId);
886
+ if (providerId !== null) providerId = assertNonEmptyString(providerId, "providerId");
887
+ if (direction !== null) direction = assertNonEmptyString(direction, "direction").toLowerCase();
888
+ if (state !== null) state = assertNonEmptyString(state, "state").toLowerCase();
889
+ if (!Number.isSafeInteger(limit) || limit <= 0) throw new TypeError("limit must be a positive safe integer");
890
+ if (!Number.isSafeInteger(offset) || offset < 0) throw new TypeError("offset must be a non-negative safe integer");
891
+
892
+ const out = [];
893
+ for (const operation of store.moneyRailOperations.values()) {
894
+ if (!operation || typeof operation !== "object") continue;
895
+ if (normalizeTenantId(operation.tenantId ?? DEFAULT_TENANT_ID) !== tenantId) continue;
896
+ if (providerId !== null && String(operation.providerId ?? "") !== providerId) continue;
897
+ if (direction !== null && String(operation.direction ?? "").toLowerCase() !== direction) continue;
898
+ if (state !== null && String(operation.state ?? "").toLowerCase() !== state) continue;
899
+ out.push(operation);
900
+ }
901
+ out.sort((left, right) => String(left.operationId ?? "").localeCompare(String(right.operationId ?? "")));
902
+ return out.slice(offset, offset + Math.min(1000, limit));
903
+ };
904
+
905
+ store.putMoneyRailOperation = async function putMoneyRailOperation({
906
+ tenantId = DEFAULT_TENANT_ID,
907
+ providerId,
908
+ operation,
909
+ requestHash = null
910
+ } = {}) {
911
+ tenantId = normalizeTenantId(tenantId);
912
+ providerId = assertNonEmptyString(providerId, "providerId");
913
+ if (!operation || typeof operation !== "object" || Array.isArray(operation)) throw new TypeError("operation is required");
914
+ const operationId = assertNonEmptyString(operation.operationId ?? null, "operation.operationId");
915
+ const direction = assertNonEmptyString(operation.direction ?? null, "operation.direction").toLowerCase();
916
+ const idempotencyKey = assertNonEmptyString(operation.idempotencyKey ?? null, "operation.idempotencyKey");
917
+ const opKey = moneyRailOperationStoreKey({ tenantId, providerId, operationId });
918
+
919
+ for (const existing of store.moneyRailOperations.values()) {
920
+ if (!existing || typeof existing !== "object") continue;
921
+ if (normalizeTenantId(existing.tenantId ?? DEFAULT_TENANT_ID) !== tenantId) continue;
922
+ if (String(existing.providerId ?? "") !== providerId) continue;
923
+ if (String(existing.direction ?? "").toLowerCase() !== direction) continue;
924
+ if (String(existing.idempotencyKey ?? "") !== idempotencyKey) continue;
925
+ if (String(existing.operationId ?? "") !== operationId) {
926
+ const err = new Error("idempotency key was already used with a different operation");
927
+ err.code = "MONEY_RAIL_IDEMPOTENCY_CONFLICT";
928
+ throw err;
929
+ }
930
+ }
931
+
932
+ const existingById = store.moneyRailOperations.get(opKey) ?? null;
933
+ if (existingById && requestHash && existingById.requestHash && String(existingById.requestHash) !== String(requestHash)) {
934
+ const err = new Error("operationId already exists with a different request");
935
+ err.code = "MONEY_RAIL_OPERATION_CONFLICT";
936
+ throw err;
937
+ }
938
+ const next = {
939
+ ...operation,
940
+ tenantId,
941
+ providerId,
942
+ operationId,
943
+ direction,
944
+ idempotencyKey,
945
+ requestHash:
946
+ requestHash && String(requestHash).trim() !== ""
947
+ ? String(requestHash)
948
+ : existingById?.requestHash && String(existingById.requestHash).trim() !== ""
949
+ ? String(existingById.requestHash)
950
+ : null
951
+ };
952
+ store.moneyRailOperations.set(opKey, next);
953
+ return { operation: next, created: !existingById };
954
+ };
955
+
956
+ store.getMoneyRailProviderEvent = async function getMoneyRailProviderEvent({
957
+ tenantId = DEFAULT_TENANT_ID,
958
+ providerId,
959
+ operationId,
960
+ eventType,
961
+ eventDedupeKey
962
+ } = {}) {
963
+ const key = moneyRailProviderEventStoreKey({ tenantId, providerId, operationId, eventType, eventDedupeKey });
964
+ return store.moneyRailProviderEvents.get(key) ?? null;
965
+ };
966
+
967
+ store.putMoneyRailProviderEvent = async function putMoneyRailProviderEvent({
968
+ tenantId = DEFAULT_TENANT_ID,
969
+ providerId,
970
+ operationId,
971
+ event
972
+ } = {}) {
973
+ tenantId = normalizeTenantId(tenantId);
974
+ providerId = assertNonEmptyString(providerId, "providerId");
975
+ operationId = assertNonEmptyString(operationId, "operationId");
976
+ if (!event || typeof event !== "object" || Array.isArray(event)) throw new TypeError("event is required");
977
+ const eventType = assertNonEmptyString(event.eventType ?? null, "event.eventType").toLowerCase();
978
+ const eventDedupeKey = assertNonEmptyString(event.eventDedupeKey ?? null, "event.eventDedupeKey");
979
+ const key = moneyRailProviderEventStoreKey({ tenantId, providerId, operationId, eventType, eventDedupeKey });
980
+ const existing = store.moneyRailProviderEvents.get(key) ?? null;
981
+ if (existing) return { event: existing, created: false };
982
+
983
+ const normalizedEvent = {
984
+ ...event,
985
+ tenantId,
986
+ providerId,
987
+ operationId,
988
+ eventType,
989
+ eventDedupeKey
990
+ };
991
+ store.moneyRailProviderEvents.set(key, normalizedEvent);
992
+ return { event: normalizedEvent, created: true };
993
+ };
994
+
995
+ store.appendBillableUsageEvent = async function appendBillableUsageEvent({ tenantId = DEFAULT_TENANT_ID, event } = {}) {
996
+ tenantId = normalizeTenantId(tenantId);
997
+ if (!event || typeof event !== "object" || Array.isArray(event)) throw new TypeError("event is required");
998
+ const eventKey = assertNonEmptyString(event.eventKey ?? null, "event.eventKey");
999
+ const eventType = assertNonEmptyString(event.eventType ?? null, "event.eventType").toLowerCase();
1000
+ const occurredAt = normalizeOptionalIso(event.occurredAt ?? event.createdAt ?? new Date().toISOString());
1001
+ const period =
1002
+ typeof event.period === "string" && /^\d{4}-\d{2}$/.test(event.period.trim())
1003
+ ? event.period.trim()
1004
+ : String((occurredAt ?? new Date().toISOString()).slice(0, 7));
1005
+ const key = billableUsageEventStoreKey({ tenantId, eventKey });
1006
+ const existing = store.billableUsageEvents.get(key) ?? null;
1007
+ if (existing) {
1008
+ if (event.eventHash && existing.eventHash && String(event.eventHash) !== String(existing.eventHash)) {
1009
+ const err = new Error("billable usage event key already exists with different immutable fields");
1010
+ err.code = "BILLABLE_USAGE_EVENT_CONFLICT";
1011
+ throw err;
1012
+ }
1013
+ return { event: existing, appended: false };
1014
+ }
1015
+
1016
+ const quantityRaw = Number(event.quantity ?? 1);
1017
+ const quantity = Number.isSafeInteger(quantityRaw) && quantityRaw >= 0 ? quantityRaw : 1;
1018
+ const amountRaw = event.amountCents === null || event.amountCents === undefined ? null : Number(event.amountCents);
1019
+ const amountCents = amountRaw === null ? null : Number.isSafeInteger(amountRaw) ? amountRaw : null;
1020
+ const normalized = {
1021
+ ...event,
1022
+ schemaVersion: event.schemaVersion ?? "BillableUsageEvent.v1",
1023
+ tenantId,
1024
+ eventKey,
1025
+ eventType,
1026
+ period,
1027
+ occurredAt: occurredAt ?? new Date().toISOString(),
1028
+ quantity,
1029
+ amountCents,
1030
+ currency:
1031
+ event.currency === null || event.currency === undefined || String(event.currency).trim() === ""
1032
+ ? null
1033
+ : String(event.currency).trim().toUpperCase(),
1034
+ createdAt: normalizeOptionalIso(event.createdAt) ?? new Date().toISOString()
1035
+ };
1036
+ store.billableUsageEvents.set(key, normalized);
1037
+ return { event: normalized, appended: true };
1038
+ };
1039
+
1040
+ store.listBillableUsageEvents = async function listBillableUsageEvents({
1041
+ tenantId = DEFAULT_TENANT_ID,
1042
+ period = null,
1043
+ eventType = null,
1044
+ limit = 200,
1045
+ offset = 0
1046
+ } = {}) {
1047
+ tenantId = normalizeTenantId(tenantId);
1048
+ if (period !== null && (typeof period !== "string" || !/^\d{4}-\d{2}$/.test(period.trim()))) {
1049
+ throw new TypeError("period must match YYYY-MM");
1050
+ }
1051
+ if (eventType !== null) eventType = assertNonEmptyString(eventType, "eventType").toLowerCase();
1052
+ if (!Number.isSafeInteger(limit) || limit <= 0) throw new TypeError("limit must be a positive safe integer");
1053
+ if (!Number.isSafeInteger(offset) || offset < 0) throw new TypeError("offset must be a non-negative safe integer");
1054
+
1055
+ const normalizedPeriod = period ? period.trim() : null;
1056
+ const out = [];
1057
+ for (const row of store.billableUsageEvents.values()) {
1058
+ if (!row || typeof row !== "object") continue;
1059
+ if (normalizeTenantId(row.tenantId ?? DEFAULT_TENANT_ID) !== tenantId) continue;
1060
+ if (normalizedPeriod !== null && String(row.period ?? "") !== normalizedPeriod) continue;
1061
+ if (eventType !== null && String(row.eventType ?? "").toLowerCase() !== eventType) continue;
1062
+ out.push(row);
1063
+ }
1064
+ out.sort(
1065
+ (left, right) =>
1066
+ String(left.occurredAt ?? "").localeCompare(String(right.occurredAt ?? "")) ||
1067
+ String(left.eventKey ?? "").localeCompare(String(right.eventKey ?? ""))
1068
+ );
1069
+ return out.slice(offset, offset + Math.min(1000, limit));
1070
+ };
1071
+
1072
+ store.getFinanceReconciliationTriage = async function getFinanceReconciliationTriage({
1073
+ tenantId = DEFAULT_TENANT_ID,
1074
+ triageKey
1075
+ } = {}) {
1076
+ const key = financeReconciliationTriageStoreKey({ tenantId, triageKey });
1077
+ return store.financeReconciliationTriages.get(key) ?? null;
1078
+ };
1079
+
1080
+ store.putFinanceReconciliationTriage = async function putFinanceReconciliationTriage({
1081
+ tenantId = DEFAULT_TENANT_ID,
1082
+ triage,
1083
+ audit = null
1084
+ } = {}) {
1085
+ tenantId = normalizeTenantId(tenantId);
1086
+ if (!triage || typeof triage !== "object" || Array.isArray(triage)) throw new TypeError("triage is required");
1087
+ const triageKey = assertNonEmptyString(triage.triageKey ?? null, "triage.triageKey");
1088
+ const sourceType = assertNonEmptyString(triage.sourceType ?? null, "triage.sourceType").toLowerCase();
1089
+ const mismatchType = assertNonEmptyString(triage.mismatchType ?? null, "triage.mismatchType");
1090
+ const mismatchKey = assertNonEmptyString(triage.mismatchKey ?? null, "triage.mismatchKey");
1091
+ const period = assertNonEmptyString(triage.period ?? null, "triage.period");
1092
+ const status = assertNonEmptyString(triage.status ?? null, "triage.status").toLowerCase();
1093
+ if (!/^\d{4}-\d{2}$/.test(period)) throw new TypeError("triage.period must match YYYY-MM");
1094
+ const key = financeReconciliationTriageStoreKey({ tenantId, triageKey });
1095
+ const nowAt = typeof store.nowIso === "function" ? store.nowIso() : new Date().toISOString();
1096
+ const existing = store.financeReconciliationTriages.get(key) ?? null;
1097
+ const normalized = {
1098
+ schemaVersion: triage.schemaVersion ?? "FinanceReconciliationTriage.v1",
1099
+ tenantId,
1100
+ triageKey,
1101
+ sourceType,
1102
+ period,
1103
+ providerId:
1104
+ triage.providerId === null || triage.providerId === undefined || String(triage.providerId).trim() === ""
1105
+ ? null
1106
+ : String(triage.providerId).trim(),
1107
+ mismatchType,
1108
+ mismatchKey,
1109
+ mismatchCode:
1110
+ triage.mismatchCode === null || triage.mismatchCode === undefined || String(triage.mismatchCode).trim() === ""
1111
+ ? null
1112
+ : String(triage.mismatchCode).trim(),
1113
+ severity:
1114
+ triage.severity === null || triage.severity === undefined || String(triage.severity).trim() === ""
1115
+ ? null
1116
+ : String(triage.severity).trim().toLowerCase(),
1117
+ status,
1118
+ ownerPrincipalId:
1119
+ triage.ownerPrincipalId === null || triage.ownerPrincipalId === undefined || String(triage.ownerPrincipalId).trim() === ""
1120
+ ? null
1121
+ : String(triage.ownerPrincipalId).trim(),
1122
+ notes:
1123
+ triage.notes === null || triage.notes === undefined || String(triage.notes).trim() === ""
1124
+ ? null
1125
+ : String(triage.notes).trim(),
1126
+ sourceReportHash:
1127
+ triage.sourceReportHash === null || triage.sourceReportHash === undefined || String(triage.sourceReportHash).trim() === ""
1128
+ ? null
1129
+ : String(triage.sourceReportHash).trim(),
1130
+ metadata:
1131
+ triage.metadata && typeof triage.metadata === "object" && !Array.isArray(triage.metadata)
1132
+ ? { ...triage.metadata }
1133
+ : null,
1134
+ actionLog: Array.isArray(triage.actionLog) ? triage.actionLog.slice(0, 50) : existing?.actionLog ?? [],
1135
+ revision:
1136
+ Number.isSafeInteger(triage.revision) && triage.revision > 0
1137
+ ? Number(triage.revision)
1138
+ : Number(existing?.revision ?? 0) + 1,
1139
+ createdAt: normalizeOptionalIso(triage.createdAt) ?? existing?.createdAt ?? nowAt,
1140
+ updatedAt: normalizeOptionalIso(triage.updatedAt) ?? nowAt,
1141
+ resolvedAt: normalizeOptionalIso(triage.resolvedAt) ?? null,
1142
+ resolvedByPrincipalId:
1143
+ triage.resolvedByPrincipalId === null || triage.resolvedByPrincipalId === undefined || String(triage.resolvedByPrincipalId).trim() === ""
1144
+ ? null
1145
+ : String(triage.resolvedByPrincipalId).trim()
1146
+ };
1147
+ store.financeReconciliationTriages.set(key, normalized);
1148
+ if (audit && typeof store.appendOpsAudit === "function") {
1149
+ await store.appendOpsAudit({ tenantId, audit });
1150
+ }
1151
+ return normalized;
1152
+ };
1153
+
1154
+ store.listFinanceReconciliationTriages = async function listFinanceReconciliationTriages({
1155
+ tenantId = DEFAULT_TENANT_ID,
1156
+ period = null,
1157
+ status = null,
1158
+ sourceType = null,
1159
+ providerId = null,
1160
+ limit = 200,
1161
+ offset = 0
1162
+ } = {}) {
1163
+ tenantId = normalizeTenantId(tenantId);
1164
+ if (period !== null && (typeof period !== "string" || !/^\d{4}-\d{2}$/.test(period.trim()))) {
1165
+ throw new TypeError("period must match YYYY-MM");
1166
+ }
1167
+ if (status !== null) status = assertNonEmptyString(status, "status").toLowerCase();
1168
+ if (sourceType !== null) sourceType = assertNonEmptyString(sourceType, "sourceType").toLowerCase();
1169
+ if (providerId !== null) providerId = assertNonEmptyString(providerId, "providerId");
1170
+ if (!Number.isSafeInteger(limit) || limit <= 0) throw new TypeError("limit must be a positive safe integer");
1171
+ if (!Number.isSafeInteger(offset) || offset < 0) throw new TypeError("offset must be a non-negative safe integer");
1172
+
1173
+ const out = [];
1174
+ const normalizedPeriod = period ? period.trim() : null;
1175
+ for (const triage of store.financeReconciliationTriages.values()) {
1176
+ if (!triage || typeof triage !== "object") continue;
1177
+ if (normalizeTenantId(triage.tenantId ?? DEFAULT_TENANT_ID) !== tenantId) continue;
1178
+ if (normalizedPeriod !== null && String(triage.period ?? "") !== normalizedPeriod) continue;
1179
+ if (status !== null && String(triage.status ?? "").toLowerCase() !== status) continue;
1180
+ if (sourceType !== null && String(triage.sourceType ?? "").toLowerCase() !== sourceType) continue;
1181
+ if (providerId !== null && String(triage.providerId ?? "") !== providerId) continue;
1182
+ out.push(triage);
1183
+ }
1184
+ out.sort((left, right) => {
1185
+ const leftMs = Date.parse(String(left?.updatedAt ?? left?.createdAt ?? ""));
1186
+ const rightMs = Date.parse(String(right?.updatedAt ?? right?.createdAt ?? ""));
1187
+ if (Number.isFinite(leftMs) && Number.isFinite(rightMs) && rightMs !== leftMs) return rightMs - leftMs;
1188
+ return String(left?.triageKey ?? "").localeCompare(String(right?.triageKey ?? ""));
1189
+ });
1190
+ return out.slice(offset, offset + Math.min(1000, limit));
1191
+ };
1192
+
1193
+ store.refreshFromDb = async function refreshFromDb() {
1194
+ // No-op for in-memory store.
1195
+ };
1196
+
1197
+ store.listAggregateEvents = async function listAggregateEvents({ tenantId = DEFAULT_TENANT_ID, aggregateType, aggregateId } = {}) {
1198
+ tenantId = normalizeTenantId(tenantId);
1199
+ if (typeof aggregateType !== "string" || aggregateType.trim() === "") throw new TypeError("aggregateType is required");
1200
+ if (typeof aggregateId !== "string" || aggregateId.trim() === "") throw new TypeError("aggregateId is required");
1201
+ const key = makeScopedKey({ tenantId, id: String(aggregateId) });
1202
+ if (aggregateType === "job") return store.jobEvents.get(key) ?? [];
1203
+ if (aggregateType === "robot") return store.robotEvents.get(key) ?? [];
1204
+ if (aggregateType === "operator") return store.operatorEvents.get(key) ?? [];
1205
+ if (aggregateType === "agent_run") return store.agentRunEvents.get(key) ?? [];
1206
+ if (aggregateType === "month") return store.monthEvents.get(key) ?? [];
1207
+ throw new TypeError(`unsupported aggregateType: ${aggregateType}`);
1208
+ };
1209
+
1210
+ store.artifacts = new Map(); // `${tenantId}\n${artifactId}` -> artifact record
1211
+ store.deliveries = new Map(); // `${tenantId}\n${deliveryId}` -> delivery record
1212
+ store.deliveryReceipts = new Map(); // `${tenantId}\n${deliveryId}` -> receipt record
1213
+ store.deliverySeq = 0;
1214
+ store.correlations = new Map(); // `${tenantId}\n${siteId}\n${correlationKey}` -> { jobId, expiresAt, createdAt }
1215
+ store.ingestRecords = new Map(); // `${tenantId}\n${source}\n${externalEventId}` -> record
1216
+ store.authKeys = new Map(); // `${tenantId}\n${keyId}` -> auth key record
1217
+ store.signerKeys = new Map(); // `${tenantId}\n${keyId}` -> signer key record
1218
+ store.opsAudit = new Map(); // `${tenantId}\n${auditId}` -> ops audit record
1219
+ store.opsAuditSeq = 0;
1220
+ store.contractsV2 = new Map(); // `${tenantId}\n${contractId}\n${contractVersion}` -> contract v2 record
1221
+ store.contractSignaturesV2 = new Map(); // `${tenantId}\n${contractHash}\n${partyRole}` -> signature record
1222
+
1223
+ store.putArtifact = async function putArtifact({ tenantId = DEFAULT_TENANT_ID, artifact }) {
1224
+ tenantId = normalizeTenantId(tenantId);
1225
+ if (!artifact || typeof artifact !== "object") throw new TypeError("artifact is required");
1226
+ const artifactId = artifact.artifactId ?? artifact.id ?? null;
1227
+ if (typeof artifactId !== "string" || artifactId.trim() === "") throw new TypeError("artifact.artifactId is required");
1228
+ const artifactType = artifact.artifactType ?? artifact.schemaVersion ?? null;
1229
+ const jobId = artifact.jobId ?? null;
1230
+ const sourceEventIdRaw = artifact.sourceEventId ?? null;
1231
+ const sourceEventId = typeof sourceEventIdRaw === "string" && sourceEventIdRaw.trim() !== "" ? sourceEventIdRaw : null;
1232
+ const key = makeScopedKey({ tenantId, id: String(artifactId) });
1233
+
1234
+ // Invariant: for artifacts tied to a specific source event, there must be exactly one artifact per
1235
+ // (jobId + artifactType + sourceEventId). This prevents duplicate settlement-backed certificates.
1236
+ if (sourceEventId && typeof artifactType === "string" && artifactType.trim() && typeof jobId === "string" && jobId.trim()) {
1237
+ for (const existing of store.artifacts.values()) {
1238
+ if (!existing || typeof existing !== "object") continue;
1239
+ if (normalizeTenantId(existing.tenantId ?? DEFAULT_TENANT_ID) !== tenantId) continue;
1240
+ if (String(existing.jobId ?? "") !== String(jobId)) continue;
1241
+ if (String(existing.artifactType ?? existing.schemaVersion ?? "") !== String(artifactType)) continue;
1242
+ if (String(existing.sourceEventId ?? "") !== String(sourceEventId)) continue;
1243
+
1244
+ const current = existing?.artifactHash ?? null;
1245
+ const next = artifact?.artifactHash ?? null;
1246
+ if (typeof current === "string" && current.trim() && typeof next === "string" && next.trim() && String(current) === String(next)) {
1247
+ return existing;
1248
+ }
1249
+ const err = new Error("artifact already exists for this job/type/sourceEventId with a different hash");
1250
+ err.code = "ARTIFACT_SOURCE_EVENT_CONFLICT";
1251
+ err.existingArtifactId = existing?.artifactId ?? existing?.id ?? null;
1252
+ err.existingArtifactHash = current;
1253
+ err.gotArtifactHash = next;
1254
+ throw err;
1255
+ }
1256
+ }
1257
+
1258
+ const existing = store.artifacts.get(key);
1259
+ if (existing) {
1260
+ const current = existing?.artifactHash ?? null;
1261
+ const next = artifact?.artifactHash ?? null;
1262
+ if (typeof current === "string" && current.trim() && typeof next === "string" && next.trim() && String(current) !== String(next)) {
1263
+ const err = new Error("artifactId already exists with a different hash");
1264
+ err.code = "ARTIFACT_HASH_MISMATCH";
1265
+ err.expectedArtifactHash = String(current);
1266
+ err.gotArtifactHash = String(next);
1267
+ throw err;
1268
+ }
1269
+ return existing;
1270
+ }
1271
+ store.artifacts.set(key, { ...artifact, tenantId, artifactId: String(artifactId) });
1272
+ return store.artifacts.get(key);
1273
+ };
1274
+
1275
+ store.listArtifacts = async function listArtifacts({ tenantId = DEFAULT_TENANT_ID, jobId = null, jobIds = null, artifactType = null, sourceEventId = null } = {}) {
1276
+ tenantId = normalizeTenantId(tenantId);
1277
+ let jobIdSet = null;
1278
+ if (jobIds !== null && jobIds !== undefined) {
1279
+ if (!Array.isArray(jobIds)) throw new TypeError("jobIds must be null or an array");
1280
+ jobIdSet = new Set();
1281
+ for (const item of jobIds) {
1282
+ if (typeof item !== "string" || item.trim() === "") throw new TypeError("jobIds[] must be non-empty strings");
1283
+ jobIdSet.add(String(item));
1284
+ }
1285
+ }
1286
+ const all = [];
1287
+ const sourceFilter = typeof sourceEventId === "string" && sourceEventId.trim() !== "" ? String(sourceEventId) : null;
1288
+ const typeFilter = typeof artifactType === "string" && artifactType.trim() !== "" ? String(artifactType) : null;
1289
+ for (const art of store.artifacts.values()) {
1290
+ if (!art || typeof art !== "object") continue;
1291
+ if (normalizeTenantId(art.tenantId ?? DEFAULT_TENANT_ID) !== tenantId) continue;
1292
+ if (jobId !== null && String(art.jobId ?? "") !== String(jobId)) continue;
1293
+ if (jobIdSet && !jobIdSet.has(String(art.jobId ?? ""))) continue;
1294
+ if (typeFilter !== null && String(art.artifactType ?? art.schemaVersion ?? "") !== typeFilter) continue;
1295
+ if (sourceFilter !== null && String(art.sourceEventId ?? "") !== sourceFilter) continue;
1296
+ all.push(art);
1297
+ }
1298
+ all.sort((a, b) => String(a.artifactId ?? "").localeCompare(String(b.artifactId ?? "")));
1299
+ return all;
1300
+ };
1301
+
1302
+ store.getArtifact = async function getArtifact({ tenantId = DEFAULT_TENANT_ID, artifactId }) {
1303
+ tenantId = normalizeTenantId(tenantId);
1304
+ if (typeof artifactId !== "string" || artifactId.trim() === "") throw new TypeError("artifactId is required");
1305
+ const key = makeScopedKey({ tenantId, id: String(artifactId) });
1306
+ return store.artifacts.get(key) ?? null;
1307
+ };
1308
+
1309
+ store.createDelivery = async function createDelivery({ tenantId = DEFAULT_TENANT_ID, delivery }) {
1310
+ tenantId = normalizeTenantId(tenantId);
1311
+ if (!delivery || typeof delivery !== "object") throw new TypeError("delivery is required");
1312
+ const dedupeKey = delivery.dedupeKey ?? null;
1313
+ if (typeof dedupeKey !== "string" || dedupeKey.trim() === "") throw new TypeError("delivery.dedupeKey is required");
1314
+
1315
+ // Enforce dedupe per-tenant.
1316
+ for (const existing of store.deliveries.values()) {
1317
+ if (!existing || typeof existing !== "object") continue;
1318
+ if (normalizeTenantId(existing.tenantId ?? DEFAULT_TENANT_ID) !== tenantId) continue;
1319
+ if (String(existing.dedupeKey ?? "") === dedupeKey) return existing;
1320
+ }
1321
+
1322
+ const cfg = typeof store.getConfig === "function" ? store.getConfig(tenantId) : store.config;
1323
+ const requestedLimit = cfg?.quotas?.maxPendingDeliveries ?? 0;
1324
+ const quota = clampQuota({
1325
+ tenantLimit: Number.isSafeInteger(requestedLimit) ? requestedLimit : 0,
1326
+ defaultLimit: 0,
1327
+ maxLimit: platformMaxPendingDeliveries
1328
+ });
1329
+ if (quota > 0) {
1330
+ let pending = 0;
1331
+ for (const d of store.deliveries.values()) {
1332
+ if (!d || typeof d !== "object") continue;
1333
+ if (normalizeTenantId(d.tenantId ?? DEFAULT_TENANT_ID) !== tenantId) continue;
1334
+ if (d.state !== "pending") continue;
1335
+ pending += 1;
1336
+ if (pending >= quota) break;
1337
+ }
1338
+ if (pending >= quota) {
1339
+ const err = new Error("tenant quota exceeded");
1340
+ err.code = "TENANT_QUOTA_EXCEEDED";
1341
+ err.quota = { kind: "pending_deliveries", limit: quota, current: pending };
1342
+ throw err;
1343
+ }
1344
+ }
1345
+
1346
+ store.deliverySeq += 1;
1347
+ const deliveryId = `dlv_${store.deliverySeq}`;
1348
+ const nowAt = typeof store.nowIso === "function" ? store.nowIso() : new Date().toISOString();
1349
+ const scopeKey = delivery.scopeKey !== undefined && delivery.scopeKey !== null ? String(delivery.scopeKey) : "";
1350
+ const orderSeq = Number.isSafeInteger(delivery.orderSeq) ? delivery.orderSeq : 0;
1351
+ const priority = Number.isSafeInteger(delivery.priority) ? delivery.priority : 0;
1352
+ const orderKey = `${scopeKey}\n${String(orderSeq)}\n${String(priority)}\n${deliveryId}`;
1353
+ const record = {
1354
+ deliveryId,
1355
+ tenantId,
1356
+ createdAt: nowAt,
1357
+ state: "pending",
1358
+ attempts: 0,
1359
+ nextAttemptAt: nowAt,
1360
+ claimedAt: null,
1361
+ worker: null,
1362
+ lastStatus: null,
1363
+ lastError: null,
1364
+ deliveredAt: null,
1365
+ ackedAt: null,
1366
+ ackReceivedAt: null,
1367
+ ackArtifactHash: null,
1368
+ expiresAt: null,
1369
+ scopeKey,
1370
+ orderSeq,
1371
+ priority,
1372
+ orderKey,
1373
+ ...delivery
1374
+ };
1375
+ store.deliveries.set(makeScopedKey({ tenantId, id: deliveryId }), record);
1376
+ return record;
1377
+ };
1378
+
1379
+ store.listDeliveries = async function listDeliveries({ tenantId = DEFAULT_TENANT_ID, state = null, limit = 200, offset = 0 } = {}) {
1380
+ tenantId = normalizeTenantId(tenantId);
1381
+ if (state !== null && (typeof state !== "string" || state.trim() === "")) throw new TypeError("state must be null or a non-empty string");
1382
+ if (!Number.isSafeInteger(limit) || limit <= 0) throw new TypeError("limit must be a positive safe integer");
1383
+ if (!Number.isSafeInteger(offset) || offset < 0) throw new TypeError("offset must be a non-negative safe integer");
1384
+
1385
+ const all = [];
1386
+ for (const d of store.deliveries.values()) {
1387
+ if (!d || typeof d !== "object") continue;
1388
+ if (normalizeTenantId(d.tenantId ?? DEFAULT_TENANT_ID) !== tenantId) continue;
1389
+ if (state !== null && d.state !== state) continue;
1390
+ all.push(d);
1391
+ }
1392
+ all.sort((a, b) => String(a.deliveryId ?? "").localeCompare(String(b.deliveryId ?? "")));
1393
+ return all.slice(offset, offset + Math.min(1000, limit));
1394
+ };
1395
+
1396
+ store.requeueDelivery = async function requeueDelivery({ tenantId = DEFAULT_TENANT_ID, deliveryId }) {
1397
+ tenantId = normalizeTenantId(tenantId);
1398
+ if (typeof deliveryId !== "string" || deliveryId.trim() === "") throw new TypeError("deliveryId is required");
1399
+ const key = makeScopedKey({ tenantId, id: deliveryId });
1400
+ const existing = store.deliveries.get(key);
1401
+ if (!existing) return null;
1402
+ const now = typeof store.nowIso === "function" ? store.nowIso() : new Date().toISOString();
1403
+ const next = {
1404
+ ...existing,
1405
+ state: "pending",
1406
+ attempts: 0,
1407
+ nextAttemptAt: now,
1408
+ claimedAt: null,
1409
+ worker: null,
1410
+ lastStatus: null,
1411
+ lastError: null,
1412
+ deliveredAt: null,
1413
+ ackedAt: null,
1414
+ ackReceivedAt: null,
1415
+ ackArtifactHash: null,
1416
+ expiresAt: null,
1417
+ updatedAt: now
1418
+ };
1419
+ store.deliveries.set(key, next);
1420
+ return next;
1421
+ };
1422
+
1423
+ store.ackDelivery = async function ackDelivery({
1424
+ tenantId = DEFAULT_TENANT_ID,
1425
+ deliveryId,
1426
+ destinationId = null,
1427
+ artifactHash = null,
1428
+ receivedAt = null,
1429
+ nowIso = typeof store.nowIso === "function" ? store.nowIso : () => new Date().toISOString()
1430
+ } = {}) {
1431
+ tenantId = normalizeTenantId(tenantId);
1432
+ if (typeof deliveryId !== "string" || deliveryId.trim() === "") throw new TypeError("deliveryId is required");
1433
+ const key = makeScopedKey({ tenantId, id: deliveryId });
1434
+ const delivery = store.deliveries.get(key) ?? null;
1435
+ if (!delivery) return null;
1436
+ if (destinationId !== null && String(delivery.destinationId ?? "") !== String(destinationId)) {
1437
+ throw new TypeError("delivery destinationId mismatch");
1438
+ }
1439
+ if (artifactHash !== null && String(delivery.artifactHash ?? "") !== String(artifactHash)) {
1440
+ throw new TypeError("delivery artifactHash mismatch");
1441
+ }
1442
+
1443
+ if (delivery.ackedAt) {
1444
+ const existingReceipt = store.deliveryReceipts.get(key) ?? null;
1445
+ return { delivery, receipt: existingReceipt };
1446
+ }
1447
+
1448
+ const ackedAt = nowIso();
1449
+ const receipt = {
1450
+ tenantId,
1451
+ deliveryId,
1452
+ destinationId: delivery.destinationId ?? null,
1453
+ artifactId: delivery.artifactId ?? null,
1454
+ artifactHash: delivery.artifactHash ?? null,
1455
+ receivedAt: receivedAt ?? null,
1456
+ ackedAt
1457
+ };
1458
+ const next = {
1459
+ ...delivery,
1460
+ ackedAt,
1461
+ ackReceivedAt: receivedAt ?? null,
1462
+ ackArtifactHash: delivery.artifactHash ?? null,
1463
+ updatedAt: ackedAt
1464
+ };
1465
+ store.deliveries.set(key, next);
1466
+ store.deliveryReceipts.set(key, receipt);
1467
+ return { delivery: next, receipt };
1468
+ };
1469
+
1470
+ store.lookupCorrelation = async function lookupCorrelation({
1471
+ tenantId = DEFAULT_TENANT_ID,
1472
+ siteId,
1473
+ correlationKey,
1474
+ nowIso = typeof store.nowIso === "function" ? store.nowIso : () => new Date().toISOString()
1475
+ }) {
1476
+ tenantId = normalizeTenantId(tenantId);
1477
+ if (typeof siteId !== "string" || siteId.trim() === "") throw new TypeError("siteId is required");
1478
+ if (typeof correlationKey !== "string" || correlationKey.trim() === "") throw new TypeError("correlationKey is required");
1479
+ const key = `${tenantId}\n${siteId}\n${correlationKey}`;
1480
+ const row = store.correlations.get(key) ?? null;
1481
+ if (!row) return null;
1482
+ if (row.expiresAt) {
1483
+ const nowMs = Date.parse(nowIso());
1484
+ const expMs = Date.parse(row.expiresAt);
1485
+ if (Number.isFinite(nowMs) && Number.isFinite(expMs) && nowMs >= expMs) return null;
1486
+ }
1487
+ return { jobId: row.jobId, expiresAt: row.expiresAt ?? null };
1488
+ };
1489
+
1490
+ store.upsertCorrelation = async function upsertCorrelation({
1491
+ tenantId = DEFAULT_TENANT_ID,
1492
+ siteId,
1493
+ correlationKey,
1494
+ jobId,
1495
+ expiresAt = null,
1496
+ force = false
1497
+ }) {
1498
+ tenantId = normalizeTenantId(tenantId);
1499
+ if (typeof siteId !== "string" || siteId.trim() === "") throw new TypeError("siteId is required");
1500
+ if (typeof correlationKey !== "string" || correlationKey.trim() === "") throw new TypeError("correlationKey is required");
1501
+ if (typeof jobId !== "string" || jobId.trim() === "") throw new TypeError("jobId is required");
1502
+ const key = `${tenantId}\n${siteId}\n${correlationKey}`;
1503
+ const existing = store.correlations.get(key);
1504
+ if (existing && existing.jobId !== jobId && !force) {
1505
+ const err = new Error("correlation key already linked to a different job");
1506
+ err.code = "CORRELATION_CONFLICT";
1507
+ err.existingJobId = existing.jobId;
1508
+ throw err;
1509
+ }
1510
+ store.correlations.set(key, { tenantId, siteId, correlationKey, jobId, expiresAt, createdAt: existing?.createdAt ?? new Date().toISOString() });
1511
+ return { jobId, expiresAt };
1512
+ };
1513
+
1514
+ store.listCorrelations = async function listCorrelations({ tenantId = DEFAULT_TENANT_ID, siteId = null, jobId = null, limit = 200, offset = 0 } = {}) {
1515
+ tenantId = normalizeTenantId(tenantId);
1516
+ if (siteId !== null && (typeof siteId !== "string" || siteId.trim() === "")) throw new TypeError("siteId must be null or a non-empty string");
1517
+ if (jobId !== null && (typeof jobId !== "string" || jobId.trim() === "")) throw new TypeError("jobId must be null or a non-empty string");
1518
+ if (!Number.isSafeInteger(limit) || limit <= 0) throw new TypeError("limit must be a positive safe integer");
1519
+ if (!Number.isSafeInteger(offset) || offset < 0) throw new TypeError("offset must be a non-negative safe integer");
1520
+ const safeLimit = Math.min(1000, limit);
1521
+ const safeOffset = offset;
1522
+
1523
+ const all = [];
1524
+ for (const row of store.correlations.values()) {
1525
+ if (!row || typeof row !== "object") continue;
1526
+ if (normalizeTenantId(row.tenantId ?? DEFAULT_TENANT_ID) !== tenantId) continue;
1527
+ if (siteId !== null && String(row.siteId ?? "") !== siteId) continue;
1528
+ if (jobId !== null && String(row.jobId ?? "") !== jobId) continue;
1529
+ all.push(row);
1530
+ }
1531
+ all.sort((a, b) => String(a.siteId ?? "").localeCompare(String(b.siteId ?? "")) || String(a.correlationKey ?? "").localeCompare(String(b.correlationKey ?? "")));
1532
+ return all.slice(safeOffset, safeOffset + safeLimit);
1533
+ };
1534
+
1535
+ store.getIngestRecord = async function getIngestRecord({ tenantId = DEFAULT_TENANT_ID, source, externalEventId } = {}) {
1536
+ tenantId = normalizeTenantId(tenantId);
1537
+ if (typeof source !== "string" || source.trim() === "") throw new TypeError("source is required");
1538
+ if (typeof externalEventId !== "string" || externalEventId.trim() === "") throw new TypeError("externalEventId is required");
1539
+ return store.ingestRecords.get(`${tenantId}\n${source}\n${externalEventId}`) ?? null;
1540
+ };
1541
+
1542
+ store.putIngestRecords = async function putIngestRecords({ tenantId = DEFAULT_TENANT_ID, records } = {}) {
1543
+ tenantId = normalizeTenantId(tenantId);
1544
+ if (!Array.isArray(records)) throw new TypeError("records must be an array");
1545
+ for (const r of records) {
1546
+ if (!r || typeof r !== "object") continue;
1547
+ const source = r.source ?? null;
1548
+ const externalEventId = r.externalEventId ?? null;
1549
+ if (typeof source !== "string" || source.trim() === "") continue;
1550
+ if (typeof externalEventId !== "string" || externalEventId.trim() === "") continue;
1551
+ const key = `${tenantId}\n${String(source)}\n${String(externalEventId)}`;
1552
+ if (store.ingestRecords.has(key)) continue;
1553
+ store.ingestRecords.set(key, { ...r, tenantId, source: String(source), externalEventId: String(externalEventId) });
1554
+ }
1555
+ };
1556
+
1557
+ store.listIngestRecords = async function listIngestRecords({
1558
+ tenantId = DEFAULT_TENANT_ID,
1559
+ status = null,
1560
+ source = null,
1561
+ limit = 200,
1562
+ offset = 0
1563
+ } = {}) {
1564
+ tenantId = normalizeTenantId(tenantId);
1565
+ if (status !== null && (typeof status !== "string" || status.trim() === "")) throw new TypeError("status must be null or a non-empty string");
1566
+ if (source !== null && (typeof source !== "string" || source.trim() === "")) throw new TypeError("source must be null or a non-empty string");
1567
+ if (!Number.isSafeInteger(limit) || limit <= 0) throw new TypeError("limit must be a positive safe integer");
1568
+ if (!Number.isSafeInteger(offset) || offset < 0) throw new TypeError("offset must be a non-negative safe integer");
1569
+
1570
+ const safeLimit = Math.min(1000, limit);
1571
+ const safeOffset = offset;
1572
+ const all = [];
1573
+ for (const r of store.ingestRecords.values()) {
1574
+ if (!r || typeof r !== "object") continue;
1575
+ if (normalizeTenantId(r.tenantId ?? DEFAULT_TENANT_ID) !== tenantId) continue;
1576
+ if (status !== null && String(r.status ?? "") !== status) continue;
1577
+ if (source !== null && String(r.source ?? "") !== source) continue;
1578
+ all.push(r);
1579
+ }
1580
+ all.sort((a, b) => String(b.receivedAt ?? "").localeCompare(String(a.receivedAt ?? "")));
1581
+ return all.slice(safeOffset, safeOffset + safeLimit);
1582
+ };
1583
+
1584
+ store.getAuthKey = async function getAuthKey({ tenantId = DEFAULT_TENANT_ID, keyId } = {}) {
1585
+ tenantId = normalizeTenantId(tenantId);
1586
+ if (typeof keyId !== "string" || keyId.trim() === "") throw new TypeError("keyId is required");
1587
+ const key = makeScopedKey({ tenantId, id: String(keyId) });
1588
+ return store.authKeys.get(key) ?? null;
1589
+ };
1590
+
1591
+ store.putAuthKey = async function putAuthKey({ tenantId = DEFAULT_TENANT_ID, authKey, audit = null } = {}) {
1592
+ tenantId = normalizeTenantId(tenantId);
1593
+ if (!authKey || typeof authKey !== "object") throw new TypeError("authKey is required");
1594
+ const keyId = authKey.keyId ?? authKey.id ?? null;
1595
+ if (typeof keyId !== "string" || keyId.trim() === "") throw new TypeError("authKey.keyId is required");
1596
+ const secretHash = authKey.secretHash ?? null;
1597
+ if (typeof secretHash !== "string" || secretHash.trim() === "") throw new TypeError("authKey.secretHash is required");
1598
+
1599
+ const nowAt = typeof store.nowIso === "function" ? store.nowIso() : new Date().toISOString();
1600
+ const scopes = normalizeScopes(authKey.scopes ?? []);
1601
+ const status = typeof authKey.status === "string" && authKey.status.trim() ? String(authKey.status).trim().toLowerCase() : "active";
1602
+
1603
+ store.ensureTenant(tenantId);
1604
+ await store.commitTx({
1605
+ at: nowAt,
1606
+ ops: [
1607
+ {
1608
+ kind: "AUTH_KEY_UPSERT",
1609
+ tenantId,
1610
+ authKey: {
1611
+ tenantId,
1612
+ keyId: String(keyId),
1613
+ secretHash: String(secretHash),
1614
+ scopes,
1615
+ status,
1616
+ description: authKey.description ?? null,
1617
+ expiresAt: authKey.expiresAt ?? null,
1618
+ createdAt: authKey.createdAt ?? nowAt,
1619
+ updatedAt: nowAt,
1620
+ lastUsedAt: authKey.lastUsedAt ?? null,
1621
+ rotatedAt: authKey.rotatedAt ?? null,
1622
+ revokedAt: authKey.revokedAt ?? null
1623
+ }
1624
+ }
1625
+ ],
1626
+ audit
1627
+ });
1628
+
1629
+ return store.getAuthKey({ tenantId, keyId: String(keyId) });
1630
+ };
1631
+
1632
+ store.touchAuthKey = async function touchAuthKey({ tenantId = DEFAULT_TENANT_ID, keyId, at = null } = {}) {
1633
+ tenantId = normalizeTenantId(tenantId);
1634
+ if (typeof keyId !== "string" || keyId.trim() === "") throw new TypeError("keyId is required");
1635
+ const nowAt = at ?? (typeof store.nowIso === "function" ? store.nowIso() : new Date().toISOString());
1636
+ const key = makeScopedKey({ tenantId, id: String(keyId) });
1637
+ const existing = store.authKeys.get(key);
1638
+ if (!existing) return false;
1639
+ store.authKeys.set(key, { ...existing, lastUsedAt: nowAt, updatedAt: nowAt });
1640
+ return true;
1641
+ };
1642
+
1643
+ store.setAuthKeyStatus = async function setAuthKeyStatus({ tenantId = DEFAULT_TENANT_ID, keyId, status, at = null, audit = null } = {}) {
1644
+ tenantId = normalizeTenantId(tenantId);
1645
+ if (typeof keyId !== "string" || keyId.trim() === "") throw new TypeError("keyId is required");
1646
+ if (typeof status !== "string" || status.trim() === "") throw new TypeError("status is required");
1647
+ const nowAt = at ?? (typeof store.nowIso === "function" ? store.nowIso() : new Date().toISOString());
1648
+ await store.commitTx({
1649
+ at: nowAt,
1650
+ ops: [
1651
+ {
1652
+ kind: "AUTH_KEY_STATUS_SET",
1653
+ tenantId,
1654
+ keyId: String(keyId),
1655
+ status: String(status).trim().toLowerCase(),
1656
+ rotatedAt: status === "rotated" ? nowAt : undefined,
1657
+ revokedAt: status === "revoked" ? nowAt : undefined
1658
+ }
1659
+ ],
1660
+ audit
1661
+ });
1662
+ return store.getAuthKey({ tenantId, keyId: String(keyId) });
1663
+ };
1664
+
1665
+ store.rotateAuthKey = async function rotateAuthKey({
1666
+ tenantId = DEFAULT_TENANT_ID,
1667
+ oldKeyId,
1668
+ newAuthKey,
1669
+ rotatedAt = null,
1670
+ audit = null
1671
+ } = {}) {
1672
+ tenantId = normalizeTenantId(tenantId);
1673
+ if (typeof oldKeyId !== "string" || oldKeyId.trim() === "") throw new TypeError("oldKeyId is required");
1674
+ if (!newAuthKey || typeof newAuthKey !== "object") throw new TypeError("newAuthKey is required");
1675
+ const newKeyId = newAuthKey.keyId ?? newAuthKey.id ?? null;
1676
+ if (typeof newKeyId !== "string" || newKeyId.trim() === "") throw new TypeError("newAuthKey.keyId is required");
1677
+ const secretHash = newAuthKey.secretHash ?? null;
1678
+ if (typeof secretHash !== "string" || secretHash.trim() === "") throw new TypeError("newAuthKey.secretHash is required");
1679
+
1680
+ const nowAt = rotatedAt ?? (typeof store.nowIso === "function" ? store.nowIso() : new Date().toISOString());
1681
+ const existing = await store.getAuthKey({ tenantId, keyId: String(oldKeyId) });
1682
+ if (!existing) return null;
1683
+ if (existing.status === "revoked") {
1684
+ const err = new Error("auth key is revoked");
1685
+ err.code = "AUTH_KEY_REVOKED";
1686
+ throw err;
1687
+ }
1688
+
1689
+ const scopes = normalizeScopes(newAuthKey.scopes ?? existing.scopes ?? []);
1690
+ const expiresAt = newAuthKey.expiresAt ?? existing.expiresAt ?? null;
1691
+ const description = newAuthKey.description ?? existing.description ?? null;
1692
+
1693
+ await store.commitTx({
1694
+ at: nowAt,
1695
+ ops: [
1696
+ { kind: "AUTH_KEY_STATUS_SET", tenantId, keyId: String(oldKeyId), status: "rotated", rotatedAt: nowAt },
1697
+ {
1698
+ kind: "AUTH_KEY_UPSERT",
1699
+ tenantId,
1700
+ authKey: {
1701
+ tenantId,
1702
+ keyId: String(newKeyId),
1703
+ secretHash: String(secretHash),
1704
+ scopes,
1705
+ status: "active",
1706
+ description,
1707
+ expiresAt,
1708
+ createdAt: nowAt,
1709
+ updatedAt: nowAt,
1710
+ lastUsedAt: null,
1711
+ rotatedAt: null,
1712
+ revokedAt: null
1713
+ }
1714
+ }
1715
+ ],
1716
+ audit
1717
+ });
1718
+
1719
+ return {
1720
+ rotatedAt: nowAt,
1721
+ oldKeyId: String(oldKeyId),
1722
+ newKeyId: String(newKeyId),
1723
+ oldKey: await store.getAuthKey({ tenantId, keyId: String(oldKeyId) }),
1724
+ newKey: await store.getAuthKey({ tenantId, keyId: String(newKeyId) })
1725
+ };
1726
+ };
1727
+
1728
+ store.listAuthKeys = async function listAuthKeys({ tenantId = DEFAULT_TENANT_ID } = {}) {
1729
+ tenantId = normalizeTenantId(tenantId);
1730
+ const all = [];
1731
+ for (const v of store.authKeys.values()) {
1732
+ if (!v || typeof v !== "object") continue;
1733
+ if (normalizeTenantId(v.tenantId ?? DEFAULT_TENANT_ID) !== tenantId) continue;
1734
+ all.push(v);
1735
+ }
1736
+ all.sort((a, b) => String(a.keyId ?? "").localeCompare(String(b.keyId ?? "")));
1737
+ return all;
1738
+ };
1739
+
1740
+ store.appendOpsAudit = async function appendOpsAudit({ tenantId = DEFAULT_TENANT_ID, audit }) {
1741
+ tenantId = normalizeTenantId(tenantId);
1742
+ if (!audit || typeof audit !== "object") throw new TypeError("audit is required");
1743
+ const nowAt = typeof store.nowIso === "function" ? store.nowIso() : new Date().toISOString();
1744
+
1745
+ store.ensureTenant(tenantId);
1746
+ store.opsAuditSeq += 1;
1747
+ const id = store.opsAuditSeq;
1748
+ const record = { ...audit, id, tenantId, at: audit?.at ?? nowAt };
1749
+ await store.commitTx({ at: nowAt, ops: [{ kind: "OPS_AUDIT_APPEND", tenantId, audit: record }] });
1750
+ return record;
1751
+ };
1752
+
1753
+ store.listOpsAudit = async function listOpsAudit({ tenantId = DEFAULT_TENANT_ID, limit = 200, offset = 0 } = {}) {
1754
+ tenantId = normalizeTenantId(tenantId);
1755
+ if (!Number.isSafeInteger(limit) || limit <= 0) throw new TypeError("limit must be a positive safe integer");
1756
+ if (!Number.isSafeInteger(offset) || offset < 0) throw new TypeError("offset must be a non-negative safe integer");
1757
+ const safeLimit = Math.min(1000, limit);
1758
+ const safeOffset = offset;
1759
+
1760
+ const all = [];
1761
+ for (const row of store.opsAudit.values()) {
1762
+ if (!row || typeof row !== "object") continue;
1763
+ if (normalizeTenantId(row.tenantId ?? DEFAULT_TENANT_ID) !== tenantId) continue;
1764
+ all.push(row);
1765
+ }
1766
+ all.sort((a, b) => Number(b.id ?? 0) - Number(a.id ?? 0));
1767
+ return all.slice(safeOffset, safeOffset + safeLimit);
1768
+ };
1769
+
1770
+ store.getSignerKey = async function getSignerKey({ tenantId = DEFAULT_TENANT_ID, keyId } = {}) {
1771
+ tenantId = normalizeTenantId(tenantId);
1772
+ if (typeof keyId !== "string" || keyId.trim() === "") throw new TypeError("keyId is required");
1773
+ const key = makeScopedKey({ tenantId, id: String(keyId) });
1774
+ return store.signerKeys.get(key) ?? null;
1775
+ };
1776
+
1777
+ store.putSignerKey = async function putSignerKey({ tenantId = DEFAULT_TENANT_ID, signerKey, audit = null } = {}) {
1778
+ tenantId = normalizeTenantId(tenantId);
1779
+ if (!signerKey || typeof signerKey !== "object") throw new TypeError("signerKey is required");
1780
+ const keyId = signerKey.keyId ?? signerKey.id ?? null;
1781
+ if (typeof keyId !== "string" || keyId.trim() === "") throw new TypeError("signerKey.keyId is required");
1782
+ const publicKeyPem = signerKey.publicKeyPem ?? null;
1783
+ if (typeof publicKeyPem !== "string" || publicKeyPem.trim() === "") throw new TypeError("signerKey.publicKeyPem is required");
1784
+ const purpose = normalizeSignerKeyPurpose(signerKey.purpose ?? "server");
1785
+ const status = normalizeSignerKeyStatus(signerKey.status ?? "active");
1786
+
1787
+ const nowAt = typeof store.nowIso === "function" ? store.nowIso() : new Date().toISOString();
1788
+ await store.commitTx({
1789
+ at: nowAt,
1790
+ ops: [
1791
+ {
1792
+ kind: "SIGNER_KEY_UPSERT",
1793
+ tenantId,
1794
+ signerKey: {
1795
+ tenantId,
1796
+ keyId: String(keyId),
1797
+ publicKeyPem: String(publicKeyPem),
1798
+ purpose,
1799
+ status,
1800
+ description: signerKey.description ?? null,
1801
+ validFrom: signerKey.validFrom ?? null,
1802
+ validTo: signerKey.validTo ?? null,
1803
+ createdAt: signerKey.createdAt ?? nowAt,
1804
+ updatedAt: nowAt,
1805
+ lastUsedAt: signerKey.lastUsedAt ?? null,
1806
+ rotatedAt: signerKey.rotatedAt ?? null,
1807
+ revokedAt: signerKey.revokedAt ?? null
1808
+ }
1809
+ }
1810
+ ],
1811
+ audit
1812
+ });
1813
+
1814
+ return store.getSignerKey({ tenantId, keyId: String(keyId) });
1815
+ };
1816
+
1817
+ store.setSignerKeyStatus = async function setSignerKeyStatus({ tenantId = DEFAULT_TENANT_ID, keyId, status, at = null, audit = null } = {}) {
1818
+ tenantId = normalizeTenantId(tenantId);
1819
+ if (typeof keyId !== "string" || keyId.trim() === "") throw new TypeError("keyId is required");
1820
+ const normalizedStatus = normalizeSignerKeyStatus(status);
1821
+ const nowAt = at ?? (typeof store.nowIso === "function" ? store.nowIso() : new Date().toISOString());
1822
+ await store.commitTx({
1823
+ at: nowAt,
1824
+ ops: [
1825
+ {
1826
+ kind: "SIGNER_KEY_STATUS_SET",
1827
+ tenantId,
1828
+ keyId: String(keyId),
1829
+ status: normalizedStatus,
1830
+ rotatedAt: normalizedStatus === "rotated" ? nowAt : undefined,
1831
+ revokedAt: normalizedStatus === "revoked" ? nowAt : undefined
1832
+ }
1833
+ ],
1834
+ audit
1835
+ });
1836
+ return store.getSignerKey({ tenantId, keyId: String(keyId) });
1837
+ };
1838
+
1839
+ store.listSignerKeys = async function listSignerKeys({ tenantId = DEFAULT_TENANT_ID } = {}) {
1840
+ tenantId = normalizeTenantId(tenantId);
1841
+ const all = [];
1842
+ for (const v of store.signerKeys.values()) {
1843
+ if (!v || typeof v !== "object") continue;
1844
+ if (normalizeTenantId(v.tenantId ?? DEFAULT_TENANT_ID) !== tenantId) continue;
1845
+ all.push(v);
1846
+ }
1847
+ all.sort((a, b) => String(a.keyId ?? "").localeCompare(String(b.keyId ?? "")));
1848
+ return all;
1849
+ };
1850
+
1851
+ store.getContractV2 = async function getContractV2({ tenantId = DEFAULT_TENANT_ID, contractId, contractVersion } = {}) {
1852
+ tenantId = normalizeTenantId(tenantId);
1853
+ if (typeof contractId !== "string" || contractId.trim() === "") throw new TypeError("contractId is required");
1854
+ const v = Number(contractVersion);
1855
+ if (!Number.isSafeInteger(v) || v <= 0) throw new TypeError("contractVersion must be a positive safe integer");
1856
+ const key = `${tenantId}\n${String(contractId)}\n${String(v)}`;
1857
+ return store.contractsV2.get(key) ?? null;
1858
+ };
1859
+
1860
+ store.getContractV2ByHash = async function getContractV2ByHash({ tenantId = DEFAULT_TENANT_ID, contractHash } = {}) {
1861
+ tenantId = normalizeTenantId(tenantId);
1862
+ if (typeof contractHash !== "string" || contractHash.trim() === "") throw new TypeError("contractHash is required");
1863
+ for (const c of store.contractsV2.values()) {
1864
+ if (!c || typeof c !== "object") continue;
1865
+ if (normalizeTenantId(c.tenantId ?? DEFAULT_TENANT_ID) !== tenantId) continue;
1866
+ if (String(c.contractHash ?? "") !== String(contractHash)) continue;
1867
+ return c;
1868
+ }
1869
+ return null;
1870
+ };
1871
+
1872
+ store.listContractsV2 = async function listContractsV2({ tenantId = DEFAULT_TENANT_ID, status = null, limit = 200, offset = 0 } = {}) {
1873
+ tenantId = normalizeTenantId(tenantId);
1874
+ if (status !== null && (typeof status !== "string" || status.trim() === "")) throw new TypeError("status must be null or non-empty string");
1875
+ if (!Number.isSafeInteger(limit) || limit <= 0) throw new TypeError("limit must be a positive safe integer");
1876
+ if (!Number.isSafeInteger(offset) || offset < 0) throw new TypeError("offset must be a non-negative safe integer");
1877
+ const safeLimit = Math.min(1000, limit);
1878
+ const safeOffset = offset;
1879
+ const all = [];
1880
+ for (const c of store.contractsV2.values()) {
1881
+ if (!c || typeof c !== "object") continue;
1882
+ if (normalizeTenantId(c.tenantId ?? DEFAULT_TENANT_ID) !== tenantId) continue;
1883
+ if (status !== null && String(c.status ?? "") !== String(status)) continue;
1884
+ all.push(c);
1885
+ }
1886
+ all.sort((a, b) => String(a.contractId ?? "").localeCompare(String(b.contractId ?? "")) || Number(b.contractVersion ?? 0) - Number(a.contractVersion ?? 0));
1887
+ return all.slice(safeOffset, safeOffset + safeLimit);
1888
+ };
1889
+
1890
+ store.getLatestContractV2 = async function getLatestContractV2({ tenantId = DEFAULT_TENANT_ID, contractId } = {}) {
1891
+ tenantId = normalizeTenantId(tenantId);
1892
+ if (typeof contractId !== "string" || contractId.trim() === "") throw new TypeError("contractId is required");
1893
+ let best = null;
1894
+ for (const c of store.contractsV2.values()) {
1895
+ if (!c || typeof c !== "object") continue;
1896
+ if (normalizeTenantId(c.tenantId ?? DEFAULT_TENANT_ID) !== tenantId) continue;
1897
+ if (String(c.contractId ?? "") !== String(contractId)) continue;
1898
+ if (!best || Number(c.contractVersion ?? 0) > Number(best.contractVersion ?? 0)) best = c;
1899
+ }
1900
+ return best;
1901
+ };
1902
+
1903
+ store.createContractDraftV2 = async function createContractDraftV2({ tenantId = DEFAULT_TENANT_ID, contractId, contractVersion, doc, audit = null } = {}) {
1904
+ tenantId = normalizeTenantId(tenantId);
1905
+ if (typeof contractId !== "string" || contractId.trim() === "") throw new TypeError("contractId is required");
1906
+ const v = Number(contractVersion);
1907
+ if (!Number.isSafeInteger(v) || v <= 0) throw new TypeError("contractVersion must be a positive safe integer");
1908
+ if (!doc || typeof doc !== "object") throw new TypeError("doc is required");
1909
+ const nowAt = typeof store.nowIso === "function" ? store.nowIso() : new Date().toISOString();
1910
+ const key = `${tenantId}\n${String(contractId)}\n${String(v)}`;
1911
+ const existing = store.contractsV2.get(key) ?? null;
1912
+ if (existing && String(existing.status ?? "") !== "DRAFT") {
1913
+ const err = new Error("contract is not editable");
1914
+ err.code = "CONTRACT_NOT_EDITABLE";
1915
+ throw err;
1916
+ }
1917
+ const record = {
1918
+ tenantId,
1919
+ contractId: String(contractId),
1920
+ contractVersion: v,
1921
+ status: "DRAFT",
1922
+ effectiveFrom: doc?.effective?.from ?? null,
1923
+ effectiveTo: doc?.effective?.to ?? null,
1924
+ contractHash: existing?.contractHash ?? null,
1925
+ policyHash: existing?.policyHash ?? null,
1926
+ compilerId: existing?.compilerId ?? null,
1927
+ scope: { ...(doc?.scope ?? {}) },
1928
+ doc,
1929
+ createdAt: existing?.createdAt ?? nowAt,
1930
+ updatedAt: nowAt
1931
+ };
1932
+ store.contractsV2.set(key, record);
1933
+ if (audit && typeof store.appendOpsAudit === "function") {
1934
+ await store.appendOpsAudit({ tenantId, audit });
1935
+ }
1936
+ return store.getContractV2({ tenantId, contractId: String(contractId), contractVersion: v });
1937
+ };
1938
+
1939
+ store.publishContractV2 = async function publishContractV2({ tenantId = DEFAULT_TENANT_ID, contractId, contractVersion, contractHash, audit = null } = {}) {
1940
+ tenantId = normalizeTenantId(tenantId);
1941
+ if (typeof contractId !== "string" || contractId.trim() === "") throw new TypeError("contractId is required");
1942
+ const v = Number(contractVersion);
1943
+ if (!Number.isSafeInteger(v) || v <= 0) throw new TypeError("contractVersion must be a positive safe integer");
1944
+ if (typeof contractHash !== "string" || contractHash.trim() === "") throw new TypeError("contractHash is required");
1945
+ const key = `${tenantId}\n${String(contractId)}\n${String(v)}`;
1946
+ const existing = store.contractsV2.get(key) ?? null;
1947
+ if (!existing) {
1948
+ const err = new Error("contract not found");
1949
+ err.code = "NOT_FOUND";
1950
+ throw err;
1951
+ }
1952
+ if (existing.contractHash && existing.contractHash !== contractHash) {
1953
+ const err = new Error("contract hash mismatch");
1954
+ err.code = "CONTRACT_HASH_MISMATCH";
1955
+ throw err;
1956
+ }
1957
+ const nowAt = typeof store.nowIso === "function" ? store.nowIso() : new Date().toISOString();
1958
+ const next = { ...existing, status: "PUBLISHED", contractHash: String(contractHash), updatedAt: nowAt };
1959
+ store.contractsV2.set(key, next);
1960
+ if (audit && typeof store.appendOpsAudit === "function") {
1961
+ await store.appendOpsAudit({ tenantId, audit });
1962
+ }
1963
+ return store.getContractV2({ tenantId, contractId: String(contractId), contractVersion: v });
1964
+ };
1965
+
1966
+ store.putContractSignatureV2 = async function putContractSignatureV2({ tenantId = DEFAULT_TENANT_ID, contractHash, partyRole, signerKeyId, signature, audit = null } = {}) {
1967
+ tenantId = normalizeTenantId(tenantId);
1968
+ if (typeof contractHash !== "string" || contractHash.trim() === "") throw new TypeError("contractHash is required");
1969
+ if (typeof partyRole !== "string" || partyRole.trim() === "") throw new TypeError("partyRole is required");
1970
+ if (typeof signerKeyId !== "string" || signerKeyId.trim() === "") throw new TypeError("signerKeyId is required");
1971
+ if (typeof signature !== "string" || signature.trim() === "") throw new TypeError("signature is required");
1972
+ const nowAt = typeof store.nowIso === "function" ? store.nowIso() : new Date().toISOString();
1973
+ const key = `${tenantId}\n${String(contractHash)}\n${String(partyRole)}`;
1974
+ store.contractSignaturesV2.set(key, {
1975
+ tenantId,
1976
+ contractHash: String(contractHash),
1977
+ partyRole: String(partyRole),
1978
+ signerKeyId: String(signerKeyId),
1979
+ signature: String(signature),
1980
+ signedAt: nowAt
1981
+ });
1982
+ if (audit && typeof store.appendOpsAudit === "function") {
1983
+ await store.appendOpsAudit({ tenantId, audit });
1984
+ }
1985
+ return { ok: true };
1986
+ };
1987
+
1988
+ store.listContractSignaturesV2 = async function listContractSignaturesV2({ tenantId = DEFAULT_TENANT_ID, contractHash } = {}) {
1989
+ tenantId = normalizeTenantId(tenantId);
1990
+ if (typeof contractHash !== "string" || contractHash.trim() === "") throw new TypeError("contractHash is required");
1991
+ const out = [];
1992
+ for (const s of store.contractSignaturesV2.values()) {
1993
+ if (!s || typeof s !== "object") continue;
1994
+ if (normalizeTenantId(s.tenantId ?? DEFAULT_TENANT_ID) !== tenantId) continue;
1995
+ if (String(s.contractHash ?? "") !== String(contractHash)) continue;
1996
+ out.push(s);
1997
+ }
1998
+ out.sort((a, b) => String(a.partyRole ?? "").localeCompare(String(b.partyRole ?? "")));
1999
+ return out;
2000
+ };
2001
+
2002
+ store.activateContractV2 = async function activateContractV2({ tenantId = DEFAULT_TENANT_ID, contractId, contractVersion, policyHash, compilerId, audit = null } = {}) {
2003
+ tenantId = normalizeTenantId(tenantId);
2004
+ if (typeof contractId !== "string" || contractId.trim() === "") throw new TypeError("contractId is required");
2005
+ const v = Number(contractVersion);
2006
+ if (!Number.isSafeInteger(v) || v <= 0) throw new TypeError("contractVersion must be a positive safe integer");
2007
+ if (typeof policyHash !== "string" || policyHash.trim() === "") throw new TypeError("policyHash is required");
2008
+ if (typeof compilerId !== "string" || compilerId.trim() === "") throw new TypeError("compilerId is required");
2009
+ const key = `${tenantId}\n${String(contractId)}\n${String(v)}`;
2010
+ const existing = store.contractsV2.get(key) ?? null;
2011
+ if (!existing) {
2012
+ const err = new Error("contract not found");
2013
+ err.code = "NOT_FOUND";
2014
+ throw err;
2015
+ }
2016
+ const status = String(existing.status ?? "");
2017
+ if (status !== "PUBLISHED" && status !== "ACTIVE") {
2018
+ const err = new Error("contract not activatable");
2019
+ err.code = "CONTRACT_NOT_ACTIVATABLE";
2020
+ throw err;
2021
+ }
2022
+ const nowAt = typeof store.nowIso === "function" ? store.nowIso() : new Date().toISOString();
2023
+ store.contractsV2.set(key, { ...existing, status: "ACTIVE", policyHash: String(policyHash), compilerId: String(compilerId), updatedAt: nowAt });
2024
+ if (audit && typeof store.appendOpsAudit === "function") {
2025
+ await store.appendOpsAudit({ tenantId, audit });
2026
+ }
2027
+ return store.getContractV2({ tenantId, contractId: String(contractId), contractVersion: v });
2028
+ };
2029
+
2030
+ store.close = function close() {
2031
+ store.persistence?.close();
2032
+ };
2033
+
2034
+ if (store.persistence) {
2035
+ const records = store.persistence.load();
2036
+ for (const record of records) {
2037
+ if (!record || typeof record !== "object") continue;
2038
+ if (record.v !== TX_LOG_VERSION) continue;
2039
+ try {
2040
+ applyTxRecord(store, record);
2041
+ } catch (err) {
2042
+ throw new Error(`failed to replay tx log: ${err?.message}`);
2043
+ }
2044
+ }
2045
+
2046
+ // Catch up any durable side-effects driven via outbox (e.g. ledger application).
2047
+ processOutbox(store);
2048
+ }
2049
+
2050
+ // Bootstrap global governance with the current server signer key. This prevents
2051
+ // finance-grade proof bundles from introducing a new out-of-band trust root.
2052
+ // Must run after tx-log replay (if enabled) to avoid conflicting re-appends.
2053
+ (function bootstrapGlobalGovernanceServerSignerKey() {
2054
+ const nowAt = typeof store.nowIso === "function" ? store.nowIso() : new Date().toISOString();
2055
+ const globalTenantId = DEFAULT_TENANT_ID;
2056
+ const key = makeScopedKey({ tenantId: globalTenantId, id: GOVERNANCE_STREAM_ID });
2057
+ const existing = store.monthEvents.get(key) ?? [];
2058
+ const serverKeyId = store.serverSigner?.keyId ?? null;
2059
+ const serverPublicKeyPem = store.serverSigner?.publicKeyPem ?? null;
2060
+ if (!serverKeyId || !serverPublicKeyPem) return;
2061
+
2062
+ const already =
2063
+ existing.some((e) => e?.type === "SERVER_SIGNER_KEY_REGISTERED" && String(e?.payload?.keyId ?? "") === String(serverKeyId)) ||
2064
+ existing.some((e) => e?.type === "SERVER_SIGNER_KEY_ROTATED" && String(e?.payload?.newKeyId ?? "") === String(serverKeyId));
2065
+ if (already) return;
2066
+
2067
+ const payload = validateServerSignerKeyRegisteredPayload({
2068
+ tenantId: globalTenantId,
2069
+ keyId: String(serverKeyId),
2070
+ publicKeyPem: String(serverPublicKeyPem),
2071
+ registeredAt: nowAt,
2072
+ reason: "bootstrap"
2073
+ });
2074
+ const draft = createChainedEvent({
2075
+ streamId: GOVERNANCE_STREAM_ID,
2076
+ type: "SERVER_SIGNER_KEY_REGISTERED",
2077
+ at: payload.registeredAt,
2078
+ actor: { type: "ops", id: "bootstrap" },
2079
+ payload,
2080
+ id: `evt_bootstrap_server_signer_registered_${String(serverKeyId)}`
2081
+ });
2082
+ const next = appendChainedEvent({ events: existing, event: draft, signer: store.serverSigner });
2083
+ const event = next[next.length - 1];
2084
+ store.commitTx({ at: nowAt, ops: [{ kind: "MONTH_EVENTS_APPENDED", tenantId: globalTenantId, monthId: GOVERNANCE_STREAM_ID, events: [event] }] });
2085
+ })();
2086
+
2087
+ return store;
2088
+ }