chainlesschain 0.166.64 → 0.166.68

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 (199) hide show
  1. package/README.md +29 -12
  2. package/package.json +4 -4
  3. package/src/assets/web-panel/assets/{AIOps-BFbLDWTF.js → AIOps-CXkSNOGY.js} +1 -1
  4. package/src/assets/web-panel/assets/{ActionButton-CAHMtgNB.js → ActionButton-ysMR6gTs.js} +1 -1
  5. package/src/assets/web-panel/assets/{Analytics-CkrSj0oR.js → Analytics-WGZ0sWuw.js} +3 -3
  6. package/src/assets/web-panel/assets/{AppLayout-BTb0Ws1l.js → AppLayout-Cs2iRlQG.js} +4 -4
  7. package/src/assets/web-panel/assets/{Artifacts-C2Pgepj-.js → Artifacts-5IdfxWz0.js} +1 -1
  8. package/src/assets/web-panel/assets/{Audit-ZweyxXW8.js → Audit-U9V434QX.js} +1 -1
  9. package/src/assets/web-panel/assets/{BackgroundAgents-BS8tAnzP.js → BackgroundAgents-BvFwxPlC.js} +1 -1
  10. package/src/assets/web-panel/assets/{Backup-CLkG_74M.js → Backup-C9yTr9hO.js} +1 -1
  11. package/src/assets/web-panel/assets/{BaseInput-MIfNcdUZ.js → BaseInput-BdsSwUgE.js} +1 -1
  12. package/src/assets/web-panel/assets/{Chat-DBwqlWWr.js → Chat-BB_2oBgH.js} +5 -5
  13. package/src/assets/web-panel/assets/ChatBubbleRenderer-Bpf1hDUl.js +1 -0
  14. package/src/assets/web-panel/assets/{Checkbox-DdBYhlVX.js → Checkbox-v6M5m7dK.js} +1 -1
  15. package/src/assets/web-panel/assets/{Codegen-BR6MhiDo.js → Codegen-CtouWSIz.js} +1 -1
  16. package/src/assets/web-panel/assets/{Col-yO-5EbbM.js → Col-CqQJ4ORW.js} +1 -1
  17. package/src/assets/web-panel/assets/{Community-B608q_m7.js → Community-BO__QCOy.js} +1 -1
  18. package/src/assets/web-panel/assets/{Compact-BmVHi7Z7.js → Compact-D0Kq4xlH.js} +1 -1
  19. package/src/assets/web-panel/assets/{Compliance-BQ-DzutA.js → Compliance-BSLKKBjA.js} +1 -1
  20. package/src/assets/web-panel/assets/{Cowork-BEfLyXvi.js → Cowork-VsujXW5o.js} +3 -3
  21. package/src/assets/web-panel/assets/{Cron-Cld6NX-_.js → Cron-j8DbLGi5.js} +2 -2
  22. package/src/assets/web-panel/assets/{Crosschain-CUA3nDId.js → Crosschain-DWpYH1yN.js} +1 -1
  23. package/src/assets/web-panel/assets/{DID-DSI3E9zv.js → DID-mLaRxLQh.js} +2 -2
  24. package/src/assets/web-panel/assets/{Dashboard-CoWtEdhO.js → Dashboard-Cff033Jr.js} +2 -2
  25. package/src/assets/web-panel/assets/{Dropdown-CGhZ1Dyy.js → Dropdown-B1Upt6fP.js} +1 -1
  26. package/src/assets/web-panel/assets/{EmailListRenderer-BHZe2K5q.js → EmailListRenderer-CPtb8joV.js} +1 -1
  27. package/src/assets/web-panel/assets/{EvolutionSettings-Corjo98k.js → EvolutionSettings-CVh4Uv4g.js} +1 -1
  28. package/src/assets/web-panel/assets/{FamilyGuardDashboard-dPSWF3Pt.js → FamilyGuardDashboard-CrD1PhbF.js} +1 -1
  29. package/src/assets/web-panel/assets/{Federation-DT-Zr78c.js → Federation-ftxrvqW5.js} +1 -1
  30. package/src/assets/web-panel/assets/{FormItemContext-CzKq63B0.js → FormItemContext-9O80slC1.js} +1 -1
  31. package/src/assets/web-panel/assets/{GenericCardRenderer-CDkKrmu0.js → GenericCardRenderer-DaYvYIj9.js} +1 -1
  32. package/src/assets/web-panel/assets/{Git-BrwRnLOv.js → Git-BKZh0YE5.js} +2 -2
  33. package/src/assets/web-panel/assets/{Governance-C4PtCzod.js → Governance-vWbN873j.js} +1 -1
  34. package/src/assets/web-panel/assets/{Inference-CVPv5nwa.js → Inference-BN6RR-l8.js} +1 -1
  35. package/src/assets/web-panel/assets/{KnowledgeGraph-CmT9lvED.js → KnowledgeGraph-x49x9m7Q.js} +1 -1
  36. package/src/assets/web-panel/assets/{Logs-DaRgv7pL.js → Logs-Co2EPLsJ.js} +2 -2
  37. package/src/assets/web-panel/assets/{MarkdownRenderer-B3zZwlSz.js → MarkdownRenderer-D7wIB-c7.js} +1 -1
  38. package/src/assets/web-panel/assets/{Marketplace-Bm0GGEaL.js → Marketplace-DpPu6XQp.js} +1 -1
  39. package/src/assets/web-panel/assets/{McpTools-71L5h0en.js → McpTools-BR0ksiax.js} +3 -3
  40. package/src/assets/web-panel/assets/{Memory-BoWrfASi.js → Memory-BXznJ5-C.js} +2 -2
  41. package/src/assets/web-panel/assets/{MobileBridge-Dp4FcX_-.js → MobileBridge-BHSOpfv7.js} +1 -1
  42. package/src/assets/web-panel/assets/{MobileProjects-00ja0Z7O.js → MobileProjects-DdWmgIup.js} +1 -1
  43. package/src/assets/web-panel/assets/{Mtc-BZF6YNYp.js → Mtc-D9Rk_IGT.js} +4 -4
  44. package/src/assets/web-panel/assets/{MtcAudit-Bp_vcI6H.js → MtcAudit--i8q1lKc.js} +2 -2
  45. package/src/assets/web-panel/assets/{Multisig-CnCo56CS.js → Multisig-BHnNG7R9.js} +3 -3
  46. package/src/assets/web-panel/assets/{NLProgramming-BCSzNHpv.js → NLProgramming-Duo1ij2_.js} +1 -1
  47. package/src/assets/web-panel/assets/{Notes-kXoQk8B7.js → Notes-B44Le73p.js} +3 -3
  48. package/src/assets/web-panel/assets/{NotificationSettings-oN-1fkcy.js → NotificationSettings-C3oy_7Gf.js} +1 -1
  49. package/src/assets/web-panel/assets/{OrderTableRenderer-5ZVHrVZ9.js → OrderTableRenderer-Da_73SI5.js} +1 -1
  50. package/src/assets/web-panel/assets/{Organization-D4_T9Tdc.js → Organization-ChsSwKxT.js} +4 -4
  51. package/src/assets/web-panel/assets/{Overflow-d8vZwo9w.js → Overflow-DR5G_cCn.js} +1 -1
  52. package/src/assets/web-panel/assets/{P2P-0HGUdmTv.js → P2P-yfaobqow.js} +2 -2
  53. package/src/assets/web-panel/assets/PdhVaultBrowser-DgimH6Jp.js +7 -0
  54. package/src/assets/web-panel/assets/{Permissions-XHd6pVQB.js → Permissions-DhinFvtE.js} +4 -4
  55. package/src/assets/web-panel/assets/{PersonalDataHub-CB5bZU9T.js → PersonalDataHub-CfeNVic1.js} +3 -3
  56. package/src/assets/web-panel/assets/{Pipeline-Dy_qx4-0.js → Pipeline-CGKO26Nk.js} +1 -1
  57. package/src/assets/web-panel/assets/{Privacy-BgR0-uEu.js → Privacy-CxxfYEJh.js} +1 -1
  58. package/src/assets/web-panel/assets/{ProjectInit-DAcRi1Nx.js → ProjectInit-CZsaAab9.js} +2 -2
  59. package/src/assets/web-panel/assets/{ProjectSettings-Bd1Q0rK_.js → ProjectSettings-BUm_6clQ.js} +2 -2
  60. package/src/assets/web-panel/assets/{Projects-DVc9DcbM.js → Projects-Capr8bVq.js} +1 -1
  61. package/src/assets/web-panel/assets/{Providers-C3c4QfUT.js → Providers-D28VqPja.js} +1 -1
  62. package/src/assets/web-panel/assets/{QrScannerModal-Ba_GbitW.js → QrScannerModal-Cj200vUb.js} +1 -1
  63. package/src/assets/web-panel/assets/{QuickAsk-CSn5tIkO.js → QuickAsk-BGpnEiam.js} +1 -1
  64. package/src/assets/web-panel/assets/{Recommend-B3-8PLX0.js → Recommend-Ix79Tpni.js} +1 -1
  65. package/src/assets/web-panel/assets/{RemoteSession-Bd_7Zmi-.js → RemoteSession-BdGAFbIk.js} +2 -2
  66. package/src/assets/web-panel/assets/{Reputation-BU2A_wy5.js → Reputation-B1Lis0Wk.js} +1 -1
  67. package/src/assets/web-panel/assets/{Row-I0JFMjCz.js → Row-Ba_okwOW.js} +1 -1
  68. package/src/assets/web-panel/assets/{RssFeed-CNc4Dgfz.js → RssFeed-DDbEuI-m.js} +3 -3
  69. package/src/assets/web-panel/assets/{Search-uAA6ceLl.js → Search-D89wAkMy.js} +1 -1
  70. package/src/assets/web-panel/assets/{Security-U1SWj5nP.js → Security-CJKCKAU-.js} +3 -3
  71. package/src/assets/web-panel/assets/{Services-BFjZ5ASY.js → Services-mitEc1XV.js} +2 -2
  72. package/src/assets/web-panel/assets/{Skeleton-B8InBvQf.js → Skeleton-CnBjLDfX.js} +1 -1
  73. package/src/assets/web-panel/assets/{Skills-BDYwf3QV.js → Skills-DSzDYvH3.js} +1 -1
  74. package/src/assets/web-panel/assets/{Sla-Dcc6iq3q.js → Sla-CglJ_4p3.js} +1 -1
  75. package/src/assets/web-panel/assets/SpeechSettings-BicWJS7f.js +1 -0
  76. package/src/assets/web-panel/assets/{SyncSettings-BNHEYO95.js → SyncSettings-Cq7o6fmr.js} +2 -2
  77. package/src/assets/web-panel/assets/{Tasks-JbV6L1FX.js → Tasks-DOxFOBpU.js} +1 -1
  78. package/src/assets/web-panel/assets/{Templates-Yp0CUTBz.js → Templates-bY0wSbQM.js} +1 -1
  79. package/src/assets/web-panel/assets/{Tenant-CToNYxCo.js → Tenant-BAyyl0qX.js} +1 -1
  80. package/src/assets/web-panel/assets/{Terminal-D7W9UqSD.js → Terminal-BGBhSpqc.js} +2 -2
  81. package/src/assets/web-panel/assets/{TimelineRenderer-B7rqc1kE.js → TimelineRenderer-BvW5lXYz.js} +1 -1
  82. package/src/assets/web-panel/assets/{Tokens-QP7K4ppA.js → Tokens-Ua_LIx8-.js} +1 -1
  83. package/src/assets/web-panel/assets/{Trigger-CAWowQCR.js → Trigger-BGwb2KL1.js} +1 -1
  84. package/src/assets/web-panel/assets/{Trust-B-0XOP97.js → Trust-CD2IEHvj.js} +1 -1
  85. package/src/assets/web-panel/assets/{UkeySign-BtiZbiuj.js → UkeySign-D5LetK6P.js} +1 -1
  86. package/src/assets/web-panel/assets/{VideoEditing-Dee11JI0.js → VideoEditing-oP7ehFgR.js} +1 -1
  87. package/src/assets/web-panel/assets/{Wallet-y7qOmaWY.js → Wallet-BBtu4-xa.js} +4 -4
  88. package/src/assets/web-panel/assets/{WebAuthn-CjyRRWGK.js → WebAuthn-iSPRU4Ht.js} +3 -3
  89. package/src/assets/web-panel/assets/{WorkflowEditor-D7Kiz25Q.js → WorkflowEditor-DuEDhQmB.js} +1 -1
  90. package/src/assets/web-panel/assets/{chat-4F_yB-Gw.js → chat-DGDgqvvm.js} +1 -1
  91. package/src/assets/web-panel/assets/{colors-CrczPd-t.js → colors-DGQMWa1-.js} +1 -1
  92. package/src/assets/web-panel/assets/{compact-item-AenPL6fz.js → compact-item-COVznBL4.js} +1 -1
  93. package/src/assets/web-panel/assets/{createContext-BcwoqPgi.js → createContext-DIxVeHXI.js} +1 -1
  94. package/src/assets/web-panel/assets/devWarning-CjR9h-Z_.js +1 -0
  95. package/src/assets/web-panel/assets/{hasIn-YouHmap8.js → hasIn-DkxZO3E9.js} +1 -1
  96. package/src/assets/web-panel/assets/{index-fCuM1NPH.js → index-0ToBFsvW.js} +1 -1
  97. package/src/assets/web-panel/assets/{index-D0dXNgvi.js → index-2JZizEPc.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-BHA5Fyjc.js → index-BAL2p7YC.js} +1 -1
  99. package/src/assets/web-panel/assets/{index-CedvtJA_.js → index-BAlrovUm.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-5GHNjmnt.js → index-BBw2MLIe.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-C5hpEYbx.js → index-BHH95jcm.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-D8a1AEVK.js → index-BOTshZNx.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-D7m5Z4We.js → index-BQm7ntcn.js} +1 -1
  104. package/src/assets/web-panel/assets/{index-D_4VsL-L.js → index-BUqwlzc8.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-GP5u18DV.js → index-BY6MSbWT.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-CHNKoexH.js → index-BY9Ossof.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-DNHmbdGm.js → index-BgM-3a1w.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-YX4dcbgh.js → index-Bv0_u0ze.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-D5Rvq67L.js → index-C3XeNS82.js} +3 -3
  110. package/src/assets/web-panel/assets/{index-DAGfuEUu.js → index-C3bN6751.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-CZT-LLGS.js → index-CNRRrP3-.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-4r7B8sTx.js → index-CV0KnNqR.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-B5Vmr0CM.js → index-CcNGQWum.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-DE3qPp9l.js → index-Ci34vbh0.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-CWgIKCVS.js → index-ClQVcrFt.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-31dhJpt3.js → index-Cligb-Dl.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-BsGhFk79.js → index-CokrhbY2.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-B_I1INkw.js → index-CpZxDiVK.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-BaguGDJP.js → index-CyMHF2Bi.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-DPrzFdCg.js → index-DDwPBGdA.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-gy1H_PJk.js → index-DU1ArKl5.js} +1 -1
  122. package/src/assets/web-panel/assets/{index-DAh5KwVL.js → index-DV0H83eS.js} +1 -1
  123. package/src/assets/web-panel/assets/index-D_nxBMX5.js +1 -0
  124. package/src/assets/web-panel/assets/{index-q_9aqSgF.js → index-DaWQSp5a.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-B8EXHVmM.js → index-DmduvOYT.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-DVrgnhfu.js → index-ECoDhyH3.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-BwUqDg9_.js → index-ZcqTvPnt.js} +1 -1
  128. package/src/assets/web-panel/assets/{index--xwN0ZvG.js → index-b2_M6o20.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-CZ9Ikuo6.js → index-b_0qTo8O.js} +1 -1
  130. package/src/assets/web-panel/assets/{index-BoVeUGhC.js → index-dfYkGovV.js} +1 -1
  131. package/src/assets/web-panel/assets/{index-COgeZETv.js → index-jo7DbU0w.js} +1 -1
  132. package/src/assets/web-panel/assets/{index-Dfw3WyZU.js → index-usmG13jq.js} +1 -1
  133. package/src/assets/web-panel/assets/{index-BzyDSW_e.js → index-vXrktF3e.js} +1 -1
  134. package/src/assets/web-panel/assets/index-z_cTUMX-.js +1 -0
  135. package/src/assets/web-panel/assets/{initDefaultProps-Ci6zc6ZA.js → initDefaultProps-CkSeiBwL.js} +1 -1
  136. package/src/assets/web-panel/assets/{motion-DS3kjIxw.js → motion-CSzhDP0s.js} +1 -1
  137. package/src/assets/web-panel/assets/{move-DCdWAKk4.js → move-mgCt4iC6.js} +1 -1
  138. package/src/assets/web-panel/assets/{mtc-parser-B0Wfce9U.js → mtc-parser-BEZBLcKt.js} +1 -1
  139. package/src/assets/web-panel/assets/{omit-Clx9TR6z.js → omit-BsHctMEr.js} +1 -1
  140. package/src/assets/web-panel/assets/{pickAttrs-CqSiqUvN.js → pickAttrs-1BHamnGW.js} +1 -1
  141. package/src/assets/web-panel/assets/{placementArrow-BWe_v-40.js → placementArrow--Vb4Bd7l.js} +1 -1
  142. package/src/assets/web-panel/assets/{responsiveObserve-BSJ68bw6.js → responsiveObserve-DD33SqCm.js} +1 -1
  143. package/src/assets/web-panel/assets/{slide-VRPlLxZB.js → slide-DfrLtxgK.js} +1 -1
  144. package/src/assets/web-panel/assets/{statusUtils-BFBVDPdB.js → statusUtils-D9Pe_gXW.js} +1 -1
  145. package/src/assets/web-panel/assets/{styleChecker-CehOXy1f.js → styleChecker-0NY5iMun.js} +1 -1
  146. package/src/assets/web-panel/assets/{useFlexGapSupport-BCOdfK18.js → useFlexGapSupport-DSsZstwg.js} +1 -1
  147. package/src/assets/web-panel/assets/{useFs-BMKrjfJQ.js → useFs-BU8HyH59.js} +1 -1
  148. package/src/assets/web-panel/assets/{usePersonalDataHub-BIjZ7IgI.js → usePersonalDataHub-D_xttink.js} +1 -1
  149. package/src/assets/web-panel/assets/{vnode-oD0MXddQ.js → vnode-39VhX2lM.js} +1 -1
  150. package/src/assets/web-panel/assets/{zoom-D7WqH2Ai.js → zoom-D5KQ8Pks.js} +1 -1
  151. package/src/assets/web-panel/index.html +1 -1
  152. package/src/data/changelog.json +33 -7
  153. package/src/lib/dependency-install-policy.js +1 -1
  154. package/src/lib/evolution/browser-download-action-authority.js +747 -0
  155. package/src/lib/evolution/browser-download-artifact-disposal-authority.js +436 -0
  156. package/src/lib/evolution/browser-filesystem-quarantine-custody.js +2453 -0
  157. package/src/lib/evolution/browser-filesystem-quarantine-disposal.js +36 -0
  158. package/src/lib/evolution/browser-keyboard-action-authority.js +560 -0
  159. package/src/lib/evolution/browser-navigation-action-authority.js +546 -0
  160. package/src/lib/evolution/browser-quarantine-lock-maintenance-authority.js +573 -0
  161. package/src/lib/evolution/browser-quarantine-operator-revocation-authority.js +442 -0
  162. package/src/lib/evolution/browser-quarantine-retention-authority.js +503 -0
  163. package/src/lib/evolution/browser-quarantine-retention-scheduler.js +207 -0
  164. package/src/lib/evolution/browser-quarantined-download-executor.js +525 -0
  165. package/src/lib/evolution/browser-tab-open-action-authority.js +491 -0
  166. package/src/lib/evolution/browser-vision-action-authority.js +444 -0
  167. package/src/lib/evolution/browser-vision-observation-authority.js +304 -0
  168. package/src/lib/evolution/evolution-deployment-loader.js +202 -1
  169. package/src/lib/evolution/evolution-eval-child-evidence-ledger-adapter.js +5 -0
  170. package/src/lib/evolution/evolution-eval-gate.js +2 -1
  171. package/src/lib/evolution/evolution-eval-process-supervisor-worker.mjs +71 -9
  172. package/src/lib/evolution/evolution-eval-process-supervisor.js +276 -9
  173. package/src/lib/evolution/evolution-workbench-metrics.js +81 -21
  174. package/src/lib/evolution/pm-exploration-benchmark.js +747 -0
  175. package/src/lib/evolution/pm-exploration-budget-executor.js +106 -9
  176. package/src/lib/evolution/pm-exploration-egress-authority.js +382 -0
  177. package/src/lib/evolution/pm-exploration-evidence-bundle.js +149 -44
  178. package/src/lib/evolution/pm-exploration-execution-host.js +1254 -8
  179. package/src/lib/evolution/pm-exploration-process-grader.js +458 -0
  180. package/src/lib/evolution/pm-exploration-process-reviewer.js +456 -0
  181. package/src/lib/evolution/pm-exploration-process-runner.js +500 -0
  182. package/src/lib/evolution/pm-exploration-receipts.js +211 -11
  183. package/src/lib/evolution/pm-exploration-recovery-snapshot-store.js +465 -46
  184. package/src/lib/evolution/pm-exploration-transition-committer.js +185 -34
  185. package/src/lib/evolution/skill-outcome-index-authority.js +7 -3
  186. package/src/lib/governance-coverage.js +1 -1
  187. package/src/lib/headless-manifest.js +1 -1
  188. package/src/lib/protocol-replay.js +1 -1
  189. package/src/lib/read-file-loop-guard.js +5 -8
  190. package/src/lib/remote-read-loop-guard.js +25 -18
  191. package/src/lib/skill-outcome-transcript-authority.js +45 -5
  192. package/src/lib/tool-recovery-result.js +11 -0
  193. package/src/runtime/agent-core.js +26 -3
  194. package/src/assets/web-panel/assets/ChatBubbleRenderer-6T0uoJuS.js +0 -1
  195. package/src/assets/web-panel/assets/PdhVaultBrowser-Cx8vp92z.js +0 -7
  196. package/src/assets/web-panel/assets/SpeechSettings-C3Ta-mC9.js +0 -1
  197. package/src/assets/web-panel/assets/devWarning-C4qWsAvh.js +0 -1
  198. package/src/assets/web-panel/assets/index-C-ltOW-O.js +0 -1
  199. package/src/assets/web-panel/assets/index-D7Ir0TiS.js +0 -1
@@ -7,6 +7,8 @@ export const PM_EXPLORATION_SUCCESS_TRANSITION_SCHEMA =
7
7
  "chainlesschain.desktop-pm-state-transition-success/v1";
8
8
  export const PM_EXPLORATION_FAILED_TRANSITION_SCHEMA =
9
9
  "chainlesschain.desktop-pm-failed-execution-evidence/v1";
10
+ export const PM_EXPLORATION_CLONE_RECOVERY_EVENT_SCHEMA =
11
+ "chainlesschain.desktop-pm-clone-recovery-event/v1";
10
12
  export const PM_EXPLORATION_TRANSITION_DURABILITY_ACK_SCHEMA =
11
13
  "chainlesschain.pm-exploration-transition-durability-ack/v1";
12
14
  export const PM_EXPLORATION_SNAPSHOT_BOUND_TRANSITION_DURABILITY_ACK_SCHEMA =
@@ -15,6 +17,8 @@ export const PM_EXPLORATION_TRANSITION_RECOVERY_REQUEST_SCHEMA =
15
17
  "chainlesschain.pm-exploration-transition-recovery-request/v1";
16
18
  export const PM_EXPLORATION_TRANSITION_RECOVERY_SCHEMA =
17
19
  "chainlesschain.pm-exploration-transition-recovery/v1";
20
+ export const PM_EXPLORATION_SNAPSHOT_BOUND_TRANSITION_RECOVERY_SCHEMA =
21
+ "chainlesschain.pm-exploration-transition-recovery/v2";
18
22
 
19
23
  const DATABASE_SEAL_SCHEMA =
20
24
  "chainlesschain.desktop-pm-database-pre-run-seal/v1";
@@ -285,6 +289,106 @@ function failedTransition(value, expectedManifestDigest) {
285
289
  return deepFreeze({ ...core, evidenceDigest });
286
290
  }
287
291
 
292
+ function cloneRecoveryEvent(value, expectedManifestDigest) {
293
+ exact(
294
+ value,
295
+ [
296
+ "schema",
297
+ "manifestDigest",
298
+ "cloneIdentityDigest",
299
+ "sourceTransitionRevision",
300
+ "sourceFailureEvidenceDigest",
301
+ "previousStateTransitionDigest",
302
+ "recoverySnapshotAckDigest",
303
+ "restoredDatabaseSealDigest",
304
+ "restoredWorkspaceSealDigest",
305
+ "switchReceiptDigest",
306
+ "authenticated",
307
+ "durable",
308
+ "qualifiesForPromotion",
309
+ "recoveryEventDigest",
310
+ ],
311
+ "PM clone recovery event",
312
+ );
313
+ if (
314
+ value.schema !== PM_EXPLORATION_CLONE_RECOVERY_EVENT_SCHEMA ||
315
+ value.manifestDigest !== expectedManifestDigest ||
316
+ !Number.isSafeInteger(value.sourceTransitionRevision) ||
317
+ value.sourceTransitionRevision < 1 ||
318
+ value.authenticated !== false ||
319
+ value.durable !== false ||
320
+ value.qualifiesForPromotion !== false
321
+ ) {
322
+ throw new Error("PM clone recovery event fields are invalid");
323
+ }
324
+ const core = {
325
+ schema: value.schema,
326
+ manifestDigest: digest(value.manifestDigest, "manifestDigest"),
327
+ cloneIdentityDigest: digest(
328
+ value.cloneIdentityDigest,
329
+ "cloneIdentityDigest",
330
+ ),
331
+ sourceTransitionRevision: value.sourceTransitionRevision,
332
+ sourceFailureEvidenceDigest: digest(
333
+ value.sourceFailureEvidenceDigest,
334
+ "sourceFailureEvidenceDigest",
335
+ ),
336
+ previousStateTransitionDigest: optionalDigest(
337
+ value.previousStateTransitionDigest,
338
+ "previousStateTransitionDigest",
339
+ ),
340
+ recoverySnapshotAckDigest: digest(
341
+ value.recoverySnapshotAckDigest,
342
+ "recoverySnapshotAckDigest",
343
+ ),
344
+ restoredDatabaseSealDigest: digest(
345
+ value.restoredDatabaseSealDigest,
346
+ "restoredDatabaseSealDigest",
347
+ ),
348
+ restoredWorkspaceSealDigest: digest(
349
+ value.restoredWorkspaceSealDigest,
350
+ "restoredWorkspaceSealDigest",
351
+ ),
352
+ switchReceiptDigest: digest(
353
+ value.switchReceiptDigest,
354
+ "switchReceiptDigest",
355
+ ),
356
+ authenticated: false,
357
+ durable: false,
358
+ qualifiesForPromotion: false,
359
+ };
360
+ const recoveryEventDigest = digest(
361
+ value.recoveryEventDigest,
362
+ "recoveryEventDigest",
363
+ );
364
+ if (
365
+ recoveryEventDigest !==
366
+ hash(PM_EXPLORATION_CLONE_RECOVERY_EVENT_SCHEMA, core)
367
+ ) {
368
+ throw new Error("PM clone recovery event digest mismatch");
369
+ }
370
+ return deepFreeze({ ...core, recoveryEventDigest });
371
+ }
372
+
373
+ function transitionBinding(evidence) {
374
+ if (evidence.schema === PM_EXPLORATION_SUCCESS_TRANSITION_SCHEMA) {
375
+ return Object.freeze({
376
+ transitionKind: "success",
377
+ evidenceDigest: evidence.stateTransitionDigest,
378
+ });
379
+ }
380
+ if (evidence.schema === PM_EXPLORATION_FAILED_TRANSITION_SCHEMA) {
381
+ return Object.freeze({
382
+ transitionKind: "failure",
383
+ evidenceDigest: evidence.evidenceDigest,
384
+ });
385
+ }
386
+ return Object.freeze({
387
+ transitionKind: "recovery",
388
+ evidenceDigest: evidence.recoveryEventDigest,
389
+ });
390
+ }
391
+
288
392
  export function verifyPmExplorationTransitionEvidence(
289
393
  value,
290
394
  expectedManifestDigest,
@@ -305,6 +409,8 @@ export function verifyPmExplorationTransitionEvidence(
305
409
  return successTransition(value, manifestDigest);
306
410
  if (schema.value === PM_EXPLORATION_FAILED_TRANSITION_SCHEMA)
307
411
  return failedTransition(value, manifestDigest);
412
+ if (schema.value === PM_EXPLORATION_CLONE_RECOVERY_EVENT_SCHEMA)
413
+ return cloneRecoveryEvent(value, manifestDigest);
308
414
  throw new TypeError("PM transition evidence schema is invalid");
309
415
  }
310
416
 
@@ -370,34 +476,67 @@ function durabilityAck(value, binding) {
370
476
  }
371
477
 
372
478
  function transitionRecovery(value, expectedManifestDigest) {
479
+ const schemaDescriptor =
480
+ value &&
481
+ typeof value === "object" &&
482
+ !Array.isArray(value) &&
483
+ !isProxy(value) &&
484
+ Object.getPrototypeOf(value) === Object.prototype
485
+ ? Object.getOwnPropertyDescriptor(value, "schema")
486
+ : null;
487
+ const snapshotBound =
488
+ schemaDescriptor &&
489
+ "value" in schemaDescriptor &&
490
+ schemaDescriptor.value ===
491
+ PM_EXPLORATION_SNAPSHOT_BOUND_TRANSITION_RECOVERY_SCHEMA;
373
492
  exact(
374
493
  value,
375
- [
376
- "schema",
377
- "authenticated",
378
- "durable",
379
- "readbackVerified",
380
- "manifestDigest",
381
- "revision",
382
- "transitionKind",
383
- "evidenceDigest",
384
- "evidence",
385
- "ledgerHeadDigest",
386
- "ledgerEventDigest",
387
- "durabilityReceiptDigest",
388
- "qualifiesForPromotion",
389
- ],
494
+ snapshotBound
495
+ ? [
496
+ "schema",
497
+ "authenticated",
498
+ "durable",
499
+ "readbackVerified",
500
+ "manifestDigest",
501
+ "revision",
502
+ "transitionKind",
503
+ "evidenceDigest",
504
+ "evidence",
505
+ "recoverySnapshot",
506
+ "ledgerHeadDigest",
507
+ "ledgerEventDigest",
508
+ "durabilityReceiptDigest",
509
+ "qualifiesForPromotion",
510
+ ]
511
+ : [
512
+ "schema",
513
+ "authenticated",
514
+ "durable",
515
+ "readbackVerified",
516
+ "manifestDigest",
517
+ "revision",
518
+ "transitionKind",
519
+ "evidenceDigest",
520
+ "evidence",
521
+ "ledgerHeadDigest",
522
+ "ledgerEventDigest",
523
+ "durabilityReceiptDigest",
524
+ "qualifiesForPromotion",
525
+ ],
390
526
  "PM transition recovery",
391
527
  );
392
528
  if (
393
- value.schema !== PM_EXPLORATION_TRANSITION_RECOVERY_SCHEMA ||
529
+ ![
530
+ PM_EXPLORATION_TRANSITION_RECOVERY_SCHEMA,
531
+ PM_EXPLORATION_SNAPSHOT_BOUND_TRANSITION_RECOVERY_SCHEMA,
532
+ ].includes(value.schema) ||
394
533
  value.authenticated !== true ||
395
534
  value.durable !== true ||
396
535
  value.readbackVerified !== true ||
397
536
  value.manifestDigest !== expectedManifestDigest ||
398
537
  !Number.isSafeInteger(value.revision) ||
399
538
  value.revision < 0 ||
400
- ![null, "success", "failure"].includes(value.transitionKind) ||
539
+ ![null, "success", "failure", "recovery"].includes(value.transitionKind) ||
401
540
  !DIGEST.test(value.ledgerHeadDigest ?? "") ||
402
541
  value.qualifiesForPromotion !== false
403
542
  ) {
@@ -405,6 +544,7 @@ function transitionRecovery(value, expectedManifestDigest) {
405
544
  }
406
545
  if (value.transitionKind === null) {
407
546
  if (
547
+ snapshotBound ||
408
548
  value.revision !== 0 ||
409
549
  value.evidenceDigest !== null ||
410
550
  value.evidence !== null ||
@@ -427,21 +567,34 @@ function transitionRecovery(value, expectedManifestDigest) {
427
567
  value.evidence,
428
568
  expectedManifestDigest,
429
569
  );
430
- const transitionKind =
431
- evidence.schema === PM_EXPLORATION_SUCCESS_TRANSITION_SCHEMA
432
- ? "success"
433
- : "failure";
434
- const evidenceDigest =
435
- transitionKind === "success"
436
- ? evidence.stateTransitionDigest
437
- : evidence.evidenceDigest;
570
+ const { transitionKind, evidenceDigest } = transitionBinding(evidence);
438
571
  if (
439
572
  value.transitionKind !== transitionKind ||
440
573
  value.evidenceDigest !== evidenceDigest
441
574
  ) {
442
575
  throw new Error("PM transition recovery evidence binding is invalid");
443
576
  }
444
- return deepFreeze({ ...value, evidence });
577
+ if (snapshotBound && transitionKind === "recovery") {
578
+ throw new Error(
579
+ "PM clone recovery event cannot carry a transition recovery snapshot",
580
+ );
581
+ }
582
+ const recoverySnapshot = snapshotBound
583
+ ? verifyPmExplorationRecoverySnapshotAck(value.recoverySnapshot, {
584
+ manifestDigest: expectedManifestDigest,
585
+ transitionKind,
586
+ evidenceDigest,
587
+ sealDigest:
588
+ transitionKind === "success"
589
+ ? evidence.postRunSeal.sealDigest
590
+ : evidence.preRunSeal.sealDigest,
591
+ })
592
+ : null;
593
+ return deepFreeze({
594
+ ...value,
595
+ evidence,
596
+ ...(snapshotBound ? { recoverySnapshot } : {}),
597
+ });
445
598
  }
446
599
 
447
600
  export function createPmExplorationTransitionCommitter(input = {}) {
@@ -493,14 +646,12 @@ export function capturePmExplorationTransitionCommitter(value) {
493
646
  input,
494
647
  captured.manifestDigest,
495
648
  );
496
- const transitionKind =
497
- evidence.schema === PM_EXPLORATION_SUCCESS_TRANSITION_SCHEMA
498
- ? "success"
499
- : "failure";
500
- const evidenceDigest =
501
- transitionKind === "success"
502
- ? evidence.stateTransitionDigest
503
- : evidence.evidenceDigest;
649
+ const { transitionKind, evidenceDigest } = transitionBinding(evidence);
650
+ if (transitionKind === "recovery" && recoverySnapshotInput !== null) {
651
+ throw new Error(
652
+ "PM clone recovery event cannot retain another recovery snapshot",
653
+ );
654
+ }
504
655
  const recoverySnapshot =
505
656
  recoverySnapshotInput === null
506
657
  ? null
@@ -1,6 +1,9 @@
1
1
  import { createHash } from "node:crypto";
2
2
 
3
- import { verifyEvolutionWorkbenchMetricsSnapshot } from "./evolution-workbench-metrics.js";
3
+ import {
4
+ EVOLUTION_WORKBENCH_METRICS_SNAPSHOT_SCHEMA,
5
+ verifyEvolutionWorkbenchMetricsSnapshot,
6
+ } from "./evolution-workbench-metrics.js";
4
7
  import { isEvolutionWorkbenchMetricsOutcomeReader } from "./evolution-workbench-metrics-ledger-adapter.js";
5
8
 
6
9
  export const SKILL_OUTCOME_INDEX_AUTHORITY_SCHEMA =
@@ -96,8 +99,9 @@ function inspectSource(adapter) {
96
99
  descriptor,
97
100
  );
98
101
  if (
99
- snapshot.outcomeHistoryComplete !== true &&
100
- snapshot.versions.length !== 0
102
+ snapshot.versions.length !== 0 &&
103
+ (snapshot.schema !== EVOLUTION_WORKBENCH_METRICS_SNAPSHOT_SCHEMA ||
104
+ snapshot.outcomeHistoryComplete !== true)
101
105
  ) {
102
106
  throw unavailable(
103
107
  "Skill outcome index requires a complete outcome backfill",
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Governance coverage metrics — the last open item of P1-9 ("覆盖率指标") in
3
- * docs/CLAUDE_CODE_IDE_INCREMENTAL_GAP_ANALYSIS_2026-07-13.md, and the
3
+ * docs/research/ide/CLAUDE_CODE_IDE_INCREMENTAL_GAP_ANALYSIS_2026-07-13.md, and the
4
4
  * computation behind two §11.3 acceptance targets:
5
5
  *
6
6
  * - "高风险 Tool Call Ledger/Trace 覆盖率:100%"
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Deterministic-headless manifest helpers (gap-analysis 2026-07-11,
3
- * docs/CLAUDE_CODE_CLI_GAP_ANALYSIS.md P0 "确定性 Headless").
3
+ * docs/research/cli/CLAUDE_CODE_CLI_GAP_ANALYSIS.md P0 "确定性 Headless").
4
4
  *
5
5
  * The stream-json init event carries a protocol version, whether this run
6
6
  * persists its session, which ambient customization sources are live, and
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Offline protocol replay — the last open pure item of P1-9 ("离线协议回放") in
3
- * docs/CLAUDE_CODE_IDE_INCREMENTAL_GAP_ANALYSIS_2026-07-13.md.
3
+ * docs/research/ide/CLAUDE_CODE_IDE_INCREMENTAL_GAP_ANALYSIS_2026-07-13.md.
4
4
  *
5
5
  * [[event-seq-replay.js]] replays for TRANSPORT reliability (re-send a gap over a
6
6
  * lossy socket). This module replays for PROTOCOL COMPAT: take a recorded
@@ -1,5 +1,6 @@
1
1
  import { createHash } from "node:crypto";
2
2
  import { EXPLORATION_TOOLS } from "./task-progress-tracker.js";
3
+ import { isToolRecoveryPaused } from "./tool-recovery-result.js";
3
4
  const MAX_FILES = 12;
4
5
 
5
6
  function keyFor(filePath, args) {
@@ -215,14 +216,10 @@ export class ReadFileLoopGuard {
215
216
  }
216
217
 
217
218
  record(tool, result, actionable = true) {
218
- if (
219
- this.batch &&
220
- tool === "read_file" &&
221
- result?.code === "CC_TOOL_RECOVERY_PAUSED"
222
- ) {
223
- this.batch.duplicates++;
224
- return;
225
- }
219
+ // The runtime denied this call before execution. Counting its own denial
220
+ // as another duplicate would immediately schedule another "one-turn"
221
+ // pause and prevent read_file from ever becoming available again.
222
+ if (isToolRecoveryPaused(result)) return;
226
223
  if (
227
224
  !this.batch ||
228
225
  result?.error ||
@@ -1,6 +1,7 @@
1
1
  import { createHash } from "node:crypto";
2
2
  import { diagnosticExcerpt } from "./diagnostic-excerpt.js";
3
3
  import { DIAGNOSTIC_WORKFLOW_GUIDANCE } from "./diagnostic-workflow.js";
4
+ import { isToolRecoveryPaused } from "./tool-recovery-result.js";
4
5
 
5
6
  const MAX_TARGETS = 32;
6
7
  const RECOVERY_AFTER = 3;
@@ -208,22 +209,14 @@ export class RemoteReadLoopGuard {
208
209
  this.activeKey = null;
209
210
  this.revision = 0;
210
211
  this.offeredRevision = 0;
212
+ this.pausedKey = null;
211
213
  }
212
214
 
213
215
  record(tool, result, args = {}) {
214
- if (result?.code === "CC_TOOL_RECOVERY_PAUSED") {
215
- // A provider can ignore omitted tool definitions. Count that attempt
216
- // without replacing the actual failure/evidence with our own denial.
217
- const key = remoteReadTarget(tool, args)?.key || this.activeKey;
218
- const entry = this.targets.get(key);
219
- if (entry?.tool === tool && entry.repeats >= RECOVERY_AFTER) {
220
- entry.repeats++;
221
- entry.recoveryOffered = true;
222
- this.activeKey = key;
223
- this.revision++;
224
- }
225
- return;
226
- }
216
+ // Preserve the last real error/evidence, but do not count a call that the
217
+ // runtime itself refused to execute. Otherwise a one-turn pause advances
218
+ // the retry counter and remains active forever.
219
+ if (isToolRecoveryPaused(result)) return;
227
220
  const failed = failedResult(result);
228
221
  const policy = result?.shellCommandPolicy;
229
222
  const gitRepositoryKey = `git-repository:${createHash("sha256")
@@ -421,10 +414,15 @@ export class RemoteReadLoopGuard {
421
414
  }
422
415
 
423
416
  takeRecoveryTurn() {
417
+ // Recovery narrowing lasts for exactly the model request for which it was
418
+ // offered. Calling this method at the next request clears the old target
419
+ // before deciding whether fresh real evidence warrants another pause.
420
+ this.pausedKey = null;
424
421
  if (!this.recoveryHint || this.offeredRevision === this.revision) return [];
425
422
  this.offeredRevision = this.revision;
426
423
  const entry = this.targets.get(this.activeKey);
427
424
  entry.recoveryOffered = true;
425
+ this.pausedKey = this.activeKey;
428
426
  // Keep the shell available for local reproduction and validation. Only
429
427
  // repeated reads of the stalled remote target are narrowed below.
430
428
  if (entry.tool === "run_shell" && entry.github) return [];
@@ -433,14 +431,23 @@ export class RemoteReadLoopGuard {
433
431
 
434
432
  shouldPause(tool, args = {}) {
435
433
  const target = remoteReadTarget(tool, args);
436
- const entry = target && this.targets.get(target.key);
437
- return !!(
438
- entry?.github &&
439
- entry.recoveryOffered &&
440
- entry.repeats >= RECOVERY_AFTER
434
+ return !!(target && target.key === this.pausedKey);
435
+ }
436
+
437
+ hasScopedContinuation(tool) {
438
+ return [...this.targets.values()].some(
439
+ (entry) =>
440
+ entry.tool === tool &&
441
+ (entry.repeats > 0 || entry.page?.hasMore === true),
441
442
  );
442
443
  }
443
444
 
445
+ canContinue(tool, args = {}) {
446
+ const target = remoteReadTarget(tool, args);
447
+ const entry = target && this.targets.get(target.key);
448
+ return !!(entry && (entry.repeats > 0 || entry.page?.hasMore === true));
449
+ }
450
+
444
451
  get workflowHint() {
445
452
  const active = this.targets.get(this.activeKey);
446
453
  if (active?.github && !active.pullRequest) {
@@ -7,10 +7,15 @@ import {
7
7
  } from "../harness/jsonl-session-store.js";
8
8
  import { canonicalJson } from "./scheduler-kernel/contract.js";
9
9
 
10
- const { verifySkillInvocationReceipt } = skillInvocationReceipt;
10
+ const {
11
+ inspectSkillInvocationReceiptCompatibility,
12
+ verifySkillInvocationReceipt,
13
+ } = skillInvocationReceipt;
11
14
 
12
- export const SKILL_OUTCOME_AUTHORITY_SCHEMA =
15
+ export const LEGACY_SKILL_OUTCOME_AUTHORITY_SCHEMA =
13
16
  "chainlesschain.skill-outcome-transcript-authority/v1";
17
+ export const SKILL_OUTCOME_AUTHORITY_SCHEMA =
18
+ "chainlesschain.skill-outcome-transcript-authority/v2";
14
19
  export const MAX_OUTCOME_AUTHORITY_SESSIONS = 128;
15
20
  export const MAX_OUTCOME_AUTHORITY_RECEIPTS = 10_000;
16
21
 
@@ -103,13 +108,16 @@ export function buildSkillOutcomeTranscriptAuthority(
103
108
  options.maxReceipts === undefined
104
109
  ? MAX_OUTCOME_AUTHORITY_RECEIPTS
105
110
  : Number(options.maxReceipts);
111
+ const expectedEnvironmentDigest = options.expectedEnvironmentDigest ?? null;
106
112
  if (
107
113
  !Number.isSafeInteger(maxSessions) ||
108
114
  maxSessions < 1 ||
109
115
  maxSessions > MAX_OUTCOME_AUTHORITY_SESSIONS ||
110
116
  !Number.isSafeInteger(maxReceipts) ||
111
117
  maxReceipts < 1 ||
112
- maxReceipts > MAX_OUTCOME_AUTHORITY_RECEIPTS
118
+ maxReceipts > MAX_OUTCOME_AUTHORITY_RECEIPTS ||
119
+ (expectedEnvironmentDigest !== null &&
120
+ !DIGEST.test(expectedEnvironmentDigest))
113
121
  ) {
114
122
  throw new TypeError("Skill outcome authority bounds are invalid");
115
123
  }
@@ -170,8 +178,30 @@ export function buildSkillOutcomeTranscriptAuthority(
170
178
  const totals = new Map();
171
179
  let attributionEligibleReceiptCount = 0;
172
180
  let outcomeEligibleReceiptCount = 0;
181
+ let legacyEnvironmentUnboundReceiptCount = 0;
182
+ let staleEnvironmentReceiptCount = 0;
183
+ let incompleteAttributionReceiptCount = 0;
173
184
  for (const receipt of uniqueReceipts.values()) {
174
- if (receipt.attributionEligible !== true) continue;
185
+ const compatibility = inspectSkillInvocationReceiptCompatibility(receipt, {
186
+ expectedEnvironmentDigest,
187
+ });
188
+ if (compatibility.legacyEnvironmentUnbound) {
189
+ legacyEnvironmentUnboundReceiptCount += 1;
190
+ } else if (!compatibility.environmentBoundAttributionEligible) {
191
+ incompleteAttributionReceiptCount += 1;
192
+ } else if (
193
+ expectedEnvironmentDigest !== null &&
194
+ !compatibility.currentEnvironmentEligible
195
+ ) {
196
+ staleEnvironmentReceiptCount += 1;
197
+ }
198
+ if (
199
+ !compatibility.environmentBoundAttributionEligible ||
200
+ (expectedEnvironmentDigest !== null &&
201
+ !compatibility.currentEnvironmentEligible)
202
+ ) {
203
+ continue;
204
+ }
175
205
  attributionEligibleReceiptCount += 1;
176
206
  const hasOutcomeEvidence =
177
207
  receipt.graderReceipts.length > 0 || receipt.userCorrectionRef !== null;
@@ -213,7 +243,12 @@ export function buildSkillOutcomeTranscriptAuthority(
213
243
  }))
214
244
  .sort((left, right) => left.sessionId.localeCompare(right.sessionId));
215
245
  const sourceDigest = `sha256:${createHash("sha256")
216
- .update(`${SKILL_OUTCOME_AUTHORITY_SCHEMA}\0${canonicalJson(source)}`)
246
+ .update(
247
+ `${SKILL_OUTCOME_AUTHORITY_SCHEMA}\0${canonicalJson({
248
+ source,
249
+ expectedEnvironmentDigest,
250
+ })}`,
251
+ )
217
252
  .digest("hex")}`;
218
253
  return Object.freeze({
219
254
  schema: SKILL_OUTCOME_AUTHORITY_SCHEMA,
@@ -228,6 +263,11 @@ export function buildSkillOutcomeTranscriptAuthority(
228
263
  uniqueReceiptCount: uniqueReceipts.size,
229
264
  attributionEligibleReceiptCount,
230
265
  outcomeEligibleReceiptCount,
266
+ legacyEnvironmentUnboundReceiptCount,
267
+ staleEnvironmentReceiptCount,
268
+ incompleteAttributionReceiptCount,
269
+ environmentPolicy:
270
+ expectedEnvironmentDigest === null ? "bound" : "current",
231
271
  duplicateReceiptCount,
232
272
  maxSessions,
233
273
  maxReceipts,
@@ -0,0 +1,11 @@
1
+ export const TOOL_RECOVERY_PAUSED_CODE = "CC_TOOL_RECOVERY_PAUSED";
2
+
3
+ /**
4
+ * A recovery pause is a synthetic runtime result: the requested tool never
5
+ * executed and therefore produced no new evidence about the underlying task.
6
+ * Loop guards must not feed that result back into their retry counters, or a
7
+ * one-turn pause becomes a self-sustaining recovery loop.
8
+ */
9
+ export function isToolRecoveryPaused(result) {
10
+ return result?.code === TOOL_RECOVERY_PAUSED_CODE;
11
+ }
@@ -39,6 +39,7 @@ import {
39
39
  TaskProgressTracker,
40
40
  TASK_RECOVERY_TOOLS,
41
41
  } from "../lib/task-progress-tracker.js";
42
+ import { TOOL_RECOVERY_PAUSED_CODE } from "../lib/tool-recovery-result.js";
42
43
  import broker from "../lib/process-execution-broker/index.js";
43
44
  import os from "os";
44
45
  import { createHash, randomUUID } from "node:crypto";
@@ -8258,6 +8259,22 @@ async function executeToolInner(
8258
8259
  }),
8259
8260
  )
8260
8261
  .digest("hex")}`;
8262
+ const invocationEnvironmentDigest =
8263
+ runtimeEligibility?.binding?.environmentDigest ||
8264
+ `sha256:${createHash("sha256")
8265
+ .update("chainlesschain.cli-skill-invocation-environment/v1\0")
8266
+ .update(
8267
+ JSON.stringify({
8268
+ node: process.versions.node,
8269
+ platform: process.platform,
8270
+ arch: process.arch,
8271
+ provider: llmOptions?.provider ?? null,
8272
+ model: llmOptions?.model ?? null,
8273
+ toolSetDigest,
8274
+ policyDigest,
8275
+ }),
8276
+ )
8277
+ .digest("hex")}`;
8261
8278
  const invocationStartedAt = Date.now();
8262
8279
  const invocationStart = startSkillInvocation({
8263
8280
  attributionRequired: ["automatic-candidate", "canary"].includes(
@@ -8281,6 +8298,7 @@ async function executeToolInner(
8281
8298
  toolSetDigest,
8282
8299
  osSandboxPermissionPolicyDigest: policyDigest,
8283
8300
  taskCohort: "cli:run_skill",
8301
+ environmentDigest: invocationEnvironmentDigest,
8284
8302
  });
8285
8303
  const settleInvocation = (executionStatus, result = {}) =>
8286
8304
  settleSkillInvocation(invocationStart, {
@@ -14997,7 +15015,9 @@ export async function* agentLoop(messages, options) {
14997
15015
  // known, explicitly bounded section. Admission below still rejects broad
14998
15016
  // new-file reads and repeated covered ranges.
14999
15017
  const taskRecoveryTools = TASK_RECOVERY_TOOLS.filter(
15000
- (tool) => tool !== "read_file",
15018
+ (tool) =>
15019
+ tool !== "read_file" &&
15020
+ !remoteReadLoopGuard.hasScopedContinuation(tool),
15001
15021
  );
15002
15022
  const readToolRecoveryPaused =
15003
15023
  readRecoveryTurn &&
@@ -15926,10 +15946,13 @@ export async function* agentLoop(messages, options) {
15926
15946
  path.resolve(toolContext.cwd || process.cwd(), toolArgs.path),
15927
15947
  toolArgs,
15928
15948
  )
15929
- ))
15949
+ )) ||
15950
+ (taskRecoveryTurn &&
15951
+ (toolName === "web_fetch" || toolName === "web_search") &&
15952
+ !remoteReadLoopGuard.canContinue(toolName, toolArgs))
15930
15953
  ? {
15931
15954
  success: false,
15932
- code: "CC_TOOL_RECOVERY_PAUSED",
15955
+ code: TOOL_RECOVERY_PAUSED_CODE,
15933
15956
  error: `${toolName} is paused for loop recovery and was not executed. Use retained findings for an authorized action or report the specific blocker; do not repeat or disguise this call.`,
15934
15957
  }
15935
15958
  : null) ||
@@ -1 +0,0 @@
1
- import{I as v,P as u,J as S,U as n,R as a,S as y,K as C,Q as x,V as w,_ as B,b as s}from"./vendor-Bn1JzzAn.js";import{_ as k}from"./index-D5Rvq67L.js";import"./icons-DG5UD-6K.js";const N={__name:"ChatBubbleRenderer",props:{event:{type:Object,required:!0}},setup(c,{expose:d}){d();const t=c,r=s(()=>{const e=t.event.content||{};return e.text||e.body||e.message||e.title||JSON.stringify(e).slice(0,200)}),i=s(()=>{const e=t.event.content||{};return e.from||e.sender||e.senderName||t.event.actor||"(unknown)"}),l=s(()=>{const e=(t.event.actor||"").toLowerCase();return e.includes("self")||e==="me"||e.endsWith("_self")}),o=s(()=>{const e=t.event.source.adapter||"";return e.startsWith("messaging-qq")?"magenta":e==="wechat"?"green":"blue"}),m=s(()=>{if(!t.event.occurredAt)return"";try{const e=new Date(t.event.occurredAt),p=e.getFullYear(),b=String(e.getMonth()+1).padStart(2,"0"),f=String(e.getDate()).padStart(2,"0"),g=String(e.getHours()).padStart(2,"0"),h=String(e.getMinutes()).padStart(2,"0");return`${p}-${b}-${f} ${g}:${h}`}catch{return""}}),_={props:t,messageText:r,actorLabel:i,isMine:l,adapterColor:o,formattedTime:m,computed:s};return Object.defineProperty(_,"__isScriptSetup",{enumerable:!1,value:!0}),_}},T={class:"bubble"},M={class:"meta"},R={class:"actor"},V={class:"time"},q={class:"body"};function D(c,d,t,r,i,l){const o=v("a-tag");return u(),S("div",{class:B(["chat-row",{mine:r.isMine}])},[n("div",T,[n("div",M,[n("span",R,a(r.actorLabel),1),n("span",V,a(r.formattedTime),1)]),n("div",q,a(r.messageText),1),t.event.source.adapter?(u(),y(o,{key:0,class:"src",color:r.adapterColor},{default:C(()=>[x(a(t.event.source.adapter),1)]),_:1},8,["color"])):w("v-if",!0)])],2)}const A=k(N,[["render",D],["__scopeId","data-v-49238629"],["__file","/tmp/cc-web-panel-210eXb/repo/packages/web-panel/src/components/pdh/renderers/ChatBubbleRenderer.vue"]]);export{A as default};