@noodleseed/one 0.45.0 → 0.47.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 (338) hide show
  1. package/dist/commands/auth-ops.d.ts.map +1 -1
  2. package/dist/commands/auth-ops.js +28 -4
  3. package/dist/commands/auth-ops.js.map +1 -1
  4. package/dist/commands/billing-enforcement-ops.d.ts +2 -0
  5. package/dist/commands/billing-enforcement-ops.d.ts.map +1 -0
  6. package/dist/commands/billing-enforcement-ops.js +312 -0
  7. package/dist/commands/billing-enforcement-ops.js.map +1 -0
  8. package/dist/commands/billing-metering-ops.d.ts +2 -0
  9. package/dist/commands/billing-metering-ops.d.ts.map +1 -0
  10. package/dist/commands/billing-metering-ops.js +128 -0
  11. package/dist/commands/billing-metering-ops.js.map +1 -0
  12. package/dist/commands/billing-metering-validation-ops.d.ts +2 -0
  13. package/dist/commands/billing-metering-validation-ops.d.ts.map +1 -0
  14. package/dist/commands/billing-metering-validation-ops.js +186 -0
  15. package/dist/commands/billing-metering-validation-ops.js.map +1 -0
  16. package/dist/commands/billing-ops.d.ts.map +1 -1
  17. package/dist/commands/billing-ops.js +6 -0
  18. package/dist/commands/billing-ops.js.map +1 -1
  19. package/dist/commands/catalog-data-resources.d.ts.map +1 -1
  20. package/dist/commands/catalog-data-resources.js +14 -3
  21. package/dist/commands/catalog-data-resources.js.map +1 -1
  22. package/dist/commands/catalog-render.d.ts.map +1 -1
  23. package/dist/commands/catalog-render.js +7 -5
  24. package/dist/commands/catalog-render.js.map +1 -1
  25. package/dist/commands/deploy-ops.d.ts.map +1 -1
  26. package/dist/commands/deploy-ops.js +10 -1
  27. package/dist/commands/deploy-ops.js.map +1 -1
  28. package/dist/commands/deploy-output.d.ts.map +1 -1
  29. package/dist/commands/deploy-output.js +4 -0
  30. package/dist/commands/deploy-output.js.map +1 -1
  31. package/dist/commands/deploy-version-resolution.d.ts +1 -0
  32. package/dist/commands/deploy-version-resolution.d.ts.map +1 -1
  33. package/dist/commands/deploy-version-resolution.js +8 -0
  34. package/dist/commands/deploy-version-resolution.js.map +1 -1
  35. package/dist/commands/mcp-apps-chatgpt.d.ts +7 -0
  36. package/dist/commands/mcp-apps-chatgpt.d.ts.map +1 -0
  37. package/dist/commands/mcp-apps-chatgpt.js +143 -0
  38. package/dist/commands/mcp-apps-chatgpt.js.map +1 -0
  39. package/dist/commands/mcp-apps.d.ts.map +1 -1
  40. package/dist/commands/mcp-apps.js +2 -114
  41. package/dist/commands/mcp-apps.js.map +1 -1
  42. package/dist/deploy-payload-size.d.ts +3 -0
  43. package/dist/deploy-payload-size.d.ts.map +1 -0
  44. package/dist/deploy-payload-size.js +29 -0
  45. package/dist/deploy-payload-size.js.map +1 -0
  46. package/dist/deploy.d.ts.map +1 -1
  47. package/dist/deploy.js +16 -8
  48. package/dist/deploy.js.map +1 -1
  49. package/dist/saas-scaffold-template.js +1 -1
  50. package/dist/saas-scaffold-template.js.map +1 -1
  51. package/dist/sdk-version-skew.d.ts +3 -0
  52. package/dist/sdk-version-skew.d.ts.map +1 -0
  53. package/dist/sdk-version-skew.js +34 -0
  54. package/dist/sdk-version-skew.js.map +1 -0
  55. package/dist/widget-scaffold-template.d.ts.map +1 -1
  56. package/dist/widget-scaffold-template.js +4 -2
  57. package/dist/widget-scaffold-template.js.map +1 -1
  58. package/node_modules/@noodle-borg/agent-kit/dist/generated/example-files.js +3 -3
  59. package/node_modules/@noodle-borg/agent-kit/dist/generated/example-files.js.map +1 -1
  60. package/node_modules/@noodle-borg/agent-kit/dist/skill-authoring-refs.js +1 -1
  61. package/node_modules/@noodle-borg/agent-kit/dist/skill-authoring-refs.js.map +1 -1
  62. package/node_modules/@noodle-borg/agent-kit/dist/skill-content.js +1 -1
  63. package/node_modules/@noodle-borg/agent-kit/dist/skill-content.js.map +1 -1
  64. package/node_modules/@noodle-borg/agent-kit/dist/skill-embedded-assistant-ref.d.ts.map +1 -1
  65. package/node_modules/@noodle-borg/agent-kit/dist/skill-embedded-assistant-ref.js +6 -4
  66. package/node_modules/@noodle-borg/agent-kit/dist/skill-embedded-assistant-ref.js.map +1 -1
  67. package/node_modules/@noodle-borg/agent-kit/package.json +1 -1
  68. package/node_modules/@noodle-borg/authoring/dist/assistant.d.ts +9 -0
  69. package/node_modules/@noodle-borg/authoring/dist/assistant.d.ts.map +1 -1
  70. package/node_modules/@noodle-borg/authoring/dist/assistant.js.map +1 -1
  71. package/node_modules/@noodle-borg/authoring/dist/server.d.ts +7 -0
  72. package/node_modules/@noodle-borg/authoring/dist/server.d.ts.map +1 -1
  73. package/node_modules/@noodle-borg/authoring/dist/server.js +2 -0
  74. package/node_modules/@noodle-borg/authoring/dist/server.js.map +1 -1
  75. package/node_modules/@noodle-borg/compiler/dist/artifact/types.d.ts +10 -1
  76. package/node_modules/@noodle-borg/compiler/dist/artifact/types.d.ts.map +1 -1
  77. package/node_modules/@noodle-borg/compiler/dist/artifact/types.js +6 -1
  78. package/node_modules/@noodle-borg/compiler/dist/artifact/types.js.map +1 -1
  79. package/node_modules/@noodle-borg/compiler/dist/compile.d.ts.map +1 -1
  80. package/node_modules/@noodle-borg/compiler/dist/compile.js +4 -0
  81. package/node_modules/@noodle-borg/compiler/dist/compile.js.map +1 -1
  82. package/node_modules/@noodle-borg/compiler/dist/manifest/schema.d.ts +52 -0
  83. package/node_modules/@noodle-borg/compiler/dist/manifest/schema.d.ts.map +1 -1
  84. package/node_modules/@noodle-borg/compiler/dist/manifest/schema.js +17 -0
  85. package/node_modules/@noodle-borg/compiler/dist/manifest/schema.js.map +1 -1
  86. package/node_modules/@noodle-borg/protocol/dist/mapping.d.ts.map +1 -1
  87. package/node_modules/@noodle-borg/protocol/dist/mapping.js +1 -0
  88. package/node_modules/@noodle-borg/protocol/dist/mapping.js.map +1 -1
  89. package/node_modules/@noodle-borg/protocol/dist/sdk-server.js +18 -0
  90. package/node_modules/@noodle-borg/protocol/dist/sdk-server.js.map +1 -1
  91. package/node_modules/@noodle-borg/protocol/dist/tool-interaction.d.ts +3 -0
  92. package/node_modules/@noodle-borg/protocol/dist/tool-interaction.d.ts.map +1 -1
  93. package/node_modules/@noodle-borg/protocol/dist/tool-interaction.js +12 -3
  94. package/node_modules/@noodle-borg/protocol/dist/tool-interaction.js.map +1 -1
  95. package/node_modules/@noodle-borg/service/dist/assistant-interactive.d.ts.map +1 -1
  96. package/node_modules/@noodle-borg/service/dist/assistant-interactive.js +7 -3
  97. package/node_modules/@noodle-borg/service/dist/assistant-interactive.js.map +1 -1
  98. package/node_modules/@noodle-borg/service/dist/assistant-presentation.d.ts +11 -0
  99. package/node_modules/@noodle-borg/service/dist/assistant-presentation.d.ts.map +1 -1
  100. package/node_modules/@noodle-borg/service/dist/assistant-presentation.js +67 -3
  101. package/node_modules/@noodle-borg/service/dist/assistant-presentation.js.map +1 -1
  102. package/node_modules/@noodle-borg/service/dist/billing/enforcement-profile.d.ts +96 -0
  103. package/node_modules/@noodle-borg/service/dist/billing/enforcement-profile.d.ts.map +1 -0
  104. package/node_modules/@noodle-borg/service/dist/billing/enforcement-profile.js +198 -0
  105. package/node_modules/@noodle-borg/service/dist/billing/enforcement-profile.js.map +1 -0
  106. package/node_modules/@noodle-borg/service/dist/billing/integration.d.ts +25 -2
  107. package/node_modules/@noodle-borg/service/dist/billing/integration.d.ts.map +1 -1
  108. package/node_modules/@noodle-borg/service/dist/billing/integration.js +51 -5
  109. package/node_modules/@noodle-borg/service/dist/billing/integration.js.map +1 -1
  110. package/node_modules/@noodle-borg/service/dist/billing/meter-capacity.d.ts +77 -0
  111. package/node_modules/@noodle-borg/service/dist/billing/meter-capacity.d.ts.map +1 -0
  112. package/node_modules/@noodle-borg/service/dist/billing/meter-capacity.js +202 -0
  113. package/node_modules/@noodle-borg/service/dist/billing/meter-capacity.js.map +1 -0
  114. package/node_modules/@noodle-borg/service/dist/billing/meter-live-validation-contract.d.ts +8 -0
  115. package/node_modules/@noodle-borg/service/dist/billing/meter-live-validation-contract.d.ts.map +1 -0
  116. package/node_modules/@noodle-borg/service/dist/billing/meter-live-validation-contract.js +93 -0
  117. package/node_modules/@noodle-borg/service/dist/billing/meter-live-validation-contract.js.map +1 -0
  118. package/node_modules/@noodle-borg/service/dist/billing/meter-live-validation.d.ts +76 -0
  119. package/node_modules/@noodle-borg/service/dist/billing/meter-live-validation.d.ts.map +1 -0
  120. package/node_modules/@noodle-borg/service/dist/billing/meter-live-validation.js +233 -0
  121. package/node_modules/@noodle-borg/service/dist/billing/meter-live-validation.js.map +1 -0
  122. package/node_modules/@noodle-borg/service/dist/billing/meter-readiness-health.d.ts +89 -0
  123. package/node_modules/@noodle-borg/service/dist/billing/meter-readiness-health.d.ts.map +1 -0
  124. package/node_modules/@noodle-borg/service/dist/billing/meter-readiness-health.js +191 -0
  125. package/node_modules/@noodle-borg/service/dist/billing/meter-readiness-health.js.map +1 -0
  126. package/node_modules/@noodle-borg/service/dist/billing/meter-readiness.d.ts +99 -0
  127. package/node_modules/@noodle-borg/service/dist/billing/meter-readiness.d.ts.map +1 -0
  128. package/node_modules/@noodle-borg/service/dist/billing/meter-readiness.js +136 -0
  129. package/node_modules/@noodle-borg/service/dist/billing/meter-readiness.js.map +1 -0
  130. package/node_modules/@noodle-borg/service/dist/billing/meter-runtime-config.d.ts +9 -0
  131. package/node_modules/@noodle-borg/service/dist/billing/meter-runtime-config.d.ts.map +1 -0
  132. package/node_modules/@noodle-borg/service/dist/billing/meter-runtime-config.js +24 -0
  133. package/node_modules/@noodle-borg/service/dist/billing/meter-runtime-config.js.map +1 -0
  134. package/node_modules/@noodle-borg/service/dist/billing/meter-validation-epoch.d.ts +75 -0
  135. package/node_modules/@noodle-borg/service/dist/billing/meter-validation-epoch.d.ts.map +1 -0
  136. package/node_modules/@noodle-borg/service/dist/billing/meter-validation-epoch.js +127 -0
  137. package/node_modules/@noodle-borg/service/dist/billing/meter-validation-epoch.js.map +1 -0
  138. package/node_modules/@noodle-borg/service/dist/billing/postgres-enforcement-profile-schema.d.ts +4 -0
  139. package/node_modules/@noodle-borg/service/dist/billing/postgres-enforcement-profile-schema.d.ts.map +1 -0
  140. package/node_modules/@noodle-borg/service/dist/billing/postgres-enforcement-profile-schema.js +107 -0
  141. package/node_modules/@noodle-borg/service/dist/billing/postgres-enforcement-profile-schema.js.map +1 -0
  142. package/node_modules/@noodle-borg/service/dist/billing/postgres-enforcement-profile.d.ts +18 -0
  143. package/node_modules/@noodle-borg/service/dist/billing/postgres-enforcement-profile.d.ts.map +1 -0
  144. package/node_modules/@noodle-borg/service/dist/billing/postgres-enforcement-profile.js +341 -0
  145. package/node_modules/@noodle-borg/service/dist/billing/postgres-enforcement-profile.js.map +1 -0
  146. package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-clock.d.ts +3 -0
  147. package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-clock.d.ts.map +1 -0
  148. package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-clock.js +9 -0
  149. package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-clock.js.map +1 -0
  150. package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-epoch-fixtures.d.ts +13 -0
  151. package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-epoch-fixtures.d.ts.map +1 -0
  152. package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-epoch-fixtures.js +102 -0
  153. package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-epoch-fixtures.js.map +1 -0
  154. package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-epochs.d.ts +41 -0
  155. package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-epochs.d.ts.map +1 -0
  156. package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-epochs.js +289 -0
  157. package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-epochs.js.map +1 -0
  158. package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-evidence-retention.d.ts +16 -0
  159. package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-evidence-retention.d.ts.map +1 -0
  160. package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-evidence-retention.js +126 -0
  161. package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-evidence-retention.js.map +1 -0
  162. package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-live-validation.d.ts +33 -0
  163. package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-live-validation.d.ts.map +1 -0
  164. package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-live-validation.js +436 -0
  165. package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-live-validation.js.map +1 -0
  166. package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-maintenance.d.ts +26 -0
  167. package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-maintenance.d.ts.map +1 -0
  168. package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-maintenance.js +146 -0
  169. package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-maintenance.js.map +1 -0
  170. package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-partition.d.ts +8 -0
  171. package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-partition.d.ts.map +1 -0
  172. package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-partition.js +42 -0
  173. package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-partition.js.map +1 -0
  174. package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-prepare-preflight.d.ts +8 -0
  175. package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-prepare-preflight.d.ts.map +1 -0
  176. package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-prepare-preflight.js +44 -0
  177. package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-prepare-preflight.js.map +1 -0
  178. package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-readiness-live.d.ts +13 -0
  179. package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-readiness-live.d.ts.map +1 -0
  180. package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-readiness-live.js +189 -0
  181. package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-readiness-live.js.map +1 -0
  182. package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-readiness.d.ts +18 -0
  183. package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-readiness.d.ts.map +1 -0
  184. package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-readiness.js +342 -0
  185. package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-readiness.js.map +1 -0
  186. package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-reconciliation.d.ts +27 -0
  187. package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-reconciliation.d.ts.map +1 -0
  188. package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-reconciliation.js +304 -0
  189. package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-reconciliation.js.map +1 -0
  190. package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-retention.d.ts +22 -0
  191. package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-retention.d.ts.map +1 -0
  192. package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-retention.js +224 -0
  193. package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-retention.js.map +1 -0
  194. package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-runtime.d.ts +33 -0
  195. package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-runtime.d.ts.map +1 -0
  196. package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-runtime.js +173 -0
  197. package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-runtime.js.map +1 -0
  198. package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-scheduler-schema.d.ts +7 -0
  199. package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-scheduler-schema.d.ts.map +1 -0
  200. package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-scheduler-schema.js +50 -0
  201. package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-scheduler-schema.js.map +1 -0
  202. package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-scheduler-store.d.ts +34 -0
  203. package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-scheduler-store.d.ts.map +1 -0
  204. package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-scheduler-store.js +157 -0
  205. package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-scheduler-store.js.map +1 -0
  206. package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-scheduler.d.ts +56 -0
  207. package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-scheduler.d.ts.map +1 -0
  208. package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-scheduler.js +264 -0
  209. package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-scheduler.js.map +1 -0
  210. package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-schema.d.ts +6 -0
  211. package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-schema.d.ts.map +1 -0
  212. package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-schema.js +414 -0
  213. package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-schema.js.map +1 -0
  214. package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-validation.d.ts +43 -0
  215. package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-validation.d.ts.map +1 -0
  216. package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-validation.js +321 -0
  217. package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-validation.js.map +1 -0
  218. package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-window-lock.d.ts +10 -0
  219. package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-window-lock.d.ts.map +1 -0
  220. package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-window-lock.js +13 -0
  221. package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-window-lock.js.map +1 -0
  222. package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-window-schema.d.ts +6 -0
  223. package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-window-schema.d.ts.map +1 -0
  224. package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-window-schema.js +248 -0
  225. package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-window-schema.js.map +1 -0
  226. package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-writer-compaction.d.ts +29 -0
  227. package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-writer-compaction.d.ts.map +1 -0
  228. package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-writer-compaction.js +240 -0
  229. package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-writer-compaction.js.map +1 -0
  230. package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-writer-health-schema.d.ts +4 -0
  231. package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-writer-health-schema.d.ts.map +1 -0
  232. package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-writer-health-schema.js +140 -0
  233. package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-writer-health-schema.js.map +1 -0
  234. package/node_modules/@noodle-borg/service/dist/billing/postgres-migration.d.ts.map +1 -1
  235. package/node_modules/@noodle-borg/service/dist/billing/postgres-migration.js +4 -0
  236. package/node_modules/@noodle-borg/service/dist/billing/postgres-migration.js.map +1 -1
  237. package/node_modules/@noodle-borg/service/dist/billing/postgres-schema.d.ts.map +1 -1
  238. package/node_modules/@noodle-borg/service/dist/billing/postgres-schema.js +6 -0
  239. package/node_modules/@noodle-borg/service/dist/billing/postgres-schema.js.map +1 -1
  240. package/node_modules/@noodle-borg/service/dist/billing/postgres.d.ts.map +1 -1
  241. package/node_modules/@noodle-borg/service/dist/billing/postgres.js +3 -0
  242. package/node_modules/@noodle-borg/service/dist/billing/postgres.js.map +1 -1
  243. package/node_modules/@noodle-borg/service/dist/billing/service-meter-runtime.d.ts +7 -0
  244. package/node_modules/@noodle-borg/service/dist/billing/service-meter-runtime.d.ts.map +1 -0
  245. package/node_modules/@noodle-borg/service/dist/billing/service-meter-runtime.js +19 -0
  246. package/node_modules/@noodle-borg/service/dist/billing/service-meter-runtime.js.map +1 -0
  247. package/node_modules/@noodle-borg/service/dist/billing/shadow-meter.d.ts +9 -4
  248. package/node_modules/@noodle-borg/service/dist/billing/shadow-meter.d.ts.map +1 -1
  249. package/node_modules/@noodle-borg/service/dist/billing/shadow-meter.js +34 -95
  250. package/node_modules/@noodle-borg/service/dist/billing/shadow-meter.js.map +1 -1
  251. package/node_modules/@noodle-borg/service/dist/billing/usage-identity.d.ts +14 -0
  252. package/node_modules/@noodle-borg/service/dist/billing/usage-identity.d.ts.map +1 -0
  253. package/node_modules/@noodle-borg/service/dist/billing/usage-identity.js +87 -0
  254. package/node_modules/@noodle-borg/service/dist/billing/usage-identity.js.map +1 -0
  255. package/node_modules/@noodle-borg/service/dist/billing/usage-observer.d.ts +6 -0
  256. package/node_modules/@noodle-borg/service/dist/billing/usage-observer.d.ts.map +1 -0
  257. package/node_modules/@noodle-borg/service/dist/billing/usage-observer.js +26 -0
  258. package/node_modules/@noodle-borg/service/dist/billing/usage-observer.js.map +1 -0
  259. package/node_modules/@noodle-borg/service/dist/billing-public.d.ts +16 -0
  260. package/node_modules/@noodle-borg/service/dist/billing-public.d.ts.map +1 -0
  261. package/node_modules/@noodle-borg/service/dist/billing-public.js +15 -0
  262. package/node_modules/@noodle-borg/service/dist/billing-public.js.map +1 -0
  263. package/node_modules/@noodle-borg/service/dist/customer-verifier.d.ts +1 -0
  264. package/node_modules/@noodle-borg/service/dist/customer-verifier.d.ts.map +1 -1
  265. package/node_modules/@noodle-borg/service/dist/customer-verifier.js +15 -0
  266. package/node_modules/@noodle-borg/service/dist/customer-verifier.js.map +1 -1
  267. package/node_modules/@noodle-borg/service/dist/http-util.d.ts +2 -0
  268. package/node_modules/@noodle-borg/service/dist/http-util.d.ts.map +1 -1
  269. package/node_modules/@noodle-borg/service/dist/http-util.js +1 -1
  270. package/node_modules/@noodle-borg/service/dist/http-util.js.map +1 -1
  271. package/node_modules/@noodle-borg/service/dist/index.d.ts +2 -7
  272. package/node_modules/@noodle-borg/service/dist/index.d.ts.map +1 -1
  273. package/node_modules/@noodle-borg/service/dist/index.js +1 -6
  274. package/node_modules/@noodle-borg/service/dist/index.js.map +1 -1
  275. package/node_modules/@noodle-borg/service/dist/main.js +3 -0
  276. package/node_modules/@noodle-borg/service/dist/main.js.map +1 -1
  277. package/node_modules/@noodle-borg/service/dist/options.d.ts +18 -0
  278. package/node_modules/@noodle-borg/service/dist/options.d.ts.map +1 -1
  279. package/node_modules/@noodle-borg/service/dist/persistence-options.d.ts +4 -0
  280. package/node_modules/@noodle-borg/service/dist/persistence-options.d.ts.map +1 -0
  281. package/node_modules/@noodle-borg/service/dist/persistence-options.js +22 -0
  282. package/node_modules/@noodle-borg/service/dist/persistence-options.js.map +1 -0
  283. package/node_modules/@noodle-borg/service/dist/routes/assistant-interaction-stream.d.ts.map +1 -1
  284. package/node_modules/@noodle-borg/service/dist/routes/assistant-interaction-stream.js +2 -1
  285. package/node_modules/@noodle-borg/service/dist/routes/assistant-interaction-stream.js.map +1 -1
  286. package/node_modules/@noodle-borg/service/dist/routes/assistant-interactions.d.ts.map +1 -1
  287. package/node_modules/@noodle-borg/service/dist/routes/assistant-interactions.js +6 -2
  288. package/node_modules/@noodle-borg/service/dist/routes/assistant-interactions.js.map +1 -1
  289. package/node_modules/@noodle-borg/service/dist/routes/billing-enforcement-cohort.d.ts +17 -0
  290. package/node_modules/@noodle-borg/service/dist/routes/billing-enforcement-cohort.d.ts.map +1 -0
  291. package/node_modules/@noodle-borg/service/dist/routes/billing-enforcement-cohort.js +145 -0
  292. package/node_modules/@noodle-borg/service/dist/routes/billing-enforcement-cohort.js.map +1 -0
  293. package/node_modules/@noodle-borg/service/dist/routes/billing-meter-readiness.d.ts +15 -0
  294. package/node_modules/@noodle-borg/service/dist/routes/billing-meter-readiness.d.ts.map +1 -0
  295. package/node_modules/@noodle-borg/service/dist/routes/billing-meter-readiness.js +78 -0
  296. package/node_modules/@noodle-borg/service/dist/routes/billing-meter-readiness.js.map +1 -0
  297. package/node_modules/@noodle-borg/service/dist/routes/billing-meter-validation.d.ts +15 -0
  298. package/node_modules/@noodle-borg/service/dist/routes/billing-meter-validation.d.ts.map +1 -0
  299. package/node_modules/@noodle-borg/service/dist/routes/billing-meter-validation.js +108 -0
  300. package/node_modules/@noodle-borg/service/dist/routes/billing-meter-validation.js.map +1 -0
  301. package/node_modules/@noodle-borg/service/dist/routes/commercial-dispatch.d.ts +6 -0
  302. package/node_modules/@noodle-borg/service/dist/routes/commercial-dispatch.d.ts.map +1 -1
  303. package/node_modules/@noodle-borg/service/dist/routes/commercial-dispatch.js +99 -0
  304. package/node_modules/@noodle-borg/service/dist/routes/commercial-dispatch.js.map +1 -1
  305. package/node_modules/@noodle-borg/service/dist/routes/commercial-service-deps.d.ts +25 -0
  306. package/node_modules/@noodle-borg/service/dist/routes/commercial-service-deps.d.ts.map +1 -0
  307. package/node_modules/@noodle-borg/service/dist/routes/commercial-service-deps.js +35 -0
  308. package/node_modules/@noodle-borg/service/dist/routes/commercial-service-deps.js.map +1 -0
  309. package/node_modules/@noodle-borg/service/dist/routes/control-plane.d.ts.map +1 -1
  310. package/node_modules/@noodle-borg/service/dist/routes/control-plane.js +3 -1
  311. package/node_modules/@noodle-borg/service/dist/routes/control-plane.js.map +1 -1
  312. package/node_modules/@noodle-borg/service/dist/serve-options.d.ts +93 -0
  313. package/node_modules/@noodle-borg/service/dist/serve-options.d.ts.map +1 -0
  314. package/node_modules/@noodle-borg/service/dist/serve-options.js +2 -0
  315. package/node_modules/@noodle-borg/service/dist/serve-options.js.map +1 -0
  316. package/node_modules/@noodle-borg/service/dist/serve.d.ts +2 -92
  317. package/node_modules/@noodle-borg/service/dist/serve.d.ts.map +1 -1
  318. package/node_modules/@noodle-borg/service/dist/serve.js +64 -59
  319. package/node_modules/@noodle-borg/service/dist/serve.js.map +1 -1
  320. package/node_modules/@noodle-borg/service/dist/service-resource-cleanup.d.ts +22 -0
  321. package/node_modules/@noodle-borg/service/dist/service-resource-cleanup.d.ts.map +1 -0
  322. package/node_modules/@noodle-borg/service/dist/service-resource-cleanup.js +51 -0
  323. package/node_modules/@noodle-borg/service/dist/service-resource-cleanup.js.map +1 -0
  324. package/node_modules/@noodle-borg/service/dist/service.d.ts.map +1 -1
  325. package/node_modules/@noodle-borg/service/dist/service.js +10 -21
  326. package/node_modules/@noodle-borg/service/dist/service.js.map +1 -1
  327. package/node_modules/@noodle-borg/service/dist/store/cloudsql-pool.d.ts.map +1 -1
  328. package/node_modules/@noodle-borg/service/dist/store/cloudsql-pool.js +7 -1
  329. package/node_modules/@noodle-borg/service/dist/store/cloudsql-pool.js.map +1 -1
  330. package/node_modules/@noodle-borg/service/dist/store/postgres-billing.d.ts +6 -2
  331. package/node_modules/@noodle-borg/service/dist/store/postgres-billing.d.ts.map +1 -1
  332. package/node_modules/@noodle-borg/service/dist/store/postgres-billing.js +11 -1
  333. package/node_modules/@noodle-borg/service/dist/store/postgres-billing.js.map +1 -1
  334. package/node_modules/@noodle-borg/wire-contracts/dist/assistant.d.ts +3 -0
  335. package/node_modules/@noodle-borg/wire-contracts/dist/assistant.d.ts.map +1 -1
  336. package/node_modules/@noodle-borg/wire-contracts/dist/assistant.js +3 -0
  337. package/node_modules/@noodle-borg/wire-contracts/dist/assistant.js.map +1 -1
  338. package/package.json +1 -1
@@ -0,0 +1,321 @@
1
+ import { randomUUID } from 'node:crypto';
2
+ import { validateSlug } from '../store/validate.js';
3
+ import { BILLING_METER_AGGREGATE_RETENTION_MONTHS, BILLING_METER_EXACT_KEY_TOMBSTONE_RETENTION_DAYS, BILLING_METER_RECEIPT_RETENTION_DAYS, BILLING_METER_RETRY_IDENTITY_VERSION, } from './meter-readiness.js';
4
+ import { BILLING_METER_VALIDATION_WRITER_CONTRACT_VERSION } from './meter-validation-epoch.js';
5
+ import { validateBillingAccountId } from './model.js';
6
+ import { readBillingMeterTransactionTime } from './postgres-meter-clock.js';
7
+ import { billingMeterWindowLockKey } from './postgres-meter-window-lock.js';
8
+ import { validateScalarId } from './postgres-records.js';
9
+ import { validateBillingUsageRetryWindowMs } from './usage-store.js';
10
+ import { resolveUtcMonthlyUsageWindow } from './usage-window.js';
11
+ export class BillingMeterValidationIdempotencyConflictError extends Error {
12
+ code = 'billing_meter_validation_idempotency_conflict';
13
+ constructor() {
14
+ super('billing meter validation identity was reused with different semantics');
15
+ this.name = 'BillingMeterValidationIdempotencyConflictError';
16
+ }
17
+ }
18
+ /**
19
+ * Validation-only transaction for load/reconciliation proof. It is deliberately absent from request
20
+ * dispatch and accepts only a prepared epoch; it does not make or enforce a customer admission decision.
21
+ */
22
+ export async function recordBillingMeterValidationUsage(pool, input, options) {
23
+ const client = await pool.connect();
24
+ try {
25
+ await client.query('BEGIN');
26
+ const result = await recordBillingMeterValidationUsageTx(client, input, options);
27
+ await client.query('COMMIT');
28
+ return result;
29
+ }
30
+ catch (error) {
31
+ try {
32
+ await client.query('ROLLBACK');
33
+ }
34
+ catch {
35
+ // Preserve the transaction error; a broken client is discarded by pg when released.
36
+ }
37
+ throw error;
38
+ }
39
+ finally {
40
+ client.release();
41
+ }
42
+ }
43
+ /** Reuse the exact receipt/counter transaction from the live writer without accepting an epoch on its API. */
44
+ export function recordBillingMeterValidationUsageTx(client, input, options) {
45
+ const usage = normalizeValidationInput(input);
46
+ const retryWindowMs = validateBillingUsageRetryWindowMs(options.retryWindowMs);
47
+ const expectedKeyGeneration = validateFingerprint('billing meter expected key generation', options.keyGeneration);
48
+ const expectedReleaseSha = validateReleaseSha(options.releaseSha);
49
+ const expectedWriterContractVersion = validateWriterContractVersion(options.writerContractVersion ?? BILLING_METER_VALIDATION_WRITER_CONTRACT_VERSION);
50
+ const writerSessionId = options.writerSessionId === undefined
51
+ ? undefined
52
+ : validateScalarId('billing meter writer session id', options.writerSessionId);
53
+ return recordValidationUsageTx(client, usage, retryWindowMs, expectedKeyGeneration, expectedReleaseSha, expectedWriterContractVersion, writerSessionId);
54
+ }
55
+ async function recordValidationUsageTx(client, usage, retryWindowMs, expectedKeyGeneration, expectedReleaseSha, expectedWriterContractVersion, writerSessionId) {
56
+ const recordedAt = await readBillingMeterTransactionTime(client);
57
+ const dedupeKind = usage.highConfidenceKeyHash === undefined ? 'fallback' : 'exact';
58
+ const dedupeValue = usage.highConfidenceKeyHash ?? usage.fallbackFingerprint;
59
+ await client.query('SELECT pg_advisory_xact_lock(hashtextextended($1, 0))', [
60
+ `${usage.epochId}:${dedupeKind}:${dedupeValue}`,
61
+ ]);
62
+ const epoch = await client.query(`SELECT state, retry_identity_version, key_generation, release_sha, writer_contract_version
63
+ FROM billing_meter_epochs WHERE id = $1 FOR SHARE`, [usage.epochId]);
64
+ if (epoch.rows[0]?.state !== 'prepared') {
65
+ throw new Error('billing meter validation requires a prepared epoch');
66
+ }
67
+ if (epoch.rows[0].retry_identity_version !== BILLING_METER_RETRY_IDENTITY_VERSION) {
68
+ throw new Error('billing meter validation retry identity version is unsupported');
69
+ }
70
+ if (epoch.rows[0].key_generation !== expectedKeyGeneration) {
71
+ throw new Error('billing meter validation key generation does not match the prepared epoch');
72
+ }
73
+ if (epoch.rows[0].release_sha !== expectedReleaseSha) {
74
+ throw new Error('billing meter validation release SHA does not match the prepared epoch');
75
+ }
76
+ if (epoch.rows[0].writer_contract_version !== expectedWriterContractVersion) {
77
+ throw new Error('billing meter validation writer contract does not match the prepared epoch');
78
+ }
79
+ if (usage.highConfidenceKeyHash !== undefined) {
80
+ const exact = await client.query(`SELECT event_id, classification, semantic_fingerprint
81
+ FROM billing_meter_exact_key_tombstones
82
+ WHERE epoch_id = $1 AND key_hash = decode($2, 'hex')`, [usage.epochId, usage.highConfidenceKeyHash]);
83
+ const prior = exact.rows[0];
84
+ if (prior !== undefined) {
85
+ if (!prior.semantic_fingerprint.equals(Buffer.from(usage.semanticFingerprint, 'hex'))) {
86
+ throw new BillingMeterValidationIdempotencyConflictError();
87
+ }
88
+ return {
89
+ outcome: 'duplicate',
90
+ deduplicatedBy: 'high_confidence_key',
91
+ eventId: prior.event_id,
92
+ classification: prior.classification,
93
+ };
94
+ }
95
+ }
96
+ else {
97
+ const retryCutoff = new Date(Date.parse(recordedAt) - retryWindowMs).toISOString();
98
+ const retryCeiling = new Date(Date.parse(recordedAt) + retryWindowMs).toISOString();
99
+ const fallback = await client.query(`SELECT event_id, classification
100
+ FROM billing_meter_usage_events
101
+ WHERE epoch_id = $1
102
+ AND fallback_fingerprint = decode($2, 'hex')
103
+ AND semantic_fingerprint = decode($3, 'hex')
104
+ AND recorded_at >= $4
105
+ AND recorded_at <= $5
106
+ ORDER BY recorded_at DESC, event_id
107
+ LIMIT 1`, [
108
+ usage.epochId,
109
+ usage.fallbackFingerprint,
110
+ usage.semanticFingerprint,
111
+ retryCutoff,
112
+ retryCeiling,
113
+ ]);
114
+ const prior = fallback.rows[0];
115
+ if (prior !== undefined) {
116
+ return {
117
+ outcome: 'duplicate',
118
+ deduplicatedBy: 'bounded_fallback',
119
+ eventId: prior.event_id,
120
+ classification: prior.classification,
121
+ };
122
+ }
123
+ }
124
+ const resolution = await client.query(`SELECT link.billing_account_id,
125
+ link.version AS link_version,
126
+ snapshot.id AS snapshot_id,
127
+ snapshot.version AS snapshot_version,
128
+ snapshot.monthly_usage_anchor
129
+ FROM org_billing_links AS link
130
+ JOIN billing_account_active_snapshots AS active
131
+ ON active.billing_account_id = link.billing_account_id
132
+ JOIN billing_entitlement_snapshots AS snapshot
133
+ ON snapshot.billing_account_id = active.billing_account_id
134
+ AND snapshot.id = active.snapshot_id
135
+ WHERE link.org_slug = $1
136
+ AND link.active
137
+ AND snapshot.verification_status = 'verified'
138
+ FOR SHARE OF link, active, snapshot`, [usage.org]);
139
+ const attribution = resolution.rows[0];
140
+ if (attribution === undefined) {
141
+ throw new Error('billing setup is incomplete for organization');
142
+ }
143
+ const window = resolveUtcMonthlyUsageWindow(toIso(attribution.monthly_usage_anchor), recordedAt);
144
+ const resolved = {
145
+ ...usage,
146
+ billingAccountId: validateBillingAccountId(attribution.billing_account_id),
147
+ linkVersion: attribution.link_version,
148
+ snapshotId: validateScalarId('billing meter snapshot id', attribution.snapshot_id),
149
+ snapshotVersion: attribution.snapshot_version,
150
+ windowStart: window.start,
151
+ windowEnd: window.end,
152
+ admittedAt: recordedAt,
153
+ recordedAt,
154
+ };
155
+ await client.query('SELECT pg_advisory_xact_lock_shared(hashtextextended($1, 0))', [
156
+ billingMeterWindowLockKey({
157
+ epochId: resolved.epochId,
158
+ windowStart: resolved.windowStart,
159
+ windowEnd: resolved.windowEnd,
160
+ }),
161
+ ]);
162
+ const sealed = await client.query(`SELECT EXISTS (
163
+ SELECT 1
164
+ FROM billing_meter_reconciliation_runs
165
+ WHERE epoch_id = $1 AND window_start = $2 AND window_end = $3 AND sealed
166
+ ) AS sealed`, [resolved.epochId, resolved.windowStart, resolved.windowEnd]);
167
+ if (sealed.rows[0]?.sealed === true) {
168
+ throw new Error('billing meter validation window is sealed');
169
+ }
170
+ const eventId = `bmve_${randomUUID()}`;
171
+ const eventValues = [
172
+ eventId,
173
+ usage.epochId,
174
+ usage.highConfidenceKeyHash ?? null,
175
+ usage.fallbackFingerprint,
176
+ usage.semanticFingerprint,
177
+ usage.classification,
178
+ resolved.billingAccountId,
179
+ resolved.org,
180
+ resolved.app,
181
+ resolved.environment,
182
+ resolved.deploymentId,
183
+ resolved.linkVersion,
184
+ resolved.snapshotId,
185
+ resolved.snapshotVersion,
186
+ resolved.admittedAt,
187
+ resolved.windowStart,
188
+ resolved.windowEnd,
189
+ resolved.recordedAt,
190
+ ];
191
+ await client.query(`INSERT INTO billing_meter_usage_events
192
+ (event_id, epoch_id, mode, high_confidence_key_hash, fallback_fingerprint,
193
+ semantic_fingerprint, classification, billing_account_id, org_slug, app_slug,
194
+ environment, deployment_id, link_version, snapshot_id, snapshot_version, admitted_at,
195
+ window_start, window_end, recorded_at, retention_until${writerSessionId === undefined ? '' : ', writer_session_id'})
196
+ VALUES
197
+ ($1, $2, 'validation', decode($3, 'hex'), decode($4, 'hex'), decode($5, 'hex'),
198
+ $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18,
199
+ $17::timestamptz + interval '${BILLING_METER_RECEIPT_RETENTION_DAYS} days'${writerSessionId === undefined ? '' : ', $19'})`, writerSessionId === undefined ? eventValues : [...eventValues, writerSessionId]);
200
+ if (usage.highConfidenceKeyHash !== undefined) {
201
+ await client.query(`INSERT INTO billing_meter_exact_key_tombstones
202
+ (epoch_id, key_hash, semantic_fingerprint, event_id, classification, window_end,
203
+ created_at, retention_until)
204
+ VALUES
205
+ ($1, decode($2, 'hex'), decode($3, 'hex'), $4, $5, $6, $7,
206
+ $6::timestamptz + interval '${BILLING_METER_EXACT_KEY_TOMBSTONE_RETENTION_DAYS} days')`, [
207
+ usage.epochId,
208
+ usage.highConfidenceKeyHash,
209
+ usage.semanticFingerprint,
210
+ eventId,
211
+ usage.classification,
212
+ resolved.windowEnd,
213
+ resolved.recordedAt,
214
+ ]);
215
+ }
216
+ const increments = classificationIncrements(usage.classification);
217
+ const account = await upsertValidationCounter(client, {
218
+ table: 'billing_meter_account_windows',
219
+ conflict: 'epoch_id, billing_account_id, window_start',
220
+ columns: ['epoch_id', 'billing_account_id', 'window_start'],
221
+ values: [resolved.epochId, resolved.billingAccountId, resolved.windowStart],
222
+ usage: resolved,
223
+ increments,
224
+ });
225
+ const organization = await upsertValidationCounter(client, {
226
+ table: 'billing_meter_org_windows',
227
+ conflict: 'epoch_id, billing_account_id, org_slug, window_start',
228
+ columns: ['epoch_id', 'billing_account_id', 'org_slug', 'window_start'],
229
+ values: [resolved.epochId, resolved.billingAccountId, resolved.org, resolved.windowStart],
230
+ usage: resolved,
231
+ increments,
232
+ });
233
+ if (!account || !organization)
234
+ throw new Error('billing meter validation window conflict');
235
+ return {
236
+ outcome: 'recorded',
237
+ deduplicatedBy: null,
238
+ eventId,
239
+ classification: usage.classification,
240
+ };
241
+ }
242
+ async function upsertValidationCounter(client, input) {
243
+ const prefix = input.values.map((_, index) => `$${index + 1}`).join(', ');
244
+ const offset = input.values.length;
245
+ const result = await client.query(`INSERT INTO ${input.table}
246
+ (${input.columns.join(', ')}, window_end, included_calls, overage_calls, denied_calls,
247
+ first_admitted_at, last_admitted_at, updated_at, retention_until)
248
+ VALUES
249
+ (${prefix}, $${offset + 1}, $${offset + 2}, $${offset + 3}, $${offset + 4},
250
+ $${offset + 5}, $${offset + 5}, $${offset + 6},
251
+ $${offset + 1}::timestamptz + interval '${BILLING_METER_AGGREGATE_RETENTION_MONTHS} months')
252
+ ON CONFLICT (${input.conflict}) DO UPDATE SET
253
+ included_calls = ${input.table}.included_calls + EXCLUDED.included_calls,
254
+ overage_calls = ${input.table}.overage_calls + EXCLUDED.overage_calls,
255
+ denied_calls = ${input.table}.denied_calls + EXCLUDED.denied_calls,
256
+ first_admitted_at = LEAST(${input.table}.first_admitted_at, EXCLUDED.first_admitted_at),
257
+ last_admitted_at = GREATEST(${input.table}.last_admitted_at, EXCLUDED.last_admitted_at),
258
+ updated_at = EXCLUDED.updated_at
259
+ WHERE ${input.table}.window_end = EXCLUDED.window_end
260
+ RETURNING 1`, [
261
+ ...input.values,
262
+ input.usage.windowEnd,
263
+ ...input.increments,
264
+ input.usage.admittedAt,
265
+ input.usage.recordedAt,
266
+ ]);
267
+ return result.rowCount === 1;
268
+ }
269
+ function classificationIncrements(classification) {
270
+ if (classification === 'included')
271
+ return [1, 0, 0];
272
+ if (classification === 'overage')
273
+ return [0, 1, 0];
274
+ return [0, 0, 1];
275
+ }
276
+ function normalizeValidationInput(input) {
277
+ if (input.classification !== 'included' &&
278
+ input.classification !== 'overage' &&
279
+ input.classification !== 'denied') {
280
+ throw new Error('billing meter validation classification is invalid');
281
+ }
282
+ return {
283
+ ...input,
284
+ epochId: validateScalarId('billing meter epoch id', input.epochId),
285
+ org: validateSlug('org', input.org),
286
+ app: validateSlug('app', input.app),
287
+ environment: validateSlug('env', input.environment),
288
+ deploymentId: validateScalarId('billing meter deployment id', input.deploymentId),
289
+ ...(input.highConfidenceKeyHash === undefined
290
+ ? {}
291
+ : {
292
+ highConfidenceKeyHash: validateFingerprint('billing meter high-confidence key', input.highConfidenceKeyHash),
293
+ }),
294
+ fallbackFingerprint: validateFingerprint('billing meter fallback fingerprint', input.fallbackFingerprint),
295
+ semanticFingerprint: validateFingerprint('billing meter semantic fingerprint', input.semanticFingerprint),
296
+ };
297
+ }
298
+ function toIso(value) {
299
+ const date = value instanceof Date ? value : new Date(value);
300
+ if (!Number.isFinite(date.getTime()))
301
+ throw new Error('billing meter timestamp is invalid');
302
+ return date.toISOString();
303
+ }
304
+ function validateFingerprint(name, value) {
305
+ if (!/^[0-9a-f]{64}$/.test(value))
306
+ throw new Error(`${name} must be a SHA-256 digest`);
307
+ return value;
308
+ }
309
+ function validateReleaseSha(value) {
310
+ if (!/^[0-9a-f]{40}$/.test(value)) {
311
+ throw new Error('billing meter release SHA must be a full 40-character commit digest');
312
+ }
313
+ return value;
314
+ }
315
+ function validateWriterContractVersion(value) {
316
+ if (!Number.isSafeInteger(value) || value < 1) {
317
+ throw new Error('billing meter writer contract version must be positive');
318
+ }
319
+ return value;
320
+ }
321
+ //# sourceMappingURL=postgres-meter-validation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"postgres-meter-validation.js","sourceRoot":"","sources":["../../src/billing/postgres-meter-validation.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ export declare const BILLING_METER_CHANGED_WINDOW_RECONCILIATION_DELAY_MS: number;
2
+ export declare const BILLING_METER_CLEAN_WINDOW_RECONCILIATION_INTERVAL_MS: number;
3
+ export declare const BILLING_METER_FAILED_WINDOW_RECONCILIATION_DELAY_MS: number;
4
+ export declare const BILLING_METER_INTEGRITY_MODULUS = "2305843009213693951";
5
+ export declare function billingMeterWindowLockKey(input: {
6
+ readonly epochId: string;
7
+ readonly windowStart: string;
8
+ readonly windowEnd: string;
9
+ }): string;
10
+ //# sourceMappingURL=postgres-meter-window-lock.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"postgres-meter-window-lock.d.ts","sourceRoot":"","sources":["../../src/billing/postgres-meter-window-lock.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,oDAAoD,QAAkB,CAAC;AACpF,eAAO,MAAM,qDAAqD,QAAsB,CAAC;AACzF,eAAO,MAAM,mDAAmD,QAAkB,CAAC;AACnF,eAAO,MAAM,+BAA+B,wBAAwB,CAAC;AAErE,wBAAgB,yBAAyB,CAAC,KAAK,EAAE;IAC/C,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B,GAAG,MAAM,CAOT"}
@@ -0,0 +1,13 @@
1
+ export const BILLING_METER_CHANGED_WINDOW_RECONCILIATION_DELAY_MS = 15 * 60 * 1_000;
2
+ export const BILLING_METER_CLEAN_WINDOW_RECONCILIATION_INTERVAL_MS = 6 * 60 * 60 * 1_000;
3
+ export const BILLING_METER_FAILED_WINDOW_RECONCILIATION_DELAY_MS = 15 * 60 * 1_000;
4
+ export const BILLING_METER_INTEGRITY_MODULUS = '2305843009213693951';
5
+ export function billingMeterWindowLockKey(input) {
6
+ const windowStartMs = Date.parse(input.windowStart);
7
+ const windowEndMs = Date.parse(input.windowEnd);
8
+ if (!Number.isSafeInteger(windowStartMs) || !Number.isSafeInteger(windowEndMs)) {
9
+ throw new Error('billing meter window lock requires valid instants');
10
+ }
11
+ return `billing-meter-window:${input.epochId}:${windowStartMs}:${windowEndMs}`;
12
+ }
13
+ //# sourceMappingURL=postgres-meter-window-lock.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"postgres-meter-window-lock.js","sourceRoot":"","sources":["../../src/billing/postgres-meter-window-lock.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,oDAAoD,GAAG,EAAE,GAAG,EAAE,GAAG,KAAK,CAAC;AACpF,MAAM,CAAC,MAAM,qDAAqD,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,KAAK,CAAC;AACzF,MAAM,CAAC,MAAM,mDAAmD,GAAG,EAAE,GAAG,EAAE,GAAG,KAAK,CAAC;AACnF,MAAM,CAAC,MAAM,+BAA+B,GAAG,qBAAqB,CAAC;AAErE,MAAM,UAAU,yBAAyB,CAAC,KAIzC;IACC,MAAM,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;IACpD,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IAChD,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,WAAW,CAAC,EAAE,CAAC;QAC/E,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAC;IACvE,CAAC;IACD,OAAO,wBAAwB,KAAK,CAAC,OAAO,IAAI,aAAa,IAAI,WAAW,EAAE,CAAC;AACjF,CAAC"}
@@ -0,0 +1,6 @@
1
+ import type { Pool } from 'pg';
2
+ /** Create the one-row-per-window checkpoint before the receipt table adds its completeness FK. */
3
+ export declare function ensureBillingMeterWindowRegistrySchema(pool: Pool): Promise<void>;
4
+ /** Attach receipt-side checkpoint maintenance only after the partitioned receipt parent exists. */
5
+ export declare function ensureBillingMeterReceiptIntegritySchema(pool: Pool): Promise<void>;
6
+ //# sourceMappingURL=postgres-meter-window-schema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"postgres-meter-window-schema.d.ts","sourceRoot":"","sources":["../../src/billing/postgres-meter-window-schema.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,IAAI,CAAC;AAI/B,kGAAkG;AAClG,wBAAsB,sCAAsC,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAkDtF;AAED,mGAAmG;AACnG,wBAAsB,wCAAwC,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CA+LxF"}
@@ -0,0 +1,248 @@
1
+ import { BILLING_METER_AGGREGATE_RETENTION_MONTHS } from './meter-readiness.js';
2
+ import { BILLING_METER_INTEGRITY_MODULUS } from './postgres-meter-window-lock.js';
3
+ /** Create the one-row-per-window checkpoint before the receipt table adds its completeness FK. */
4
+ export async function ensureBillingMeterWindowRegistrySchema(pool) {
5
+ await pool.query(`
6
+ CREATE TABLE IF NOT EXISTS billing_meter_windows (
7
+ epoch_id text NOT NULL
8
+ REFERENCES billing_meter_epochs(id) ON DELETE RESTRICT,
9
+ window_start timestamptz NOT NULL,
10
+ window_end timestamptz NOT NULL CHECK (window_end > window_start),
11
+ receipt_included_calls bigint NOT NULL DEFAULT 0 CHECK (receipt_included_calls >= 0),
12
+ receipt_overage_calls bigint NOT NULL DEFAULT 0 CHECK (receipt_overage_calls >= 0),
13
+ receipt_denied_calls bigint NOT NULL DEFAULT 0 CHECK (receipt_denied_calls >= 0),
14
+ writer_observed_calls bigint NOT NULL DEFAULT 0 CHECK (writer_observed_calls >= 0),
15
+ account_integrity_a numeric(19, 0) NOT NULL DEFAULT 0
16
+ CHECK (account_integrity_a >= 0 AND account_integrity_a < ${BILLING_METER_INTEGRITY_MODULUS}),
17
+ account_integrity_b numeric(19, 0) NOT NULL DEFAULT 0
18
+ CHECK (account_integrity_b >= 0 AND account_integrity_b < ${BILLING_METER_INTEGRITY_MODULUS}),
19
+ org_integrity_a numeric(19, 0) NOT NULL DEFAULT 0
20
+ CHECK (org_integrity_a >= 0 AND org_integrity_a < ${BILLING_METER_INTEGRITY_MODULUS}),
21
+ org_integrity_b numeric(19, 0) NOT NULL DEFAULT 0
22
+ CHECK (org_integrity_b >= 0 AND org_integrity_b < ${BILLING_METER_INTEGRITY_MODULUS}),
23
+ first_observed_at timestamptz,
24
+ last_observed_at timestamptz,
25
+ last_writer_observed_at timestamptz,
26
+ sealed_at timestamptz,
27
+ retention_until timestamptz NOT NULL,
28
+ PRIMARY KEY (epoch_id, window_start, window_end),
29
+ CHECK (
30
+ (first_observed_at IS NULL AND last_observed_at IS NULL) OR
31
+ (first_observed_at IS NOT NULL AND last_observed_at IS NOT NULL AND
32
+ last_observed_at >= first_observed_at)
33
+ ),
34
+ CHECK (
35
+ retention_until =
36
+ window_end + interval '${BILLING_METER_AGGREGATE_RETENTION_MONTHS} months'
37
+ )
38
+ )
39
+ `);
40
+ await pool.query(`
41
+ CREATE INDEX IF NOT EXISTS billing_meter_windows_unsealed_idx
42
+ ON billing_meter_windows (epoch_id, window_end, first_observed_at)
43
+ WHERE sealed_at IS NULL
44
+ `);
45
+ await pool.query(`
46
+ CREATE INDEX IF NOT EXISTS billing_meter_windows_observation_span_idx
47
+ ON billing_meter_windows (first_observed_at, last_observed_at)
48
+ WHERE first_observed_at IS NOT NULL
49
+ `);
50
+ await pool.query(`
51
+ CREATE INDEX IF NOT EXISTS billing_meter_windows_retention_idx
52
+ ON billing_meter_windows (retention_until)
53
+ `);
54
+ }
55
+ /** Attach receipt-side checkpoint maintenance only after the partitioned receipt parent exists. */
56
+ export async function ensureBillingMeterReceiptIntegritySchema(pool) {
57
+ await pool.query(`
58
+ DO $$
59
+ BEGIN
60
+ IF NOT EXISTS (
61
+ SELECT 1 FROM pg_constraint
62
+ WHERE conrelid = 'billing_meter_usage_events'::regclass
63
+ AND conname = 'billing_meter_usage_events_window_fkey'
64
+ ) THEN
65
+ ALTER TABLE billing_meter_usage_events
66
+ ADD CONSTRAINT billing_meter_usage_events_window_fkey
67
+ FOREIGN KEY (epoch_id, window_start, window_end)
68
+ REFERENCES billing_meter_windows(epoch_id, window_start, window_end)
69
+ ON DELETE RESTRICT;
70
+ END IF;
71
+ END
72
+ $$
73
+ `);
74
+ await pool.query(`
75
+ CREATE OR REPLACE FUNCTION billing_meter_integrity_lane(
76
+ integrity_scope text,
77
+ account_id text,
78
+ organization_slug text,
79
+ usage_classification text,
80
+ lane integer
81
+ ) RETURNS numeric AS $$
82
+ WITH lane_bytes AS (
83
+ SELECT decode(
84
+ substr(
85
+ md5(
86
+ integrity_scope || ':' || octet_length(account_id)::text || ':' || account_id ||
87
+ ':' || octet_length(organization_slug)::text || ':' || organization_slug ||
88
+ ':' || usage_classification
89
+ ),
90
+ CASE lane WHEN 1 THEN 1 WHEN 2 THEN 17 END,
91
+ 16
92
+ ),
93
+ 'hex'
94
+ ) AS value
95
+ WHERE lane IN (1, 2)
96
+ )
97
+ SELECT mod(
98
+ coalesce(
99
+ sum(get_byte(value, ordinal)::numeric * power(256::numeric, 7 - ordinal)),
100
+ 0
101
+ ),
102
+ ${BILLING_METER_INTEGRITY_MODULUS}
103
+ )
104
+ FROM lane_bytes
105
+ CROSS JOIN generate_series(0, 7) AS ordinal
106
+ $$ LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE
107
+ `);
108
+ await pool.query(`
109
+ CREATE OR REPLACE FUNCTION billing_meter_receipt_before_insert()
110
+ RETURNS trigger AS $$
111
+ DECLARE
112
+ window_sealed_at timestamptz;
113
+ BEGIN
114
+ PERFORM pg_advisory_xact_lock_shared(
115
+ hashtextextended(
116
+ 'billing-meter-window:' || NEW.epoch_id || ':' ||
117
+ ((extract(epoch FROM NEW.window_start) * 1000)::bigint)::text || ':' ||
118
+ ((extract(epoch FROM NEW.window_end) * 1000)::bigint)::text,
119
+ 0
120
+ )
121
+ );
122
+ INSERT INTO billing_meter_windows
123
+ (epoch_id, window_start, window_end, retention_until)
124
+ VALUES
125
+ (NEW.epoch_id, NEW.window_start, NEW.window_end,
126
+ NEW.window_end + interval '${BILLING_METER_AGGREGATE_RETENTION_MONTHS} months')
127
+ ON CONFLICT (epoch_id, window_start, window_end) DO NOTHING;
128
+ SELECT sealed_at INTO window_sealed_at
129
+ FROM billing_meter_windows
130
+ WHERE epoch_id = NEW.epoch_id
131
+ AND window_start = NEW.window_start
132
+ AND window_end = NEW.window_end;
133
+ IF window_sealed_at IS NOT NULL THEN
134
+ RAISE EXCEPTION 'billing meter validation window is sealed';
135
+ END IF;
136
+ RETURN NEW;
137
+ END
138
+ $$ LANGUAGE plpgsql
139
+ `);
140
+ await pool.query(`
141
+ CREATE OR REPLACE FUNCTION billing_meter_receipt_after_insert()
142
+ RETURNS trigger AS $$
143
+ BEGIN
144
+ UPDATE billing_meter_windows
145
+ SET receipt_included_calls = receipt_included_calls +
146
+ CASE WHEN NEW.classification = 'included' THEN 1 ELSE 0 END,
147
+ receipt_overage_calls = receipt_overage_calls +
148
+ CASE WHEN NEW.classification = 'overage' THEN 1 ELSE 0 END,
149
+ receipt_denied_calls = receipt_denied_calls +
150
+ CASE WHEN NEW.classification = 'denied' THEN 1 ELSE 0 END,
151
+ writer_observed_calls = writer_observed_calls +
152
+ CASE WHEN to_jsonb(NEW)->>'writer_session_id' IS NULL THEN 0 ELSE 1 END,
153
+ account_integrity_a = mod(
154
+ account_integrity_a + billing_meter_integrity_lane(
155
+ 'account', NEW.billing_account_id, '', NEW.classification, 1
156
+ ),
157
+ ${BILLING_METER_INTEGRITY_MODULUS}
158
+ ),
159
+ account_integrity_b = mod(
160
+ account_integrity_b + billing_meter_integrity_lane(
161
+ 'account', NEW.billing_account_id, '', NEW.classification, 2
162
+ ),
163
+ ${BILLING_METER_INTEGRITY_MODULUS}
164
+ ),
165
+ org_integrity_a = mod(
166
+ org_integrity_a + billing_meter_integrity_lane(
167
+ 'organization', NEW.billing_account_id, NEW.org_slug, NEW.classification, 1
168
+ ),
169
+ ${BILLING_METER_INTEGRITY_MODULUS}
170
+ ),
171
+ org_integrity_b = mod(
172
+ org_integrity_b + billing_meter_integrity_lane(
173
+ 'organization', NEW.billing_account_id, NEW.org_slug, NEW.classification, 2
174
+ ),
175
+ ${BILLING_METER_INTEGRITY_MODULUS}
176
+ ),
177
+ first_observed_at = least(coalesce(first_observed_at, NEW.recorded_at), NEW.recorded_at),
178
+ last_observed_at = greatest(coalesce(last_observed_at, NEW.recorded_at), NEW.recorded_at),
179
+ last_writer_observed_at = CASE
180
+ WHEN to_jsonb(NEW)->>'writer_session_id' IS NULL THEN last_writer_observed_at
181
+ ELSE greatest(coalesce(last_writer_observed_at, NEW.recorded_at), NEW.recorded_at)
182
+ END
183
+ WHERE epoch_id = NEW.epoch_id
184
+ AND window_start = NEW.window_start
185
+ AND window_end = NEW.window_end
186
+ AND sealed_at IS NULL;
187
+ IF NOT FOUND THEN
188
+ RAISE EXCEPTION 'billing meter validation window is sealed';
189
+ END IF;
190
+ RETURN NULL;
191
+ END
192
+ $$ LANGUAGE plpgsql
193
+ `);
194
+ await pool.query(`
195
+ CREATE OR REPLACE FUNCTION billing_meter_receipt_guard_mutation()
196
+ RETURNS trigger AS $$
197
+ BEGIN
198
+ IF TG_OP = 'UPDATE' THEN
199
+ RAISE EXCEPTION 'billing meter receipts are immutable';
200
+ END IF;
201
+ IF current_setting('noodle.billing_meter_receipt_maintenance', true) = 'on' AND EXISTS (
202
+ SELECT 1 FROM billing_meter_windows
203
+ WHERE epoch_id = OLD.epoch_id
204
+ AND window_start = OLD.window_start
205
+ AND window_end = OLD.window_end
206
+ AND sealed_at IS NOT NULL
207
+ ) THEN
208
+ RETURN OLD;
209
+ END IF;
210
+ RAISE EXCEPTION 'billing meter receipt deletion requires sealed maintenance';
211
+ END
212
+ $$ LANGUAGE plpgsql
213
+ `);
214
+ await pool.query(`
215
+ DO $$
216
+ BEGIN
217
+ IF NOT EXISTS (
218
+ SELECT 1 FROM pg_trigger
219
+ WHERE tgrelid = 'billing_meter_usage_events'::regclass
220
+ AND tgname = 'billing_meter_receipt_before_insert_trigger'
221
+ ) THEN
222
+ CREATE TRIGGER billing_meter_receipt_before_insert_trigger
223
+ BEFORE INSERT ON billing_meter_usage_events
224
+ FOR EACH ROW EXECUTE FUNCTION billing_meter_receipt_before_insert();
225
+ END IF;
226
+ IF NOT EXISTS (
227
+ SELECT 1 FROM pg_trigger
228
+ WHERE tgrelid = 'billing_meter_usage_events'::regclass
229
+ AND tgname = 'billing_meter_receipt_after_insert_trigger'
230
+ ) THEN
231
+ CREATE TRIGGER billing_meter_receipt_after_insert_trigger
232
+ AFTER INSERT ON billing_meter_usage_events
233
+ FOR EACH ROW EXECUTE FUNCTION billing_meter_receipt_after_insert();
234
+ END IF;
235
+ IF NOT EXISTS (
236
+ SELECT 1 FROM pg_trigger
237
+ WHERE tgrelid = 'billing_meter_usage_events'::regclass
238
+ AND tgname = 'billing_meter_receipt_guard_mutation_trigger'
239
+ ) THEN
240
+ CREATE TRIGGER billing_meter_receipt_guard_mutation_trigger
241
+ BEFORE UPDATE OR DELETE ON billing_meter_usage_events
242
+ FOR EACH ROW EXECUTE FUNCTION billing_meter_receipt_guard_mutation();
243
+ END IF;
244
+ END
245
+ $$
246
+ `);
247
+ }
248
+ //# sourceMappingURL=postgres-meter-window-schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"postgres-meter-window-schema.js","sourceRoot":"","sources":["../../src/billing/postgres-meter-window-schema.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,wCAAwC,EAAE,MAAM,sBAAsB,CAAC;AAChF,OAAO,EAAE,+BAA+B,EAAE,MAAM,iCAAiC,CAAC;AAElF,kGAAkG;AAClG,MAAM,CAAC,KAAK,UAAU,sCAAsC,CAAC,IAAU;IACrE,MAAM,IAAI,CAAC,KAAK,CAAC;;;;;;;;;;;oEAWiD,+BAA+B;;oEAE/B,+BAA+B;;4DAEvC,+BAA+B;;4DAE/B,+BAA+B;;;;;;;;;;;;;;mCAcxD,wCAAwC;;;GAGxE,CAAC,CAAC;IACH,MAAM,IAAI,CAAC,KAAK,CAAC;;;;GAIhB,CAAC,CAAC;IACH,MAAM,IAAI,CAAC,KAAK,CAAC;;;;GAIhB,CAAC,CAAC;IACH,MAAM,IAAI,CAAC,KAAK,CAAC;;;GAGhB,CAAC,CAAC;AACL,CAAC;AAED,mGAAmG;AACnG,MAAM,CAAC,KAAK,UAAU,wCAAwC,CAAC,IAAU;IACvE,MAAM,IAAI,CAAC,KAAK,CAAC;;;;;;;;;;;;;;;;GAgBhB,CAAC,CAAC;IACH,MAAM,IAAI,CAAC,KAAK,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;UA4BT,+BAA+B;;;;;GAKtC,CAAC,CAAC;IACH,MAAM,IAAI,CAAC,KAAK,CAAC;;;;;;;;;;;;;;;;;;sCAkBmB,wCAAwC;;;;;;;;;;;;;GAa3E,CAAC,CAAC;IACH,MAAM,IAAI,CAAC,KAAK,CAAC;;;;;;;;;;;;;;;;;cAiBL,+BAA+B;;;;;;cAM/B,+BAA+B;;;;;;cAM/B,+BAA+B;;;;;;cAM/B,+BAA+B;;;;;;;;;;;;;;;;;;GAkB1C,CAAC,CAAC;IACH,MAAM,IAAI,CAAC,KAAK,CAAC;;;;;;;;;;;;;;;;;;;GAmBhB,CAAC,CAAC;IACH,MAAM,IAAI,CAAC,KAAK,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgChB,CAAC,CAAC;AACL,CAAC"}