chainlesschain 0.166.20 → 0.166.21

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 (214) hide show
  1. package/package.json +2 -2
  2. package/src/assets/web-panel/assets/{AIOps-CcJst5Zs.js → AIOps-BjMnsUci.js} +1 -1
  3. package/src/assets/web-panel/assets/{ActionButton-BpHPFKd3.js → ActionButton-DdYFP03A.js} +1 -1
  4. package/src/assets/web-panel/assets/{Analytics-DHAsASuS.js → Analytics-Bb8TuuK_.js} +3 -3
  5. package/src/assets/web-panel/assets/{AppLayout-BTKwo5RC.js → AppLayout-Kn3TIOtk.js} +5 -5
  6. package/src/assets/web-panel/assets/{Artifacts-BcCBTggA.js → Artifacts-4IxpqI_b.js} +1 -1
  7. package/src/assets/web-panel/assets/{Audit-z1JvJYbT.js → Audit-BOV2caqU.js} +1 -1
  8. package/src/assets/web-panel/assets/{BackgroundAgents-CJ7DCMDR.js → BackgroundAgents-B86k-ay4.js} +1 -1
  9. package/src/assets/web-panel/assets/{Backup-CKpxw4uw.js → Backup-C5_ie1e3.js} +1 -1
  10. package/src/assets/web-panel/assets/{BaseInput-2jI_IlUB.js → BaseInput-xpwg6QCW.js} +1 -1
  11. package/src/assets/web-panel/assets/{Chat-C_4RfBeN.js → Chat-CVZOcZau.js} +5 -5
  12. package/src/assets/web-panel/assets/ChatBubbleRenderer-D8fPYhUu.js +1 -0
  13. package/src/assets/web-panel/assets/{Checkbox-BnF4z4N1.js → Checkbox-MKTq3zdP.js} +1 -1
  14. package/src/assets/web-panel/assets/{Codegen-m_LMamhM.js → Codegen-JUk3wzep.js} +1 -1
  15. package/src/assets/web-panel/assets/{Col-DzMbA760.js → Col-JPvTA0kC.js} +1 -1
  16. package/src/assets/web-panel/assets/{Community-SScuZUcW.js → Community-Tqgl87NQ.js} +1 -1
  17. package/src/assets/web-panel/assets/{Compact-CiOHRvwQ.js → Compact-BuAFYBmN.js} +1 -1
  18. package/src/assets/web-panel/assets/{Compliance-97FzYz-6.js → Compliance-CXS9WIPZ.js} +1 -1
  19. package/src/assets/web-panel/assets/{Cowork-C0ss-SRl.js → Cowork-Ds2bFHrr.js} +2 -2
  20. package/src/assets/web-panel/assets/{Cron-CCbdc9fp.js → Cron-C_dV_OeW.js} +2 -2
  21. package/src/assets/web-panel/assets/{Crosschain-BPnabXej.js → Crosschain-BsO6tIRo.js} +1 -1
  22. package/src/assets/web-panel/assets/{DID-B65hFnHs.js → DID-rNOFqBac.js} +2 -2
  23. package/src/assets/web-panel/assets/{Dashboard-B6qR_TF2.js → Dashboard-C2fcKKVY.js} +2 -2
  24. package/src/assets/web-panel/assets/{Dropdown-6c-2Fxm-.js → Dropdown-Y7Ndr0X_.js} +1 -1
  25. package/src/assets/web-panel/assets/{EmailListRenderer-GD57mfiz.js → EmailListRenderer-DcP_uPmL.js} +1 -1
  26. package/src/assets/web-panel/assets/{FamilyGuardDashboard-B2mxG6LN.js → FamilyGuardDashboard-Cwn3gDzk.js} +1 -1
  27. package/src/assets/web-panel/assets/{Federation-cZS-uvAo.js → Federation-ClQuOsqb.js} +1 -1
  28. package/src/assets/web-panel/assets/{FormItemContext-UbSfBIe1.js → FormItemContext-DfwtmlcK.js} +1 -1
  29. package/src/assets/web-panel/assets/GenericCardRenderer-zNZhtbC5.js +1 -0
  30. package/src/assets/web-panel/assets/{Git-DAlhOiDA.js → Git-BZmdW-G5.js} +2 -2
  31. package/src/assets/web-panel/assets/{Governance-B-RRVaP8.js → Governance-CqBk4lEn.js} +1 -1
  32. package/src/assets/web-panel/assets/{Inference-DBl-pXYR.js → Inference-Dbmt3ZXk.js} +1 -1
  33. package/src/assets/web-panel/assets/{KnowledgeGraph-DjqOkvgY.js → KnowledgeGraph-hMTH6qf3.js} +1 -1
  34. package/src/assets/web-panel/assets/{Logs-CEV7AEAD.js → Logs-CkiYgiW2.js} +2 -2
  35. package/src/assets/web-panel/assets/{MarkdownRenderer-BDCxa4d1.js → MarkdownRenderer-BL1FElXg.js} +1 -1
  36. package/src/assets/web-panel/assets/{Marketplace-oRjzfmYJ.js → Marketplace-CbB6wfin.js} +1 -1
  37. package/src/assets/web-panel/assets/{McpTools-BiTnznLw.js → McpTools-BSwiFtte.js} +3 -3
  38. package/src/assets/web-panel/assets/{Memory-DR0C5K4N.js → Memory-B03PeHrz.js} +2 -2
  39. package/src/assets/web-panel/assets/{MobileBridge--oR8wEcp.js → MobileBridge-CRGrnd-X.js} +1 -1
  40. package/src/assets/web-panel/assets/{MobileProjects-DKqpYMuG.js → MobileProjects-CE_5v2kO.js} +1 -1
  41. package/src/assets/web-panel/assets/{Mtc-Dg0D6fDQ.js → Mtc-Dp11QVx1.js} +2 -2
  42. package/src/assets/web-panel/assets/{MtcAudit-D4_-yWTK.js → MtcAudit-CYu-3JBu.js} +5 -5
  43. package/src/assets/web-panel/assets/{Multisig-Coz55FxA.js → Multisig-CGyJ0Xl3.js} +3 -3
  44. package/src/assets/web-panel/assets/{NLProgramming-BWVjgW9Y.js → NLProgramming-CoWi_ov1.js} +1 -1
  45. package/src/assets/web-panel/assets/{Notes-BflVuGwr.js → Notes-CgU9DDo9.js} +3 -3
  46. package/src/assets/web-panel/assets/{NotificationSettings-CT0F_dJ7.js → NotificationSettings-DX4I2b4W.js} +1 -1
  47. package/src/assets/web-panel/assets/OrderTableRenderer-CwHc15Zs.js +1 -0
  48. package/src/assets/web-panel/assets/{Organization-CMDTM2z5.js → Organization-oopLO_tk.js} +4 -4
  49. package/src/assets/web-panel/assets/{Overflow-acKvvYpC.js → Overflow-BFVvjMyf.js} +1 -1
  50. package/src/assets/web-panel/assets/{P2P-CRq5j9Ax.js → P2P-CBy5t-Tk.js} +2 -2
  51. package/src/assets/web-panel/assets/{PdhVaultBrowser-DmtzN6Kn.js → PdhVaultBrowser--YWJNsu6.js} +4 -4
  52. package/src/assets/web-panel/assets/{Permissions-SZ-kjJDa.js → Permissions-C2dZ8scb.js} +3 -3
  53. package/src/assets/web-panel/assets/{PersonalDataHub-DXh-ZfgJ.js → PersonalDataHub-Bs3l7Hlx.js} +6 -6
  54. package/src/assets/web-panel/assets/{Pipeline-DhBU9ftP.js → Pipeline-DEBWbZuD.js} +1 -1
  55. package/src/assets/web-panel/assets/{Privacy-BgEXpO_V.js → Privacy-CjHBb6NU.js} +1 -1
  56. package/src/assets/web-panel/assets/{ProjectInit-B2DJ-dmK.js → ProjectInit-D2WipUz5.js} +2 -2
  57. package/src/assets/web-panel/assets/{ProjectSettings-ve3SocWc.js → ProjectSettings-B6WfnrGB.js} +2 -2
  58. package/src/assets/web-panel/assets/{Projects-5ZvFasSJ.js → Projects-FF_thRi6.js} +1 -1
  59. package/src/assets/web-panel/assets/{Providers-C8fcF3BK.js → Providers-CCv5M_Dv.js} +1 -1
  60. package/src/assets/web-panel/assets/{QrScannerModal-unjO8lNO.js → QrScannerModal-CGthxU54.js} +1 -1
  61. package/src/assets/web-panel/assets/{QuickAsk-BT1QtT7D.js → QuickAsk-CnPmXPFb.js} +1 -1
  62. package/src/assets/web-panel/assets/{Recommend-BSjFrY1w.js → Recommend-Df_tGEa9.js} +1 -1
  63. package/src/assets/web-panel/assets/{RemoteSession-CWV0bICg.js → RemoteSession-Z58N0Loe.js} +2 -2
  64. package/src/assets/web-panel/assets/{Reputation-BMjiMsk2.js → Reputation-CZTBQ2Vt.js} +1 -1
  65. package/src/assets/web-panel/assets/{Row-9XCY22PM.js → Row-CdK3YpCQ.js} +1 -1
  66. package/src/assets/web-panel/assets/{RssFeed-DQ9PDy7Q.js → RssFeed-CFMVT5sb.js} +3 -3
  67. package/src/assets/web-panel/assets/{Search-Boym2HwG.js → Search-DrF8RIvD.js} +1 -1
  68. package/src/assets/web-panel/assets/{Security-Gbq3lGQb.js → Security-Ddk2f2DM.js} +4 -4
  69. package/src/assets/web-panel/assets/{Services-OcUfLdnu.js → Services-CCuK-VOo.js} +2 -2
  70. package/src/assets/web-panel/assets/{Skeleton-BjTog6cA.js → Skeleton-DxCpHzeM.js} +1 -1
  71. package/src/assets/web-panel/assets/{Skills-Dny4ft_1.js → Skills-t2oTDgcv.js} +1 -1
  72. package/src/assets/web-panel/assets/{Sla-Cy_VnhpZ.js → Sla-Df63M9_R.js} +1 -1
  73. package/src/assets/web-panel/assets/{SpeechSettings-CrFuL_lp.js → SpeechSettings-l7ox6KuX.js} +1 -1
  74. package/src/assets/web-panel/assets/{SyncSettings-k-FnjuOR.js → SyncSettings-COd_tgPp.js} +2 -2
  75. package/src/assets/web-panel/assets/{Tasks-ZEqDSo0_.js → Tasks-CzDCcrik.js} +1 -1
  76. package/src/assets/web-panel/assets/{Templates-CYYksYV5.js → Templates-D-vfxTGA.js} +1 -1
  77. package/src/assets/web-panel/assets/{Tenant-BvTTRTHS.js → Tenant-BlpT_Gxc.js} +1 -1
  78. package/src/assets/web-panel/assets/{Terminal-DMOQOtkj.js → Terminal-D5rq52Hg.js} +2 -2
  79. package/src/assets/web-panel/assets/TimelineRenderer-DdoMndkK.js +1 -0
  80. package/src/assets/web-panel/assets/{Tokens-VW6Wocdp.js → Tokens-BhgBsI6g.js} +1 -1
  81. package/src/assets/web-panel/assets/{Trigger-BtOxZqP6.js → Trigger-DwwzoikZ.js} +1 -1
  82. package/src/assets/web-panel/assets/{Trust-XcGJoTQx.js → Trust-HkTpzXFb.js} +1 -1
  83. package/src/assets/web-panel/assets/{UkeySign-aASNCs5j.js → UkeySign-D9nk6Ehe.js} +1 -1
  84. package/src/assets/web-panel/assets/{VideoEditing-Bz89M52u.js → VideoEditing-BKk0rfoy.js} +1 -1
  85. package/src/assets/web-panel/assets/{Wallet-uU4dSS_N.js → Wallet-IVWIU_Lq.js} +4 -4
  86. package/src/assets/web-panel/assets/{WebAuthn-Brrroxgr.js → WebAuthn-CFTCpfsG.js} +4 -4
  87. package/src/assets/web-panel/assets/{WorkflowEditor-Cny-evI9.js → WorkflowEditor-Dnf4Obif.js} +1 -1
  88. package/src/assets/web-panel/assets/{chat-CJ5iSwWq.js → chat-D2snERdj.js} +1 -1
  89. package/src/assets/web-panel/assets/{colors-DWa-2flG.js → colors-DKEjK1N1.js} +1 -1
  90. package/src/assets/web-panel/assets/{compact-item-DFwUfptU.js → compact-item-BEDLwQdt.js} +1 -1
  91. package/src/assets/web-panel/assets/{createContext-FHWWcyeB.js → createContext-DA9iW1a0.js} +1 -1
  92. package/src/assets/web-panel/assets/devWarning-DyhgpXPf.js +1 -0
  93. package/src/assets/web-panel/assets/{hasIn-QY_TElrN.js → hasIn-5l2xEcY9.js} +1 -1
  94. package/src/assets/web-panel/assets/{index-hw1J_Oxs.js → index-5pW4t1iD.js} +1 -1
  95. package/src/assets/web-panel/assets/{index-BR4RMPnB.js → index-7P1b8HZo.js} +1 -1
  96. package/src/assets/web-panel/assets/{index-BUNwuu5v.js → index-B00GeekA.js} +1 -1
  97. package/src/assets/web-panel/assets/{index-B18zERdP.js → index-B4QYBliR.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-wqiOz655.js → index-B7_W_rYd.js} +1 -1
  99. package/src/assets/web-panel/assets/{index-BQCtBurK.js → index-BO9dQjpt.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-DUfILsc-.js → index-BZ5lY2zx.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-DUepuy7O.js → index-B_eCoZgW.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-uRUZdL7I.js → index-BgfImyZI.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-CUoLd1dt.js → index-Bq5P3piS.js} +1 -1
  104. package/src/assets/web-panel/assets/{index-BiHRihC0.js → index-Bqc8tdIF.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-BcVr-LOk.js → index-C7sKbM5s.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-DDpXDi4J.js → index-CGlotREA.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-CjejB-z9.js → index-CRPrHE7h.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-D2rPJ6Sv.js → index-CX1x4AFn.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-w3SdYwaC.js → index-CbTPvp2_.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-D-Mhq8K6.js → index-CjWltbi_.js} +1 -1
  111. package/src/assets/web-panel/assets/index-Ck1jhFE0.js +1 -0
  112. package/src/assets/web-panel/assets/{index-Bd7McYpJ.js → index-CkMKuqUs.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-BYbwQ7SP.js → index-CmruhzFi.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-2ufsNuVn.js → index-Csfb-7hw.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-0umhind6.js → index-CxEtQYdi.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-B33frlaD.js → index-D7z4zB_a.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-Dy2PnKZx.js → index-DLoalqRX.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-CUiTugu3.js → index-DU2TXJu-.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-CGv5In_T.js → index-DXet1xol.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-DCHMVYG1.js → index-Dbd7eEex.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-th467RN6.js → index-Dbkghqn_.js} +1 -1
  122. package/src/assets/web-panel/assets/{index-CkmgbT7h.js → index-Dg2a9owQ.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-aTiI7lOQ.js → index-DpqtbXdE.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-C5F1vwec.js → index-DqwPFbOb.js} +3 -3
  125. package/src/assets/web-panel/assets/{index-DaHvj4jA.js → index-DvV03Ayk.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-BRsGZBHc.js → index-NJieh3T1.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-CeGn0A4W.js → index-Td8ZwyoC.js} +1 -1
  128. package/src/assets/web-panel/assets/index-c8jJEHVs.js +1 -0
  129. package/src/assets/web-panel/assets/{index-va4Rt-yM.js → index-e-e40id6.js} +1 -1
  130. package/src/assets/web-panel/assets/{index-CKS7n6mE.js → index-fccZmC_h.js} +1 -1
  131. package/src/assets/web-panel/assets/{index-BEjwv2x6.js → index-fgYk0QXO.js} +1 -1
  132. package/src/assets/web-panel/assets/{index-Dlq-u9E4.js → index-yYEQXYaU.js} +1 -1
  133. package/src/assets/web-panel/assets/{initDefaultProps-BeSPUFDz.js → initDefaultProps-CPrcB1TC.js} +1 -1
  134. package/src/assets/web-panel/assets/{motion-Dcajvjm9.js → motion-BQ7mWRh_.js} +1 -1
  135. package/src/assets/web-panel/assets/{move-B76orau-.js → move-CzOEq99p.js} +1 -1
  136. package/src/assets/web-panel/assets/{mtc-parser-zB6yFwcX.js → mtc-parser-BlQI5jrw.js} +1 -1
  137. package/src/assets/web-panel/assets/{omit-BsbNjz8w.js → omit-DlW4gxmv.js} +1 -1
  138. package/src/assets/web-panel/assets/{pickAttrs-BiJ9tssQ.js → pickAttrs-BBYms5nP.js} +1 -1
  139. package/src/assets/web-panel/assets/{placementArrow-BdfMjMeN.js → placementArrow-az2MPJ_7.js} +1 -1
  140. package/src/assets/web-panel/assets/{responsiveObserve-rV4LGpbU.js → responsiveObserve-D1-ibEol.js} +1 -1
  141. package/src/assets/web-panel/assets/{slide-HsVw1qFQ.js → slide-DHGqa4GA.js} +1 -1
  142. package/src/assets/web-panel/assets/{statusUtils-D1ry8XPE.js → statusUtils-CYGDo6lD.js} +1 -1
  143. package/src/assets/web-panel/assets/{styleChecker-B1t6aQQ_.js → styleChecker-Cl2EM9K6.js} +1 -1
  144. package/src/assets/web-panel/assets/{useFlexGapSupport-C8qbl-9w.js → useFlexGapSupport-DdYhzuv1.js} +1 -1
  145. package/src/assets/web-panel/assets/{useFs-R7g_mYTC.js → useFs-DWumPuBW.js} +1 -1
  146. package/src/assets/web-panel/assets/{usePersonalDataHub-Cd-kCe7Z.js → usePersonalDataHub-DxAO-Aqi.js} +1 -1
  147. package/src/assets/web-panel/assets/{vnode-9WhK5UWA.js → vnode-CplsQf_N.js} +1 -1
  148. package/src/assets/web-panel/assets/{zoom-CUqppPco.js → zoom-Cw5HXNSG.js} +1 -1
  149. package/src/assets/web-panel/index.html +1 -1
  150. package/src/command-help-index.json +2 -2
  151. package/src/commands/agent.js +19 -1
  152. package/src/commands/evolution-knowledge.js +54 -0
  153. package/src/commands/evolution-workbench.js +83 -0
  154. package/src/commands/evolution.js +6 -1
  155. package/src/commands/serve.js +16 -0
  156. package/src/commands/skill.js +158 -16
  157. package/src/data/changelog.json +13 -0
  158. package/src/gateways/ws/session-protocol.js +2 -0
  159. package/src/gateways/ws/ws-agent-handler.js +124 -69
  160. package/src/gateways/ws/ws-server.js +19 -0
  161. package/src/generated/cc-agent-protocol.schema.json +7 -1
  162. package/src/harness/jsonl-session-store.js +25 -1
  163. package/src/index.js +1 -1
  164. package/src/lib/app-server/cli-agent-kernel-adapter.js +8 -0
  165. package/src/lib/app-server/graph-runtime.js +40 -1
  166. package/src/lib/app-server/server.js +181 -3
  167. package/src/lib/app-server/websocket-transport.js +2 -0
  168. package/src/lib/evolution/agent-evolution-runtime-composition-brand.js +17 -0
  169. package/src/lib/evolution/agent-evolution-runtime-composition.js +165 -1
  170. package/src/lib/evolution/controlled-skill-production-pilot.js +912 -0
  171. package/src/lib/evolution/evolution-artifact-ports.js +21 -0
  172. package/src/lib/evolution/evolution-raw-crypto-shred.js +185 -0
  173. package/src/lib/evolution/evolution-workbench-batch-executor.js +195 -0
  174. package/src/lib/evolution/evolution-workbench-cli-host.js +169 -0
  175. package/src/lib/evolution/evolution-workbench-metrics-ledger-adapter.js +648 -0
  176. package/src/lib/evolution/evolution-workbench-metrics.js +943 -0
  177. package/src/lib/evolution/evolution-workbench-projection.js +734 -0
  178. package/src/lib/evolution/evolution-workbench-version-control.js +272 -0
  179. package/src/lib/evolution/governed-knowledge-conflict-merge.js +352 -0
  180. package/src/lib/evolution/governed-knowledge-dependency-authority.js +273 -0
  181. package/src/lib/evolution/governed-knowledge-dependency-ledger-executor.js +646 -0
  182. package/src/lib/evolution/governed-knowledge-merge-ledger-executor.js +644 -0
  183. package/src/lib/evolution/governed-knowledge-merge-publisher-authority.js +282 -0
  184. package/src/lib/evolution/governed-knowledge-node-crypto-authority.js +348 -0
  185. package/src/lib/evolution/governed-knowledge-rbac-approval-authority.js +621 -0
  186. package/src/lib/evolution/governed-knowledge-review-host.js +249 -0
  187. package/src/lib/evolution/governed-knowledge-sync-ledger-adapter.js +643 -0
  188. package/src/lib/evolution/governed-knowledge-sync-merge-publisher.js +259 -0
  189. package/src/lib/evolution/governed-knowledge-sync.js +485 -0
  190. package/src/lib/evolution/governed-knowledge-trust-ledger.js +707 -0
  191. package/src/lib/evolution/governed-skill-marketplace.js +430 -0
  192. package/src/lib/evolution/governed-wiki-pruning.js +435 -0
  193. package/src/lib/evolution/skill-outcome-index-authority.js +268 -0
  194. package/src/lib/evolution/skill-outcome-source-catalog-authority.js +237 -0
  195. package/src/lib/public-ide-capability-manifest.js +4 -0
  196. package/src/lib/skill-outcome-authority.js +43 -0
  197. package/src/lib/skill-outcome-transcript-authority.js +252 -0
  198. package/src/lib/skill-retrieval-router-benchmark.js +135 -0
  199. package/src/lib/skill-retrieval-router.js +235 -0
  200. package/src/lib/skill-vector-authority.js +325 -0
  201. package/src/lib/skill-vector-process-authority.js +386 -0
  202. package/src/repl/agent-repl.js +7 -1
  203. package/src/runtime/agent-core.js +72 -6
  204. package/src/runtime/agent-runtime.js +42 -0
  205. package/src/runtime/headless-runner.js +32 -0
  206. package/src/runtime/headless-stream.js +36 -1
  207. package/src/runtime/runtime-factory.js +62 -4
  208. package/src/assets/web-panel/assets/ChatBubbleRenderer-eMmw1eZF.js +0 -1
  209. package/src/assets/web-panel/assets/GenericCardRenderer-BMAtvGt1.js +0 -1
  210. package/src/assets/web-panel/assets/OrderTableRenderer-Dyrnqy_o.js +0 -1
  211. package/src/assets/web-panel/assets/TimelineRenderer-CnudkJxk.js +0 -1
  212. package/src/assets/web-panel/assets/devWarning-DxufPwXC.js +0 -1
  213. package/src/assets/web-panel/assets/index-ZMTB9p5z.js +0 -1
  214. package/src/assets/web-panel/assets/index-_PvIDelE.js +0 -1
@@ -0,0 +1,435 @@
1
+ import { createHash } from "node:crypto";
2
+
3
+ import {
4
+ WIKI_PATTERN_STATUS,
5
+ WIKI_STATE_SCHEMA,
6
+ digestWikiState,
7
+ } from "./evidence-backed-wiki-maintainer.js";
8
+
9
+ export const GOVERNED_WIKI_PRUNING_PLAN_SCHEMA =
10
+ "chainlesschain.governed-wiki-pruning-plan/v1";
11
+ export const GOVERNED_WIKI_PRUNING_CONTROL_SCHEMA =
12
+ "chainlesschain.governed-wiki-pruning-control/v1";
13
+ export const GOVERNED_ONLINE_ADAPTATION_AUTHORIZATION_SCHEMA =
14
+ "chainlesschain.governed-online-adaptation-authorization/v1";
15
+
16
+ const DIGEST = /^sha256:[a-f0-9]{64}$/u;
17
+ const TERMINAL_PATTERN_STATUSES = new Set([
18
+ WIKI_PATTERN_STATUS.REVOKED,
19
+ WIKI_PATTERN_STATUS.TOMBSTONED,
20
+ ]);
21
+
22
+ function canonical(value) {
23
+ if (value === null || typeof value !== "object") return JSON.stringify(value);
24
+ if (Array.isArray(value)) return `[${value.map(canonical).join(",")}]`;
25
+ return `{${Object.keys(value)
26
+ .sort()
27
+ .map((key) => `${JSON.stringify(key)}:${canonical(value[key])}`)
28
+ .join(",")}}`;
29
+ }
30
+
31
+ function hash(domain, value) {
32
+ return `sha256:${createHash("sha256")
33
+ .update(domain)
34
+ .update("\0")
35
+ .update(canonical(value))
36
+ .digest("hex")}`;
37
+ }
38
+
39
+ function clone(value) {
40
+ return value == null ? value : structuredClone(value);
41
+ }
42
+
43
+ function freeze(value) {
44
+ if (value && typeof value === "object" && !Object.isFrozen(value)) {
45
+ Object.freeze(value);
46
+ for (const child of Object.values(value)) freeze(child);
47
+ }
48
+ return value;
49
+ }
50
+
51
+ function string(value, name) {
52
+ if (typeof value !== "string" || value.trim() === "")
53
+ throw new TypeError(`${name} is required`);
54
+ return value;
55
+ }
56
+
57
+ function digest(value, name) {
58
+ if (!DIGEST.test(value ?? "")) throw new TypeError(`${name} is invalid`);
59
+ return value;
60
+ }
61
+
62
+ function time(value, name) {
63
+ string(value, name);
64
+ if (!Number.isFinite(Date.parse(value)))
65
+ throw new TypeError(`${name} must be an ISO timestamp`);
66
+ return value;
67
+ }
68
+
69
+ function boundedUniqueStrings(value, name, maximum = 256) {
70
+ if (
71
+ !Array.isArray(value) ||
72
+ value.length > maximum ||
73
+ value.some((item) => typeof item !== "string" || item.trim() === "")
74
+ )
75
+ throw new TypeError(`${name} must be a bounded string list`);
76
+ return [...new Set(value)].sort();
77
+ }
78
+
79
+ function normalizeDescriptor(input) {
80
+ const staleGraceDays = Number(input?.staleGraceDays ?? 30);
81
+ const maxActions = Number(input?.maxActions ?? 512);
82
+ if (
83
+ !Number.isInteger(staleGraceDays) ||
84
+ staleGraceDays < 0 ||
85
+ !Number.isInteger(maxActions) ||
86
+ maxActions < 1 ||
87
+ maxActions > 4096
88
+ )
89
+ throw new TypeError("Wiki pruning policy is invalid");
90
+ return freeze({
91
+ tenantId: string(input?.tenantId, "tenantId"),
92
+ staleGraceDays,
93
+ maxActions,
94
+ });
95
+ }
96
+
97
+ function verifyStateEnvelope(envelope, tenantId, expectedStateDigest) {
98
+ const state = envelope?.state;
99
+ if (
100
+ envelope?.trusted !== true ||
101
+ state?.schema !== WIKI_STATE_SCHEMA ||
102
+ state.tenantId !== tenantId ||
103
+ envelope.stateDigest !== expectedStateDigest ||
104
+ digestWikiState(state) !== expectedStateDigest
105
+ )
106
+ throw new Error("Wiki pruning requires an exact trusted Wiki state");
107
+ return clone(state);
108
+ }
109
+
110
+ function verifiedAt(pattern) {
111
+ return pattern.lastVerifiedAt ?? pattern.updatedAt;
112
+ }
113
+
114
+ function assertPlan(plan, tenantId) {
115
+ if (
116
+ plan?.schema !== GOVERNED_WIKI_PRUNING_PLAN_SCHEMA ||
117
+ plan.tenantId !== tenantId ||
118
+ !DIGEST.test(plan?.planDigest ?? "")
119
+ )
120
+ throw new TypeError("Wiki pruning plan is invalid");
121
+ const core = clone(plan);
122
+ delete core.planDigest;
123
+ if (hash(GOVERNED_WIKI_PRUNING_PLAN_SCHEMA, core) !== plan.planDigest)
124
+ throw new Error("Wiki pruning plan digest is invalid");
125
+ return freeze(clone(plan));
126
+ }
127
+
128
+ function operationRequest(plan, operation, payload) {
129
+ const request = freeze({
130
+ tenantId: plan.tenantId,
131
+ planDigest: plan.planDigest,
132
+ wikiStateDigest: plan.wikiStateDigest,
133
+ operation,
134
+ payload: clone(payload),
135
+ });
136
+ return freeze({
137
+ request,
138
+ requestDigest: hash(
139
+ "chainlesschain.governed-wiki-pruning-operation/v1",
140
+ request,
141
+ ),
142
+ });
143
+ }
144
+
145
+ function requireDurableAck(result, requestDigest, label) {
146
+ if (
147
+ result?.authenticated !== true ||
148
+ result.durable !== true ||
149
+ result.requestDigest !== requestDigest ||
150
+ !DIGEST.test(result.receiptDigest ?? "")
151
+ )
152
+ throw new Error(`${label} was not durably acknowledged`);
153
+ return result.receiptDigest;
154
+ }
155
+
156
+ export class GovernedWikiPruning {
157
+ constructor({ descriptor, ports } = {}) {
158
+ this.descriptor = normalizeDescriptor(descriptor);
159
+ for (const name of [
160
+ "loadWikiState",
161
+ "resolveDeletionReceipt",
162
+ "commitControl",
163
+ "applyDependencyDispositions",
164
+ "applyWikiRevision",
165
+ "cryptoShred",
166
+ "publishRetrievalProjection",
167
+ "verifyOfflineClosure",
168
+ ]) {
169
+ if (typeof ports?.[name] !== "function")
170
+ throw new TypeError(`Wiki pruning port ${name} is required`);
171
+ this[`_${name}`] = ports[name].bind(ports);
172
+ }
173
+ }
174
+
175
+ async plan({
176
+ expectedStateDigest,
177
+ effectiveAt,
178
+ deletionReceiptDigests = [],
179
+ }) {
180
+ digest(expectedStateDigest, "expectedStateDigest");
181
+ time(effectiveAt, "effectiveAt");
182
+ const receiptDigests = boundedUniqueStrings(
183
+ deletionReceiptDigests,
184
+ "deletionReceiptDigests",
185
+ this.descriptor.maxActions,
186
+ );
187
+ receiptDigests.forEach((value) => digest(value, "deletionReceiptDigest"));
188
+ const state = verifyStateEnvelope(
189
+ await this._loadWikiState({ tenantId: this.descriptor.tenantId }),
190
+ this.descriptor.tenantId,
191
+ expectedStateDigest,
192
+ );
193
+ const cutoff =
194
+ Date.parse(effectiveAt) - this.descriptor.staleGraceDays * 86_400_000;
195
+ const patternActions = [];
196
+ const retrievalRemovals = [];
197
+ for (const pattern of Object.values(state.patterns).sort((a, b) =>
198
+ a.patternId.localeCompare(b.patternId),
199
+ )) {
200
+ if (
201
+ pattern.status === WIKI_PATTERN_STATUS.STALE &&
202
+ Number.isFinite(Date.parse(verifiedAt(pattern))) &&
203
+ Date.parse(verifiedAt(pattern)) <= cutoff
204
+ )
205
+ patternActions.push({
206
+ type: "tombstone",
207
+ patternId: pattern.patternId,
208
+ reason: "stale-grace-elapsed",
209
+ });
210
+ if (
211
+ pattern.status === WIKI_PATTERN_STATUS.STALE ||
212
+ TERMINAL_PATTERN_STATUSES.has(pattern.status)
213
+ )
214
+ retrievalRemovals.push(pattern.patternId);
215
+ }
216
+
217
+ const deletions = [];
218
+ const dependencyDispositions = [];
219
+ for (const receiptDigest of receiptDigests) {
220
+ const receipt = await this._resolveDeletionReceipt({
221
+ tenantId: this.descriptor.tenantId,
222
+ receiptDigest,
223
+ });
224
+ const evidence = state.evidence?.[receipt?.evidenceRef];
225
+ if (
226
+ receipt?.authenticated !== true ||
227
+ receipt.tenantId !== this.descriptor.tenantId ||
228
+ receipt.decision !== "delete" ||
229
+ receipt.receiptDigest !== receiptDigest ||
230
+ evidence == null ||
231
+ receipt.sourceDigest !== evidence.sourceDigest ||
232
+ receipt.artifactRef !== evidence.artifactRef ||
233
+ typeof receipt.rawArtifactRef !== "string" ||
234
+ !receipt.rawArtifactRef.startsWith(
235
+ `artifact://${this.descriptor.tenantId}/raw/`,
236
+ ) ||
237
+ !DIGEST.test(receipt.rawCipherDigest ?? "") ||
238
+ typeof receipt.keyRef !== "string" ||
239
+ !receipt.keyRef.startsWith(`kms://${this.descriptor.tenantId}/`)
240
+ )
241
+ throw new Error("privacy deletion receipt is not exactly bound");
242
+ const dependentPatternIds = [
243
+ ...new Set(state.evidenceDependents?.[receipt.evidenceRef] ?? []),
244
+ ].sort();
245
+ for (const patternId of dependentPatternIds) {
246
+ const pattern = state.patterns[patternId];
247
+ if (!pattern) throw new Error("Wiki evidence dependency is corrupt");
248
+ dependencyDispositions.push({
249
+ evidenceRef: receipt.evidenceRef,
250
+ patternId,
251
+ action: pattern.skillNames?.length > 0 ? "rollback" : "tombstone",
252
+ skillNames: [...(pattern.skillNames ?? [])].sort(),
253
+ });
254
+ retrievalRemovals.push(patternId);
255
+ }
256
+ deletions.push({
257
+ evidenceRef: receipt.evidenceRef,
258
+ sourceDigest: evidence.sourceDigest,
259
+ artifactRef: evidence.artifactRef,
260
+ rawArtifactRef: receipt.rawArtifactRef,
261
+ rawCipherDigest: receipt.rawCipherDigest,
262
+ keyRef: receipt.keyRef,
263
+ receiptDigest,
264
+ });
265
+ }
266
+ const actionCount =
267
+ patternActions.length + deletions.length + dependencyDispositions.length;
268
+ if (actionCount > this.descriptor.maxActions)
269
+ throw new Error("Wiki pruning plan exceeds its action budget");
270
+ const core = {
271
+ schema: GOVERNED_WIKI_PRUNING_PLAN_SCHEMA,
272
+ tenantId: this.descriptor.tenantId,
273
+ wikiStateDigest: expectedStateDigest,
274
+ effectiveAt,
275
+ patternActions,
276
+ retrievalRemovals: [...new Set(retrievalRemovals)].sort(),
277
+ dependencyDispositions,
278
+ deletions,
279
+ auditPolicy: {
280
+ retainWikiRevisions: true,
281
+ retainEvolutionLog: true,
282
+ retainDeletionReceipts: true,
283
+ removeDeletedEvidenceFromRetrieval: true,
284
+ },
285
+ };
286
+ return freeze({
287
+ ...core,
288
+ planDigest: hash(GOVERNED_WIKI_PRUNING_PLAN_SCHEMA, core),
289
+ });
290
+ }
291
+
292
+ async execute({ plan: input, expectedControlDigest = null }) {
293
+ const plan = assertPlan(input, this.descriptor.tenantId);
294
+ if (expectedControlDigest != null)
295
+ digest(expectedControlDigest, "expectedControlDigest");
296
+ verifyStateEnvelope(
297
+ await this._loadWikiState({ tenantId: this.descriptor.tenantId }),
298
+ this.descriptor.tenantId,
299
+ plan.wikiStateDigest,
300
+ );
301
+ const preparedCore = {
302
+ schema: GOVERNED_WIKI_PRUNING_CONTROL_SCHEMA,
303
+ tenantId: this.descriptor.tenantId,
304
+ planDigest: plan.planDigest,
305
+ wikiStateDigest: plan.wikiStateDigest,
306
+ phase: "prepared",
307
+ operationReceiptDigests: [],
308
+ };
309
+ const prepared = freeze({
310
+ ...preparedCore,
311
+ controlDigest: hash(GOVERNED_WIKI_PRUNING_CONTROL_SCHEMA, preparedCore),
312
+ });
313
+ const preparation = await this._commitControl({
314
+ state: prepared,
315
+ expectedControlDigest,
316
+ });
317
+ if (
318
+ preparation?.authenticated !== true ||
319
+ preparation.durable !== true ||
320
+ preparation.controlDigest !== prepared.controlDigest
321
+ )
322
+ throw new Error("Wiki pruning preparation was not durably committed");
323
+
324
+ const receipts = [];
325
+ for (const [operation, payload, invoke] of [
326
+ [
327
+ "dependency-dispositions",
328
+ plan.dependencyDispositions,
329
+ this._applyDependencyDispositions,
330
+ ],
331
+ ["wiki-revision", plan.patternActions, this._applyWikiRevision],
332
+ ]) {
333
+ const call = operationRequest(plan, operation, payload);
334
+ receipts.push(
335
+ requireDurableAck(
336
+ await invoke(call),
337
+ call.requestDigest,
338
+ `Wiki pruning ${operation}`,
339
+ ),
340
+ );
341
+ }
342
+ for (const deletion of plan.deletions) {
343
+ const call = operationRequest(plan, "crypto-shred", deletion);
344
+ receipts.push(
345
+ requireDurableAck(
346
+ await this._cryptoShred(call),
347
+ call.requestDigest,
348
+ "Wiki privacy deletion",
349
+ ),
350
+ );
351
+ }
352
+ const projection = operationRequest(plan, "retrieval-projection", {
353
+ removals: plan.retrievalRemovals,
354
+ });
355
+ receipts.push(
356
+ requireDurableAck(
357
+ await this._publishRetrievalProjection(projection),
358
+ projection.requestDigest,
359
+ "Wiki retrieval projection",
360
+ ),
361
+ );
362
+ const finalCore = {
363
+ ...preparedCore,
364
+ phase: "finalized",
365
+ operationReceiptDigests: receipts,
366
+ };
367
+ const finalized = freeze({
368
+ ...finalCore,
369
+ controlDigest: hash(GOVERNED_WIKI_PRUNING_CONTROL_SCHEMA, finalCore),
370
+ });
371
+ const completion = await this._commitControl({
372
+ state: finalized,
373
+ expectedControlDigest: prepared.controlDigest,
374
+ });
375
+ if (
376
+ completion?.authenticated !== true ||
377
+ completion.durable !== true ||
378
+ completion.controlDigest !== finalized.controlDigest
379
+ )
380
+ throw new Error("Wiki pruning completion was not durably committed");
381
+ return finalized;
382
+ }
383
+
384
+ async authorizeOnlineAdaptation(input = {}) {
385
+ const requested = boundedUniqueStrings(
386
+ input.requestedCapabilities ?? [],
387
+ "requestedCapabilities",
388
+ 64,
389
+ );
390
+ const baseline = boundedUniqueStrings(
391
+ input.baselineCapabilities ?? [],
392
+ "baselineCapabilities",
393
+ 64,
394
+ );
395
+ if (
396
+ input.tenantId !== this.descriptor.tenantId ||
397
+ input.candidateOnly !== true ||
398
+ input.promotionGateRequired !== true ||
399
+ input.crossTenant === true ||
400
+ requested.some((capability) => !baseline.includes(capability))
401
+ )
402
+ throw new Error("online adaptation cannot expand authority");
403
+ const closure = await this._verifyOfflineClosure({
404
+ tenantId: this.descriptor.tenantId,
405
+ receiptDigest: digest(
406
+ input.offlineClosureReceiptDigest,
407
+ "offlineClosureReceiptDigest",
408
+ ),
409
+ });
410
+ if (
411
+ closure?.authenticated !== true ||
412
+ closure.stable !== true ||
413
+ closure.tenantId !== this.descriptor.tenantId ||
414
+ closure.receiptDigest !== input.offlineClosureReceiptDigest
415
+ )
416
+ throw new Error("online adaptation requires stable offline closure");
417
+ const core = {
418
+ schema: GOVERNED_ONLINE_ADAPTATION_AUTHORIZATION_SCHEMA,
419
+ tenantId: this.descriptor.tenantId,
420
+ sessionId: string(input.sessionId, "sessionId"),
421
+ baselineCapabilities: baseline,
422
+ requestedCapabilities: requested,
423
+ candidateOnly: true,
424
+ promotionGateRequired: true,
425
+ offlineClosureReceiptDigest: closure.receiptDigest,
426
+ };
427
+ return freeze({
428
+ ...core,
429
+ authorizationDigest: hash(
430
+ GOVERNED_ONLINE_ADAPTATION_AUTHORIZATION_SCHEMA,
431
+ core,
432
+ ),
433
+ });
434
+ }
435
+ }
@@ -0,0 +1,268 @@
1
+ import { createHash } from "node:crypto";
2
+
3
+ import { verifyEvolutionWorkbenchMetricsSnapshot } from "./evolution-workbench-metrics.js";
4
+ import { isEvolutionWorkbenchMetricsOutcomeReader } from "./evolution-workbench-metrics-ledger-adapter.js";
5
+
6
+ export const SKILL_OUTCOME_INDEX_AUTHORITY_SCHEMA =
7
+ "chainlesschain.skill-outcome-index-authority/v1";
8
+ export const MAX_SKILL_OUTCOME_INDEX_SOURCES = 128;
9
+ export const MAX_SKILL_OUTCOME_INDEX_VERSIONS = 10_000;
10
+
11
+ const LEDGER_DIGEST = /^sha256:[a-f0-9]{64}$/u;
12
+
13
+ function canonical(value) {
14
+ if (value === null || typeof value !== "object") {
15
+ return JSON.stringify(value);
16
+ }
17
+ if (Array.isArray(value)) return `[${value.map(canonical).join(",")}]`;
18
+ return `{${Object.keys(value)
19
+ .sort()
20
+ .map((key) => `${JSON.stringify(key)}:${canonical(value[key])}`)
21
+ .join(",")}}`;
22
+ }
23
+
24
+ function sha256(value) {
25
+ return `sha256:${createHash("sha256").update(value).digest("hex")}`;
26
+ }
27
+
28
+ function bounded(value) {
29
+ return (
30
+ typeof value === "string" &&
31
+ value.length > 0 &&
32
+ value.length <= 256 &&
33
+ value.trim() === value
34
+ );
35
+ }
36
+
37
+ function unavailable(
38
+ message,
39
+ code = "CC_SKILL_OUTCOME_INDEX_AUTHORITY_UNAVAILABLE",
40
+ ) {
41
+ const error = new Error(message);
42
+ error.code = code;
43
+ return error;
44
+ }
45
+
46
+ function verifyLedgerAuthority(value, found) {
47
+ if (
48
+ value?.schema !== "chainlesschain.evolution-ledger-verification/v2" ||
49
+ value.status !== "verified" ||
50
+ value.authenticated !== true ||
51
+ value.durable !== true ||
52
+ !bounded(value.ledgerId) ||
53
+ !LEDGER_DIGEST.test(value.identityDigest || "") ||
54
+ (value.headDigest !== null &&
55
+ !LEDGER_DIGEST.test(value.headDigest || "")) ||
56
+ (found && value.headDigest === null) ||
57
+ !Number.isSafeInteger(value.sequence) ||
58
+ value.sequence < 0 ||
59
+ !Number.isSafeInteger(value.eventCount) ||
60
+ value.eventCount < 0 ||
61
+ value.sequence !== value.eventCount ||
62
+ !bounded(value.witnessId) ||
63
+ !Number.isSafeInteger(value.witnessGeneration) ||
64
+ value.witnessGeneration < 0 ||
65
+ !LEDGER_DIGEST.test(value.witnessDigest || "")
66
+ ) {
67
+ throw unavailable("Skill outcome index ledger authority is invalid");
68
+ }
69
+ return value;
70
+ }
71
+
72
+ function inspectSource(adapter) {
73
+ const loaded = adapter.loadOutcomeSnapshot();
74
+ const descriptor = loaded?.descriptor;
75
+ if (
76
+ !descriptor ||
77
+ !bounded(descriptor.tenantId) ||
78
+ !bounded(descriptor.evolutionRunId) ||
79
+ !bounded(descriptor.skillName) ||
80
+ loaded.authenticated !== true ||
81
+ loaded.durable !== true ||
82
+ typeof loaded.found !== "boolean"
83
+ ) {
84
+ throw unavailable("Skill outcome index source is invalid");
85
+ }
86
+ const ledger = verifyLedgerAuthority(loaded.ledgerAuthority, loaded.found);
87
+ if (!loaded.found) {
88
+ return Object.freeze({
89
+ descriptor,
90
+ ledger,
91
+ snapshot: null,
92
+ });
93
+ }
94
+ const snapshot = verifyEvolutionWorkbenchMetricsSnapshot(
95
+ loaded.snapshot,
96
+ descriptor,
97
+ );
98
+ if (
99
+ snapshot.outcomeHistoryComplete !== true &&
100
+ snapshot.versions.length !== 0
101
+ ) {
102
+ throw unavailable(
103
+ "Skill outcome index requires a complete outcome backfill",
104
+ "CC_SKILL_OUTCOME_INDEX_BACKFILL_REQUIRED",
105
+ );
106
+ }
107
+ return Object.freeze({ descriptor, ledger, snapshot });
108
+ }
109
+
110
+ export function buildSkillOutcomeIndexAuthority(
111
+ { tenantId, readers, maxSources = MAX_SKILL_OUTCOME_INDEX_SOURCES } = {},
112
+ dependencies = {},
113
+ ) {
114
+ const isReader =
115
+ dependencies.isMetricsOutcomeReader ||
116
+ isEvolutionWorkbenchMetricsOutcomeReader;
117
+ if (
118
+ !bounded(tenantId) ||
119
+ !Array.isArray(readers) ||
120
+ readers.length < 1 ||
121
+ !Number.isSafeInteger(maxSources) ||
122
+ maxSources < 1 ||
123
+ maxSources > MAX_SKILL_OUTCOME_INDEX_SOURCES ||
124
+ readers.length > maxSources ||
125
+ typeof isReader !== "function" ||
126
+ readers.some(
127
+ (reader) =>
128
+ !isReader(reader) || typeof reader?.loadOutcomeSnapshot !== "function",
129
+ )
130
+ ) {
131
+ throw new TypeError("Skill outcome index readers are invalid or unbounded");
132
+ }
133
+
134
+ const sources = readers.map(inspectSource);
135
+ if (sources.some((source) => source.descriptor.tenantId !== tenantId)) {
136
+ throw unavailable("Skill outcome index crossed its tenant boundary");
137
+ }
138
+ const sourceIds = new Set();
139
+ let versionCount = 0;
140
+ let outcomeSampleCount = 0;
141
+ const totals = new Map();
142
+ for (const source of sources) {
143
+ const sourceId = [
144
+ source.descriptor.tenantId,
145
+ source.descriptor.evolutionRunId,
146
+ source.descriptor.skillName,
147
+ ].join("\0");
148
+ if (sourceIds.has(sourceId)) {
149
+ throw unavailable("Skill outcome index contains a duplicate source");
150
+ }
151
+ sourceIds.add(sourceId);
152
+ if (!source.snapshot) continue;
153
+ versionCount += source.snapshot.versions.length;
154
+ if (versionCount > MAX_SKILL_OUTCOME_INDEX_VERSIONS) {
155
+ throw unavailable(
156
+ "Skill outcome index version capacity exceeded",
157
+ "CC_SKILL_OUTCOME_INDEX_CAPACITY",
158
+ );
159
+ }
160
+ for (const version of source.snapshot.versions) {
161
+ if (
162
+ !Number.isSafeInteger(version.outcomeReceiptCount) ||
163
+ !Number.isSafeInteger(version.outcomeCompleted) ||
164
+ !Number.isSafeInteger(version.userCorrectionCount)
165
+ ) {
166
+ throw unavailable("Skill outcome index version is not outcome-aware");
167
+ }
168
+ if (version.outcomeReceiptCount === 0) continue;
169
+ const total = totals.get(version.contentDigest) || {
170
+ samples: 0,
171
+ successes: 0,
172
+ corrections: 0,
173
+ };
174
+ total.samples += version.outcomeReceiptCount;
175
+ total.successes += version.outcomeCompleted;
176
+ total.corrections += version.userCorrectionCount;
177
+ if (
178
+ !Number.isSafeInteger(total.samples) ||
179
+ !Number.isSafeInteger(total.successes) ||
180
+ !Number.isSafeInteger(total.corrections)
181
+ ) {
182
+ throw unavailable(
183
+ "Skill outcome index aggregate capacity exceeded",
184
+ "CC_SKILL_OUTCOME_INDEX_CAPACITY",
185
+ );
186
+ }
187
+ totals.set(version.contentDigest, total);
188
+ outcomeSampleCount += version.outcomeReceiptCount;
189
+ if (!Number.isSafeInteger(outcomeSampleCount)) {
190
+ throw unavailable(
191
+ "Skill outcome index sample capacity exceeded",
192
+ "CC_SKILL_OUTCOME_INDEX_CAPACITY",
193
+ );
194
+ }
195
+ }
196
+ }
197
+
198
+ const metrics = Object.fromEntries(
199
+ [...totals.entries()]
200
+ .sort(([left], [right]) => left.localeCompare(right))
201
+ .map(([contentDigest, total]) => [
202
+ contentDigest,
203
+ Object.freeze({
204
+ samples: total.samples,
205
+ successRate: total.successes / total.samples,
206
+ correctionRate: total.corrections / total.samples,
207
+ }),
208
+ ]),
209
+ );
210
+ const sourceProjection = sources
211
+ .map(({ descriptor, ledger, snapshot }) => ({
212
+ tenantId: descriptor.tenantId,
213
+ evolutionRunId: descriptor.evolutionRunId,
214
+ skillName: descriptor.skillName,
215
+ snapshotDigest: snapshot?.snapshotDigest || null,
216
+ ledgerId: ledger.ledgerId,
217
+ identityDigest: ledger.identityDigest,
218
+ headDigest: ledger.headDigest,
219
+ eventCount: ledger.eventCount,
220
+ witnessId: ledger.witnessId,
221
+ witnessGeneration: ledger.witnessGeneration,
222
+ witnessDigest: ledger.witnessDigest,
223
+ }))
224
+ .sort(
225
+ (left, right) =>
226
+ left.tenantId.localeCompare(right.tenantId) ||
227
+ left.evolutionRunId.localeCompare(right.evolutionRunId) ||
228
+ left.skillName.localeCompare(right.skillName),
229
+ );
230
+ const sourceDigest = sha256(
231
+ `${SKILL_OUTCOME_INDEX_AUTHORITY_SCHEMA}\0${canonical(sourceProjection)}`,
232
+ );
233
+ return Object.freeze({
234
+ schema: SKILL_OUTCOME_INDEX_AUTHORITY_SCHEMA,
235
+ status: "verified-indexed",
236
+ metrics: Object.freeze(metrics),
237
+ evidence: Object.freeze({
238
+ schema: SKILL_OUTCOME_INDEX_AUTHORITY_SCHEMA,
239
+ status: "verified-indexed",
240
+ sourceDigest,
241
+ sourceCount: sources.length,
242
+ snapshotCount: sources.filter(({ snapshot }) => snapshot !== null).length,
243
+ versionCount,
244
+ outcomeSampleCount,
245
+ maxSources,
246
+ maxVersions: MAX_SKILL_OUTCOME_INDEX_VERSIONS,
247
+ antiRollbackWitness: true,
248
+ }),
249
+ });
250
+ }
251
+
252
+ export function unavailableSkillOutcomeIndexAuthority(error) {
253
+ return Object.freeze({
254
+ schema: SKILL_OUTCOME_INDEX_AUTHORITY_SCHEMA,
255
+ status: "unavailable",
256
+ metrics: null,
257
+ evidence: Object.freeze({
258
+ schema: SKILL_OUTCOME_INDEX_AUTHORITY_SCHEMA,
259
+ status: "unavailable",
260
+ code:
261
+ typeof error?.code === "string" &&
262
+ error.code.startsWith("CC_SKILL_OUTCOME_INDEX_")
263
+ ? error.code
264
+ : "CC_SKILL_OUTCOME_INDEX_AUTHORITY_UNAVAILABLE",
265
+ antiRollbackWitness: false,
266
+ }),
267
+ });
268
+ }