chainlesschain 0.166.99 → 0.166.101

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 (176) hide show
  1. package/README.md +7 -8
  2. package/package.json +2 -2
  3. package/src/assets/linux-subreaper/linux-arm64/manifest.json +1 -1
  4. package/src/assets/linux-subreaper/linux-x64/manifest.json +1 -1
  5. package/src/assets/web-panel/assets/{AIOps-BUgaCgVU.js → AIOps-BjBS_29I.js} +1 -1
  6. package/src/assets/web-panel/assets/{ActionButton-b0MpUSSZ.js → ActionButton-CUnnQUaj.js} +1 -1
  7. package/src/assets/web-panel/assets/{Analytics-hbXTvHqO.js → Analytics-BqYZxgnY.js} +3 -3
  8. package/src/assets/web-panel/assets/{AppLayout-CLQoAVu4.js → AppLayout-m8B886ka.js} +4 -4
  9. package/src/assets/web-panel/assets/{Artifacts-ytHzl2L2.js → Artifacts-JEOxU3Ug.js} +1 -1
  10. package/src/assets/web-panel/assets/{Audit-BuhkLm0C.js → Audit-DAXS5c9J.js} +1 -1
  11. package/src/assets/web-panel/assets/{BackgroundAgents-CS81hxZV.js → BackgroundAgents-e3a9XHw3.js} +1 -1
  12. package/src/assets/web-panel/assets/{Backup-DzR-_Qvi.js → Backup-D3Qmp68h.js} +1 -1
  13. package/src/assets/web-panel/assets/{BaseInput-r8Ku_lYw.js → BaseInput-C7CXyiUl.js} +1 -1
  14. package/src/assets/web-panel/assets/{Chat-C3Uxtoaa.js → Chat-2AHlAGi8.js} +6 -6
  15. package/src/assets/web-panel/assets/ChatBubbleRenderer-D3KsyCUV.js +1 -0
  16. package/src/assets/web-panel/assets/{Checkbox-BnG2P5yc.js → Checkbox-YfBuQlBH.js} +1 -1
  17. package/src/assets/web-panel/assets/{Codegen-BdgU6HZy.js → Codegen-DCCQDfTL.js} +1 -1
  18. package/src/assets/web-panel/assets/{Col-DT8t9wmf.js → Col-03i2WfrV.js} +1 -1
  19. package/src/assets/web-panel/assets/{Community-ChkxR5oe.js → Community-CJQIpng6.js} +1 -1
  20. package/src/assets/web-panel/assets/{Compact-DIwLeTk3.js → Compact-CCtcQ2pq.js} +1 -1
  21. package/src/assets/web-panel/assets/{Compliance-CAqzGLvW.js → Compliance-Vxl7ZszJ.js} +1 -1
  22. package/src/assets/web-panel/assets/{Cowork-Bb3jejMG.js → Cowork-DN-BwA8I.js} +2 -2
  23. package/src/assets/web-panel/assets/{Cron-BYRkZLta.js → Cron-Dc2Q46X7.js} +2 -2
  24. package/src/assets/web-panel/assets/{Crosschain-BD6z227t.js → Crosschain-CQCblsl-.js} +1 -1
  25. package/src/assets/web-panel/assets/{DID-DA3G5Wgo.js → DID-YYvqUR8C.js} +2 -2
  26. package/src/assets/web-panel/assets/{Dashboard-yaZePHOu.js → Dashboard-Cafy3DZT.js} +2 -2
  27. package/src/assets/web-panel/assets/{Dropdown-BqY5MBx2.js → Dropdown-BOyYpIpv.js} +1 -1
  28. package/src/assets/web-panel/assets/{EmailListRenderer-cIWwOgHm.js → EmailListRenderer-B7NYjc1j.js} +1 -1
  29. package/src/assets/web-panel/assets/{EvolutionSettings-zvV6ymca.js → EvolutionSettings-C5wfxztf.js} +1 -1
  30. package/src/assets/web-panel/assets/{FamilyGuardDashboard-CAmh1U2b.js → FamilyGuardDashboard-aA7KnDGK.js} +1 -1
  31. package/src/assets/web-panel/assets/{Federation-5qd2LCg8.js → Federation-DlgXUu1L.js} +1 -1
  32. package/src/assets/web-panel/assets/{FormItemContext-Bdkj1sRJ.js → FormItemContext-B5YsrLDg.js} +1 -1
  33. package/src/assets/web-panel/assets/{GenericCardRenderer-B-gWN2P3.js → GenericCardRenderer-DaWojPFw.js} +1 -1
  34. package/src/assets/web-panel/assets/{Git-BEMh_NGd.js → Git-dkhh6Fx2.js} +2 -2
  35. package/src/assets/web-panel/assets/{Governance-qLGvA2Hw.js → Governance-Cz6vmkjc.js} +1 -1
  36. package/src/assets/web-panel/assets/{Inference-DblBwYuW.js → Inference-DWt0hbh8.js} +1 -1
  37. package/src/assets/web-panel/assets/{KnowledgeGraph-BISegVD_.js → KnowledgeGraph-BZJ0Z-nL.js} +1 -1
  38. package/src/assets/web-panel/assets/Logs-BaBBmL1A.js +2 -0
  39. package/src/assets/web-panel/assets/MarkdownRenderer-C1yByobo.js +1 -0
  40. package/src/assets/web-panel/assets/{Marketplace-CHKXMOkH.js → Marketplace-ct8sgQ0s.js} +1 -1
  41. package/src/assets/web-panel/assets/{McpTools-B5G1elqd.js → McpTools-CXKCRGYQ.js} +3 -3
  42. package/src/assets/web-panel/assets/{Memory-O5Ib0uTR.js → Memory-O7ZwlS6a.js} +2 -2
  43. package/src/assets/web-panel/assets/{MobileBridge-BaGYL7rT.js → MobileBridge-By12C-eC.js} +1 -1
  44. package/src/assets/web-panel/assets/MobileProjects-Ba-EVdex.js +1 -0
  45. package/src/assets/web-panel/assets/{Mtc-CNjJ97jg.js → Mtc-g-932zV2.js} +2 -2
  46. package/src/assets/web-panel/assets/{MtcAudit-DjBN-Wqz.js → MtcAudit-BW8hB0ly.js} +4 -4
  47. package/src/assets/web-panel/assets/{Multisig-B850R9lO.js → Multisig-zspLaMbT.js} +3 -3
  48. package/src/assets/web-panel/assets/{NLProgramming-Bn8sbFfV.js → NLProgramming-dJeUPDoq.js} +1 -1
  49. package/src/assets/web-panel/assets/{Notes-BpLmMp3Q.js → Notes-C4msiRQL.js} +3 -3
  50. package/src/assets/web-panel/assets/{NotificationSettings-Dbk97rjb.js → NotificationSettings-MOCHM-qg.js} +1 -1
  51. package/src/assets/web-panel/assets/{OrderTableRenderer-BOBX_I72.js → OrderTableRenderer-CX0T66NM.js} +1 -1
  52. package/src/assets/web-panel/assets/{Organization-B45DpOuE.js → Organization-DOZurBfk.js} +4 -4
  53. package/src/assets/web-panel/assets/{Overflow-DmKH7eer.js → Overflow-qOT9BhUp.js} +1 -1
  54. package/src/assets/web-panel/assets/{P2P-CC4FaXTl.js → P2P-BMoy7Eo4.js} +2 -2
  55. package/src/assets/web-panel/assets/{PdhVaultBrowser-C2SgP4PI.js → PdhVaultBrowser-ByyV1q-D.js} +3 -3
  56. package/src/assets/web-panel/assets/{Permissions-BQB4QFj_.js → Permissions-6Qyro4ye.js} +4 -4
  57. package/src/assets/web-panel/assets/{PersonalDataHub-Dy6GGpn4.js → PersonalDataHub-DR3DRNSX.js} +4 -4
  58. package/src/assets/web-panel/assets/{Pipeline-B9HB5pRc.js → Pipeline-Cr6TTdud.js} +1 -1
  59. package/src/assets/web-panel/assets/{Privacy-D7pOmg-p.js → Privacy-B70otG0l.js} +1 -1
  60. package/src/assets/web-panel/assets/{ProjectInit-DglBqvec.js → ProjectInit-BHCqxoSk.js} +2 -2
  61. package/src/assets/web-panel/assets/{ProjectSettings-Bho22znM.js → ProjectSettings-B80GZpZk.js} +2 -2
  62. package/src/assets/web-panel/assets/{Projects-C0bSuM8U.js → Projects-cq-b9-fQ.js} +1 -1
  63. package/src/assets/web-panel/assets/{Providers-BgAgo1Yr.js → Providers-dsVTimHa.js} +1 -1
  64. package/src/assets/web-panel/assets/{QrScannerModal-C2fBjCC8.js → QrScannerModal-DRJ8YepZ.js} +1 -1
  65. package/src/assets/web-panel/assets/{QuickAsk-C8MiF-rk.js → QuickAsk-BSXdEjIB.js} +1 -1
  66. package/src/assets/web-panel/assets/{Recommend-D_TzHdQf.js → Recommend-CQLJGyKC.js} +1 -1
  67. package/src/assets/web-panel/assets/{RemoteSession-BHO7b6xE.js → RemoteSession-BF9WUFVZ.js} +2 -2
  68. package/src/assets/web-panel/assets/{Reputation-BPxNmNhD.js → Reputation-Cy9o5tvW.js} +1 -1
  69. package/src/assets/web-panel/assets/{Row-fwhot5Bk.js → Row-BP346_3b.js} +1 -1
  70. package/src/assets/web-panel/assets/{RssFeed-CZbD1B-5.js → RssFeed-BKulxXf3.js} +3 -3
  71. package/src/assets/web-panel/assets/{Search-BRs6YpAE.js → Search-EemQj2Dv.js} +1 -1
  72. package/src/assets/web-panel/assets/{Security-CB344tKC.js → Security-DcWPAwwk.js} +4 -4
  73. package/src/assets/web-panel/assets/{Services-Beo-7fEl.js → Services-Bltqciay.js} +2 -2
  74. package/src/assets/web-panel/assets/{Skeleton-CDXx96vD.js → Skeleton-BwRyOGY8.js} +1 -1
  75. package/src/assets/web-panel/assets/{Skills-b-mQTJK4.js → Skills-D98qlvpJ.js} +1 -1
  76. package/src/assets/web-panel/assets/{Sla-BvjP-IS9.js → Sla-BUTtBMY0.js} +1 -1
  77. package/src/assets/web-panel/assets/{SpeechSettings-C6wsV-cO.js → SpeechSettings-C7kcY_98.js} +1 -1
  78. package/src/assets/web-panel/assets/{SyncSettings-BQZoko-e.js → SyncSettings-Bsk6lKvT.js} +2 -2
  79. package/src/assets/web-panel/assets/{Tasks-6Z0rJJVO.js → Tasks-DvSrtz0P.js} +1 -1
  80. package/src/assets/web-panel/assets/{Templates-Cc9IXtEQ.js → Templates-BUM6LwPs.js} +1 -1
  81. package/src/assets/web-panel/assets/{Tenant-BLc7AjOI.js → Tenant-D9TkOm7z.js} +1 -1
  82. package/src/assets/web-panel/assets/{Terminal-CUN49v85.js → Terminal-CP8ZVErN.js} +2 -2
  83. package/src/assets/web-panel/assets/{TimelineRenderer-CX-SksHN.js → TimelineRenderer-V3SoKZ1T.js} +1 -1
  84. package/src/assets/web-panel/assets/{Tokens-Btrm0-rK.js → Tokens-CCRlUTOA.js} +1 -1
  85. package/src/assets/web-panel/assets/{Trigger-CIboUvKe.js → Trigger-CznUcPme.js} +1 -1
  86. package/src/assets/web-panel/assets/{Trust-Rv9jEs5v.js → Trust-D1GIk_NF.js} +1 -1
  87. package/src/assets/web-panel/assets/{UkeySign-B_xomdD5.js → UkeySign-DHtvtyC-.js} +1 -1
  88. package/src/assets/web-panel/assets/{VideoEditing-CrvWeMow.js → VideoEditing-CVxdaJIq.js} +1 -1
  89. package/src/assets/web-panel/assets/{Wallet-BjvWgk_7.js → Wallet-D221OjyE.js} +4 -4
  90. package/src/assets/web-panel/assets/{WebAuthn-CwfpFw92.js → WebAuthn-Cw0-ESsq.js} +5 -5
  91. package/src/assets/web-panel/assets/{WorkflowEditor-Dkk2QsOe.js → WorkflowEditor-ZYScrBx3.js} +1 -1
  92. package/src/assets/web-panel/assets/{chat-Dah1DVes.js → chat-BU0e1obR.js} +1 -1
  93. package/src/assets/web-panel/assets/{colors-JEpgQ10k.js → colors-gzYweuha.js} +1 -1
  94. package/src/assets/web-panel/assets/{compact-item--DuG_cxf.js → compact-item-ChAXal_k.js} +1 -1
  95. package/src/assets/web-panel/assets/{createContext-BJ_GZvon.js → createContext-of3FolD7.js} +1 -1
  96. package/src/assets/web-panel/assets/devWarning-Pa13TVrO.js +1 -0
  97. package/src/assets/web-panel/assets/{hasIn-yZRLDmWK.js → hasIn-4PsK_Kx8.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-DQ4Fch3e.js → index-1dzYRBbg.js} +1 -1
  99. package/src/assets/web-panel/assets/{index-L9CFyRIi.js → index-B5L7zddz.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-DxnkldGo.js → index-BOeX7BzS.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-D6Le2m3d.js → index-BdxRVNPY.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-DaDLWIWo.js → index-BfI4dXbi.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-o2qO_dYf.js → index-Bftq5rJR.js} +1 -1
  104. package/src/assets/web-panel/assets/index-BhQg-v6V.js +1 -0
  105. package/src/assets/web-panel/assets/{index-DhX48E81.js → index-By-pper5.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-Bdg_nWD1.js → index-CCLsbul3.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-cHx5KzUt.js → index-CGFL59q4.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-DemMuw7n.js → index-CHv_63Cp.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-DZBesaCN.js → index-CO2owKe0.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-CxB49Mow.js → index-CeEE_SGZ.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-BKl40wrO.js → index-Cn1clrxx.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-VIgVth92.js → index-Cx4Z6nUl.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-kZE-K3ZO.js → index-CxzBcXOa.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-rkvSOceQ.js → index-CyDQNprx.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-Cmr0AzcK.js → index-D-Zss5KL.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-DddwZCT9.js → index-D1PGrfHE.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-BUjyj7qR.js → index-DDYj14Q4.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-CjuD8smQ.js → index-DEB5fQqG.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-asia_JPc.js → index-DEXBckNR.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-DFJbJ8rs.js → index-DEzjUgkl.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-CFj7ylAJ.js → index-DJVrzXtk.js} +1 -1
  122. package/src/assets/web-panel/assets/index-DUD5o-vW.js +1 -0
  123. package/src/assets/web-panel/assets/{index-DroaQypF.js → index-DZ0oKtBg.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-DbMGGcpZ.js → index-D_5LTPMH.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-IjOa5lYn.js → index-D_9k680X.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-vdTrEOj7.js → index-D_ialOHx.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-9L3Pg2tc.js → index-DjRAIRX7.js} +1 -1
  128. package/src/assets/web-panel/assets/{index-Dq-8PFhL.js → index-Djfgsjfy.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-CJLz3SpM.js → index-DsoV9rzn.js} +1 -1
  130. package/src/assets/web-panel/assets/{index-BWkKE8Oj.js → index-Dy0ojH6G.js} +3 -3
  131. package/src/assets/web-panel/assets/{index-C8nXkCMf.js → index-E8oDMSAo.js} +1 -1
  132. package/src/assets/web-panel/assets/{index-C56b8e9s.js → index-Ef5YkVAn.js} +1 -1
  133. package/src/assets/web-panel/assets/{index-C6ohEAEV.js → index-Wr91cnWr.js} +1 -1
  134. package/src/assets/web-panel/assets/{index-1QZASeW1.js → index-cFkMIx1x.js} +1 -1
  135. package/src/assets/web-panel/assets/{index-BM7xJKGD.js → index-wo0De0iG.js} +1 -1
  136. package/src/assets/web-panel/assets/{index-CQedFuDw.js → index-yMf7zmWv.js} +1 -1
  137. package/src/assets/web-panel/assets/{initDefaultProps-anKyyjGc.js → initDefaultProps-D0Bx6pgr.js} +1 -1
  138. package/src/assets/web-panel/assets/{motion-Cqp0nx5A.js → motion-BnLuJqJ5.js} +1 -1
  139. package/src/assets/web-panel/assets/{move-Ca3mgkM2.js → move-Bxpq9xgR.js} +1 -1
  140. package/src/assets/web-panel/assets/{mtc-parser-BmwuhJ3z.js → mtc-parser-BdmrNhOs.js} +1 -1
  141. package/src/assets/web-panel/assets/{omit-C9Mf05WJ.js → omit-tjJD34BZ.js} +1 -1
  142. package/src/assets/web-panel/assets/{pickAttrs-2PbxB9Ds.js → pickAttrs-CMFzLt7b.js} +1 -1
  143. package/src/assets/web-panel/assets/{placementArrow-CTVbOFHt.js → placementArrow-BZf6O3cd.js} +1 -1
  144. package/src/assets/web-panel/assets/{responsiveObserve-Nrm8Vbmr.js → responsiveObserve-DFDLazsV.js} +1 -1
  145. package/src/assets/web-panel/assets/{slide-Dh4r1zqR.js → slide-CMbTvp4Y.js} +1 -1
  146. package/src/assets/web-panel/assets/{statusUtils-vzNoQL-r.js → statusUtils-FOan8MI7.js} +1 -1
  147. package/src/assets/web-panel/assets/{styleChecker-BXpGfNkI.js → styleChecker-DTABspd4.js} +1 -1
  148. package/src/assets/web-panel/assets/{useFlexGapSupport-CVWBRdhs.js → useFlexGapSupport-CNHXWBpY.js} +1 -1
  149. package/src/assets/web-panel/assets/{useFs-BJWMLffI.js → useFs-5K-c_RoL.js} +1 -1
  150. package/src/assets/web-panel/assets/{usePersonalDataHub-CWCe5VHG.js → usePersonalDataHub-Di0hL4G-.js} +1 -1
  151. package/src/assets/web-panel/assets/{vnode-D-NBEb8m.js → vnode-DTyDv4ja.js} +1 -1
  152. package/src/assets/web-panel/assets/{zoom-C0mnhfGf.js → zoom-ontRt8ft.js} +1 -1
  153. package/src/assets/web-panel/index.html +1 -1
  154. package/src/commands/eval.js +11 -8
  155. package/src/data/changelog.json +26 -0
  156. package/src/harness/provider-backed-compaction.js +13 -5
  157. package/src/harness/worktree-isolator.js +20 -8
  158. package/src/lib/chat-core.js +57 -25
  159. package/src/lib/context-memory-kernel/live-compaction.js +142 -61
  160. package/src/lib/eval/verify01-execution-window.js +70 -0
  161. package/src/lib/eval/verify01-execution.js +9 -1
  162. package/src/lib/eval/verify01-host-capture.js +6 -2
  163. package/src/lib/formal-budget-authority.js +533 -0
  164. package/src/lib/formal-budget-contract.js +609 -0
  165. package/src/lib/formal-budget-transport.js +345 -0
  166. package/src/lib/provider-http-error.js +16 -0
  167. package/src/lib/stream-retry.js +195 -1
  168. package/src/runtime/agent-core.js +272 -32
  169. package/src/runtime/headless-stream.js +136 -4
  170. package/src/assets/web-panel/assets/ChatBubbleRenderer-RvblDu77.js +0 -1
  171. package/src/assets/web-panel/assets/Logs-BD2UR7kE.js +0 -2
  172. package/src/assets/web-panel/assets/MarkdownRenderer-B-TlDCmr.js +0 -1
  173. package/src/assets/web-panel/assets/MobileProjects-Dsctbob8.js +0 -1
  174. package/src/assets/web-panel/assets/devWarning-B6kQEceX.js +0 -1
  175. package/src/assets/web-panel/assets/index-CSeiH6HA.js +0 -1
  176. package/src/assets/web-panel/assets/index-CayGTz6d.js +0 -1
@@ -2,6 +2,7 @@ import { randomUUID } from "node:crypto";
2
2
  import {
3
3
  canonicalDigest,
4
4
  InMemorySessionContextPort,
5
+ getCompactionPlanRejection,
5
6
  } from "@chainlesschain/context-memory-kernel";
6
7
  import { sessionExists } from "../../harness/jsonl-session-store.js";
7
8
  import {
@@ -11,6 +12,17 @@ import {
11
12
  } from "./message-adapter.js";
12
13
  import { JsonlSessionContextPort } from "./jsonl-session-context-port.js";
13
14
  import { createCliContextMemoryRuntime } from "./runtime.js";
15
+ import { projectRuntimeTokenUsage } from "../runtime-usage-ledger.js";
16
+
17
+ const rejectedCompactionUsage = new WeakMap();
18
+
19
+ // Only the owned canonical adapter can associate an error with its completed
20
+ // summarizer. A caller-supplied error property is never a settlement authority.
21
+ export function getRejectedCompactionUsage(error) {
22
+ return error && typeof error === "object"
23
+ ? rejectedCompactionUsage.get(error) || null
24
+ : null;
25
+ }
14
26
 
15
27
  function estimatedTokens(messages) {
16
28
  return Math.max(
@@ -20,7 +32,9 @@ function estimatedTokens(messages) {
20
32
  typeof message?.content === "string"
21
33
  ? message.content
22
34
  : JSON.stringify(message?.content ?? "");
23
- return total + Math.max(1, Math.ceil(Buffer.byteLength(content, "utf8") / 4));
35
+ return (
36
+ total + Math.max(1, Math.ceil(Buffer.byteLength(content, "utf8") / 4))
37
+ );
24
38
  }, 0),
25
39
  );
26
40
  }
@@ -125,13 +139,22 @@ class CallbackSessionContextPort extends InMemorySessionContextPort {
125
139
  }
126
140
 
127
141
  function kernelBudget(compressor) {
128
- const inputBudget = Math.max(256, Math.trunc(Number(compressor?.maxTokens)) || 16_384);
129
- const reservedOutputTokens = Math.max(1, Math.min(2048, Math.floor(inputBudget / 10)));
142
+ const inputBudget = Math.max(
143
+ 256,
144
+ Math.trunc(Number(compressor?.maxTokens)) || 16_384,
145
+ );
146
+ const reservedOutputTokens = Math.max(
147
+ 1,
148
+ Math.min(2048, Math.floor(inputBudget / 10)),
149
+ );
130
150
  return {
131
151
  modelWindowTokens: inputBudget + reservedOutputTokens,
132
152
  reservedOutputTokens,
133
153
  safetyMarginTokens: 0,
134
- recoveryReserveTokens: Math.min(256, Math.max(1, Math.floor(inputBudget * 0.05))),
154
+ recoveryReserveTokens: Math.min(
155
+ 256,
156
+ Math.max(1, Math.floor(inputBudget * 0.05)),
157
+ ),
135
158
  };
136
159
  }
137
160
 
@@ -175,7 +198,10 @@ function usageReceipt(stats, provider, model) {
175
198
  * summarizer for the Kernel-selected dropped partition; it cannot commit or
176
199
  * choose the authoritative output on its own.
177
200
  */
178
- export async function compactLiveMessagesCanonical(messagesInput, options = {}) {
201
+ export async function compactLiveMessagesCanonical(
202
+ messagesInput,
203
+ options = {},
204
+ ) {
179
205
  const messages = Array.isArray(messagesInput) ? [...messagesInput] : [];
180
206
  const sessionId = String(options.sessionId || `live-${randomUUID()}`);
181
207
  const operationId = String(options.operationId || `compact-${randomUUID()}`);
@@ -185,10 +211,13 @@ export async function compactLiveMessagesCanonical(messagesInput, options = {})
185
211
  new Date(Number((options.clock || Date.now)())).toISOString();
186
212
  const compressor = options.compressor;
187
213
  if (!compressor || typeof compressor.compress !== "function") {
188
- throw new TypeError("canonical live compaction requires a compatibility summarizer");
214
+ throw new TypeError(
215
+ "canonical live compaction requires a compatibility summarizer",
216
+ );
189
217
  }
190
218
 
191
219
  let summaryStats = null;
220
+ let summaryReceipt = null;
192
221
  let runtime;
193
222
  let verifiedAuthoritySnapshot = null;
194
223
  const persistentSession =
@@ -227,9 +256,7 @@ export async function compactLiveMessagesCanonical(messagesInput, options = {})
227
256
  memoryPort: bootstrapRuntime.memoryPort,
228
257
  sessionPort,
229
258
  });
230
- } else if (
231
- persistentSession
232
- ) {
259
+ } else if (persistentSession) {
233
260
  runtime = createCliContextMemoryRuntime({
234
261
  sessionId,
235
262
  scopeKey: `cli:session:${sessionId}`,
@@ -265,13 +292,13 @@ export async function compactLiveMessagesCanonical(messagesInput, options = {})
265
292
  });
266
293
  }
267
294
  if (!runtime.decision.canonical) {
268
- const error = new Error("canonical live compaction is not authoritative for this cohort");
295
+ const error = new Error(
296
+ "canonical live compaction is not authoritative for this cohort",
297
+ );
269
298
  error.code = "legacy_writer_fenced";
270
299
  throw error;
271
300
  }
272
- if (
273
- persistentSession
274
- ) {
301
+ if (persistentSession) {
275
302
  const authority =
276
303
  verifiedAuthoritySnapshot ||
277
304
  (await runtime.sessionPort.readSnapshot(sessionId));
@@ -296,52 +323,102 @@ export async function compactLiveMessagesCanonical(messagesInput, options = {})
296
323
  const provider = options.provider || "provider.local";
297
324
  const model = options.model || "default";
298
325
  const memoryRevision = await runtime.memoryPort.getRevision();
299
- const receipt = await runtime.kernel.compactContext({
300
- operationId,
301
- sessionId,
302
- ...kernelBudget(compressor),
303
- sink: provider,
304
- scopeAdmissions: [{ scope: "session", scopeId: sessionId }],
305
- policyVersion: "cli-context-policy-v1",
306
- modelProfile: model,
307
- memoryRevision,
308
- allowFallback: false,
309
- now: operationNow,
310
- metadata: {
311
- inputMessageCount: messages.length,
312
- originalTokens: estimatedTokens(messages),
313
- trigger,
314
- provider,
315
- model,
316
- },
317
- summarizer: async (droppedItems, context) => {
318
- const droppedMessages = contextItemsToMessages(droppedItems);
319
- const result = await compressor.compress(droppedMessages, {
320
- preserveToolPairs: true,
321
- ...(options.compressOptions || {}),
322
- });
323
- summaryStats = result.stats || {};
324
- const reduced =
325
- Number(summaryStats.saved || 0) > 0 ||
326
- result.messages.length < droppedMessages.length;
327
- const item = reduced
328
- ? createSummaryContextItem({
329
- messages: result.messages,
330
- parents: droppedItems,
331
- operationId: context.operationId,
332
- now: operationNow,
333
- })
334
- : null;
335
- return {
336
- items: item ? [item] : [],
337
- usageReceipt: usageReceipt(summaryStats, provider, model),
338
- degraded: summaryStats.degraded === true,
339
- ...(summaryStats.degradedReason
340
- ? { degradedReason: String(summaryStats.degradedReason).slice(0, 160) }
341
- : {}),
342
- };
343
- },
344
- });
326
+ let receipt;
327
+ try {
328
+ receipt = await runtime.kernel.compactContext({
329
+ operationId,
330
+ sessionId,
331
+ ...kernelBudget(compressor),
332
+ sink: provider,
333
+ scopeAdmissions: [{ scope: "session", scopeId: sessionId }],
334
+ policyVersion: "cli-context-policy-v1",
335
+ modelProfile: model,
336
+ memoryRevision,
337
+ allowFallback: false,
338
+ now: operationNow,
339
+ metadata: {
340
+ inputMessageCount: messages.length,
341
+ originalTokens: estimatedTokens(messages),
342
+ trigger,
343
+ provider,
344
+ model,
345
+ },
346
+ summarizer: async (droppedItems, context) => {
347
+ const droppedMessages = contextItemsToMessages(droppedItems);
348
+ const result = await compressor.compress(droppedMessages, {
349
+ preserveToolPairs: true,
350
+ ...(options.compressOptions || {}),
351
+ });
352
+ summaryStats = result.stats || {};
353
+ summaryReceipt = usageReceipt(summaryStats, provider, model);
354
+ const reduced =
355
+ Number(summaryStats.saved || 0) > 0 ||
356
+ result.messages.length < droppedMessages.length;
357
+ const item = reduced
358
+ ? createSummaryContextItem({
359
+ messages: result.messages,
360
+ parents: droppedItems,
361
+ operationId: context.operationId,
362
+ now: operationNow,
363
+ })
364
+ : null;
365
+ return {
366
+ items: item ? [item] : [],
367
+ usageReceipt: summaryReceipt,
368
+ degraded: summaryStats.degraded === true,
369
+ ...(summaryStats.degradedReason
370
+ ? {
371
+ degradedReason: String(summaryStats.degradedReason).slice(
372
+ 0,
373
+ 160,
374
+ ),
375
+ }
376
+ : {}),
377
+ };
378
+ },
379
+ });
380
+ } catch (error) {
381
+ const rejection = getCompactionPlanRejection(error);
382
+ if (
383
+ rejection?.operationId === operationId &&
384
+ rejection.sessionId === sessionId &&
385
+ summaryReceipt !== null &&
386
+ rejection.usageReceipt &&
387
+ canonicalDigest(rejection.usageReceipt) ===
388
+ canonicalDigest(summaryReceipt) &&
389
+ summaryStats?.summaryUsageUnknown !== true
390
+ ) {
391
+ try {
392
+ const usage = projectRuntimeTokenUsage({
393
+ ...(summaryStats.summaryCallId
394
+ ? { callId: summaryStats.summaryCallId }
395
+ : {}),
396
+ provider: summaryStats.summaryProvider || provider,
397
+ model: summaryStats.summaryModel || model,
398
+ source: "semantic-compaction",
399
+ usage: {
400
+ input_tokens: summaryStats.summaryUsage?.inputTokens,
401
+ output_tokens: summaryStats.summaryUsage?.outputTokens,
402
+ cache_read_input_tokens:
403
+ summaryStats.summaryUsage?.cacheReadTokens ?? 0,
404
+ cache_creation_input_tokens:
405
+ summaryStats.summaryUsage?.cacheCreationTokens ?? 0,
406
+ },
407
+ });
408
+ rejectedCompactionUsage.set(
409
+ error,
410
+ Object.freeze({
411
+ ...usage,
412
+ usage: Object.freeze(usage.usage),
413
+ receipt: Object.freeze({ ...summaryReceipt }),
414
+ }),
415
+ );
416
+ } catch {
417
+ // Missing or invalid usage retains the caller's unknown outcome path.
418
+ }
419
+ }
420
+ throw error;
421
+ }
345
422
  if (!["committed", "degraded"].includes(receipt.status)) {
346
423
  return {
347
424
  messages,
@@ -361,12 +438,16 @@ export async function compactLiveMessagesCanonical(messagesInput, options = {})
361
438
  messages: outputMessages,
362
439
  stats: {
363
440
  ...(summaryStats || {}),
364
- strategy: receipt.status === "degraded" ? "deterministic-fallback" : "canonical",
441
+ strategy:
442
+ receipt.status === "degraded" ? "deterministic-fallback" : "canonical",
365
443
  originalMessages: messages.length,
366
444
  compressedMessages: outputMessages.length,
367
445
  originalTokens: estimatedTokens(messages),
368
446
  compressedTokens: estimatedTokens(outputMessages),
369
- saved: Math.max(0, estimatedTokens(messages) - estimatedTokens(outputMessages)),
447
+ saved: Math.max(
448
+ 0,
449
+ estimatedTokens(messages) - estimatedTokens(outputMessages),
450
+ ),
370
451
  canonicalAlreadySettled: true,
371
452
  canonicalReceipt: receipt,
372
453
  },
@@ -0,0 +1,70 @@
1
+ function windowError(code, message) {
2
+ return Object.assign(new Error(`VERIFY-01 ${message}`), { code });
3
+ }
4
+
5
+ function timestamp(value) {
6
+ if (typeof value !== "string") return NaN;
7
+ // Frozen windows need an explicit timezone, valid calendar date, and at
8
+ // most millisecond precision. Date.parse alone normalizes February 30 and
9
+ // accepts local-time/numeric strings that are not suitable for admission.
10
+ const match =
11
+ /^(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2})(?:\.(\d{1,3}))?(Z|[+-]\d{2}:\d{2})$/u.exec(
12
+ value,
13
+ );
14
+ if (!match) return NaN;
15
+ const localUtc = `${match[1]}.${(match[2] || "").padEnd(3, "0")}Z`;
16
+ const localTime = Date.parse(localUtc);
17
+ if (
18
+ !Number.isFinite(localTime) ||
19
+ new Date(localTime).toISOString() !== localUtc
20
+ )
21
+ return NaN;
22
+ return Date.parse(value);
23
+ }
24
+
25
+ /**
26
+ * Admission immediately before a formal task starts or launches its agent.
27
+ * This pure guard neither executes a task nor records an observation. It does
28
+ * not establish human approval, account funding, or a provider spend limit.
29
+ * Call with the full frozen task budget at task start; recheck with the
30
+ * remaining required time at dispatch if preparation can span a window edge.
31
+ */
32
+ export function assertVerify01ExecutionWindow(
33
+ plan,
34
+ { now = Date.now(), requiredTimeMs = 0 } = {},
35
+ ) {
36
+ const start = timestamp(plan?.window?.start);
37
+ const end = timestamp(plan?.window?.end);
38
+ if (
39
+ !Number.isFinite(start) ||
40
+ !Number.isFinite(end) ||
41
+ start >= end ||
42
+ !Number.isFinite(now) ||
43
+ !Number.isFinite(requiredTimeMs) ||
44
+ requiredTimeMs < 0
45
+ ) {
46
+ throw windowError(
47
+ "CC_VERIFY01_WINDOW_INVALID",
48
+ "execution window, current time, and required task duration must be valid",
49
+ );
50
+ }
51
+ if (now < start) {
52
+ throw windowError(
53
+ "CC_VERIFY01_WINDOW_NOT_STARTED",
54
+ "execution window has not started; no task may be launched",
55
+ );
56
+ }
57
+ if (now >= end) {
58
+ throw windowError(
59
+ "CC_VERIFY01_WINDOW_EXPIRED",
60
+ "execution window has expired; no task may be launched",
61
+ );
62
+ }
63
+ if (requiredTimeMs > end - now) {
64
+ throw windowError(
65
+ "CC_VERIFY01_WINDOW_INSUFFICIENT_TIME",
66
+ "execution window cannot fit the required task time budget",
67
+ );
68
+ }
69
+ return { startedAt: now, windowEndMs: end };
70
+ }
@@ -15,6 +15,7 @@ import { createHash } from "node:crypto";
15
15
  import executionBroker from "../process-execution-broker/index.js";
16
16
  import { evalDigest, createEvalComparison } from "./evidence.js";
17
17
  import { outcomeDigest } from "./outcomes.js";
18
+ import { assertVerify01ExecutionWindow } from "./verify01-execution-window.js";
18
19
  import {
19
20
  readBytes,
20
21
  readJson,
@@ -30,7 +31,8 @@ export const VERIFY01_SUITES = [
30
31
  const agentBindings = new WeakSet();
31
32
  const EMPTY_DELIVERABLE_DIGEST = evalDigest(Buffer.alloc(0));
32
33
 
33
- function createAgentBinding(directory, allowedPaths, provider, model) {
34
+ function createAgentBinding(directory, allowedPaths, provider, model, window) {
35
+ assertVerify01ExecutionWindow({ window });
34
36
  const workspace = canonicalDirectory(directory);
35
37
  for (const relative of allowedPaths) {
36
38
  const file = regularPath(workspace, relative);
@@ -72,6 +74,7 @@ function createAgentBinding(directory, allowedPaths, provider, model) {
72
74
  root,
73
75
  provider,
74
76
  model,
77
+ executionWindow: Object.freeze({ ...window }),
75
78
  allowedPaths: Object.freeze([...allowedPaths]),
76
79
  environment,
77
80
  });
@@ -86,6 +89,7 @@ export function captureVerify01AgentBinding(binding, directory) {
86
89
  agentBindings.has(binding),
87
90
  "unrecognized VERIFY01 agent binding",
88
91
  );
92
+ assertVerify01ExecutionWindow({ window: binding.executionWindow });
89
93
  requireValue(
90
94
  canonicalDirectory(directory) === binding.workspace,
91
95
  "VERIFY01 agent binding belongs to another workspace",
@@ -420,6 +424,9 @@ export function loadVerify01Suite(options = {}) {
420
424
  costBudgetUsd: sample.costBudget,
421
425
  expectedFiles: [...reviewed.allowedChangedPaths],
422
426
  async setup(directory, budget) {
427
+ receipt.windowAdmission = assertVerify01ExecutionWindow(bundle.plan, {
428
+ requiredTimeMs: sample.timeBudgetMs,
429
+ });
423
430
  receipt.workspace = directory;
424
431
  receipt.checkout = await materializeCheckout(
425
432
  projectRoot,
@@ -450,6 +457,7 @@ export function loadVerify01Suite(options = {}) {
450
457
  reviewed.allowedChangedPaths,
451
458
  options.provider,
452
459
  options.model,
460
+ bundle.plan.window,
453
461
  );
454
462
  receipt.agentBinding = {
455
463
  workspace: agentBinding.workspace,
@@ -3,6 +3,7 @@ import path from "node:path";
3
3
  import { randomUUID } from "node:crypto";
4
4
  import { evalDigest } from "./evidence.js";
5
5
  import { outcomeDigest } from "./outcomes.js";
6
+ import { assertVerify01ExecutionWindow } from "./verify01-execution-window.js";
6
7
  import {
7
8
  requireValue,
8
9
  relativeFile,
@@ -202,8 +203,11 @@ export async function prepareVerify01HostTask(bundle, preparation, options) {
202
203
  !fs.existsSync(workspace) && !fs.existsSync(root),
203
204
  "workspace and capture directory must be new; retry cannot overwrite an attempt",
204
205
  );
205
- const startedAt = new Date().toISOString(),
206
- deadline = Date.now() + sample.timeBudgetMs;
206
+ const windowAdmission = assertVerify01ExecutionWindow(bundle.plan, {
207
+ requiredTimeMs: sample.timeBudgetMs,
208
+ });
209
+ const startedAt = new Date(windowAdmission.startedAt).toISOString(),
210
+ deadline = windowAdmission.startedAt + sample.timeBudgetMs;
207
211
  fs.mkdirSync(workspace, { recursive: true, mode: 0o700 });
208
212
  fs.mkdirSync(root, { recursive: true, mode: 0o700 });
209
213
  const stageBudget = budget(deadline);