chainlesschain 0.166.46 → 0.166.48

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 (232) hide show
  1. package/README.md +6 -4
  2. package/package.json +4 -2
  3. package/src/assets/web-panel/assets/{AIOps-Cp8KiMmv.js → AIOps-BLGEffkh.js} +1 -1
  4. package/src/assets/web-panel/assets/{ActionButton-B4d9BGsm.js → ActionButton-Cz1z2VGD.js} +1 -1
  5. package/src/assets/web-panel/assets/{Analytics-Cf9yXTkv.js → Analytics-C3j9cf6q.js} +3 -3
  6. package/src/assets/web-panel/assets/{AppLayout-40UkmxtP.js → AppLayout-BR9ERuCA.js} +4 -4
  7. package/src/assets/web-panel/assets/{Artifacts-Ckkb4oOA.js → Artifacts-CozJCm4y.js} +1 -1
  8. package/src/assets/web-panel/assets/{Audit-Dnf569k5.js → Audit-DC5g9Ra2.js} +1 -1
  9. package/src/assets/web-panel/assets/{BackgroundAgents-CA6bLem4.js → BackgroundAgents-B1zrQ0dW.js} +1 -1
  10. package/src/assets/web-panel/assets/{Backup-ChQU0I_Q.js → Backup-ChVnfjpm.js} +1 -1
  11. package/src/assets/web-panel/assets/{BaseInput-BHeZXnNN.js → BaseInput-8_vLQsLf.js} +1 -1
  12. package/src/assets/web-panel/assets/{Chat-DcFVYB2E.js → Chat-Dct9bm6L.js} +5 -5
  13. package/src/assets/web-panel/assets/ChatBubbleRenderer-BvoSsCKh.js +1 -0
  14. package/src/assets/web-panel/assets/{Checkbox-2PDbejv2.js → Checkbox-DZQIsCIC.js} +1 -1
  15. package/src/assets/web-panel/assets/{Codegen-DJBn1RAu.js → Codegen-CdzHxmnq.js} +1 -1
  16. package/src/assets/web-panel/assets/{Col-CPRq7n6y.js → Col-DdAN8LeW.js} +1 -1
  17. package/src/assets/web-panel/assets/{Community-axvINFMi.js → Community-CNgjT9MA.js} +1 -1
  18. package/src/assets/web-panel/assets/{Compact-_OX4Qbe0.js → Compact-BtQiX6G-.js} +1 -1
  19. package/src/assets/web-panel/assets/{Compliance-DWAkvzRL.js → Compliance-OGX5ma3j.js} +1 -1
  20. package/src/assets/web-panel/assets/{Cowork-CUIJ25oj.js → Cowork-CgugQnGM.js} +3 -3
  21. package/src/assets/web-panel/assets/{Cron-nR0m7H3_.js → Cron-Bpg7cPFD.js} +2 -2
  22. package/src/assets/web-panel/assets/{Crosschain-CgTLXzh_.js → Crosschain-D1hsuswf.js} +1 -1
  23. package/src/assets/web-panel/assets/{DID-BllzRB6Q.js → DID-miDRsMBw.js} +2 -2
  24. package/src/assets/web-panel/assets/{Dashboard-C9f0IIBN.js → Dashboard-CGcl8htP.js} +2 -2
  25. package/src/assets/web-panel/assets/{Dropdown-BkahetiO.js → Dropdown-BFaxTdVE.js} +1 -1
  26. package/src/assets/web-panel/assets/{EmailListRenderer-rartVC-k.js → EmailListRenderer-BQdGLZIO.js} +1 -1
  27. package/src/assets/web-panel/assets/{EvolutionSettings-BqpG3XHV.js → EvolutionSettings-bMvgBk6r.js} +1 -1
  28. package/src/assets/web-panel/assets/{FamilyGuardDashboard-DgUdFvw1.js → FamilyGuardDashboard-c1WVC_--.js} +1 -1
  29. package/src/assets/web-panel/assets/{Federation-oFpIQU6g.js → Federation-DyAcFrQY.js} +1 -1
  30. package/src/assets/web-panel/assets/{FormItemContext-BUH5xlyP.js → FormItemContext-CfwpfD2B.js} +1 -1
  31. package/src/assets/web-panel/assets/{GenericCardRenderer-ilRa-ueg.js → GenericCardRenderer-DkJcbBpS.js} +1 -1
  32. package/src/assets/web-panel/assets/{Git-DlHHSF8j.js → Git-DgYIrPJh.js} +2 -2
  33. package/src/assets/web-panel/assets/{Governance-yQiiXIWe.js → Governance-BF1tYPJ6.js} +1 -1
  34. package/src/assets/web-panel/assets/{Inference-BUDRVGOP.js → Inference-BFkwRIrU.js} +1 -1
  35. package/src/assets/web-panel/assets/{KnowledgeGraph-BaGyIoN1.js → KnowledgeGraph-DpCoqhBa.js} +1 -1
  36. package/src/assets/web-panel/assets/{Logs-C1cO6zE0.js → Logs-DU2qAJmD.js} +2 -2
  37. package/src/assets/web-panel/assets/{MarkdownRenderer-_z_Iaoes.js → MarkdownRenderer-QWv7UJLq.js} +1 -1
  38. package/src/assets/web-panel/assets/{Marketplace-CM8cGL0K.js → Marketplace-Dz9NUrfo.js} +1 -1
  39. package/src/assets/web-panel/assets/{McpTools-CDqAMU0U.js → McpTools-B67I3d5v.js} +3 -3
  40. package/src/assets/web-panel/assets/{Memory-CfB0-Ofv.js → Memory-crkElJSy.js} +2 -2
  41. package/src/assets/web-panel/assets/{MobileBridge-BL18ytvB.js → MobileBridge-BO20VbdX.js} +1 -1
  42. package/src/assets/web-panel/assets/{MobileProjects-PIyyxbuJ.js → MobileProjects-Ba-3gZZd.js} +1 -1
  43. package/src/assets/web-panel/assets/{Mtc-BTTrFCol.js → Mtc-BAHZM084.js} +4 -4
  44. package/src/assets/web-panel/assets/{MtcAudit-JHZn037c.js → MtcAudit-CL3DzajL.js} +4 -4
  45. package/src/assets/web-panel/assets/{Multisig-CMf9NEdB.js → Multisig-BSWWzvWH.js} +3 -3
  46. package/src/assets/web-panel/assets/{NLProgramming-Dhk3qaus.js → NLProgramming-fnxqXM_3.js} +1 -1
  47. package/src/assets/web-panel/assets/{Notes-6F8EarNN.js → Notes-qUZPIQXT.js} +3 -3
  48. package/src/assets/web-panel/assets/{NotificationSettings-gxdaVEit.js → NotificationSettings-x9Xrixqu.js} +1 -1
  49. package/src/assets/web-panel/assets/{OrderTableRenderer-gVgXQWdc.js → OrderTableRenderer-BtMtQUt7.js} +1 -1
  50. package/src/assets/web-panel/assets/{Organization-CzvHcDNO.js → Organization-C946Hzna.js} +4 -4
  51. package/src/assets/web-panel/assets/{Overflow-Dclx30Vv.js → Overflow-BYf8KIts.js} +1 -1
  52. package/src/assets/web-panel/assets/{P2P-CM0Wm9vZ.js → P2P-Cbqf5dnv.js} +2 -2
  53. package/src/assets/web-panel/assets/PdhVaultBrowser-rmxp0cuF.js +7 -0
  54. package/src/assets/web-panel/assets/{Permissions-B_oATenG.js → Permissions-CZBw45EW.js} +3 -3
  55. package/src/assets/web-panel/assets/{PersonalDataHub-CptiVBh5.js → PersonalDataHub-BKwUAt43.js} +4 -4
  56. package/src/assets/web-panel/assets/{Pipeline-DkHzgyyI.js → Pipeline-DmFD2QW4.js} +1 -1
  57. package/src/assets/web-panel/assets/{Privacy-DzZvwcKh.js → Privacy-KpuwWvt5.js} +1 -1
  58. package/src/assets/web-panel/assets/{ProjectInit-CzkCs-5G.js → ProjectInit-Bt8UheX6.js} +2 -2
  59. package/src/assets/web-panel/assets/{ProjectSettings-BB8dcxRD.js → ProjectSettings-2ZeAn9CP.js} +2 -2
  60. package/src/assets/web-panel/assets/{Projects-B7PW9CFY.js → Projects-zBuet8Zs.js} +1 -1
  61. package/src/assets/web-panel/assets/{Providers-Tfx-ti1V.js → Providers-DcEAnw6L.js} +1 -1
  62. package/src/assets/web-panel/assets/{QrScannerModal-EvWlNhfX.js → QrScannerModal-qF7liYG9.js} +1 -1
  63. package/src/assets/web-panel/assets/{QuickAsk-CUspgbNC.js → QuickAsk-qiESlVBJ.js} +1 -1
  64. package/src/assets/web-panel/assets/{Recommend-COY2g77J.js → Recommend-Bk-cQyi9.js} +1 -1
  65. package/src/assets/web-panel/assets/{RemoteSession-BzMBU6E6.js → RemoteSession-CwrekErS.js} +2 -2
  66. package/src/assets/web-panel/assets/{Reputation-RtYRF4YP.js → Reputation-Bmw_UQtW.js} +1 -1
  67. package/src/assets/web-panel/assets/{Row-Bva3l9Lc.js → Row-CPdqZIUX.js} +1 -1
  68. package/src/assets/web-panel/assets/{RssFeed-BhjzLvW3.js → RssFeed-D_W-xxvS.js} +2 -2
  69. package/src/assets/web-panel/assets/{Search-BYzT2PTR.js → Search-Hu0oDFj_.js} +1 -1
  70. package/src/assets/web-panel/assets/{Security-Bcl4-KTv.js → Security-DeRxUwmq.js} +3 -3
  71. package/src/assets/web-panel/assets/{Services-BRRa4A0f.js → Services-CsNmHFkf.js} +2 -2
  72. package/src/assets/web-panel/assets/{Skeleton-DYQ016qy.js → Skeleton-gv_Vz0tN.js} +1 -1
  73. package/src/assets/web-panel/assets/{Skills-CAUKL9JA.js → Skills-Dgg-_rCB.js} +1 -1
  74. package/src/assets/web-panel/assets/{Sla-BTyUqfuD.js → Sla-Bpu-bsEJ.js} +1 -1
  75. package/src/assets/web-panel/assets/{SpeechSettings-CUjMihrs.js → SpeechSettings-CrhleHuF.js} +1 -1
  76. package/src/assets/web-panel/assets/{SyncSettings-CvfOSupr.js → SyncSettings-JHjUN6I9.js} +2 -2
  77. package/src/assets/web-panel/assets/{Tasks-EvjNXrWH.js → Tasks-DKRWKkl9.js} +1 -1
  78. package/src/assets/web-panel/assets/{Templates-wPAp0EoM.js → Templates-leiWntLq.js} +1 -1
  79. package/src/assets/web-panel/assets/{Tenant-CP0D-q9Q.js → Tenant--1bYulvn.js} +1 -1
  80. package/src/assets/web-panel/assets/{Terminal-CQ0f2iFg.js → Terminal-C0y6FvSS.js} +2 -2
  81. package/src/assets/web-panel/assets/{TimelineRenderer-D3JrGSPb.js → TimelineRenderer-CQK4PVv4.js} +1 -1
  82. package/src/assets/web-panel/assets/{Tokens-yXf2PPp9.js → Tokens-DbIvF-DV.js} +1 -1
  83. package/src/assets/web-panel/assets/{Trigger-DfmMOoZ2.js → Trigger-CkXJ2vuq.js} +1 -1
  84. package/src/assets/web-panel/assets/{Trust-BTCyMgf1.js → Trust-B02WXJPw.js} +1 -1
  85. package/src/assets/web-panel/assets/{UkeySign-DKCwIBHi.js → UkeySign-VPMkfzmw.js} +1 -1
  86. package/src/assets/web-panel/assets/{VideoEditing-CQpDSzLO.js → VideoEditing-C5ezUnah.js} +1 -1
  87. package/src/assets/web-panel/assets/{Wallet-CyFrzC3K.js → Wallet-CYfvYRrY.js} +4 -4
  88. package/src/assets/web-panel/assets/{WebAuthn-D6Nr_1kd.js → WebAuthn-DtKl-kpr.js} +4 -4
  89. package/src/assets/web-panel/assets/{WorkflowEditor-CgR9tNrB.js → WorkflowEditor-DACITF-u.js} +1 -1
  90. package/src/assets/web-panel/assets/{chat-CRG_IeyP.js → chat-qnygfnLi.js} +1 -1
  91. package/src/assets/web-panel/assets/{colors-MdE3TStI.js → colors-D4mISLBD.js} +1 -1
  92. package/src/assets/web-panel/assets/{compact-item-B0LRuiNV.js → compact-item-BBPfxYGL.js} +1 -1
  93. package/src/assets/web-panel/assets/{createContext-B_V5fjcX.js → createContext-Byx4ndHp.js} +1 -1
  94. package/src/assets/web-panel/assets/devWarning-DBy6gsuI.js +1 -0
  95. package/src/assets/web-panel/assets/{hasIn-DSL-c_hr.js → hasIn-CGjLkkn3.js} +1 -1
  96. package/src/assets/web-panel/assets/{index-DE7bSYmW.js → index-B8UpadHC.js} +1 -1
  97. package/src/assets/web-panel/assets/{index-BD0w-888.js → index-B9jH-h4X.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-BbZZ7P_c.js → index-BN7_TSgU.js} +1 -1
  99. package/src/assets/web-panel/assets/{index-BIDCNwy6.js → index-BNe2lCk6.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-CkN53KiJ.js → index-B_fHPZ8E.js} +1 -1
  101. package/src/assets/web-panel/assets/index-BfEDXk_E.js +1 -0
  102. package/src/assets/web-panel/assets/{index-BsAEd-Do.js → index-BklGH3YI.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-CS3bOhV7.js → index-BmKYaaGP.js} +1 -1
  104. package/src/assets/web-panel/assets/{index-B3iW-mhn.js → index-BxQF1wCU.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-SmQfEHjp.js → index-ByA1NyFP.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-0200QxC4.js → index-BzeBBAl5.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-c8OqO3rq.js → index-C3abGsSW.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-C-aKWR2v.js → index-C9tcHs46.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-BNhWoD6d.js → index-CD5Btq6p.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-CVDi4rS9.js → index-CFMWjuav.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-CEOAZm5j.js → index-CMj8qmpX.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-C67dPW0L.js → index-CVUJjQAT.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-D3pJBTvo.js → index-CWhI8G14.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-DtOTppk8.js → index-CZjNamSU.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-DRRY44XP.js → index-CmHE-lY_.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-Tg3yl8wc.js → index-CoA8WsVr.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-CXMeisJK.js → index-Cpg3AWRy.js} +1 -1
  118. package/src/assets/web-panel/assets/index-CrxUwNM8.js +1 -0
  119. package/src/assets/web-panel/assets/{index-Bq8-2Ibv.js → index-CsVuQsY1.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-BHp1nSur.js → index-CydHMjwc.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-CPYshcic.js → index-DH6iC5b2.js} +1 -1
  122. package/src/assets/web-panel/assets/{index-DBwBZwio.js → index-DZXhKAk9.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-Didyuq2Z.js → index-D_g9mA1N.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-CdHMc9LQ.js → index-DboTeuPF.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-C5dqieYX.js → index-DfgpKd64.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-CdplnAS9.js → index-Dmfe0L2Z.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-KaSejHjf.js → index-Dzni_5Qw.js} +1 -1
  128. package/src/assets/web-panel/assets/{index-BpwGsAA-.js → index-J5JkStvY.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-OBhlHSMN.js → index-Ne8UGllV.js} +3 -3
  130. package/src/assets/web-panel/assets/{index-CZICtYJ0.js → index-O09jXbir.js} +1 -1
  131. package/src/assets/web-panel/assets/{index-DVgTf7CZ.js → index-Y7el_3WS.js} +1 -1
  132. package/src/assets/web-panel/assets/{index-BQAsL19t.js → index-c_tBkIlU.js} +1 -1
  133. package/src/assets/web-panel/assets/{index-BMm8tO2X.js → index-lKJWAmd4.js} +1 -1
  134. package/src/assets/web-panel/assets/{index-CNytQuFq.js → index-xzRKTy0R.js} +1 -1
  135. package/src/assets/web-panel/assets/{initDefaultProps-P8SBN6Di.js → initDefaultProps-XuhfEIhB.js} +1 -1
  136. package/src/assets/web-panel/assets/{motion-BubbjUT_.js → motion-Cbxh6AxO.js} +1 -1
  137. package/src/assets/web-panel/assets/{move-Chcykv0I.js → move-C7IEnFly.js} +1 -1
  138. package/src/assets/web-panel/assets/{mtc-parser-DyiYuGDu.js → mtc-parser-lLADx4LL.js} +1 -1
  139. package/src/assets/web-panel/assets/{omit-Rdwb_Neb.js → omit-mIbic_k-.js} +1 -1
  140. package/src/assets/web-panel/assets/{pickAttrs-CCr0MYHl.js → pickAttrs-_xIYEqu3.js} +1 -1
  141. package/src/assets/web-panel/assets/{placementArrow-B1ZXz3bb.js → placementArrow-ClB-E0ny.js} +1 -1
  142. package/src/assets/web-panel/assets/{responsiveObserve-BGEdwej6.js → responsiveObserve-D36Bg2ut.js} +1 -1
  143. package/src/assets/web-panel/assets/{slide-CpnsUMaT.js → slide-CUuO08Bl.js} +1 -1
  144. package/src/assets/web-panel/assets/{statusUtils-C7x-TVp_.js → statusUtils-BKahwLbv.js} +1 -1
  145. package/src/assets/web-panel/assets/{styleChecker-CC5k_791.js → styleChecker-2pT-T8vy.js} +1 -1
  146. package/src/assets/web-panel/assets/{useFlexGapSupport-BpZFKsJW.js → useFlexGapSupport-DyH5g7Rg.js} +1 -1
  147. package/src/assets/web-panel/assets/{useFs-CVq5HySy.js → useFs-CTOauB3X.js} +1 -1
  148. package/src/assets/web-panel/assets/{usePersonalDataHub-BGkdLryu.js → usePersonalDataHub-B02JYIMe.js} +1 -1
  149. package/src/assets/web-panel/assets/{vnode-uLtOUEK-.js → vnode-Do22wQrc.js} +1 -1
  150. package/src/assets/web-panel/assets/{zoom-BfVC9iUs.js → zoom-BfnL7rit.js} +1 -1
  151. package/src/assets/web-panel/index.html +1 -1
  152. package/src/command-help-index.json +3 -3
  153. package/src/commands/agent.js +8 -0
  154. package/src/commands/background-session.js +31 -3
  155. package/src/commands/chat.js +5 -1
  156. package/src/commands/eval.js +86 -28
  157. package/src/commands/llm.js +104 -1
  158. package/src/commands/plugin.js +161 -1
  159. package/src/commands/sandbox.js +121 -2
  160. package/src/commands/serve.js +11 -2
  161. package/src/commands/skill.js +29 -0
  162. package/src/data/changelog.json +26 -0
  163. package/src/gateways/ws/session-protocol.js +13 -0
  164. package/src/gateways/ws/ws-agent-handler.js +17 -0
  165. package/src/gateways/ws/ws-server.js +3 -0
  166. package/src/gateways/ws/ws-session-state.js +131 -0
  167. package/src/generated/cc-agent-protocol.schema.json +48 -1
  168. package/src/lazy-dispatch.js +8 -1
  169. package/src/lib/agent-sandbox.js +337 -53
  170. package/src/lib/app-server/cli-agent-kernel-adapter.js +28 -0
  171. package/src/lib/app-server/server.js +93 -0
  172. package/src/lib/background-agent-keeper-client.js +2 -0
  173. package/src/lib/background-agent-keeper-protocol.js +7 -0
  174. package/src/lib/background-agent-list-index.js +222 -0
  175. package/src/lib/background-agent-supervisor.js +232 -47
  176. package/src/lib/codex-app-server-adapter.js +82 -27
  177. package/src/lib/context-memory-kernel/durable-memory-port.js +31 -8
  178. package/src/lib/context-memory-kernel/provider-context.js +118 -19
  179. package/src/lib/deferred-question-context.js +278 -0
  180. package/src/lib/eval/evidence.js +202 -64
  181. package/src/lib/eval/plugin-suite.js +1181 -0
  182. package/src/lib/eval/runner.js +10 -3
  183. package/src/lib/evolution/agent-evolution-runtime-composition.js +236 -1
  184. package/src/lib/evolution/agent-model-projection.js +97 -1
  185. package/src/lib/evolution/evidence-backed-wiki-maintainer.js +154 -1
  186. package/src/lib/evolution/evolution-artifact-ports.js +6 -0
  187. package/src/lib/evolution/evolution-deployment-loader.js +87 -3
  188. package/src/lib/evolution/evolution-eval-gate.js +8 -0
  189. package/src/lib/evolution/evolution-eval-runtime-composition.js +255 -0
  190. package/src/lib/evolution/evolution-evidence-artifact-adapter.js +58 -2
  191. package/src/lib/evolution/evolution-ledger-file-backend.js +23 -2
  192. package/src/lib/evolution/evolution-ledger-manifest-chain.js +223 -7
  193. package/src/lib/evolution/evolution-ledger-v2-journal.js +525 -0
  194. package/src/lib/evolution/evolution-ledger-v2-manifest-backend.js +46 -2
  195. package/src/lib/evolution/evolution-ledger.js +57 -1
  196. package/src/lib/evolution/evolution-run-ledger-adapter.js +93 -0
  197. package/src/lib/evolution/evolution-run-wiki-evidence-resolver.js +259 -0
  198. package/src/lib/evolution/governed-hub-llm.js +238 -5
  199. package/src/lib/evolution/governed-hub-resolver.js +82 -4
  200. package/src/lib/evolution/governed-hub-skill.js +11 -5
  201. package/src/lib/evolution/governed-skill-synthesis-provider-chat.js +10 -1
  202. package/src/lib/evolution/skill-runtime-revalidation-ledger-adapter.js +254 -0
  203. package/src/lib/evolution/skill-runtime-revalidation.js +530 -0
  204. package/src/lib/evolution/skill-target-matrix-eval.js +4 -4
  205. package/src/lib/evolution/wiki-evidence-commit-guard.js +366 -0
  206. package/src/lib/evolution/wiki-informed-skill-proposer.js +13 -1
  207. package/src/lib/goal-context.js +14 -5
  208. package/src/lib/interaction-adapter.js +166 -1
  209. package/src/lib/model-capabilities.js +271 -0
  210. package/src/lib/model-context-catalog.js +105 -0
  211. package/src/lib/model-context-window.js +4 -49
  212. package/src/lib/openai-responses.js +428 -0
  213. package/src/lib/plugin-runtime/scopes.js +7 -1
  214. package/src/lib/remote-read-loop-guard.js +2 -2
  215. package/src/lib/runtime-usage-ledger.js +16 -0
  216. package/src/lib/session-host-snapshot.js +16 -0
  217. package/src/lib/skill-loader.js +12 -0
  218. package/src/lib/with-file-lock.js +3 -1
  219. package/src/repl/agent-repl.js +5 -1
  220. package/src/runtime/agent-core.js +348 -23
  221. package/src/runtime/agent-runtime.js +7 -0
  222. package/src/runtime/coding-agent-contract-shared.cjs +13 -1
  223. package/src/runtime/headless-runner.js +4 -1
  224. package/src/runtime/headless-stream.js +283 -45
  225. package/src/runtime/runtime-factory.js +26 -2
  226. package/src/workers/background-agent-keeper.js +23 -13
  227. package/src/workers/background-agent-worker.js +27 -13
  228. package/src/assets/web-panel/assets/ChatBubbleRenderer-Bi2SY9E_.js +0 -1
  229. package/src/assets/web-panel/assets/PdhVaultBrowser-fYmQzmTA.js +0 -7
  230. package/src/assets/web-panel/assets/devWarning-BtFLt3qI.js +0 -1
  231. package/src/assets/web-panel/assets/index-BhuWQHeG.js +0 -1
  232. package/src/assets/web-panel/assets/index-D-4tFek3.js +0 -1
@@ -8,8 +8,9 @@
8
8
  * runEvalSuite gives each task a fresh temp workspace, runs `setup` to lay down
9
9
  * the starting files, hands `prompt` to the agent (via an injected `runAgent` so
10
10
  * the harness is testable without a live LLM), then runs `check` to decide
11
- * pass/fail deterministically. The score is the fraction of tasks whose check
12
- * passed — a verifiable success-rate metric, per the plan's north star.
11
+ * artifacts deterministically. Task success requires both a passing artifact
12
+ * check and an explicitly successful execution; failed runs can retain useful
13
+ * artifact-check results without inflating the reliability score.
13
14
  *
14
15
  * The real `cc eval` command wires `runAgent` to a headless `cc agent -p` run;
15
16
  * unit tests inject a fake runAgent to exercise scoring/report logic offline.
@@ -146,9 +147,15 @@ export async function runEvalSuite(tasks, opts = {}) {
146
147
  // and still run check() (the workspace may be partially done).
147
148
  rec.error = `agent error: ${agentErr.message}`;
148
149
  }
149
- rec.executionSucceeded = agentResult?.ok === true && !rec.error;
150
+ rec.executionSucceeded =
151
+ agentResult?.ok === true &&
152
+ !rec.error &&
153
+ (agentResult.error == null || agentResult.error === "");
150
154
  rec.agentOk = rec.executionSucceeded;
151
155
  rec.executionEvidence = agentResult?.executionEvidence || null;
156
+ if (agentResult?.evaluationMetrics !== undefined) {
157
+ rec.evaluationMetrics = agentResult.evaluationMetrics;
158
+ }
152
159
  if (!rec.executionSucceeded && !rec.error) {
153
160
  rec.error = `agent error: ${agentResult?.error || "execution did not report success"}`;
154
161
  }
@@ -11,6 +11,7 @@ import {
11
11
  import {
12
12
  EvolutionEvidenceBundleVerifier,
13
13
  EvolutionEvidenceProjector,
14
+ EvolutionEvidenceReader,
14
15
  } from "./evolution-evidence-projector.js";
15
16
  import { EvolutionArtifactPorts } from "./evolution-artifact-ports.js";
16
17
  import {
@@ -18,12 +19,17 @@ import {
18
19
  createEvolutionLedgerFileBackend,
19
20
  } from "./evolution-ledger-file-backend.js";
20
21
  import { EvolutionRunLedgerAdapter } from "./evolution-run-ledger-adapter.js";
22
+ import { createEvolutionRunWikiEvidenceResolver } from "./evolution-run-wiki-evidence-resolver.js";
23
+ import { WikiMaintainerLedgerAdapter } from "./wiki-maintainer-ledger-adapter.js";
24
+ import { EvidenceBackedWikiMaintainer } from "./evidence-backed-wiki-maintainer.js";
25
+ import { createWikiEvidenceCommitGuard } from "./wiki-evidence-commit-guard.js";
21
26
  import { EvolutionWorkbenchMetricsLedgerAdapter } from "./evolution-workbench-metrics-ledger-adapter.js";
22
27
  import { EvolutionReleaseTrainLedgerAdapter } from "./evolution-release-train-ledger-adapter.js";
23
28
  import { WikiSkillProposalLedgerAdapter } from "./wiki-skill-proposal-ledger-adapter.js";
24
29
  import { EvolutionReleaseTrainStageOutputLedgerAdapter } from "./evolution-release-train-stage-output-ledger-adapter.js";
25
30
  import { createEvolutionReleaseTrainDomainStages } from "./evolution-release-train-domain-stages.js";
26
31
  import { createEvolutionReleaseTrain } from "./evolution-release-train.js";
32
+ import { createEvolutionEvalRuntimeStageConfiguration } from "./evolution-eval-runtime-composition.js";
27
33
  import { captureSkillOutcomeSourceCatalogAuthority } from "./skill-outcome-source-catalog-authority.js";
28
34
  import {
29
35
  captureAgentEvolutionIngress,
@@ -62,6 +68,36 @@ const SKILL_OUTCOME_CATALOG_ENTRY_KEYS = new Set(["runId", "skillNames"]);
62
68
  const MAX_SKILL_OUTCOME_SOURCES = 128;
63
69
  const RELEASE_TRAIN_STAGE_KEYS = new Set(["plan", "stages"]);
64
70
  const RELEASE_TRAIN_DOMAIN_KEYS = new Set(["plan", "domain"]);
71
+ const WIKI_MAINTENANCE_KEYS = new Set([
72
+ "principalEnvelope",
73
+ "schemaPolicies",
74
+ "readAuthorities",
75
+ "commitCoordinator",
76
+ "maintainer",
77
+ ]);
78
+ const WIKI_READ_AUTHORITY_KEYS = new Set([
79
+ "evidenceState",
80
+ "principalResolver",
81
+ "accessPolicy",
82
+ ]);
83
+ const WIKI_COMMIT_COORDINATOR_KEYS = new Set(["acquireCurrentEvidence"]);
84
+ const WIKI_MAINTAINER_KEYS = new Set([
85
+ "maintainerModel",
86
+ "rulesDigest",
87
+ "minCorroboratingSources",
88
+ "derive",
89
+ ]);
90
+ const WIKI_STAGE_KEYS = new Set(["request", "usage"]);
91
+ const DOMAIN_STAGE_KEYS = new Set([
92
+ "wiki-maintain",
93
+ "propose",
94
+ "candidate",
95
+ "eval",
96
+ "review",
97
+ "pilot",
98
+ "promotion",
99
+ "wiki-impact",
100
+ ]);
65
101
 
66
102
  function exactRecord(value, keys, label) {
67
103
  if (
@@ -191,6 +227,7 @@ export function createAgentEvolutionRuntimeComposition({
191
227
  evidenceIdGenerator,
192
228
  ingressIdGenerator,
193
229
  wikiMaintenanceProducer = null,
230
+ wikiMaintenance: wikiMaintenanceInput = null,
194
231
  releaseTrain: releaseTrainInput = null,
195
232
  completionTriggerKind,
196
233
  secure = true,
@@ -199,7 +236,18 @@ export function createAgentEvolutionRuntimeComposition({
199
236
  random,
200
237
  lockTimeoutMs,
201
238
  witnessMaximumBytes,
239
+ ledgerV2: ledgerV2Input = null,
202
240
  } = {}) {
241
+ const ledgerV2 =
242
+ ledgerV2Input === null
243
+ ? null
244
+ : Object.freeze({
245
+ ...exactRecord(
246
+ ledgerV2Input,
247
+ new Set(["createBackend", "minimumRetainedUntil"]),
248
+ "ledger v2 production composition",
249
+ ),
250
+ });
203
251
  const tenantId = identifier(tenantIdInput, "tenantId");
204
252
  const runId = identifier(runIdInput, "runId");
205
253
  const audience = identifier(audienceInput, "audience");
@@ -218,6 +266,79 @@ export function createAgentEvolutionRuntimeComposition({
218
266
  "authorities.artifact",
219
267
  );
220
268
  const clock = normalizeClock(clockInput);
269
+ let wikiConfiguration = null;
270
+ if (wikiMaintenanceInput !== null) {
271
+ const input = exactRecord(
272
+ wikiMaintenanceInput,
273
+ WIKI_MAINTENANCE_KEYS,
274
+ "wikiMaintenance",
275
+ );
276
+ const readers = exactRecord(
277
+ input.readAuthorities,
278
+ WIKI_READ_AUTHORITY_KEYS,
279
+ "wikiMaintenance.readAuthorities",
280
+ );
281
+ const maintainer = exactRecord(
282
+ input.maintainer,
283
+ WIKI_MAINTAINER_KEYS,
284
+ "wikiMaintenance.maintainer",
285
+ );
286
+ const coordinator = exactRecord(
287
+ input.commitCoordinator,
288
+ WIKI_COMMIT_COORDINATOR_KEYS,
289
+ "wikiMaintenance.commitCoordinator",
290
+ );
291
+ if (
292
+ utilTypes.isAsyncFunction(coordinator.acquireCurrentEvidence) ||
293
+ utilTypes.isGeneratorFunction(coordinator.acquireCurrentEvidence)
294
+ ) {
295
+ throw new TypeError("Wiki commit coordinator must be synchronous");
296
+ }
297
+ const commitCoordinator = Object.freeze({
298
+ acquireCurrentEvidence: capture(
299
+ coordinator,
300
+ "acquireCurrentEvidence",
301
+ "Wiki commit coordinator",
302
+ ),
303
+ });
304
+ if (
305
+ !Number.isSafeInteger(maintainer.minCorroboratingSources) ||
306
+ maintainer.minCorroboratingSources < 2 ||
307
+ maintainer.minCorroboratingSources > 128
308
+ ) {
309
+ throw new TypeError(
310
+ "Wiki corroboration threshold must be between 2 and 128",
311
+ );
312
+ }
313
+ wikiConfiguration = Object.freeze({
314
+ principalEnvelope: input.principalEnvelope,
315
+ schemaPolicies: input.schemaPolicies,
316
+ commitCoordinator,
317
+ descriptor: Object.freeze({
318
+ tenantId,
319
+ evolutionRunId: runId,
320
+ maintainerModel: maintainer.maintainerModel,
321
+ rulesDigest: maintainer.rulesDigest,
322
+ minCorroboratingSources: maintainer.minCorroboratingSources,
323
+ }),
324
+ derive: capture(maintainer, "derive", "Wiki maintainer"),
325
+ evidenceState: captureAuthority(
326
+ readers.evidenceState,
327
+ "resolve",
328
+ "Wiki evidence state",
329
+ ),
330
+ principalResolver: captureAuthority(
331
+ readers.principalResolver,
332
+ "resolve",
333
+ "Wiki principal resolver",
334
+ ),
335
+ accessPolicy: captureAuthority(
336
+ readers.accessPolicy,
337
+ "authorize",
338
+ "Wiki access policy",
339
+ ),
340
+ });
341
+ }
221
342
  if (
222
343
  typeof evidenceIdGenerator !== "function" ||
223
344
  utilTypes.isProxy(evidenceIdGenerator)
@@ -342,6 +463,15 @@ export function createAgentEvolutionRuntimeComposition({
342
463
  ledgerAuthority: authorities.ledger,
343
464
  witnessAuthority: authorities.witness,
344
465
  artifactResolver: ledgerArtifactResolver,
466
+ ...(ledgerV2 === null
467
+ ? {}
468
+ : {
469
+ manifestV2: {
470
+ ...ledgerV2,
471
+ artifactPorts,
472
+ descriptor: { tenantId, artifactTenantId: tenantId, audience },
473
+ },
474
+ }),
345
475
  secure,
346
476
  clock,
347
477
  ...(fsImpl === undefined ? {} : { fsImpl }),
@@ -384,6 +514,66 @@ export function createAgentEvolutionRuntimeComposition({
384
514
  ledgerArtifactResolver,
385
515
  now: clock,
386
516
  });
517
+ let wikiMaintenance = null;
518
+ let wikiMaintainer = null;
519
+ if (wikiConfiguration !== null) {
520
+ const evidenceReader = new EvolutionEvidenceReader({
521
+ attestationVerifier: ports.attestationVerifier,
522
+ evidenceState: wikiConfiguration.evidenceState,
523
+ principalResolver: wikiConfiguration.principalResolver,
524
+ accessPolicy: wikiConfiguration.accessPolicy,
525
+ now: () => new Date(clock()),
526
+ });
527
+ const wikiEvidence = createEvolutionRunWikiEvidenceResolver({
528
+ runAdapter,
529
+ evidenceAdapter,
530
+ evidenceReader,
531
+ principalEnvelope: wikiConfiguration.principalEnvelope,
532
+ schemaPolicies: wikiConfiguration.schemaPolicies,
533
+ });
534
+ const wikiAdapter = new WikiMaintainerLedgerAdapter({
535
+ descriptor: {
536
+ tenantId,
537
+ artifactTenantId: tenantId,
538
+ evolutionRunId: runId,
539
+ audience,
540
+ purpose: "evolution-ledger",
541
+ },
542
+ artifactPorts,
543
+ ledger: backend.ledger,
544
+ ledgerArtifactResolver,
545
+ });
546
+ const wikiCommit = createWikiEvidenceCommitGuard({
547
+ wikiAdapter,
548
+ commitCoordinator: wikiConfiguration.commitCoordinator,
549
+ principalEnvelope: wikiConfiguration.principalEnvelope,
550
+ clock,
551
+ });
552
+ wikiMaintainer = new EvidenceBackedWikiMaintainer({
553
+ descriptor: wikiConfiguration.descriptor,
554
+ policy: {
555
+ trustedProjectionRead: true,
556
+ rawEvidenceRead: false,
557
+ activeSkillWrite: false,
558
+ shell: false,
559
+ network: false,
560
+ secretRead: false,
561
+ },
562
+ ports: {
563
+ ...wikiAdapter.maintainerPorts({
564
+ resolveEvidence: wikiEvidence.resolveEvidence,
565
+ derive: wikiConfiguration.derive,
566
+ }),
567
+ commitRevision: wikiCommit.commitRevision,
568
+ },
569
+ });
570
+ // The host receives only scoped maintenance and authenticated Wiki reads,
571
+ // never a Raw store, caller-supplied bundle, or write/approval capability.
572
+ wikiMaintenance = Object.freeze({
573
+ maintain: Object.freeze(wikiMaintainer.maintain.bind(wikiMaintainer)),
574
+ loadWiki: Object.freeze(() => wikiAdapter.loadWiki()),
575
+ });
576
+ }
387
577
  const skillOutcomeReaders = new Map();
388
578
  const createSkillOutcomeReader = Object.freeze((skillNameInput) => {
389
579
  const skillName = identifier(skillNameInput, "skillName");
@@ -415,6 +605,14 @@ export function createAgentEvolutionRuntimeComposition({
415
605
  releaseTrainKeys,
416
606
  "releaseTrain",
417
607
  );
608
+ if (
609
+ wikiMaintainer !== null &&
610
+ !Object.hasOwn(releaseTrainConfig, "domain")
611
+ ) {
612
+ throw new TypeError(
613
+ "authorized Wiki maintenance requires production release train domain stages",
614
+ );
615
+ }
418
616
  if (
419
617
  releaseTrainConfig.plan?.tenantId !== tenantId ||
420
618
  typeof releaseTrainConfig.plan?.skillId !== "string"
@@ -463,8 +661,35 @@ export function createAgentEvolutionRuntimeComposition({
463
661
  ledger: backend.ledger,
464
662
  ledgerArtifactResolver,
465
663
  });
664
+ let domain = releaseTrainConfig.domain;
665
+ exactRecord(domain, DOMAIN_STAGE_KEYS, "releaseTrain.domain");
666
+ domain = {
667
+ ...domain,
668
+ eval: createEvolutionEvalRuntimeStageConfiguration({
669
+ configuration: domain.eval,
670
+ tenantId,
671
+ runId,
672
+ artifactPorts,
673
+ ledger: backend.ledger,
674
+ ledgerArtifactResolver,
675
+ audience,
676
+ now: clock,
677
+ }),
678
+ };
679
+ if (wikiMaintainer !== null) {
680
+ exactRecord(domain, DOMAIN_STAGE_KEYS, "releaseTrain.domain");
681
+ const wikiStage = exactRecord(
682
+ domain["wiki-maintain"],
683
+ WIKI_STAGE_KEYS,
684
+ "authorized wiki-maintain stage",
685
+ );
686
+ domain = {
687
+ ...domain,
688
+ "wiki-maintain": { ...wikiStage, maintainer: wikiMaintainer },
689
+ };
690
+ }
466
691
  stages = createEvolutionReleaseTrainDomainStages({
467
- domain: releaseTrainConfig.domain,
692
+ domain,
468
693
  proposalLedger,
469
694
  outputLedger,
470
695
  });
@@ -513,6 +738,15 @@ export function createAgentEvolutionRuntimeComposition({
513
738
  ledgerAuthority: cacheSourceAuthorities.ledger,
514
739
  witnessAuthority: cacheSourceAuthorities.witness,
515
740
  artifactResolver: sourceResolver,
741
+ ...(ledgerV2 === null
742
+ ? {}
743
+ : {
744
+ manifestV2: {
745
+ ...ledgerV2,
746
+ artifactPorts: sourcePorts,
747
+ descriptor: { tenantId, artifactTenantId: tenantId, audience },
748
+ },
749
+ }),
516
750
  secure,
517
751
  clock,
518
752
  ...(fsImpl === undefined ? {} : { fsImpl }),
@@ -553,6 +787,7 @@ export function createAgentEvolutionRuntimeComposition({
553
787
  runId,
554
788
  evolutionIngress,
555
789
  createSkillOutcomeReader,
790
+ wikiMaintenance,
556
791
  loadRun: Object.freeze(() => runAdapter.load()),
557
792
  ledgerDescriptor: backend.descriptor,
558
793
  storage,
@@ -11,6 +11,8 @@ const MESSAGE_KEYS = new Set([
11
11
  "tool_call_id",
12
12
  "name",
13
13
  "_thinkingBlocks",
14
+ "_openaiReasoningItems",
15
+ "_openaiReasoningSummary",
14
16
  ]);
15
17
  const OPAQUE_BLOCK_SCHEMA =
16
18
  "chainlesschain.evolution-agent-opaque-transport-block/v1";
@@ -124,6 +126,9 @@ function opaqueKind(value, path) {
124
126
  if (/^messages\.\d+\._thinkingBlocks\.\d+$/u.test(path)) {
125
127
  return thinkingBlock(value) ? value.type : null;
126
128
  }
129
+ if (/^messages\.\d+\._openaiReasoningItems\.\d+$/u.test(path)) {
130
+ return openAIReasoningItem(value) ? "openai_reasoning" : null;
131
+ }
127
132
  return null;
128
133
  }
129
134
 
@@ -142,13 +147,70 @@ function isOpaqueBlock(value) {
142
147
  return (
143
148
  exactKeys(value, OPAQUE_BLOCK_KEYS) &&
144
149
  value.schema === OPAQUE_BLOCK_SCHEMA &&
145
- ["image", "thinking", "redacted_thinking"].includes(value.kind) &&
150
+ ["image", "thinking", "redacted_thinking", "openai_reasoning"].includes(
151
+ value.kind,
152
+ ) &&
146
153
  /^sha256:[a-f0-9]{64}$/u.test(value.digest) &&
147
154
  Number.isSafeInteger(value.byteLength) &&
148
155
  value.byteLength > 0
149
156
  );
150
157
  }
151
158
 
159
+ function openAIReasoningItem(value) {
160
+ if (
161
+ !value ||
162
+ typeof value !== "object" ||
163
+ Array.isArray(value) ||
164
+ ![Object.prototype, null].includes(Object.getPrototypeOf(value)) ||
165
+ value.type !== "reasoning" ||
166
+ Object.keys(value).some(
167
+ (key) =>
168
+ !["type", "id", "encrypted_content", "summary", "status"].includes(key),
169
+ )
170
+ ) {
171
+ return null;
172
+ }
173
+ if (
174
+ Object.hasOwn(value, "id") &&
175
+ (typeof value.id !== "string" ||
176
+ !/^[A-Za-z0-9._:-]{1,256}$/u.test(value.id))
177
+ ) {
178
+ return null;
179
+ }
180
+ if (
181
+ Object.hasOwn(value, "encrypted_content") &&
182
+ (typeof value.encrypted_content !== "string" ||
183
+ value.encrypted_content.length < 1 ||
184
+ value.encrypted_content.length > 256 * 1024 ||
185
+ !/^[\x21-\x7e]+$/u.test(value.encrypted_content))
186
+ ) {
187
+ return null;
188
+ }
189
+ if (Object.hasOwn(value, "summary")) {
190
+ if (
191
+ !Array.isArray(value.summary) ||
192
+ value.summary.length < 1 ||
193
+ value.summary.length > 16 ||
194
+ value.summary.some(
195
+ (part) =>
196
+ !exactKeys(part, new Set(["type", "text"])) ||
197
+ part.type !== "summary_text" ||
198
+ typeof part.text !== "string" ||
199
+ part.text.length > 8192,
200
+ )
201
+ ) {
202
+ return null;
203
+ }
204
+ }
205
+ if (
206
+ Object.hasOwn(value, "status") &&
207
+ !["completed", "in_progress", "incomplete"].includes(value.status)
208
+ ) {
209
+ return null;
210
+ }
211
+ return Object.keys(value).length > 1 ? value : null;
212
+ }
213
+
152
214
  function assertContentBlock(value, path, allowOpaqueTransportBlocks) {
153
215
  if (allowOpaqueTransportBlocks && isOpaqueBlock(value)) return;
154
216
  if (
@@ -214,6 +276,36 @@ function assertMessageShape(message, index, allowOpaqueTransportBlocks) {
214
276
  }
215
277
  });
216
278
  }
279
+ if (Object.hasOwn(message, "_openaiReasoningItems")) {
280
+ if (
281
+ message.role !== "assistant" ||
282
+ !Array.isArray(message._openaiReasoningItems) ||
283
+ !message._openaiReasoningItems.length ||
284
+ message._openaiReasoningItems.length > 16
285
+ ) {
286
+ throw new TypeError(
287
+ "OpenAI reasoning replay requires bounded assistant items",
288
+ );
289
+ }
290
+ message._openaiReasoningItems.forEach((item, itemIndex) => {
291
+ if (
292
+ !(allowOpaqueTransportBlocks && isOpaqueBlock(item)) &&
293
+ !openAIReasoningItem(item)
294
+ ) {
295
+ throw new TypeError(
296
+ `OpenAI reasoning item at messages.${index}._openaiReasoningItems.${itemIndex} is unsupported`,
297
+ );
298
+ }
299
+ });
300
+ }
301
+ if (
302
+ Object.hasOwn(message, "_openaiReasoningSummary") &&
303
+ (message.role !== "assistant" ||
304
+ typeof message._openaiReasoningSummary !== "string" ||
305
+ message._openaiReasoningSummary.length > 8192)
306
+ ) {
307
+ throw new TypeError("OpenAI reasoning summary is unsupported");
308
+ }
217
309
  }
218
310
 
219
311
  // Capture before the first await. Accessors, proxies and exotic objects cannot
@@ -326,6 +418,10 @@ function textPath(path, allowStructuredArgumentText = true) {
326
418
  /^messages\.\d+\._thinkingBlocks\.\d+\.(?:thinking|signature|data)$/u.test(
327
419
  path,
328
420
  ) ||
421
+ /^messages\.\d+\._openaiReasoningItems\.\d+\.(?:encrypted_content|summary\.\d+\.text)$/u.test(
422
+ path,
423
+ ) ||
424
+ /^messages\.\d+\._openaiReasoningSummary$/u.test(path) ||
329
425
  (allowStructuredArgumentText
330
426
  ? /^messages\.\d+\.tool_calls\.\d+\.function\.arguments(?:\.|$)/u.test(
331
427
  path,
@@ -1,4 +1,5 @@
1
1
  import { createHash } from "node:crypto";
2
+ import { assertEvolutionContentContainsNoKnownSecrets } from "./evolution-evidence-projector.js";
2
3
 
3
4
  export const WIKI_STATE_SCHEMA = "chainlesschain.evolution-wiki-state/v1";
4
5
  export const WIKI_EVIDENCE_SCHEMA = "chainlesschain.evolution-wiki-evidence/v1";
@@ -126,6 +127,105 @@ function assertMetadataOnly(value, path = "data") {
126
127
  }
127
128
  }
128
129
 
130
+ function assertWikiPlaintextSafe(value) {
131
+ const isDecisionDigestRef = (candidate) =>
132
+ typeof candidate === "string" &&
133
+ candidate.startsWith("decision:") &&
134
+ DIGEST.test(candidate.slice("decision:".length));
135
+ const isBoundMaintenanceRequestMapKey = (path, key, child) =>
136
+ path.length === 1 &&
137
+ path[0] === "maintenanceRequests" &&
138
+ MAINTENANCE_REQUEST_ID.test(key) &&
139
+ child &&
140
+ typeof child === "object" &&
141
+ !Array.isArray(child) &&
142
+ DIGEST.test(child.requestDigest ?? "") &&
143
+ key === `wiki-maintenance:${child.requestDigest.slice("sha256:".length)}`;
144
+ const isBoundProposalDecisionEvidence = (path, key, child) =>
145
+ path.length === 1 &&
146
+ path[0] === "evidence" &&
147
+ isDecisionDigestRef(key) &&
148
+ child &&
149
+ typeof child === "object" &&
150
+ !Array.isArray(child) &&
151
+ child.kind === "proposal-decision" &&
152
+ child.ref === key;
153
+ const isProposalDecisionEvidenceRecord = (path, item) =>
154
+ path.length === 2 &&
155
+ path[0] === "evidence" &&
156
+ isDecisionDigestRef(path[1]) &&
157
+ item?.kind === "proposal-decision" &&
158
+ item.ref === path[1];
159
+ const isBoundProposalDecisionArtifactRef = (path, item, key, child) =>
160
+ key === "artifactRef" &&
161
+ isProposalDecisionEvidenceRecord(path, item) &&
162
+ DIGEST.test(item.data?.releaseDigest ?? "") &&
163
+ child ===
164
+ `artifact://${item.tenantId}/trusted/${item.data.releaseDigest.slice("sha256:".length)}`;
165
+ const isBoundProposalDecisionReceiptRef = (path, item, key, child) =>
166
+ path.length === 4 &&
167
+ path[0] === "skillImpact" &&
168
+ path[2] === "decisions" &&
169
+ path[3] === "[]" &&
170
+ key === "receiptRef" &&
171
+ DIGEST.test(item.candidateId ?? "") &&
172
+ child === `decision:${item.candidateId}`;
173
+ const isProposalImpactCandidateSubject = (path, item, key, child) =>
174
+ path.length === 2 &&
175
+ path[0] === "evolutionLog" &&
176
+ path[1] === "[]" &&
177
+ key === "subjectId" &&
178
+ item.type === "proposal-impact-recorded" &&
179
+ DIGEST.test(child ?? "");
180
+ const isBoundProtocolValue = (path, item, key, child) =>
181
+ (key.endsWith("Digest") && DIGEST.test(child ?? "")) ||
182
+ (key === "candidateId" && DIGEST.test(child ?? "")) ||
183
+ isProposalImpactCandidateSubject(path, item, key, child) ||
184
+ isBoundProposalDecisionReceiptRef(path, item, key, child) ||
185
+ isBoundProposalDecisionArtifactRef(path, item, key, child) ||
186
+ (isProposalDecisionEvidenceRecord(path, item) &&
187
+ key === "ref" &&
188
+ child === path[1]) ||
189
+ (key === "revisionId" && REVISION_ID.test(child ?? "")) ||
190
+ (key === "requestId" && MAINTENANCE_REQUEST_ID.test(child ?? ""));
191
+ const inspect = (item, path = []) => {
192
+ if (typeof item === "string") {
193
+ assertEvolutionContentContainsNoKnownSecrets(item);
194
+ } else if (Array.isArray(item)) {
195
+ item.forEach((child) => inspect(child, [...path, "[]"]));
196
+ } else if (item && typeof item === "object") {
197
+ for (const [key, child] of Object.entries(item)) {
198
+ // Maintenance requests are stored under their validated, digest-bound
199
+ // request ID. The map key is opaque protocol metadata, not model text;
200
+ // inspecting random hash bytes as prose can falsely match PII patterns.
201
+ // Restrict the exemption to the state map and inspect its complete
202
+ // record so an untrusted lookalike key cannot bypass this boundary.
203
+ if (
204
+ !isBoundMaintenanceRequestMapKey(path, key, child) &&
205
+ !isBoundProposalDecisionEvidence(path, key, child)
206
+ )
207
+ assertEvolutionContentContainsNoKnownSecrets(key);
208
+ // Protocol metadata can carry random hash bytes that accidentally match
209
+ // a PII detector. Every exemption is bound to its state path, schema and
210
+ // sibling fields; prose and lookalikes still go through the detector.
211
+ if (isBoundProtocolValue(path, item, key, child)) continue;
212
+ if (["string", "number"].includes(typeof child))
213
+ assertEvolutionContentContainsNoKnownSecrets(`${key}=${child}`);
214
+ inspect(child, [...path, key]);
215
+ }
216
+ }
217
+ };
218
+ try {
219
+ inspect(value);
220
+ } catch (cause) {
221
+ const error = new Error("Wiki revision contains secret or PII plaintext", {
222
+ cause,
223
+ });
224
+ error.code = "WIKI_MAINTAINER_SECRET_LEAK";
225
+ throw error;
226
+ }
227
+ }
228
+
129
229
  export function createEmptyWikiState(tenantId) {
130
230
  return freeze({
131
231
  schema: WIKI_STATE_SCHEMA,
@@ -301,6 +401,36 @@ function evidenceUsable(item, effectiveAt) {
301
401
  );
302
402
  }
303
403
 
404
+ // Corroboration needs distinct content AND distinct trust domains. Counting
405
+ // either set alone lets the same observation be repeated under new identities.
406
+ // A bounded bipartite matching also handles policies requiring >2 sources,
407
+ // where min(unique contents, unique domains) can still overcount independence.
408
+ function independentSourceCount(evidence) {
409
+ const domains = new Map();
410
+ for (const item of evidence) {
411
+ if (!domains.has(item.trustDomain))
412
+ domains.set(item.trustDomain, new Set());
413
+ domains.get(item.trustDomain).add(item.sourceDigest);
414
+ }
415
+ const matchedSources = new Map();
416
+ const match = (domain, visited) => {
417
+ for (const source of domains.get(domain)) {
418
+ if (visited.has(source)) continue;
419
+ visited.add(source);
420
+ if (
421
+ !matchedSources.has(source) ||
422
+ match(matchedSources.get(source), visited)
423
+ ) {
424
+ matchedSources.set(source, domain);
425
+ return true;
426
+ }
427
+ }
428
+ return false;
429
+ };
430
+ for (const domain of domains.keys()) match(domain, new Set());
431
+ return matchedSources.size;
432
+ }
433
+
304
434
  function rebuildDerivedState(state, effectiveAt, descriptor) {
305
435
  const dependents = {};
306
436
  for (const pattern of Object.values(state.patterns)) {
@@ -352,7 +482,10 @@ function rebuildDerivedState(state, effectiveAt, descriptor) {
352
482
  pattern.status = WIKI_PATTERN_STATUS.STALE;
353
483
  } else if (negative.length > 0 || pattern.contradicts.length > 0)
354
484
  pattern.status = WIKI_PATTERN_STATUS.CONTRADICTED;
355
- else if (hasGrader || domains.length >= descriptor.minCorroboratingSources)
485
+ else if (
486
+ hasGrader ||
487
+ independentSourceCount(positive) >= descriptor.minCorroboratingSources
488
+ )
356
489
  pattern.status = WIKI_PATTERN_STATUS.CORROBORATED;
357
490
  else pattern.status = WIKI_PATTERN_STATUS.HYPOTHESIS;
358
491
  pattern.trustDomains = domains;
@@ -735,6 +868,10 @@ export class EvidenceBackedWikiMaintainer {
735
868
  revisionId: state.revisionId,
736
869
  };
737
870
  }
871
+ // Trusted inputs do not make a model's derived output safe to persist.
872
+ // Inspect the complete outgoing state, including reasons, index and log,
873
+ // before publishing any revision artifact. Share the Raw/Skill policy.
874
+ assertWikiPlaintextSafe(state);
738
875
  const stateDigest = hash(state);
739
876
  const revision = freeze({
740
877
  ...revisionPayload,
@@ -742,6 +879,22 @@ export class EvidenceBackedWikiMaintainer {
742
879
  stateDigest,
743
880
  state: freeze(clone(state)),
744
881
  });
882
+ // Derivation may await a model or another worker. Re-resolve through the
883
+ // trusted evidence boundary immediately before writing: prior read success
884
+ // is not permission to publish after revocation, deletion, or expiry. A
885
+ // changed but valid envelope requires fresh derivation, never a silent swap.
886
+ for (const ref of refs) {
887
+ const current = verifyEvidence(
888
+ await this._ports.resolveEvidence(ref),
889
+ this.descriptor.tenantId,
890
+ ref,
891
+ );
892
+ if (current.envelopeDigest !== evidenceByRef.get(ref).envelopeDigest) {
893
+ const error = new Error("Wiki evidence changed during derivation");
894
+ error.code = "WIKI_MAINTAINER_EVIDENCE_CHANGED";
895
+ throw error;
896
+ }
897
+ }
745
898
  const committed = await this._ports.commitRevision(
746
899
  freeze({ expectedStateDigest: priorStateDigest, revision }),
747
900
  );