@cat-factory/orchestration 0.225.0 → 0.228.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 (74) hide show
  1. package/dist/container/dependencies.d.ts +23 -1
  2. package/dist/container/dependencies.d.ts.map +1 -1
  3. package/dist/container/foundation.d.ts.map +1 -1
  4. package/dist/container/foundation.js +17 -6
  5. package/dist/container/foundation.js.map +1 -1
  6. package/dist/container/modules.js +2 -2
  7. package/dist/container/modules.js.map +1 -1
  8. package/dist/container/platform-modules.d.ts.map +1 -1
  9. package/dist/container/platform-modules.js +1 -0
  10. package/dist/container/platform-modules.js.map +1 -1
  11. package/dist/container.d.ts +21 -8
  12. package/dist/container.d.ts.map +1 -1
  13. package/dist/container.js +4 -1
  14. package/dist/container.js.map +1 -1
  15. package/dist/index.d.ts +1 -1
  16. package/dist/index.d.ts.map +1 -1
  17. package/dist/index.js +1 -1
  18. package/dist/index.js.map +1 -1
  19. package/dist/modules/board/BoardService.d.ts +22 -9
  20. package/dist/modules/board/BoardService.d.ts.map +1 -1
  21. package/dist/modules/board/BoardService.js +42 -106
  22. package/dist/modules/board/BoardService.js.map +1 -1
  23. package/dist/modules/board/publicBoardReads.d.ts +3 -3
  24. package/dist/modules/board/publicBoardReads.d.ts.map +1 -1
  25. package/dist/modules/board/publicBoardReads.js.map +1 -1
  26. package/dist/modules/board/reparentWrite.d.ts +43 -0
  27. package/dist/modules/board/reparentWrite.d.ts.map +1 -0
  28. package/dist/modules/board/reparentWrite.js +126 -0
  29. package/dist/modules/board/reparentWrite.js.map +1 -0
  30. package/dist/modules/board/riskPolicySelectionGuard.d.ts +45 -4
  31. package/dist/modules/board/riskPolicySelectionGuard.d.ts.map +1 -1
  32. package/dist/modules/board/riskPolicySelectionGuard.js +84 -20
  33. package/dist/modules/board/riskPolicySelectionGuard.js.map +1 -1
  34. package/dist/modules/boardScan/BoardScanService.js +6 -6
  35. package/dist/modules/boardScan/BoardScanService.js.map +1 -1
  36. package/dist/modules/execution/ExecutionServiceDependencies.d.ts +2 -1
  37. package/dist/modules/execution/ExecutionServiceDependencies.d.ts.map +1 -1
  38. package/dist/modules/execution/MergeResolver.d.ts +3 -3
  39. package/dist/modules/execution/MergeResolver.d.ts.map +1 -1
  40. package/dist/modules/execution/MergeResolver.js +76 -34
  41. package/dist/modules/execution/MergeResolver.js.map +1 -1
  42. package/dist/modules/execution/PostMergeBoardController.d.ts.map +1 -1
  43. package/dist/modules/execution/PostMergeBoardController.js +6 -1
  44. package/dist/modules/execution/PostMergeBoardController.js.map +1 -1
  45. package/dist/modules/execution/RunMergePolicy.d.ts +3 -2
  46. package/dist/modules/execution/RunMergePolicy.d.ts.map +1 -1
  47. package/dist/modules/execution/RunMergePolicy.js +1 -1
  48. package/dist/modules/execution/RunMergePolicy.js.map +1 -1
  49. package/dist/modules/execution/StepGraph.d.ts.map +1 -1
  50. package/dist/modules/execution/StepGraph.js +20 -0
  51. package/dist/modules/execution/StepGraph.js.map +1 -1
  52. package/dist/modules/execution/policy-types.d.ts +5 -4
  53. package/dist/modules/execution/policy-types.d.ts.map +1 -1
  54. package/dist/modules/merge/RiskPolicyService.d.ts +22 -11
  55. package/dist/modules/merge/RiskPolicyService.d.ts.map +1 -1
  56. package/dist/modules/merge/RiskPolicyService.js +27 -48
  57. package/dist/modules/merge/RiskPolicyService.js.map +1 -1
  58. package/dist/modules/merge/riskPolicyResolution.d.ts +36 -4
  59. package/dist/modules/merge/riskPolicyResolution.d.ts.map +1 -1
  60. package/dist/modules/merge/riskPolicyResolution.js +36 -8
  61. package/dist/modules/merge/riskPolicyResolution.js.map +1 -1
  62. package/dist/modules/observability/retentionPass.d.ts +82 -1
  63. package/dist/modules/observability/retentionPass.d.ts.map +1 -1
  64. package/dist/modules/observability/retentionPass.js +104 -0
  65. package/dist/modules/observability/retentionPass.js.map +1 -1
  66. package/dist/modules/reports/ReportsService.d.ts +29 -6
  67. package/dist/modules/reports/ReportsService.d.ts.map +1 -1
  68. package/dist/modules/reports/ReportsService.js +64 -18
  69. package/dist/modules/reports/ReportsService.js.map +1 -1
  70. package/dist/modules/reports/reports.logic.d.ts +16 -2
  71. package/dist/modules/reports/reports.logic.d.ts.map +1 -1
  72. package/dist/modules/reports/reports.logic.js +26 -5
  73. package/dist/modules/reports/reports.logic.js.map +1 -1
  74. package/package.json +11 -11
@@ -1 +1 @@
1
- {"version":3,"file":"RiskPolicyService.js","sourceRoot":"","sources":["../../../src/modules/merge/RiskPolicyService.ts"],"names":[],"mappings":"AAWA,OAAO,EACL,WAAW,EACX,aAAa,EACb,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,GAChB,MAAM,qBAAqB,CAAA;AAgB5B;;;;;;;;GAQG;AACH,MAAM,OAAO,iBAAiB;IACX,OAAO,CAAsB;IAC7B,mBAAmB,CAAqB;IACxC,WAAW,CAAa;IACxB,KAAK,CAAO;IACZ,KAAK,CAAyC;IAE/D,YAAY,IAAmC;QAC7C,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,oBAAoB,CAAA;QACxC,IAAI,CAAC,mBAAmB,GAAG,IAAI,CAAC,mBAAmB,CAAA;QACnD,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,WAAW,CAAA;QACnC,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAA;QACvB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,eAAe,CAAA;IACnC,CAAC;IAED;;;;OAIG;IACK,KAAK,CAAC,UAAU,CAAC,WAAmB;QAC1C,MAAM,IAAI,CAAC,KAAK,EAAE,eAAe,CAAC,WAAW,CAAC,CAAA;IAChD,CAAC;IAED,kFAAkF;IAClF,KAAK,CAAC,IAAI,CAAC,WAAmB;QAC5B,MAAM,gBAAgB,CAAC,IAAI,CAAC,mBAAmB,EAAE,WAAW,CAAC,CAAA;QAC7D,MAAM,IAAI,CAAC,YAAY,CAAC,WAAW,CAAC,CAAA;QACpC,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW,CAAC,CAAA;IACvC,CAAC;IAED,uFAAuF;IACvF,KAAK,CAAC,MAAM,CAAC,WAAmB,EAAE,KAA4B;QAC5D,MAAM,gBAAgB,CAAC,IAAI,CAAC,mBAAmB,EAAE,WAAW,CAAC,CAAA;QAC7D,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW,CAAC,CAAA;QACrD,MAAM,MAAM,GAAe;YACzB,EAAE,EAAE,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC;YAC/B,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,aAAa,EAAE,KAAK,CAAC,aAAa;YAClC,OAAO,EAAE,KAAK,CAAC,OAAO;YACtB,SAAS,EAAE,KAAK,CAAC,SAAS;YAC1B,aAAa,EAAE,KAAK,CAAC,aAAa;YAClC,wBAAwB,EAAE,KAAK,CAAC,wBAAwB;YACxD,4BAA4B,EAAE,KAAK,CAAC,4BAA4B;YAChE,0BAA0B,EAAE,KAAK,CAAC,0BAA0B;YAC5D,yBAAyB,EAAE,KAAK,CAAC,yBAAyB;YAC1D,kBAAkB,EAAE,KAAK,CAAC,kBAAkB;YAC5C,uBAAuB,EAAE,KAAK,CAAC,uBAAuB;YACtD,aAAa,EAAE,KAAK,CAAC,aAAa;YAClC,eAAe,EAAE,KAAK,CAAC,eAAe;YACtC,gBAAgB,EAAE,KAAK,CAAC,gBAAgB;YACxC,YAAY,EAAE,KAAK,CAAC,YAAY,IAAI,IAAI;YACxC,UAAU,EAAE,KAAK,CAAC,UAAU;YAC5B,gBAAgB,EAAE,KAAK,CAAC,gBAAgB;YACxC,WAAW,EAAE,KAAK,CAAC,WAAW;YAC9B,uBAAuB,EAAE,KAAK,CAAC,uBAAuB;YACtD,2EAA2E;YAC3E,SAAS,EAAE,QAAQ,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS;YACzD,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE;SAC5B,CAAA;QACD,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC,CAAA;QAC9C,MAAM,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,CAAA;QAClC,OAAO,MAAM,CAAA;IACf,CAAC;IAED,+EAA+E;IAC/E,KAAK,CAAC,MAAM,CAAC,WAAmB,EAAE,EAAU,EAAE,KAA4B;QACxE,MAAM,gBAAgB,CAAC,IAAI,CAAC,mBAAmB,EAAE,WAAW,CAAC,CAAA;QAC7D,MAAM,QAAQ,GAAG,WAAW,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,WAAW,EAAE,EAAE,CAAC,EAAE,YAAY,EAAE,EAAE,CAAC,CAAA;QACvF,IAAI,QAAQ,CAAC,SAAS,IAAI,KAAK,CAAC,SAAS,KAAK,KAAK,EAAE,CAAC;YACpD,MAAM,IAAI,aAAa,CAAC,kEAAkE,CAAC,CAAA;QAC7F,CAAC;QACD,MAAM,OAAO,GAAe;YAC1B,GAAG,QAAQ;YACX,GAAG,CAAC,KAAK,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACzD,GAAG,CAAC,KAAK,CAAC,aAAa,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,KAAK,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACpF,GAAG,CAAC,KAAK,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAClE,GAAG,CAAC,KAAK,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACxE,GAAG,CAAC,KAAK,CAAC,aAAa,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,KAAK,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACpF,GAAG,CAAC,KAAK,CAAC,wBAAwB,KAAK,SAAS;gBAC9C,CAAC,CAAC,EAAE,wBAAwB,EAAE,KAAK,CAAC,wBAAwB,EAAE;gBAC9D,CAAC,CAAC,EAAE,CAAC;YACP,GAAG,CAAC,KAAK,CAAC,4BAA4B,KAAK,SAAS;gBAClD,CAAC,CAAC,EAAE,4BAA4B,EAAE,KAAK,CAAC,4BAA4B,EAAE;gBACtE,CAAC,CAAC,EAAE,CAAC;YACP,GAAG,CAAC,KAAK,CAAC,0BAA0B,KAAK,SAAS;gBAChD,CAAC,CAAC,EAAE,0BAA0B,EAAE,KAAK,CAAC,0BAA0B,EAAE;gBAClE,CAAC,CAAC,EAAE,CAAC;YACP,GAAG,CAAC,KAAK,CAAC,yBAAyB,KAAK,SAAS;gBAC/C,CAAC,CAAC,EAAE,yBAAyB,EAAE,KAAK,CAAC,yBAAyB,EAAE;gBAChE,CAAC,CAAC,EAAE,CAAC;YACP,GAAG,CAAC,KAAK,CAAC,kBAAkB,KAAK,SAAS;gBACxC,CAAC,CAAC,EAAE,kBAAkB,EAAE,KAAK,CAAC,kBAAkB,EAAE;gBAClD,CAAC,CAAC,EAAE,CAAC;YACP,GAAG,CAAC,KAAK,CAAC,uBAAuB,KAAK,SAAS;gBAC7C,CAAC,CAAC,EAAE,uBAAuB,EAAE,KAAK,CAAC,uBAAuB,EAAE;gBAC5D,CAAC,CAAC,EAAE,CAAC;YACP,GAAG,CAAC,KAAK,CAAC,aAAa,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,KAAK,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACpF,GAAG,CAAC,KAAK,CAAC,eAAe,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,eAAe,EAAE,KAAK,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC1F,GAAG,CAAC,KAAK,CAAC,gBAAgB,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,gBAAgB,EAAE,KAAK,CAAC,gBAAgB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC7F,GAAG,CAAC,KAAK,CAAC,YAAY,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,KAAK,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACjF,yFAAyF;YACzF,wFAAwF;YACxF,wFAAwF;YACxF,0FAA0F;YAC1F,mFAAmF;YACnF,GAAG,CAAC,KAAK,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,KAAK,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC3E,GAAG,CAAC,KAAK,CAAC,gBAAgB,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,gBAAgB,EAAE,KAAK,CAAC,gBAAgB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC7F,GAAG,CAAC,KAAK,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC9E,GAAG,CAAC,KAAK,CAAC,uBAAuB,KAAK,SAAS;gBAC7C,CAAC,CAAC,EAAE,uBAAuB,EAAE,KAAK,CAAC,uBAAuB,EAAE;gBAC5D,CAAC,CAAC,EAAE,CAAC;YACP,GAAG,CAAC,KAAK,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACzE,CAAA;QACD,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,OAAO,CAAC,CAAA;QAC/C,MAAM,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,CAAA;QAClC,OAAO,OAAO,CAAA;IAChB,CAAC;IAED,6DAA6D;IAC7D,KAAK,CAAC,MAAM,CAAC,WAAmB,EAAE,EAAU;QAC1C,MAAM,gBAAgB,CAAC,IAAI,CAAC,mBAAmB,EAAE,WAAW,CAAC,CAAA;QAC7D,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,WAAW,EAAE,EAAE,CAAC,CAAA;QACxD,IAAI,QAAQ,EAAE,SAAS,EAAE,CAAC;YACxB,MAAM,IAAI,aAAa,CAAC,iEAAiE,CAAC,CAAA;QAC5F,CAAC;QACD,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,EAAE,CAAC,CAAA;QAC1C,MAAM,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,CAAA;IACpC,CAAC;IAED;;;;;;;;;;;OAWG;IACH,KAAK,CAAC,MAAM,CAAC,WAAmB,EAAE,EAAU;QAC1C,MAAM,gBAAgB,CAAC,IAAI,CAAC,mBAAmB,EAAE,WAAW,CAAC,CAAA;QAC7D,MAAM,IAAI,GAAG,gBAAgB,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAA;QACxD,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,MAAM,IAAI,eAAe,CACvB,gBAAgB,EAAE,oGAAoG,CACvH,CAAA;QACH,CAAC;QACD,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,WAAW,EAAE,EAAE,CAAC,CAAA;QACxD,oFAAoF;QACpF,qFAAqF;QACrF,oFAAoF;QACpF,MAAM,SAAS,GAAG,QAAQ;YACxB,CAAC,CAAC,QAAQ,CAAC,SAAS;YACpB,CAAC,CAAC,IAAI,CAAC,SAAS,IAAI,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC,KAAK,IAAI,CAAA;QAC3E,MAAM,MAAM,GAAe;YACzB,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;YACtB,SAAS;YACT,SAAS,EAAE,QAAQ,EAAE,SAAS,IAAI,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE;SACnD,CAAA;QACD,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC,CAAA;QAC9C,MAAM,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,CAAA;QAClC,OAAO,MAAM,CAAA;IACf,CAAC;IAED,sFAAsF;IAC9E,KAAK,CAAC,YAAY,CAAC,WAAmB;QAC5C,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW,CAAC,CAAA;QACpD,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC;YAAE,OAAM;QAC9B,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAA;QAC5B,mFAAmF;QACnF,IAAI,MAAM,GAAG,CAAC,CAAA;QACd,KAAK,MAAM,IAAI,IAAI,gBAAgB,EAAE,EAAE,CAAC;YACtC,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE;gBACrC,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;gBACtB,SAAS,EAAE,GAAG,GAAG,MAAM,EAAE;aAC1B,CAAC,CAAA;QACJ,CAAC;QACD,wFAAwF;QACxF,0FAA0F;QAC1F,MAAM,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,CAAA;IACpC,CAAC;IAED,2FAA2F;IACnF,QAAQ,CAAC,IAAoB;QACnC,OAAO;YACL,EAAE,EAAE,IAAI,CAAC,EAAE;YACX,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,aAAa,EAAE,IAAI,CAAC,aAAa;YACjC,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,aAAa,EAAE,IAAI,CAAC,aAAa;YACjC,wBAAwB,EAAE,IAAI,CAAC,wBAAwB;YACvD,4BAA4B,EAAE,IAAI,CAAC,4BAA4B;YAC/D,0BAA0B,EAAE,IAAI,CAAC,0BAA0B;YAC3D,yBAAyB,EAAE,IAAI,CAAC,yBAAyB;YACzD,kBAAkB,EAAE,IAAI,CAAC,kBAAkB;YAC3C,uBAAuB,EAAE,IAAI,CAAC,uBAAuB;YACrD,aAAa,EAAE,IAAI,CAAC,aAAa;YACjC,eAAe,EAAE,IAAI,CAAC,eAAe;YACrC,gBAAgB,EAAE,IAAI,CAAC,gBAAgB;YACvC,YAAY,EAAE,IAAI,CAAC,YAAY;YAC/B,gBAAgB,EAAE,IAAI,CAAC,gBAAgB;YACvC,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,uBAAuB,EAAE,IAAI,CAAC,uBAAuB;YACrD,UAAU,EAAE,IAAI,CAAC,UAAU;YAC3B,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,OAAO,EAAE,IAAI,CAAC,OAAO;SACtB,CAAA;IACH,CAAC;CACF"}
1
+ {"version":3,"file":"RiskPolicyService.js","sourceRoot":"","sources":["../../../src/modules/merge/RiskPolicyService.ts"],"names":[],"mappings":"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"}
@@ -1,8 +1,22 @@
1
1
  import type { GroupCacheHandle, RiskPolicy, RiskPolicyCacheValue } from '@cat-factory/kernel';
2
2
  import type { RiskPolicyRepository } from '@cat-factory/kernel';
3
3
  import type { ResolvedRunRiskPolicy } from '../execution/policy-types.js';
4
- /** Reads one preset row, possibly through a cache slice. */
5
- export type RiskPolicyRead = (key: string, load: () => Promise<RiskPolicy | null>) => Promise<RiskPolicy | null>;
4
+ /**
5
+ * WHICH row a resolution wants: the id the task pinned, or the workspace's default.
6
+ *
7
+ * A discriminated target rather than the cache key string it used to be. The key spelling is one
8
+ * reader's encoding, and picking the id back out of it (`key.slice('picked:'.length)`) is the
9
+ * shape that reads as correct until someone renames a prefix; a second reader that answers off a
10
+ * preloaded library needs the id, not the key.
11
+ */
12
+ export type RiskPolicyTarget = {
13
+ kind: 'picked';
14
+ id: string;
15
+ } | {
16
+ kind: 'default';
17
+ };
18
+ /** Reads one preset row, possibly through a cache slice or a preloaded library. */
19
+ export type RiskPolicyRead = (target: RiskPolicyTarget, load: () => Promise<RiskPolicy | null>) => Promise<RiskPolicy | null>;
6
20
  /** Read straight from the repository, for the paths with no cache slice wired to read through. */
7
21
  export declare const directRiskPolicyRead: RiskPolicyRead;
8
22
  /**
@@ -12,12 +26,30 @@ export declare const directRiskPolicyRead: RiskPolicyRead;
12
26
  * exactly as an uncached read would. That is what the `RiskPolicyCacheValue` wrapper is for.
13
27
  */
14
28
  export declare function cachedRiskPolicyRead(cache: GroupCacheHandle<RiskPolicyCacheValue> | undefined, workspaceId: string): RiskPolicyRead;
29
+ /**
30
+ * Answer every resolution in one workspace out of its library, already read in full.
31
+ *
32
+ * For the caller that resolves MANY ids in the same workspace at once (the board's preset guard,
33
+ * judging every block in a moved subtree), where the per-id shape is the banned N+1: one point
34
+ * read per pin plus the workspace default re-read once per pin. A preset library is a handful of
35
+ * rows a workspace admin maintains by hand, so reading it whole is one query whatever the subtree
36
+ * holds, and the workspace default stops being a repeated round trip.
37
+ *
38
+ * `load` is never called: the library IS the answer, and a miss (a pinned id that no longer exists,
39
+ * a workspace with no default seeded) is a real null that falls through to the same place an
40
+ * uncached read's null would, which is {@link FALLBACK_RISK_POLICY}.
41
+ */
42
+ export declare function preloadedRiskPolicyRead(library: readonly RiskPolicy[]): RiskPolicyRead;
15
43
  /**
16
44
  * Resolve the preset governing `riskPolicyId` in a workspace.
17
45
  *
18
46
  * An ABSENT repository is not a hole to guard: with no preset library there is nothing for a task
19
- * to point at, so every task in the deployment is governed by {@link DEFAULT_RISK_POLICY}, whose
20
- * role layer is empty and therefore holds nobody to anything.
47
+ * to point at, so every task in the deployment is governed by {@link FALLBACK_RISK_POLICY}, whose
48
+ * role layer is empty and therefore holds nobody to anything, and which auto-merges nothing, so
49
+ * the deployment that configured no policy lands no PR without a human.
50
+ *
51
+ * A wired repository answers from a library the board was seeded with at CREATION, so reaching
52
+ * the fallback is a deployment-level fact rather than a question of who had read what first.
21
53
  */
22
54
  export declare function resolveRiskPolicy(input: {
23
55
  repository: RiskPolicyRepository | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"riskPolicyResolution.d.ts","sourceRoot":"","sources":["../../../src/modules/merge/riskPolicyResolution.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,UAAU,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAA;AAC7F,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAA;AAE/D,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAA;AAkBzE,4DAA4D;AAC5D,MAAM,MAAM,cAAc,GAAG,CAC3B,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,KACnC,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAAA;AAE/B,kGAAkG;AAClG,eAAO,MAAM,oBAAoB,EAAE,cAAuC,CAAA;AAE1E;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,gBAAgB,CAAC,oBAAoB,CAAC,GAAG,SAAS,EACzD,WAAW,EAAE,MAAM,GAClB,cAAc,CAIhB;AAED;;;;;;GAMG;AACH,wBAAsB,iBAAiB,CAAC,KAAK,EAAE;IAC7C,UAAU,EAAE,oBAAoB,GAAG,SAAS,CAAA;IAC5C,WAAW,EAAE,MAAM,CAAA;IACnB,YAAY,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAA;IACvC,IAAI,CAAC,EAAE,cAAc,CAAA;CACtB,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAWjC"}
1
+ {"version":3,"file":"riskPolicyResolution.d.ts","sourceRoot":"","sources":["../../../src/modules/merge/riskPolicyResolution.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,UAAU,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAA;AAC7F,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAA;AAE/D,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAA;AAkBzE;;;;;;;GAOG;AACH,MAAM,MAAM,gBAAgB,GAAG;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,CAAA;AAEnF,mFAAmF;AACnF,MAAM,MAAM,cAAc,GAAG,CAC3B,MAAM,EAAE,gBAAgB,EACxB,IAAI,EAAE,MAAM,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,KACnC,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAAA;AAE/B,kGAAkG;AAClG,eAAO,MAAM,oBAAoB,EAAE,cAA0C,CAAA;AAO7E;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,gBAAgB,CAAC,oBAAoB,CAAC,GAAG,SAAS,EACzD,WAAW,EAAE,MAAM,GAClB,cAAc,CAKhB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,SAAS,UAAU,EAAE,GAAG,cAAc,CAKtF;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,iBAAiB,CAAC,KAAK,EAAE;IAC7C,UAAU,EAAE,oBAAoB,GAAG,SAAS,CAAA;IAC5C,WAAW,EAAE,MAAM,CAAA;IACnB,YAAY,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAA;IACvC,IAAI,CAAC,EAAE,cAAc,CAAA;CACtB,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAcjC"}
@@ -1,6 +1,10 @@
1
- import { DEFAULT_RISK_POLICY } from '@cat-factory/kernel';
1
+ import { FALLBACK_RISK_POLICY } from '@cat-factory/kernel';
2
2
  /** Read straight from the repository, for the paths with no cache slice wired to read through. */
3
- export const directRiskPolicyRead = (_key, load) => load();
3
+ export const directRiskPolicyRead = (_target, load) => load();
4
+ /** The cache key one target resolves under; the ONE place that spelling lives. */
5
+ function cacheKeyOf(target) {
6
+ return target.kind === 'picked' ? `picked:${target.id}` : 'default';
7
+ }
4
8
  /**
5
9
  * Read through the `AppCaches.riskPolicy` slice, grouped by workspace (one preset write drops the
6
10
  * whole library) and keyed per resolved id, so a task's pick and the workspace default cache
@@ -10,25 +14,49 @@ export const directRiskPolicyRead = (_key, load) => load();
10
14
  export function cachedRiskPolicyRead(cache, workspaceId) {
11
15
  if (!cache)
12
16
  return directRiskPolicyRead;
13
- return async (key, load) => (await cache.get(key, workspaceId, async () => ({ policy: await load() }))).policy;
17
+ return async (target, load) => (await cache.get(cacheKeyOf(target), workspaceId, async () => ({ policy: await load() })))
18
+ .policy;
19
+ }
20
+ /**
21
+ * Answer every resolution in one workspace out of its library, already read in full.
22
+ *
23
+ * For the caller that resolves MANY ids in the same workspace at once (the board's preset guard,
24
+ * judging every block in a moved subtree), where the per-id shape is the banned N+1: one point
25
+ * read per pin plus the workspace default re-read once per pin. A preset library is a handful of
26
+ * rows a workspace admin maintains by hand, so reading it whole is one query whatever the subtree
27
+ * holds, and the workspace default stops being a repeated round trip.
28
+ *
29
+ * `load` is never called: the library IS the answer, and a miss (a pinned id that no longer exists,
30
+ * a workspace with no default seeded) is a real null that falls through to the same place an
31
+ * uncached read's null would, which is {@link FALLBACK_RISK_POLICY}.
32
+ */
33
+ export function preloadedRiskPolicyRead(library) {
34
+ const byId = new Map(library.map((preset) => [preset.id, preset]));
35
+ const workspaceDefault = library.find((preset) => preset.isDefault) ?? null;
36
+ return (target) => Promise.resolve(target.kind === 'picked' ? (byId.get(target.id) ?? null) : workspaceDefault);
14
37
  }
15
38
  /**
16
39
  * Resolve the preset governing `riskPolicyId` in a workspace.
17
40
  *
18
41
  * An ABSENT repository is not a hole to guard: with no preset library there is nothing for a task
19
- * to point at, so every task in the deployment is governed by {@link DEFAULT_RISK_POLICY}, whose
20
- * role layer is empty and therefore holds nobody to anything.
42
+ * to point at, so every task in the deployment is governed by {@link FALLBACK_RISK_POLICY}, whose
43
+ * role layer is empty and therefore holds nobody to anything, and which auto-merges nothing, so
44
+ * the deployment that configured no policy lands no PR without a human.
45
+ *
46
+ * A wired repository answers from a library the board was seeded with at CREATION, so reaching
47
+ * the fallback is a deployment-level fact rather than a question of who had read what first.
21
48
  */
22
49
  export async function resolveRiskPolicy(input) {
23
50
  const { repository, workspaceId, riskPolicyId } = input;
24
51
  if (!repository)
25
- return DEFAULT_RISK_POLICY;
52
+ return FALLBACK_RISK_POLICY;
26
53
  const read = input.read ?? directRiskPolicyRead;
27
54
  if (riskPolicyId) {
28
- const picked = await read(`picked:${riskPolicyId}`, () => repository.get(workspaceId, riskPolicyId));
55
+ const picked = await read({ kind: 'picked', id: riskPolicyId }, () => repository.get(workspaceId, riskPolicyId));
29
56
  if (picked)
30
57
  return picked;
31
58
  }
32
- return (await read('default', () => repository.getDefault(workspaceId))) ?? DEFAULT_RISK_POLICY;
59
+ return ((await read({ kind: 'default' }, () => repository.getDefault(workspaceId))) ??
60
+ FALLBACK_RISK_POLICY);
33
61
  }
34
62
  //# sourceMappingURL=riskPolicyResolution.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"riskPolicyResolution.js","sourceRoot":"","sources":["../../../src/modules/merge/riskPolicyResolution.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAA;AAyBzD,kGAAkG;AAClG,MAAM,CAAC,MAAM,oBAAoB,GAAmB,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,CAAA;AAE1E;;;;;GAKG;AACH,MAAM,UAAU,oBAAoB,CAClC,KAAyD,EACzD,WAAmB;IAEnB,IAAI,CAAC,KAAK;QAAE,OAAO,oBAAoB,CAAA;IACvC,OAAO,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,CACzB,CAAC,MAAM,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,WAAW,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAA;AACtF,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,KAKvC;IACC,MAAM,EAAE,UAAU,EAAE,WAAW,EAAE,YAAY,EAAE,GAAG,KAAK,CAAA;IACvD,IAAI,CAAC,UAAU;QAAE,OAAO,mBAAmB,CAAA;IAC3C,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,IAAI,oBAAoB,CAAA;IAC/C,IAAI,YAAY,EAAE,CAAC;QACjB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,UAAU,YAAY,EAAE,EAAE,GAAG,EAAE,CACvD,UAAU,CAAC,GAAG,CAAC,WAAW,EAAE,YAAY,CAAC,CAC1C,CAAA;QACD,IAAI,MAAM;YAAE,OAAO,MAAM,CAAA;IAC3B,CAAC;IACD,OAAO,CAAC,MAAM,IAAI,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,mBAAmB,CAAA;AACjG,CAAC"}
1
+ {"version":3,"file":"riskPolicyResolution.js","sourceRoot":"","sources":["../../../src/modules/merge/riskPolicyResolution.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAA;AAmC1D,kGAAkG;AAClG,MAAM,CAAC,MAAM,oBAAoB,GAAmB,CAAC,OAAO,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,CAAA;AAE7E,kFAAkF;AAClF,SAAS,UAAU,CAAC,MAAwB;IAC1C,OAAO,MAAM,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,UAAU,MAAM,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAA;AACrE,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,oBAAoB,CAClC,KAAyD,EACzD,WAAmB;IAEnB,IAAI,CAAC,KAAK;QAAE,OAAO,oBAAoB,CAAA;IACvC,OAAO,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,CAC5B,CAAC,MAAM,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC;SACvF,MAAM,CAAA;AACb,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,uBAAuB,CAAC,OAA8B;IACpE,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC,CAAA;IAClE,MAAM,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,IAAI,CAAA;IAC3E,OAAO,CAAC,MAAM,EAAE,EAAE,CAChB,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAA;AAChG,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,KAKvC;IACC,MAAM,EAAE,UAAU,EAAE,WAAW,EAAE,YAAY,EAAE,GAAG,KAAK,CAAA;IACvD,IAAI,CAAC,UAAU;QAAE,OAAO,oBAAoB,CAAA;IAC5C,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,IAAI,oBAAoB,CAAA;IAC/C,IAAI,YAAY,EAAE,CAAC;QACjB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,YAAY,EAAE,EAAE,GAAG,EAAE,CACnE,UAAU,CAAC,GAAG,CAAC,WAAW,EAAE,YAAY,CAAC,CAC1C,CAAA;QACD,IAAI,MAAM;YAAE,OAAO,MAAM,CAAA;IAC3B,CAAC;IACD,OAAO,CACL,CAAC,MAAM,IAAI,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,GAAG,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC,CAAC;QAC3E,oBAAoB,CACrB,CAAA;AACH,CAAC"}
@@ -1,4 +1,4 @@
1
- import { type Logger } from '@cat-factory/kernel';
1
+ import { type Logger, type SpendRollupRepository } from '@cat-factory/kernel';
2
2
  /** One pass's isolation state: the per-table runner plus the names it could not prune. */
3
3
  export interface RetentionPass {
4
4
  /**
@@ -45,4 +45,85 @@ export declare function createRetentionPass(logger?: Logger): RetentionPass;
45
45
  * history. Shared by both facades so the two cannot drift on how much they heal.
46
46
  */
47
47
  export declare const RUN_DAY_ROLLUP_LOOKBACK_MS: number;
48
+ /** How far back a steady-state spend-rollup pass recomputes, for the reason above. */
49
+ export declare const SPEND_DAY_ROLLUP_LOOKBACK_MS: number;
50
+ /**
51
+ * The most a SINGLE spend-rollup pass will aggregate. The catch-up walk below can ask for an
52
+ * arbitrarily wide window (a deployment that has never rolled up, a sweep down for a week),
53
+ * and one unbounded `GROUP BY` over a busy deployment's whole ledger is how a cron pass turns
54
+ * into a row-limit error on D1 or a long-running query on Postgres, which would then fail on
55
+ * every subsequent pass too, since the window only widens.
56
+ */
57
+ export declare const SPEND_DAY_ROLLUP_MAX_SPAN_MS: number;
58
+ /**
59
+ * How far back the FIRST pass on a deployment reaches. The rollup serves the 90-day report
60
+ * window, so a rollup that started at "today" would under-report that window for a quarter
61
+ * while looking complete: the ledger holds the data, and the reader has no way to see that
62
+ * the newer store simply had not been asked yet. Older history than this is deliberately not
63
+ * backfilled: `rolledUpThrough` states where the durable record begins.
64
+ *
65
+ * It also serves as the FLOOR under a resumed pass when the ledger has no retention window of
66
+ * its own to derive one from. See {@link spendRollupWindow}.
67
+ */
68
+ export declare const SPEND_DAY_ROLLUP_BACKFILL_MS: number;
69
+ /** One spend-rollup pass's window, plus whatever it had to give up on to produce it. */
70
+ export interface SpendRollupWindow {
71
+ from: number;
72
+ to: number;
73
+ /**
74
+ * The span the catch-up horizon dropped, or null when the walk covers everything the last
75
+ * pass left. NON-NULL IS A PERMANENT DATA GAP, not a deferral: nothing re-offers these days
76
+ * to a later pass, and the watermark advances past them. Whoever calls this must SAY so:
77
+ * `through_day` is a high-water mark and cannot represent a hole, so the log line is the
78
+ * only place the hole is ever named.
79
+ */
80
+ skipped: {
81
+ from: number;
82
+ to: number;
83
+ } | null;
84
+ }
85
+ /**
86
+ * The window one spend-rollup pass should materialise, given what the last pass covered and
87
+ * how long the LEDGER it folds is retained.
88
+ *
89
+ * Unlike the run rollup, which recomputes a fixed trailing lookback, this one walks FORWARD
90
+ * from the sweep's own watermark. The difference is that a gap here is permanent: nothing
91
+ * else retains the attribution the rollup is folding, so a day the sweep skipped while it was
92
+ * down is a day whose TCO history is simply missing, forever. Resuming from the watermark
93
+ * turns "the sweep was down for a week" into a few catch-up passes instead.
94
+ *
95
+ * Which is why the catch-up horizon is derived from `ledgerRetentionMs` rather than reusing
96
+ * the backfill constant. The two answer different questions and only look alike. The backfill
97
+ * bounds a FIRST pass, where the choice is how much history to adopt and 90 days is a
98
+ * judgement call. A resumed pass has no such choice: every day between the watermark and now
99
+ * is a day this deployment has already committed to recording, and the ledger still HOLDS it
100
+ * (the prune runs in this same sweep, so a sweep that was down pruned nothing either). A
101
+ * horizon shorter than the ledger's own retention would step over those days while they were
102
+ * still readable, which is losing data that was there for the asking. Past the ledger's
103
+ * retention there is genuinely nothing left to fold, so that is where the walk stops, and the
104
+ * pathological watermark the horizon exists to contain (hand-edited, restored from a backup,
105
+ * epoch-zero) is still contained.
106
+ *
107
+ * Pure so both facades share it (and so the walk is unit-testable without a database): the
108
+ * caller reads the watermark, calls this, materialises `[from, to)`, and reports `skipped`.
109
+ *
110
+ * @param ledgerRetentionMs how long `token_usage` is kept; 0 or less means the ledger is
111
+ * never pruned, in which case there is no retention edge to derive a horizon from and the
112
+ * backfill constant is the floor.
113
+ */
114
+ export declare function spendRollupWindow(throughDay: number | null, now: number, ledgerRetentionMs: number): SpendRollupWindow;
115
+ /**
116
+ * One sweep's spend-rollup step, shared by both facades: read the watermark, walk the window,
117
+ * materialise it, and NAME any span the catch-up horizon had to give up on.
118
+ *
119
+ * It is one function rather than four lines repeated per facade because the reporting half is
120
+ * the half that goes missing. Materialising is obvious and both facades would write it; the
121
+ * warning is what turns a permanent hole in the durable record from an invisible event into an
122
+ * operator-visible one, and a hole nobody logs is indistinguishable from a quarter nobody
123
+ * spent anything in, which is the exact failure this whole table exists to prevent.
124
+ *
125
+ * Runs INSIDE {@link RetentionPass.materialize}, so a throw here is isolated and named like
126
+ * any other table's, and the ledger prune that follows it in the sweep still runs.
127
+ */
128
+ export declare function materializeSpendRollup(pass: RetentionPass, repository: Pick<SpendRollupRepository, 'rollupSpendDays' | 'spendRollupWatermark'>, now: number, ledgerRetentionMs: number, logger?: Logger): Promise<number>;
48
129
  //# sourceMappingURL=retentionPass.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"retentionPass.d.ts","sourceRoot":"","sources":["../../../src/modules/observability/retentionPass.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,MAAM,EAAiB,MAAM,qBAAqB,CAAA;AAiBhE,0FAA0F;AAC1F,MAAM,WAAW,aAAa;IAC5B;;;;OAIG;IACH,KAAK,CACH,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,EAChB,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,GACvC,OAAO,CAAC,MAAM,CAAC,CAAA;IAClB;;;OAGG;IACH,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;IAClE;;;;;;;;;OASG;IACH,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;IACzE;;;OAGG;IACH,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,CAAA;CAC1B;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,aAAa,CAyBlE;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,0BAA0B,QAAuB,CAAA"}
1
+ {"version":3,"file":"retentionPass.d.ts","sourceRoot":"","sources":["../../../src/modules/observability/retentionPass.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,MAAM,EAAE,KAAK,qBAAqB,EAAiB,MAAM,qBAAqB,CAAA;AAiB5F,0FAA0F;AAC1F,MAAM,WAAW,aAAa;IAC5B;;;;OAIG;IACH,KAAK,CACH,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,EAChB,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,GACvC,OAAO,CAAC,MAAM,CAAC,CAAA;IAClB;;;OAGG;IACH,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;IAClE;;;;;;;;;OASG;IACH,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;IACzE;;;OAGG;IACH,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,CAAA;CAC1B;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,aAAa,CAyBlE;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,0BAA0B,QAAuB,CAAA;AAE9D,sFAAsF;AACtF,eAAO,MAAM,4BAA4B,QAAuB,CAAA;AAEhE;;;;;;GAMG;AACH,eAAO,MAAM,4BAA4B,QAAwB,CAAA;AAEjE;;;;;;;;;GASG;AACH,eAAO,MAAM,4BAA4B,QAAwB,CAAA;AAEjE,wFAAwF;AACxF,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAA;IACZ,EAAE,EAAE,MAAM,CAAA;IACV;;;;;;OAMG;IACH,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAA;CAC7C;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAgB,iBAAiB,CAC/B,UAAU,EAAE,MAAM,GAAG,IAAI,EACzB,GAAG,EAAE,MAAM,EACX,iBAAiB,EAAE,MAAM,GACxB,iBAAiB,CAmBnB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,sBAAsB,CAC1C,IAAI,EAAE,aAAa,EACnB,UAAU,EAAE,IAAI,CAAC,qBAAqB,EAAE,iBAAiB,GAAG,sBAAsB,CAAC,EACnF,GAAG,EAAE,MAAM,EACX,iBAAiB,EAAE,MAAM,EACzB,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,MAAM,CAAC,CAwBjB"}
@@ -40,4 +40,108 @@ export function createRetentionPass(logger) {
40
40
  * history. Shared by both facades so the two cannot drift on how much they heal.
41
41
  */
42
42
  export const RUN_DAY_ROLLUP_LOOKBACK_MS = 3 * 24 * 60 * 60_000;
43
+ /** How far back a steady-state spend-rollup pass recomputes, for the reason above. */
44
+ export const SPEND_DAY_ROLLUP_LOOKBACK_MS = 3 * 24 * 60 * 60_000;
45
+ /**
46
+ * The most a SINGLE spend-rollup pass will aggregate. The catch-up walk below can ask for an
47
+ * arbitrarily wide window (a deployment that has never rolled up, a sweep down for a week),
48
+ * and one unbounded `GROUP BY` over a busy deployment's whole ledger is how a cron pass turns
49
+ * into a row-limit error on D1 or a long-running query on Postgres, which would then fail on
50
+ * every subsequent pass too, since the window only widens.
51
+ */
52
+ export const SPEND_DAY_ROLLUP_MAX_SPAN_MS = 30 * 24 * 60 * 60_000;
53
+ /**
54
+ * How far back the FIRST pass on a deployment reaches. The rollup serves the 90-day report
55
+ * window, so a rollup that started at "today" would under-report that window for a quarter
56
+ * while looking complete: the ledger holds the data, and the reader has no way to see that
57
+ * the newer store simply had not been asked yet. Older history than this is deliberately not
58
+ * backfilled: `rolledUpThrough` states where the durable record begins.
59
+ *
60
+ * It also serves as the FLOOR under a resumed pass when the ledger has no retention window of
61
+ * its own to derive one from. See {@link spendRollupWindow}.
62
+ */
63
+ export const SPEND_DAY_ROLLUP_BACKFILL_MS = 90 * 24 * 60 * 60_000;
64
+ /**
65
+ * The window one spend-rollup pass should materialise, given what the last pass covered and
66
+ * how long the LEDGER it folds is retained.
67
+ *
68
+ * Unlike the run rollup, which recomputes a fixed trailing lookback, this one walks FORWARD
69
+ * from the sweep's own watermark. The difference is that a gap here is permanent: nothing
70
+ * else retains the attribution the rollup is folding, so a day the sweep skipped while it was
71
+ * down is a day whose TCO history is simply missing, forever. Resuming from the watermark
72
+ * turns "the sweep was down for a week" into a few catch-up passes instead.
73
+ *
74
+ * Which is why the catch-up horizon is derived from `ledgerRetentionMs` rather than reusing
75
+ * the backfill constant. The two answer different questions and only look alike. The backfill
76
+ * bounds a FIRST pass, where the choice is how much history to adopt and 90 days is a
77
+ * judgement call. A resumed pass has no such choice: every day between the watermark and now
78
+ * is a day this deployment has already committed to recording, and the ledger still HOLDS it
79
+ * (the prune runs in this same sweep, so a sweep that was down pruned nothing either). A
80
+ * horizon shorter than the ledger's own retention would step over those days while they were
81
+ * still readable, which is losing data that was there for the asking. Past the ledger's
82
+ * retention there is genuinely nothing left to fold, so that is where the walk stops, and the
83
+ * pathological watermark the horizon exists to contain (hand-edited, restored from a backup,
84
+ * epoch-zero) is still contained.
85
+ *
86
+ * Pure so both facades share it (and so the walk is unit-testable without a database): the
87
+ * caller reads the watermark, calls this, materialises `[from, to)`, and reports `skipped`.
88
+ *
89
+ * @param ledgerRetentionMs how long `token_usage` is kept; 0 or less means the ledger is
90
+ * never pruned, in which case there is no retention edge to derive a horizon from and the
91
+ * backfill constant is the floor.
92
+ */
93
+ export function spendRollupWindow(throughDay, now, ledgerRetentionMs) {
94
+ // A `null` watermark is "no pass has ever completed", not "start from now": see the
95
+ // backfill constant. Once there IS one, the steady-state lookback still applies on top of
96
+ // it, so a day that was still accruing when it was covered gets recomputed rather than
97
+ // frozen half-counted.
98
+ const resume = throughDay == null
99
+ ? now - SPEND_DAY_ROLLUP_BACKFILL_MS
100
+ : Math.min(throughDay, now - SPEND_DAY_ROLLUP_LOOKBACK_MS);
101
+ const horizon = now - Math.max(ledgerRetentionMs, SPEND_DAY_ROLLUP_BACKFILL_MS);
102
+ // Never walk back past the horizon, and never aggregate more than one pass's worth in one
103
+ // query. A first pass is bounded by its own backfill choice, so only a RESUMED one can be
104
+ // cut here, and only that one has days it was already committed to.
105
+ const from = Math.max(resume, horizon);
106
+ return {
107
+ from,
108
+ to: Math.min(now, from + SPEND_DAY_ROLLUP_MAX_SPAN_MS),
109
+ skipped: throughDay != null && resume < horizon ? { from: resume, to: horizon } : null,
110
+ };
111
+ }
112
+ /**
113
+ * One sweep's spend-rollup step, shared by both facades: read the watermark, walk the window,
114
+ * materialise it, and NAME any span the catch-up horizon had to give up on.
115
+ *
116
+ * It is one function rather than four lines repeated per facade because the reporting half is
117
+ * the half that goes missing. Materialising is obvious and both facades would write it; the
118
+ * warning is what turns a permanent hole in the durable record from an invisible event into an
119
+ * operator-visible one, and a hole nobody logs is indistinguishable from a quarter nobody
120
+ * spent anything in, which is the exact failure this whole table exists to prevent.
121
+ *
122
+ * Runs INSIDE {@link RetentionPass.materialize}, so a throw here is isolated and named like
123
+ * any other table's, and the ledger prune that follows it in the sweep still runs.
124
+ */
125
+ export async function materializeSpendRollup(pass, repository, now, ledgerRetentionMs, logger) {
126
+ return await pass.materialize('spend_days', async () => {
127
+ const watermark = await repository.spendRollupWatermark();
128
+ const { from, to, skipped } = spendRollupWindow(watermark, now, ledgerRetentionMs);
129
+ if (skipped) {
130
+ // WARN rather than error: the pass itself is healthy and everything from `from` on will
131
+ // be recorded. What is lost is bounded and already gone, so this is the one and only
132
+ // notice it gets. `through_day` is a high-water mark and will advance straight over the
133
+ // hole, so nothing downstream can restate it later.
134
+ logger?.warn('retention: the durable spend rollup skipped days it can no longer fold; ' +
135
+ 'that attribution is permanently absent', {
136
+ scope: 'retention',
137
+ table: 'spend_days',
138
+ skippedFrom: skipped.from,
139
+ skippedTo: skipped.to,
140
+ skippedDays: Math.round((skipped.to - skipped.from) / (24 * 60 * 60_000)),
141
+ watermark,
142
+ });
143
+ }
144
+ return await repository.rollupSpendDays(from, to);
145
+ });
146
+ }
43
147
  //# sourceMappingURL=retentionPass.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"retentionPass.js","sourceRoot":"","sources":["../../../src/modules/observability/retentionPass.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAqDhE;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CAAC,MAAe;IACjD,MAAM,MAAM,GAAa,EAAE,CAAA;IAC3B,MAAM,OAAO,GAAG,KAAK,EAAE,KAAa,EAAE,GAA0B,EAAmB,EAAE;QACnF,IAAI,CAAC;YACH,OAAO,MAAM,GAAG,EAAE,CAAA;QACpB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;YAClB,yFAAyF;YACzF,uFAAuF;YACvF,6DAA6D;YAC7D,MAAM,EAAE,IAAI,CAAC,0DAA0D,EAAE;gBACvE,KAAK,EAAE,WAAW;gBAClB,KAAK;gBACL,GAAG,aAAa,CAAC,KAAK,CAAC;aACxB,CAAC,CAAA;YACF,OAAO,CAAC,CAAA;QACV,CAAC;IACH,CAAC,CAAA;IACD,OAAO;QACL,KAAK,EAAE,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,CACnC,QAAQ,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,GAAG,GAAG,QAAQ,CAAC,CAAC;QAChF,MAAM,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC;QAC3C,WAAW,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC;QACpD,MAAM;KACP,CAAA;AACH,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,MAAM,CAAA"}
1
+ {"version":3,"file":"retentionPass.js","sourceRoot":"","sources":["../../../src/modules/observability/retentionPass.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,15 @@
1
1
  import type { ReportWindow, ReportsView } from '@cat-factory/contracts';
2
- import type { Clock, ReportsRepository } from '@cat-factory/kernel';
2
+ import type { Clock, ReportsRepository, SpendRollupRepository } from '@cat-factory/kernel';
3
3
  export interface ReportsServiceDependencies {
4
4
  reportsRepository: ReportsRepository;
5
+ /**
6
+ * The durable cost-attribution rollup, which serves the long windows. Optional so a facade
7
+ * that has not wired it (or a unit test) falls back to the ledger for every window rather
8
+ * than losing the two long ones: the ledger holds ~13 months, so the fallback is accurate
9
+ * until retention reaches it, and the projection still SAYS `ledger` so nothing reads as
10
+ * durable that is not.
11
+ */
12
+ spendRollupRepository?: SpendRollupRepository;
5
13
  clock: Clock;
6
14
  /**
7
15
  * The deployment's spend currency (the base pricing table's), so the SPA formats every
@@ -12,20 +20,35 @@ export interface ReportsServiceDependencies {
12
20
  currency: string;
13
21
  }
14
22
  /**
15
- * Cross-cutting usage analytics: composes the rollups behind {@link ReportsRepository}
16
- * into the Reports view: spend sliced by model, agent kind, repository and tracker ticket,
17
- * spend and run activity sliced by workspace / service / task type, and a spend trend, over a
18
- * time window. The repository and ticket slices are the TCO axes: what an organisation budgets
19
- * against, answered by a grouped query rather than a hand-written join against the database.
23
+ * Cross-cutting usage analytics: composes the rollups behind {@link ReportsRepository} and
24
+ * {@link SpendRollupRepository} into the Reports view: spend sliced by model, agent kind,
25
+ * repository, tracker ticket and run, spend and run activity sliced by workspace / service /
26
+ * task type, and a spend trend, over a time window. Run, repository and ticket are the TCO
27
+ * axes: what an organisation budgets against, answered by a grouped query rather than a
28
+ * hand-written join against the database.
20
29
  *
21
30
  * The dual of {@link PlatformObservabilityService}: that answers "is the deployment
22
31
  * healthy", this answers "where are the money and the work going". Every breakdown is one
23
32
  * SQL GROUP BY, and they are independent aggregates run in parallel — NOT an N+1. The
24
33
  * reshaping (totals fold, trend zero-fill) is the pure logic in `reports.logic.ts`.
34
+ *
35
+ * Two stores answer the spend half, routed by window exactly as the operator dashboard routes
36
+ * its own: `24h`/`7d` scan the `token_usage` ledger live, `30d`/`90d` read the durable
37
+ * `spend_days` rollup, which carries each run's board shape frozen at spend time and is never
38
+ * pruned. The projection reports which answered (`source`) and, on the rollup path, how far
39
+ * the sweep has covered (`rolledUpThrough`), because an un-materialised rollup and an idle
40
+ * quarter produce the same empty breakdown and are opposite facts.
25
41
  */
26
42
  export declare class ReportsService {
27
43
  private readonly deps;
28
44
  constructor(deps: ReportsServiceDependencies);
29
45
  summarize(accountId: string, window: ReportWindow, workspaceId?: string | null): Promise<ReportsView>;
46
+ /**
47
+ * Bind the window's spend reads to the store that serves them, and report which one that
48
+ * turned out to be. The window PREFERS the rollup on the long windows; an unwired rollup
49
+ * repository degrades to the ledger, and the returned `source` says so rather than
50
+ * labelling ledger numbers as durable ones.
51
+ */
52
+ private spendSource;
30
53
  }
31
54
  //# sourceMappingURL=ReportsService.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ReportsService.d.ts","sourceRoot":"","sources":["../../../src/modules/reports/ReportsService.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAA;AACvE,OAAO,KAAK,EAAE,KAAK,EAA4B,iBAAiB,EAAE,MAAM,qBAAqB,CAAA;AAU7F,MAAM,WAAW,0BAA0B;IACzC,iBAAiB,EAAE,iBAAiB,CAAA;IACpC,KAAK,EAAE,KAAK,CAAA;IACZ;;;;;OAKG;IACH,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED;;;;;;;;;;;GAWG;AACH,qBAAa,cAAc;IACb,OAAO,CAAC,QAAQ,CAAC,IAAI;IAAjC,YAA6B,IAAI,EAAE,0BAA0B,EAAI;IAE3D,SAAS,CACb,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,YAAY,EACpB,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,GAC1B,OAAO,CAAC,WAAW,CAAC,CA6DtB;CACF"}
1
+ {"version":3,"file":"ReportsService.d.ts","sourceRoot":"","sources":["../../../src/modules/reports/ReportsService.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAGV,YAAY,EACZ,WAAW,EACZ,MAAM,wBAAwB,CAAA;AAC/B,OAAO,KAAK,EACV,KAAK,EAKL,iBAAiB,EACjB,qBAAqB,EACtB,MAAM,qBAAqB,CAAA;AAsB5B,MAAM,WAAW,0BAA0B;IACzC,iBAAiB,EAAE,iBAAiB,CAAA;IACpC;;;;;;OAMG;IACH,qBAAqB,CAAC,EAAE,qBAAqB,CAAA;IAC7C,KAAK,EAAE,KAAK,CAAA;IACZ;;;;;OAKG;IACH,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,qBAAa,cAAc;IACb,OAAO,CAAC,QAAQ,CAAC,IAAI;IAAjC,YAA6B,IAAI,EAAE,0BAA0B,EAAI;IAE3D,SAAS,CACb,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,YAAY,EACpB,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,GAC1B,OAAO,CAAC,WAAW,CAAC,CAsEtB;IAED;;;;;OAKG;IACH,OAAO,CAAC,WAAW;CA6BpB"}
@@ -1,15 +1,23 @@
1
1
  import { REPORT_WINDOWS, alignWindowStart, buildSpendTrend, foldTotals, toActivityRow, toSpendRow, } from './reports.logic.js';
2
2
  /**
3
- * Cross-cutting usage analytics: composes the rollups behind {@link ReportsRepository}
4
- * into the Reports view: spend sliced by model, agent kind, repository and tracker ticket,
5
- * spend and run activity sliced by workspace / service / task type, and a spend trend, over a
6
- * time window. The repository and ticket slices are the TCO axes: what an organisation budgets
7
- * against, answered by a grouped query rather than a hand-written join against the database.
3
+ * Cross-cutting usage analytics: composes the rollups behind {@link ReportsRepository} and
4
+ * {@link SpendRollupRepository} into the Reports view: spend sliced by model, agent kind,
5
+ * repository, tracker ticket and run, spend and run activity sliced by workspace / service /
6
+ * task type, and a spend trend, over a time window. Run, repository and ticket are the TCO
7
+ * axes: what an organisation budgets against, answered by a grouped query rather than a
8
+ * hand-written join against the database.
8
9
  *
9
10
  * The dual of {@link PlatformObservabilityService}: that answers "is the deployment
10
11
  * healthy", this answers "where are the money and the work going". Every breakdown is one
11
12
  * SQL GROUP BY, and they are independent aggregates run in parallel — NOT an N+1. The
12
13
  * reshaping (totals fold, trend zero-fill) is the pure logic in `reports.logic.ts`.
14
+ *
15
+ * Two stores answer the spend half, routed by window exactly as the operator dashboard routes
16
+ * its own: `24h`/`7d` scan the `token_usage` ledger live, `30d`/`90d` read the durable
17
+ * `spend_days` rollup, which carries each run's board shape frozen at spend time and is never
18
+ * pruned. The projection reports which answered (`source`) and, on the rollup path, how far
19
+ * the sweep has covered (`rolledUpThrough`), because an un-materialised rollup and an idle
20
+ * quarter produce the same empty breakdown and are opposite facts.
13
21
  */
14
22
  export class ReportsService {
15
23
  deps;
@@ -17,27 +25,31 @@ export class ReportsService {
17
25
  this.deps = deps;
18
26
  }
19
27
  async summarize(accountId, window, workspaceId) {
20
- const { windowMs, bucketMs } = REPORT_WINDOWS[window];
28
+ const { windowMs, bucketMs, source: preferred } = REPORT_WINDOWS[window];
21
29
  const until = this.deps.clock.now();
22
30
  // Snapped to a bucket edge so the trend's leading column is a COMPLETE bucket; every
23
31
  // breakdown and the totals aggregate over the same snapped window, so the tiles and the
24
- // chart can never describe different spans. See `alignWindowStart`.
32
+ // chart can never describe different spans. It is also what keeps a rollup-backed window
33
+ // on whole UTC days. See `alignWindowStart`.
25
34
  const since = alignWindowStart(until, windowMs, bucketMs);
26
35
  const scope = { accountId, workspaceId: workspaceId ?? null };
27
36
  const range = { since, until };
28
37
  const repo = this.deps.reportsRepository;
29
- const [byModel, byAgentKind, spendByWorkspace, spendByService, spendByRepo, spendByTaskType, spendByTicket, activityByWorkspace, activityByService, activityByTaskType, trend,] = await Promise.all([
30
- repo.spendByDimension(scope, 'model', range),
31
- repo.spendByDimension(scope, 'agentKind', range),
32
- repo.spendByDimension(scope, 'workspace', range),
33
- repo.spendByDimension(scope, 'service', range),
34
- repo.spendByDimension(scope, 'repo', range),
35
- repo.spendByDimension(scope, 'taskType', range),
36
- repo.spendByDimension(scope, 'ticket', range),
38
+ const { source, spend } = this.spendSource(preferred);
39
+ const [byModel, byAgentKind, spendByWorkspace, spendByService, spendByRepo, spendByTaskType, spendByTicket, spendByRun, activityByWorkspace, activityByService, activityByTaskType, trend, rolledUpThrough,] = await Promise.all([
40
+ spend.byDimension(scope, 'model', range),
41
+ spend.byDimension(scope, 'agentKind', range),
42
+ spend.byDimension(scope, 'workspace', range),
43
+ spend.byDimension(scope, 'service', range),
44
+ spend.byDimension(scope, 'repo', range),
45
+ spend.byDimension(scope, 'taskType', range),
46
+ spend.byDimension(scope, 'ticket', range),
47
+ spend.byDimension(scope, 'run', range),
37
48
  repo.activityByDimension(scope, 'workspace', range),
38
49
  repo.activityByDimension(scope, 'service', range),
39
50
  repo.activityByDimension(scope, 'taskType', range),
40
- repo.spendTrend(scope, range, bucketMs),
51
+ spend.trend(scope, range, bucketMs),
52
+ spend.watermark(),
41
53
  ]);
42
54
  const spendByModel = byModel.map(toSpendRow);
43
55
  return {
@@ -46,8 +58,10 @@ export class ReportsService {
46
58
  since,
47
59
  workspaceId: workspaceId ?? null,
48
60
  currency: this.deps.currency,
49
- // Every spend breakdown partitions the same ledger rows, so the totals fold from
50
- // whichever one is at hand rather than costing a sixth query.
61
+ source,
62
+ rolledUpThrough,
63
+ // Every spend breakdown partitions the same rows, so the totals fold from
64
+ // whichever one is at hand rather than costing another query.
51
65
  totals: foldTotals(spendByModel),
52
66
  spend: {
53
67
  byModel: spendByModel,
@@ -57,6 +71,7 @@ export class ReportsService {
57
71
  byRepo: spendByRepo.map(toSpendRow),
58
72
  byTaskType: spendByTaskType.map(toSpendRow),
59
73
  byTicket: spendByTicket.map(toSpendRow),
74
+ byRun: spendByRun.map(toSpendRow),
60
75
  },
61
76
  activity: {
62
77
  byWorkspace: activityByWorkspace.map(toActivityRow),
@@ -66,5 +81,36 @@ export class ReportsService {
66
81
  trend: { bucketMs, points: buildSpendTrend(trend, since, until, bucketMs) },
67
82
  };
68
83
  }
84
+ /**
85
+ * Bind the window's spend reads to the store that serves them, and report which one that
86
+ * turned out to be. The window PREFERS the rollup on the long windows; an unwired rollup
87
+ * repository degrades to the ledger, and the returned `source` says so rather than
88
+ * labelling ledger numbers as durable ones.
89
+ */
90
+ spendSource(preferred) {
91
+ const rollup = this.deps.spendRollupRepository;
92
+ if (preferred === 'daily-rollup' && rollup) {
93
+ return {
94
+ source: 'daily-rollup',
95
+ spend: {
96
+ byDimension: (scope, dimension, range) => rollup.spendByDimension(scope, dimension, range),
97
+ trend: (scope, range, bucketMs) => rollup.spendTrend(scope, range, bucketMs),
98
+ watermark: () => rollup.spendRollupWatermark(),
99
+ },
100
+ };
101
+ }
102
+ const repo = this.deps.reportsRepository;
103
+ return {
104
+ source: 'ledger',
105
+ spend: {
106
+ byDimension: (scope, dimension, range) => repo.spendByDimension(scope, dimension, range),
107
+ trend: (scope, range, bucketMs) => repo.spendTrend(scope, range, bucketMs),
108
+ // Null, not a stale watermark: there is no rollup in this path, so there is nothing
109
+ // about it that could be behind, and reporting one would invite the reader to believe
110
+ // the ledger numbers were bounded by it.
111
+ watermark: () => Promise.resolve(null),
112
+ },
113
+ };
114
+ }
69
115
  }
70
116
  //# sourceMappingURL=ReportsService.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ReportsService.js","sourceRoot":"","sources":["../../../src/modules/reports/ReportsService.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ReportsService.js","sourceRoot":"","sources":["../../../src/modules/reports/ReportsService.ts"],"names":[],"mappings":"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"}