chainlesschain 0.165.9 → 0.166.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 (190) hide show
  1. package/completions/_cc +2 -1
  2. package/completions/cc.bash +2 -2
  3. package/completions/cc.fish +2 -2
  4. package/completions/cc.ps1 +2 -1
  5. package/package.json +2 -2
  6. package/src/assets/web-panel/assets/{AIOps-DxwjrnEA.js → AIOps-D5_pwQ7M.js} +1 -1
  7. package/src/assets/web-panel/assets/{ActionButton-JdbYowzn.js → ActionButton-DgoYO32D.js} +1 -1
  8. package/src/assets/web-panel/assets/{Analytics-C06GCahv.js → Analytics-BIpoZ4QH.js} +3 -3
  9. package/src/assets/web-panel/assets/{AppLayout-BUVEEyi1.js → AppLayout-BJ3XrCEe.js} +3 -3
  10. package/src/assets/web-panel/assets/{Artifacts-D_ORzkJd.js → Artifacts-DUFs_izZ.js} +1 -1
  11. package/src/assets/web-panel/assets/{Audit-8o_Y5ejG.js → Audit-BZdPwwfL.js} +1 -1
  12. package/src/assets/web-panel/assets/{BackgroundAgents-DrkHd5VU.js → BackgroundAgents-DK9Fn-8B.js} +1 -1
  13. package/src/assets/web-panel/assets/{Backup-CKBZCX11.js → Backup-Bd6bOhV_.js} +1 -1
  14. package/src/assets/web-panel/assets/{BaseInput-C8HkI399.js → BaseInput-CRnWlXrd.js} +1 -1
  15. package/src/assets/web-panel/assets/{Chat-zb2H2Wux.js → Chat-D1G_yEl6.js} +6 -6
  16. package/src/assets/web-panel/assets/{ChatBubbleRenderer-BDcNpU_F.js → ChatBubbleRenderer-DDAlEtm-.js} +1 -1
  17. package/src/assets/web-panel/assets/{Checkbox-MwPtQmNz.js → Checkbox-CP35SH7R.js} +1 -1
  18. package/src/assets/web-panel/assets/{Codegen-3p5QCkFK.js → Codegen-DugeL4pj.js} +1 -1
  19. package/src/assets/web-panel/assets/{Col-BPLlhn52.js → Col-DPuJsvKg.js} +1 -1
  20. package/src/assets/web-panel/assets/{Community-C-3dBNOM.js → Community-CZqNjNNp.js} +1 -1
  21. package/src/assets/web-panel/assets/{Compact-BUcy-F_b.js → Compact-eeyIPEAb.js} +1 -1
  22. package/src/assets/web-panel/assets/{Compliance-CI8NxT8m.js → Compliance-MGzTw87k.js} +1 -1
  23. package/src/assets/web-panel/assets/{Cowork-DaDEBS-Q.js → Cowork-D3goVIA5.js} +2 -2
  24. package/src/assets/web-panel/assets/{Cron-BSv9HXu5.js → Cron-9HA8hLLG.js} +2 -2
  25. package/src/assets/web-panel/assets/{Crosschain-yuiKlJmv.js → Crosschain-DCSOX3l6.js} +1 -1
  26. package/src/assets/web-panel/assets/{DID-D6LfldB0.js → DID-ji3lN5Bc.js} +2 -2
  27. package/src/assets/web-panel/assets/{Dashboard-CBhLqG61.js → Dashboard-DlZvF1E5.js} +2 -2
  28. package/src/assets/web-panel/assets/{Dropdown-BG8pIl3O.js → Dropdown-2FyZcow9.js} +1 -1
  29. package/src/assets/web-panel/assets/{EmailListRenderer-CY92VIE6.js → EmailListRenderer-qH2bSpSY.js} +1 -1
  30. package/src/assets/web-panel/assets/{FamilyGuardDashboard-1Q_ehauM.js → FamilyGuardDashboard-Bfx47wZj.js} +1 -1
  31. package/src/assets/web-panel/assets/{Federation-D3XirJIU.js → Federation-DhGcZbIv.js} +1 -1
  32. package/src/assets/web-panel/assets/{FormItemContext-DfI9UuGZ.js → FormItemContext-BMgi9_YQ.js} +1 -1
  33. package/src/assets/web-panel/assets/{GenericCardRenderer-IeCZk2m7.js → GenericCardRenderer-DugMac-4.js} +1 -1
  34. package/src/assets/web-panel/assets/{Git-DzK4IJAZ.js → Git-D943BpH-.js} +2 -2
  35. package/src/assets/web-panel/assets/{Governance-BHf5KfmQ.js → Governance-DZ66a8Aa.js} +1 -1
  36. package/src/assets/web-panel/assets/{Inference-BmaxSALS.js → Inference-B00Mp2tN.js} +1 -1
  37. package/src/assets/web-panel/assets/{KnowledgeGraph-BgePFLA9.js → KnowledgeGraph-BdwXXO2Q.js} +1 -1
  38. package/src/assets/web-panel/assets/{Logs-nqgxpOc4.js → Logs-_MVXyYWc.js} +2 -2
  39. package/src/assets/web-panel/assets/MarkdownRenderer-hOTeNyi7.js +1 -0
  40. package/src/assets/web-panel/assets/{Marketplace-Bu8to-86.js → Marketplace-CxeHRsnO.js} +1 -1
  41. package/src/assets/web-panel/assets/{McpTools-BFWTzEk0.js → McpTools-BOieTxZ4.js} +3 -3
  42. package/src/assets/web-panel/assets/{Memory-B026G2GA.js → Memory-BQD26CM3.js} +2 -2
  43. package/src/assets/web-panel/assets/{MobileBridge-CM2Eeg6I.js → MobileBridge-CPJ8ZlvR.js} +1 -1
  44. package/src/assets/web-panel/assets/{MobileProjects-B79Ob3hy.js → MobileProjects-D7qRVu0y.js} +1 -1
  45. package/src/assets/web-panel/assets/{Mtc-CxevSZuV.js → Mtc-BOyndGuk.js} +2 -2
  46. package/src/assets/web-panel/assets/{MtcAudit-X396cPEX.js → MtcAudit-CXQ_8ZoR.js} +4 -4
  47. package/src/assets/web-panel/assets/{Multisig-HWIB_aZ1.js → Multisig-32Oh9KbH.js} +3 -3
  48. package/src/assets/web-panel/assets/{NLProgramming-gnYD1Xwy.js → NLProgramming-CFAd00CX.js} +1 -1
  49. package/src/assets/web-panel/assets/{Notes-Dn2Gf_J1.js → Notes-BBCY_qJA.js} +3 -3
  50. package/src/assets/web-panel/assets/{NotificationSettings-BRKBQ5rq.js → NotificationSettings-uaQ0PdmW.js} +1 -1
  51. package/src/assets/web-panel/assets/{OrderTableRenderer-Dy___Cgo.js → OrderTableRenderer-kpBxJ-SG.js} +1 -1
  52. package/src/assets/web-panel/assets/{Organization-cqfccxnt.js → Organization-CmFn7Oeo.js} +4 -4
  53. package/src/assets/web-panel/assets/{Overflow-CSX4FHN3.js → Overflow-R_avat3a.js} +1 -1
  54. package/src/assets/web-panel/assets/{P2P-Bwa4aghp.js → P2P-BIhLFmkY.js} +2 -2
  55. package/src/assets/web-panel/assets/{PdhVaultBrowser-Dhszyjig.js → PdhVaultBrowser-DTJjk-_i.js} +3 -3
  56. package/src/assets/web-panel/assets/{Permissions-CXzTyk6e.js → Permissions-CkzYv8Yb.js} +4 -4
  57. package/src/assets/web-panel/assets/{PersonalDataHub-CFCAAJbb.js → PersonalDataHub--0QvN2Nz.js} +4 -4
  58. package/src/assets/web-panel/assets/{Pipeline-BPJbx6xt.js → Pipeline-Bfw5gQCH.js} +1 -1
  59. package/src/assets/web-panel/assets/{Privacy-BbiXvEHz.js → Privacy-DicjKfax.js} +1 -1
  60. package/src/assets/web-panel/assets/{ProjectInit-B-s7-wSD.js → ProjectInit-DUl_ykBp.js} +2 -2
  61. package/src/assets/web-panel/assets/{ProjectSettings-Dyug206y.js → ProjectSettings-CPYDvN8a.js} +2 -2
  62. package/src/assets/web-panel/assets/{Projects-BtAI5Fwo.js → Projects-DnZ9_fAr.js} +1 -1
  63. package/src/assets/web-panel/assets/{Providers-JpIPmz6N.js → Providers-BX1jP31w.js} +1 -1
  64. package/src/assets/web-panel/assets/{QrScannerModal-CZdoN64A.js → QrScannerModal-COab5qUl.js} +1 -1
  65. package/src/assets/web-panel/assets/{QuickAsk-BwvnoRIT.js → QuickAsk-CdKQ_JZ0.js} +1 -1
  66. package/src/assets/web-panel/assets/{Recommend-ASMlMQrD.js → Recommend-BPFHg8pK.js} +1 -1
  67. package/src/assets/web-panel/assets/{RemoteSession-BiJzKFKi.js → RemoteSession-CqrfTJvO.js} +3 -3
  68. package/src/assets/web-panel/assets/{Reputation-C80TWLIO.js → Reputation-DM-l8Pb3.js} +1 -1
  69. package/src/assets/web-panel/assets/{Row-C1VNmjmX.js → Row-CKGBTeCw.js} +1 -1
  70. package/src/assets/web-panel/assets/{RssFeed-T2MyGUlG.js → RssFeed-Wb0YHIkc.js} +3 -3
  71. package/src/assets/web-panel/assets/{Search-DXM6O83L.js → Search-DiBjxKv-.js} +1 -1
  72. package/src/assets/web-panel/assets/{Security-nv69kU7W.js → Security-BAVEmbWP.js} +4 -4
  73. package/src/assets/web-panel/assets/{Services-AyHWe7Qj.js → Services-A_a3TIRn.js} +2 -2
  74. package/src/assets/web-panel/assets/{Skeleton-D6PWLxFI.js → Skeleton-CloHJ-I7.js} +1 -1
  75. package/src/assets/web-panel/assets/{Skills-BqVeOmNQ.js → Skills-CkvV5hKa.js} +1 -1
  76. package/src/assets/web-panel/assets/{Sla-BegIPl9M.js → Sla-BYozxxsV.js} +1 -1
  77. package/src/assets/web-panel/assets/{SpeechSettings-CKJn3xk-.js → SpeechSettings-CWianiZF.js} +1 -1
  78. package/src/assets/web-panel/assets/{SyncSettings-Th4cnAMl.js → SyncSettings-BR4G75do.js} +2 -2
  79. package/src/assets/web-panel/assets/{Tasks-BuKfBroh.js → Tasks-D6gyUVrM.js} +1 -1
  80. package/src/assets/web-panel/assets/{Templates-CMuWN8Ac.js → Templates-DbfYIRzT.js} +1 -1
  81. package/src/assets/web-panel/assets/{Tenant-C4je8E8Q.js → Tenant-BHutvukT.js} +1 -1
  82. package/src/assets/web-panel/assets/{Terminal-agJESOcO.js → Terminal-CYEiy2wJ.js} +2 -2
  83. package/src/assets/web-panel/assets/{TimelineRenderer-D2qDuVZ_.js → TimelineRenderer-D9s1AxfE.js} +1 -1
  84. package/src/assets/web-panel/assets/{Tokens-Cvmn99rH.js → Tokens-ij9vxnoy.js} +1 -1
  85. package/src/assets/web-panel/assets/{Trigger-D_QYIHH8.js → Trigger-Dq_DCVeQ.js} +1 -1
  86. package/src/assets/web-panel/assets/{Trust-BmzvQLnX.js → Trust-Bs6wdfoH.js} +1 -1
  87. package/src/assets/web-panel/assets/{UkeySign-D_LopHwH.js → UkeySign-CLazyr5t.js} +1 -1
  88. package/src/assets/web-panel/assets/{VideoEditing-DoWl3PhQ.js → VideoEditing-viWotIHA.js} +1 -1
  89. package/src/assets/web-panel/assets/{Wallet-5NYcAkxe.js → Wallet-DlZ-A78d.js} +4 -4
  90. package/src/assets/web-panel/assets/{WebAuthn-B-_Q3ewp.js → WebAuthn-DSmOND3Y.js} +3 -3
  91. package/src/assets/web-panel/assets/{WorkflowEditor-CHET-gi2.js → WorkflowEditor-BempLOJi.js} +1 -1
  92. package/src/assets/web-panel/assets/{chat-C6nvb-n6.js → chat-CyJzf4JI.js} +1 -1
  93. package/src/assets/web-panel/assets/{colors-CTDE9LTX.js → colors-C62q7WrL.js} +1 -1
  94. package/src/assets/web-panel/assets/{compact-item-KnemdF8D.js → compact-item-7dYM1KW3.js} +1 -1
  95. package/src/assets/web-panel/assets/{createContext-DUJR3Uek.js → createContext-CYTy7z2Q.js} +1 -1
  96. package/src/assets/web-panel/assets/devWarning-BdTg_AMF.js +1 -0
  97. package/src/assets/web-panel/assets/{hasIn-CFNTaby8.js → hasIn-DHoclUqm.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-65HO56Bv.js → index-2C8Xx2UO.js} +1 -1
  99. package/src/assets/web-panel/assets/{index-ox6mIwE2.js → index-3pI7AfmD.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-JGTiDeOW.js → index-4gWv-Ubg.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-rVDD7AAR.js → index-94ktimZG.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-OmuhFYKE.js → index-9uR7rc9a.js} +1 -1
  103. package/src/assets/web-panel/assets/index-B6WvFV4N.js +1 -0
  104. package/src/assets/web-panel/assets/index-BKgfptzA.js +1 -0
  105. package/src/assets/web-panel/assets/{index-CquKnw5r.js → index-BMRmxFU_.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-DzReoLyh.js → index-BMxvWauP.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-DP-PbO11.js → index-BghdJ87W.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-CSD9_I2_.js → index-Bzz0aJ86.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-DF1Y0Vuw.js → index-C2efftJb.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-B8RtbSkV.js → index-C5YWYlW9.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-CHfUdnJH.js → index-CVTnruDt.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-BwZM1rod.js → index-CW86F2Zw.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-CyEtHvEE.js → index-CZRBvN6i.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-Ceu92a8D.js → index-CjeViaU-.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-DJyPeBBk.js → index-CnEZ4ZHj.js} +3 -3
  116. package/src/assets/web-panel/assets/{index-BdiC4LOs.js → index-D6BC4mmz.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-k6uorYmf.js → index-DA-_807C.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-DqPpJkte.js → index-DAYanuSk.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-NtAcnJYW.js → index-DHgSRimK.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-Wlc7o_C8.js → index-DJzZaPlb.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-CKvBF3Ov.js → index-DK84lAS0.js} +1 -1
  122. package/src/assets/web-panel/assets/{index-CcF0D7UZ.js → index-DKdv8cju.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-CnLpuTAU.js → index-DNLD3nZY.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-DZgCRMxk.js → index-DOFAwpUK.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-v-mtxmWH.js → index-DYKwGrAn.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-Cc7dbl_p.js → index-DghnbMlY.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-BuizJo2E.js → index-DhJjifZe.js} +1 -1
  128. package/src/assets/web-panel/assets/{index-NUR0If7O.js → index-DkczsbiP.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-u0h6QqVV.js → index-DvEtHpLc.js} +1 -1
  130. package/src/assets/web-panel/assets/{index-bxTPfdri.js → index-Dyq9tK5u.js} +1 -1
  131. package/src/assets/web-panel/assets/{index-DfJzS3Qa.js → index-LK1MZoBj.js} +1 -1
  132. package/src/assets/web-panel/assets/{index-DF-fcTvQ.js → index-NuNCstRO.js} +1 -1
  133. package/src/assets/web-panel/assets/{index-BXWg1crv.js → index-QXtrdrub.js} +1 -1
  134. package/src/assets/web-panel/assets/{index-BTetEUWd.js → index-XrsAHHQN.js} +1 -1
  135. package/src/assets/web-panel/assets/{index-BHqSqnW7.js → index-ZXYp76IB.js} +1 -1
  136. package/src/assets/web-panel/assets/{index-C96N9xeL.js → index-lHfNxiB5.js} +1 -1
  137. package/src/assets/web-panel/assets/{initDefaultProps-qEt8dI-t.js → initDefaultProps-CwCl5sFQ.js} +1 -1
  138. package/src/assets/web-panel/assets/{motion-DetKPWy-.js → motion-BFJFy70N.js} +1 -1
  139. package/src/assets/web-panel/assets/{move-BeNYeDV2.js → move-ByrtVGq8.js} +1 -1
  140. package/src/assets/web-panel/assets/{mtc-parser-C0q0MK_T.js → mtc-parser-BFiH1mT3.js} +1 -1
  141. package/src/assets/web-panel/assets/{omit-DLKkrKpE.js → omit-bdvgpivj.js} +1 -1
  142. package/src/assets/web-panel/assets/{pickAttrs-Bw1tWsY8.js → pickAttrs-BlfuuE3s.js} +1 -1
  143. package/src/assets/web-panel/assets/{placementArrow-DeesBLbd.js → placementArrow-t2SC3DMy.js} +1 -1
  144. package/src/assets/web-panel/assets/{responsiveObserve-bqLhxHhn.js → responsiveObserve-CoEXv2Li.js} +1 -1
  145. package/src/assets/web-panel/assets/{slide-DGCXRoQm.js → slide-BfXCf0Fu.js} +1 -1
  146. package/src/assets/web-panel/assets/{statusUtils-H-re3Egl.js → statusUtils-DNsdyOuS.js} +1 -1
  147. package/src/assets/web-panel/assets/{styleChecker-BXg4qGX_.js → styleChecker-9aHukmoG.js} +1 -1
  148. package/src/assets/web-panel/assets/{useFlexGapSupport-CKLb2KA6.js → useFlexGapSupport-dTkPxzHN.js} +1 -1
  149. package/src/assets/web-panel/assets/{useFs-CTAhHeyw.js → useFs-DINwfItP.js} +1 -1
  150. package/src/assets/web-panel/assets/{usePersonalDataHub-BQ4pDh5g.js → usePersonalDataHub-Bj_RriBV.js} +1 -1
  151. package/src/assets/web-panel/assets/{vnode-jrSK6j4j.js → vnode-BzRAZrTc.js} +1 -1
  152. package/src/assets/web-panel/assets/{zoom-fOQE24pw.js → zoom-CamPjkeK.js} +1 -1
  153. package/src/assets/web-panel/index.html +1 -1
  154. package/src/command-help-index.json +4 -4
  155. package/src/command-manifest.json +1 -1
  156. package/src/commands/agent.js +1 -1
  157. package/src/commands/graph.js +100 -0
  158. package/src/commands/mcp.js +49 -21
  159. package/src/commands/orchestrate.js +85 -18
  160. package/src/commands/serve.js +39 -0
  161. package/src/commands/team.js +2 -0
  162. package/src/data/changelog.json +26 -0
  163. package/src/generated/cc-agent-protocol.schema.json +1964 -0
  164. package/src/lib/agent-sandbox.js +4 -7
  165. package/src/lib/app-server/bounded-queue.js +87 -0
  166. package/src/lib/app-server/cli-agent-kernel-adapter.js +309 -0
  167. package/src/lib/app-server/protocol.js +125 -0
  168. package/src/lib/app-server/rollout-store.js +603 -0
  169. package/src/lib/app-server/server.js +922 -0
  170. package/src/lib/app-server/sqlite-rollout-store.js +315 -0
  171. package/src/lib/app-server/stdio-transport.js +118 -0
  172. package/src/lib/codex-app-server-adapter.js +249 -0
  173. package/src/lib/graph-kernel/adapters.js +238 -0
  174. package/src/lib/graph-kernel/compiler.js +911 -0
  175. package/src/lib/graph-kernel/eval.js +207 -0
  176. package/src/lib/graph-kernel/event-store.js +101 -0
  177. package/src/lib/graph-kernel/index.js +7 -0
  178. package/src/lib/graph-kernel/runtime.js +2660 -0
  179. package/src/lib/graph-kernel/trace-reducer.js +315 -0
  180. package/src/lib/graph-kernel/trigger-adapter.js +183 -0
  181. package/src/lib/orchestrator.js +2 -1
  182. package/src/lib/record-replay/index.js +1 -0
  183. package/src/lib/record-replay/skill-recorder.js +386 -0
  184. package/src/lib/webhook-security.js +159 -0
  185. package/src/repl/agent-repl.js +5 -4
  186. package/src/repl/prompt-interactions.js +11 -1
  187. package/src/assets/web-panel/assets/MarkdownRenderer-xkX6izBt.js +0 -1
  188. package/src/assets/web-panel/assets/devWarning-1DqLH1KX.js +0 -1
  189. package/src/assets/web-panel/assets/index-BhJtcPWo.js +0 -1
  190. package/src/assets/web-panel/assets/index-Cq8MWPDT.js +0 -1
@@ -0,0 +1,207 @@
1
+ import { graphDigest } from "./compiler.js";
2
+
3
+ function artifactOutcome(projection) {
4
+ return Object.fromEntries(
5
+ projection.artifactGraph.artifacts
6
+ .map((artifact) => [artifact.id, artifact.digest])
7
+ .sort(([left], [right]) => left.localeCompare(right)),
8
+ );
9
+ }
10
+
11
+ function terminalNodes(projection) {
12
+ return Object.fromEntries(
13
+ projection.taskGraph.nodes
14
+ .map((node) => [node.id, node.status])
15
+ .sort(([left], [right]) => left.localeCompare(right)),
16
+ );
17
+ }
18
+
19
+ export function scheduleEquivalence(left, right) {
20
+ const leftOutcome = {
21
+ status: left.status,
22
+ nodes: terminalNodes(left),
23
+ artifacts: artifactOutcome(left),
24
+ };
25
+ const rightOutcome = {
26
+ status: right.status,
27
+ nodes: terminalNodes(right),
28
+ artifacts: artifactOutcome(right),
29
+ };
30
+ return Object.freeze({
31
+ equivalent: JSON.stringify(leftOutcome) === JSON.stringify(rightOutcome),
32
+ leftDigest: graphDigest(leftOutcome, "cc.graph.eval-outcome/v1"),
33
+ rightDigest: graphDigest(rightOutcome, "cc.graph.eval-outcome/v1"),
34
+ left: leftOutcome,
35
+ right: rightOutcome,
36
+ });
37
+ }
38
+
39
+ export function evaluateGraphProjection(projection) {
40
+ const attemptsByNode = new Map();
41
+ for (const attempt of projection.attempts) {
42
+ const values = attemptsByNode.get(attempt.nodeId) || [];
43
+ values.push(attempt);
44
+ attemptsByNode.set(attempt.nodeId, values);
45
+ }
46
+ const accepted = projection.attempts.filter(
47
+ (attempt) => attempt.status === "accepted",
48
+ ).length;
49
+ const duplicateAttempts = [...attemptsByNode.values()].reduce(
50
+ (total, attempts) => total + Math.max(0, attempts.length - 1),
51
+ 0,
52
+ );
53
+ const visibleMessages = projection.messageGraph.edges.length;
54
+ const sentMessages = projection.messageGraph.messages.length;
55
+ const completedHandoffs = projection.handoffs.filter(
56
+ (handoff) => handoff.status === "committed",
57
+ ).length;
58
+ const terminalHandoffs = projection.handoffs.filter((handoff) =>
59
+ ["committed", "rejected", "revoked", "expired"].includes(handoff.status),
60
+ ).length;
61
+ const durations = projection.attempts.map((attempt) =>
62
+ Math.max(0, Date.parse(attempt.updatedAt) - Date.parse(attempt.createdAt)),
63
+ );
64
+ const totalWorkMs = durations.reduce((total, value) => total + value, 0);
65
+ const criticalMs = projection.criticalPath.durationMs;
66
+ const metrics = {
67
+ terminalSuccess: projection.status === "succeeded" ? 1 : 0,
68
+ acceptedAttempts: accepted,
69
+ duplicateAttempts,
70
+ duplicateWorkRatio:
71
+ projection.attempts.length === 0
72
+ ? 0
73
+ : duplicateAttempts / projection.attempts.length,
74
+ messageVisibilityRate:
75
+ sentMessages === 0 ? 1 : visibleMessages / sentMessages,
76
+ handoffCompletionRate:
77
+ projection.handoffs.length === 0
78
+ ? 1
79
+ : terminalHandoffs / projection.handoffs.length,
80
+ custodyCommitRate:
81
+ projection.handoffs.length === 0
82
+ ? 1
83
+ : completedHandoffs / projection.handoffs.length,
84
+ criticalPathUtilization:
85
+ totalWorkMs === 0 ? 1 : Math.min(1, criticalMs / totalWorkMs),
86
+ totalWorkMs,
87
+ criticalPathMs: criticalMs,
88
+ deadlocked: projection.status === "deadlocked" ? 1 : 0,
89
+ reconciliationRequired:
90
+ projection.status === "reconciliation_required" ? 1 : 0,
91
+ };
92
+ return Object.freeze({
93
+ schema: "chainlesschain.graph-eval/v1",
94
+ runId: projection.runId,
95
+ revisionDigest: projection.revisionDigest,
96
+ projectionDigest: projection.projectionDigest,
97
+ metrics: Object.freeze(metrics),
98
+ });
99
+ }
100
+
101
+ export function enforceGraphEvalThresholds(report, thresholds = {}) {
102
+ const failures = [];
103
+ for (const [metric, constraint] of Object.entries(thresholds)) {
104
+ const actual = report.metrics[metric];
105
+ if (typeof actual !== "number") {
106
+ failures.push({ metric, actual: null, reason: "metric_missing" });
107
+ continue;
108
+ }
109
+ if (constraint.min != null && actual < constraint.min) {
110
+ failures.push({ metric, actual, expected: `>= ${constraint.min}` });
111
+ }
112
+ if (constraint.max != null && actual > constraint.max) {
113
+ failures.push({ metric, actual, expected: `<= ${constraint.max}` });
114
+ }
115
+ }
116
+ return Object.freeze({
117
+ passed: failures.length === 0,
118
+ failures: Object.freeze(failures.map(Object.freeze)),
119
+ });
120
+ }
121
+
122
+ export async function runGraphEvalSuite({
123
+ suiteId,
124
+ commitSha,
125
+ cases,
126
+ execute,
127
+ thresholds = {},
128
+ } = {}) {
129
+ if (!/^[a-f0-9]{40}(?:[a-f0-9]{24})?$/u.test(String(commitSha || ""))) {
130
+ throw new TypeError(
131
+ "Graph Eval suite requires an exact 40 or 64 character commit SHA",
132
+ );
133
+ }
134
+ if (!Array.isArray(cases) || !cases.length || typeof execute !== "function") {
135
+ throw new TypeError(
136
+ "Graph Eval suite requires cases and an execute function",
137
+ );
138
+ }
139
+ const results = [];
140
+ for (const definition of [...cases].sort((left, right) =>
141
+ left.id.localeCompare(right.id),
142
+ )) {
143
+ const seeds = [...new Set(definition.seeds || [0])].sort(
144
+ (left, right) => left - right,
145
+ );
146
+ for (const seed of seeds) {
147
+ const control = await execute({
148
+ caseId: definition.id,
149
+ seed,
150
+ mode: "single_agent_control",
151
+ fault: null,
152
+ });
153
+ const candidate = await execute({
154
+ caseId: definition.id,
155
+ seed,
156
+ mode: "graph_candidate",
157
+ fault: definition.fault || null,
158
+ });
159
+ const controlEval = evaluateGraphProjection(control);
160
+ const candidateEval = evaluateGraphProjection(candidate);
161
+ const equivalence = scheduleEquivalence(control, candidate);
162
+ results.push({
163
+ caseId: definition.id,
164
+ seed,
165
+ fault: definition.fault || null,
166
+ controlProjectionDigest: control.projectionDigest,
167
+ candidateProjectionDigest: candidate.projectionDigest,
168
+ scheduleEquivalent: equivalence.equivalent,
169
+ metrics: candidateEval.metrics,
170
+ controlMetrics: controlEval.metrics,
171
+ });
172
+ }
173
+ }
174
+ const total = results.length;
175
+ const sum = (field) =>
176
+ results.reduce(
177
+ (value, result) => value + Number(result.metrics[field] || 0),
178
+ 0,
179
+ );
180
+ const metrics = {
181
+ caseRuns: total,
182
+ successRate: sum("terminalSuccess") / total,
183
+ scheduleEquivalenceRate:
184
+ results.filter((result) => result.scheduleEquivalent).length / total,
185
+ deadlockRate: sum("deadlocked") / total,
186
+ reconciliationRate: sum("reconciliationRequired") / total,
187
+ meanDuplicateWorkRatio: sum("duplicateWorkRatio") / total,
188
+ meanMessageVisibilityRate: sum("messageVisibilityRate") / total,
189
+ meanHandoffCompletionRate: sum("handoffCompletionRate") / total,
190
+ totalWorkMs: sum("totalWorkMs"),
191
+ totalCriticalPathMs: sum("criticalPathMs"),
192
+ };
193
+ const gate = enforceGraphEvalThresholds({ metrics }, thresholds);
194
+ const body = {
195
+ schema: "chainlesschain.graph-eval-suite/v1",
196
+ suiteId: String(suiteId || "graph-eval"),
197
+ commitSha,
198
+ thresholds,
199
+ metrics,
200
+ gate,
201
+ results,
202
+ };
203
+ return Object.freeze({
204
+ ...body,
205
+ reportDigest: graphDigest(body, "cc.graph.eval-suite/v1"),
206
+ });
207
+ }
@@ -0,0 +1,101 @@
1
+ import path from "node:path";
2
+ import {
3
+ JsonlRolloutStore,
4
+ defaultRolloutStoreDirectory,
5
+ } from "../app-server/rollout-store.js";
6
+
7
+ export const GRAPH_EVENT_SCHEMA = "chainlesschain.graph-event/v1";
8
+
9
+ export function defaultGraphEventStoreDirectory() {
10
+ return path.join(path.dirname(defaultRolloutStoreDirectory()), "graph-runs");
11
+ }
12
+
13
+ function clone(value) {
14
+ return value == null ? value : JSON.parse(JSON.stringify(value));
15
+ }
16
+
17
+ export class GraphEventStore {
18
+ constructor({
19
+ rolloutStore = new JsonlRolloutStore({
20
+ directory: defaultGraphEventStoreDirectory(),
21
+ }),
22
+ } = {}) {
23
+ this.rolloutStore = rolloutStore;
24
+ }
25
+
26
+ start(runId, metadata = {}) {
27
+ this.rolloutStore.start({
28
+ threadId: runId,
29
+ title: `GraphRun ${runId}`,
30
+ metadata: { kind: "graph_run", ...metadata },
31
+ });
32
+ return this.head(runId);
33
+ }
34
+
35
+ append(runId, type, payload, { idempotencyKey = null, traceId = null } = {}) {
36
+ const record = this.rolloutStore.append({
37
+ threadId: runId,
38
+ eventType: `graph.${type}`,
39
+ traceId,
40
+ idempotencyKey,
41
+ payload: {
42
+ schema: GRAPH_EVENT_SCHEMA,
43
+ type,
44
+ ...clone(payload),
45
+ },
46
+ });
47
+ return Object.freeze({
48
+ schema: GRAPH_EVENT_SCHEMA,
49
+ runId,
50
+ seq: record.event_seq,
51
+ type,
52
+ timestamp: record.timestamp,
53
+ prevHash: record.prev_hash,
54
+ hash: record.hash,
55
+ idempotencyKey: record.idempotency_key,
56
+ payload: clone(record.payload),
57
+ });
58
+ }
59
+
60
+ read(runId, { afterSeq = 0, limit = 100_000 } = {}) {
61
+ return this.rolloutStore
62
+ .read(runId, { afterSeq, limit })
63
+ .filter((record) => record.event_type.startsWith("graph."))
64
+ .map((record) =>
65
+ Object.freeze({
66
+ schema: GRAPH_EVENT_SCHEMA,
67
+ runId,
68
+ seq: record.event_seq,
69
+ type: record.payload?.type || record.event_type.slice(6),
70
+ timestamp: record.timestamp,
71
+ prevHash: record.prev_hash,
72
+ hash: record.hash,
73
+ idempotencyKey: record.idempotency_key,
74
+ payload: clone(record.payload),
75
+ }),
76
+ );
77
+ }
78
+
79
+ head(runId) {
80
+ const events = this.rolloutStore.read(runId);
81
+ const record = events.at(-1);
82
+ return record
83
+ ? Object.freeze({ seq: record.event_seq, hash: record.hash })
84
+ : Object.freeze({ seq: 0, hash: null });
85
+ }
86
+
87
+ listRuns(options = {}) {
88
+ return this.rolloutStore
89
+ .list({ includeArchived: true, ...options })
90
+ .filter((thread) => thread.metadata?.kind === "graph_run")
91
+ .map((thread) =>
92
+ Object.freeze({
93
+ runId: thread.id,
94
+ revision: thread.revision,
95
+ headHash: thread.headHash,
96
+ status: thread.status,
97
+ updatedAt: thread.updatedAt,
98
+ }),
99
+ );
100
+ }
101
+ }
@@ -0,0 +1,7 @@
1
+ export * from "./compiler.js";
2
+ export * from "./event-store.js";
3
+ export * from "./runtime.js";
4
+ export * from "./trace-reducer.js";
5
+ export * from "./eval.js";
6
+ export * from "./trigger-adapter.js";
7
+ export * from "./adapters.js";