chainlesschain 0.163.3 → 0.163.4
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.
- package/package.json +3 -2
- package/scripts/command-lifecycle-report.mjs +330 -38
- package/src/assets/web-panel/assets/{AIOps-DIY6KxV-.js → AIOps-DB5X7qqV.js} +1 -1
- package/src/assets/web-panel/assets/{ActionButton-BXH0muPt.js → ActionButton-DxHRtKLk.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-D39w8vmg.js → Analytics-DIH5QrxT.js} +2 -2
- package/src/assets/web-panel/assets/{AppLayout-CUU1zvLs.js → AppLayout-uu0oxVz7.js} +4 -4
- package/src/assets/web-panel/assets/{Artifacts-D8azHO3T.js → Artifacts-BNSMiW9Y.js} +1 -1
- package/src/assets/web-panel/assets/{Audit-D0tAwXTg.js → Audit-DcAzB4_x.js} +1 -1
- package/src/assets/web-panel/assets/{BackgroundAgents-C29mhJll.js → BackgroundAgents-ClSsvjIc.js} +1 -1
- package/src/assets/web-panel/assets/{Backup-D6Aa1Gro.js → Backup-BMciY0js.js} +1 -1
- package/src/assets/web-panel/assets/{BaseInput-B1uoHbPQ.js → BaseInput-Hn3b57Sh.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-Bs4DLOR5.js → Chat-CoSlC53V.js} +5 -5
- package/src/assets/web-panel/assets/{ChatBubbleRenderer-DUYIBSle.js → ChatBubbleRenderer-CFevJ3So.js} +1 -1
- package/src/assets/web-panel/assets/{Checkbox-CNcBPEa4.js → Checkbox-B4L4Eu4w.js} +1 -1
- package/src/assets/web-panel/assets/{Codegen-CIY89763.js → Codegen-C77FgRxF.js} +1 -1
- package/src/assets/web-panel/assets/{Col-CsPYFmgo.js → Col-BrLtJLH3.js} +1 -1
- package/src/assets/web-panel/assets/{Community-BBocEge4.js → Community-Be7pXXhA.js} +1 -1
- package/src/assets/web-panel/assets/{Compact-TQ8Ux0Lf.js → Compact-DuGPecjo.js} +1 -1
- package/src/assets/web-panel/assets/{Compliance-DfBsZTft.js → Compliance-CzS66mjP.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-Cg-I6FVH.js → Cowork-CEhjCoyK.js} +2 -2
- package/src/assets/web-panel/assets/{Cron-DTQzfRTp.js → Cron-D7ir8Vja.js} +2 -2
- package/src/assets/web-panel/assets/{Crosschain-DGxEKGpR.js → Crosschain-BcXmuLxf.js} +1 -1
- package/src/assets/web-panel/assets/{DID-DLZ1RDSr.js → DID-Cto1dtBy.js} +2 -2
- package/src/assets/web-panel/assets/{Dashboard-XneICKNI.js → Dashboard-B7KjgwOX.js} +2 -2
- package/src/assets/web-panel/assets/{Dropdown-BRU00J1-.js → Dropdown-COMqxijg.js} +1 -1
- package/src/assets/web-panel/assets/{EmailListRenderer-BzCbJuAy.js → EmailListRenderer-BZrya-nf.js} +1 -1
- package/src/assets/web-panel/assets/{FamilyGuardDashboard-D7BRyNBG.js → FamilyGuardDashboard-AmVeMq0J.js} +1 -1
- package/src/assets/web-panel/assets/{Federation-D9DeFIhW.js → Federation-kZU8c-27.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-6rAtA9Ko.js → FormItemContext-sOV22v2-.js} +1 -1
- package/src/assets/web-panel/assets/{GenericCardRenderer-8Hqy80pU.js → GenericCardRenderer-BUuLtGCz.js} +1 -1
- package/src/assets/web-panel/assets/{Git-Cmvkj1rt.js → Git-K-ZxsLsH.js} +2 -2
- package/src/assets/web-panel/assets/{Governance-BRiQUjjw.js → Governance-D3OEnawI.js} +1 -1
- package/src/assets/web-panel/assets/{Inference-CKN_EzVf.js → Inference-Bll0gRmP.js} +1 -1
- package/src/assets/web-panel/assets/{KnowledgeGraph-BCDHwpwQ.js → KnowledgeGraph-DBXwjr53.js} +1 -1
- package/src/assets/web-panel/assets/{Logs-DK9ovhaB.js → Logs-CEzPwEfP.js} +2 -2
- package/src/assets/web-panel/assets/MarkdownRenderer-CLmCbHx6.js +1 -0
- package/src/assets/web-panel/assets/{Marketplace-BILPGakp.js → Marketplace-BYyRyOPz.js} +1 -1
- package/src/assets/web-panel/assets/{McpTools-DTVCOr9-.js → McpTools-DVu8w_rM.js} +3 -3
- package/src/assets/web-panel/assets/{Memory-Hzc1iow4.js → Memory-tenuZ_hO.js} +2 -2
- package/src/assets/web-panel/assets/{MobileBridge-GXfgnGYV.js → MobileBridge-Bxgy4ozS.js} +1 -1
- package/src/assets/web-panel/assets/{MobileProjects-B-3TJWsS.js → MobileProjects-Dgx1D6sc.js} +1 -1
- package/src/assets/web-panel/assets/{Mtc-DwSJMWtK.js → Mtc-CRfJ8r8j.js} +4 -4
- package/src/assets/web-panel/assets/{MtcAudit-D2uxf-DA.js → MtcAudit-BBJq4Aiz.js} +4 -4
- package/src/assets/web-panel/assets/{Multisig-DG6kbKK0.js → Multisig-B3ii9lai.js} +3 -3
- package/src/assets/web-panel/assets/{NLProgramming-f5p49EDU.js → NLProgramming-FIi-Cubv.js} +1 -1
- package/src/assets/web-panel/assets/{Notes-FUgHyzSD.js → Notes-DIq8MPf1.js} +3 -3
- package/src/assets/web-panel/assets/{NotificationSettings-DCHGee7e.js → NotificationSettings-BFOD9eGd.js} +1 -1
- package/src/assets/web-panel/assets/{OrderTableRenderer-Dm6LlIoa.js → OrderTableRenderer--41u7vre.js} +1 -1
- package/src/assets/web-panel/assets/{Organization-BawA7qAg.js → Organization-B_0AWztW.js} +4 -4
- package/src/assets/web-panel/assets/{Overflow-D6a5wZU1.js → Overflow-B6I7TuXv.js} +1 -1
- package/src/assets/web-panel/assets/{P2P-K8WavwnA.js → P2P-Cdf6qens.js} +2 -2
- package/src/assets/web-panel/assets/{PdhVaultBrowser-4JAJYaqx.js → PdhVaultBrowser-B_0FcQJY.js} +3 -3
- package/src/assets/web-panel/assets/{Permissions-BDWvi8PD.js → Permissions-6nFBjsQp.js} +3 -3
- package/src/assets/web-panel/assets/{PersonalDataHub-DF_K4E9i.js → PersonalDataHub-nQYV7xpn.js} +3 -3
- package/src/assets/web-panel/assets/{Pipeline-BYeZlesI.js → Pipeline-CBVod5jm.js} +1 -1
- package/src/assets/web-panel/assets/{Privacy-BIHlgnIc.js → Privacy-D52jW1Nt.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectInit-Cvf-6B5P.js → ProjectInit-Bdx3BYhf.js} +2 -2
- package/src/assets/web-panel/assets/{ProjectSettings-CnwfJrRz.js → ProjectSettings-b7xr4DUa.js} +2 -2
- package/src/assets/web-panel/assets/{Projects-b-jPXzF4.js → Projects-DhfifCKx.js} +1 -1
- package/src/assets/web-panel/assets/Providers-Dy_PgDMr.js +1 -0
- package/src/assets/web-panel/assets/{QrScannerModal-VLf3gAfL.js → QrScannerModal-FQKSmc3e.js} +1 -1
- package/src/assets/web-panel/assets/{QuickAsk-B5vGjRiF.js → QuickAsk-CSTrhzcF.js} +1 -1
- package/src/assets/web-panel/assets/{Recommend--UW4iYs-.js → Recommend-CxMABOUh.js} +1 -1
- package/src/assets/web-panel/assets/{RemoteSession-DMSPcfKR.js → RemoteSession-Cv2T8yRa.js} +2 -2
- package/src/assets/web-panel/assets/{Reputation-kQXlEHmj.js → Reputation-CE1k4Vvu.js} +1 -1
- package/src/assets/web-panel/assets/{Row-CxGu3pit.js → Row-BNgNcAV_.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-Bi5lo8MZ.js → RssFeed-5ZiBZ3ph.js} +3 -3
- package/src/assets/web-panel/assets/{Search-Cq_H5RTh.js → Search-mDOIF1UV.js} +1 -1
- package/src/assets/web-panel/assets/{Security-YFbmkaQS.js → Security-CtuCTC-e.js} +3 -3
- package/src/assets/web-panel/assets/{Services-DLOGdaLm.js → Services-DxFO2Zg7.js} +2 -2
- package/src/assets/web-panel/assets/{Skeleton-CteIxb3D.js → Skeleton-CKmKkH9y.js} +1 -1
- package/src/assets/web-panel/assets/{Skills-CccopaIZ.js → Skills-Bmzl9qkk.js} +1 -1
- package/src/assets/web-panel/assets/{Sla-AzfEQKX1.js → Sla-9RqaWHOC.js} +1 -1
- package/src/assets/web-panel/assets/{SpeechSettings-ekGo5l77.js → SpeechSettings-CGdzFIYw.js} +1 -1
- package/src/assets/web-panel/assets/{SyncSettings-BmZmAgYH.js → SyncSettings-CvNuCeBT.js} +2 -2
- package/src/assets/web-panel/assets/{Tasks-D7q3Z4uL.js → Tasks-B_sLdcnw.js} +1 -1
- package/src/assets/web-panel/assets/{Templates-CX1Tgeka.js → Templates-D9_YijdK.js} +1 -1
- package/src/assets/web-panel/assets/{Tenant-Zc59jF4i.js → Tenant-Cuc7BUSP.js} +1 -1
- package/src/assets/web-panel/assets/{Terminal-CXOD7y83.js → Terminal-6VYRnJgd.js} +2 -2
- package/src/assets/web-panel/assets/{TimelineRenderer-B1aBHPBo.js → TimelineRenderer-GtK8xd8Y.js} +1 -1
- package/src/assets/web-panel/assets/{Tokens-zALlOq_U.js → Tokens-BZ94Lt5W.js} +1 -1
- package/src/assets/web-panel/assets/{Trigger-CQfJMXaq.js → Trigger-DEcZgDaX.js} +1 -1
- package/src/assets/web-panel/assets/{Trust-BU0RcM-w.js → Trust-CC3z9THe.js} +1 -1
- package/src/assets/web-panel/assets/{UkeySign-IFZ3HsbH.js → UkeySign-Cvtw8cV3.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-BzslgW0v.js → VideoEditing-CL4e6Bn3.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet-BZAcQNS6.js → Wallet-ycEemP27.js} +2 -2
- package/src/assets/web-panel/assets/{WebAuthn-CBK1DMi0.js → WebAuthn-DgZ4X_aw.js} +5 -5
- package/src/assets/web-panel/assets/{WorkflowEditor-BlMTPzO-.js → WorkflowEditor-D0qMhSv7.js} +1 -1
- package/src/assets/web-panel/assets/{chat-B51-8QVn.js → chat-DsAg01Zn.js} +1 -1
- package/src/assets/web-panel/assets/{colors-504RTByU.js → colors-B0oqAhrQ.js} +1 -1
- package/src/assets/web-panel/assets/{compact-item-C-GP6IQM.js → compact-item-CmX0Rabz.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-DOkIj7ID.js → createContext-Be4cn1Ub.js} +1 -1
- package/src/assets/web-panel/assets/devWarning-CP2qzG6D.js +1 -0
- package/src/assets/web-panel/assets/{hasIn-DN7V-_FW.js → hasIn-D5v12kVq.js} +1 -1
- package/src/assets/web-panel/assets/{index-kt_5rfcZ.js → index-0eWLkQKT.js} +1 -1
- package/src/assets/web-panel/assets/{index-CUhQpiYv.js → index-301ogenv.js} +1 -1
- package/src/assets/web-panel/assets/{index-f4Bo4KXm.js → index-5LGY0JbG.js} +1 -1
- package/src/assets/web-panel/assets/{index--n-ZciV3.js → index-7VKDn-t1.js} +1 -1
- package/src/assets/web-panel/assets/{index-D1phyca8.js → index-8WvYGnON.js} +1 -1
- package/src/assets/web-panel/assets/{index-7jIqHbzw.js → index-B1YGjOWC.js} +1 -1
- package/src/assets/web-panel/assets/{index-DEMPUVa3.js → index-B3mUHuVc.js} +1 -1
- package/src/assets/web-panel/assets/{index-Bkxhaeta.js → index-BA4oulaP.js} +1 -1
- package/src/assets/web-panel/assets/{index-CYopNjcJ.js → index-BBREnn1V.js} +1 -1
- package/src/assets/web-panel/assets/{index-P2mfY27Z.js → index-BBvyHguy.js} +1 -1
- package/src/assets/web-panel/assets/{index-DA2f1UV3.js → index-BKmsS2jj.js} +1 -1
- package/src/assets/web-panel/assets/{index-CP2A226L.js → index-BRIqLy1m.js} +1 -1
- package/src/assets/web-panel/assets/{index-CfiEM64n.js → index-BXGSbelg.js} +3 -3
- package/src/assets/web-panel/assets/{index-B2-x9bS8.js → index-BaE0Ui07.js} +1 -1
- package/src/assets/web-panel/assets/{index-CySTJKeq.js → index-BoAIAZ5C.js} +1 -1
- package/src/assets/web-panel/assets/{index-kAqQXfP6.js → index-BqltWojQ.js} +1 -1
- package/src/assets/web-panel/assets/{index-DAOpQvl_.js → index-CGiIyTZw.js} +1 -1
- package/src/assets/web-panel/assets/index-CKB0vbJU.js +1 -0
- package/src/assets/web-panel/assets/{index-C4DV_5uA.js → index-CZ2wUEgr.js} +1 -1
- package/src/assets/web-panel/assets/{index-yYTQZypF.js → index-CZpfzcuy.js} +1 -1
- package/src/assets/web-panel/assets/{index-et5JIPHO.js → index-Ckrk3pIV.js} +1 -1
- package/src/assets/web-panel/assets/{index-DaA__-q1.js → index-CqoCZ5vR.js} +1 -1
- package/src/assets/web-panel/assets/{index-By6u5IV1.js → index-CyWBir7N.js} +1 -1
- package/src/assets/web-panel/assets/{index-CKTfZyfU.js → index-CyyGTMKd.js} +1 -1
- package/src/assets/web-panel/assets/{index-B_vGU-Js.js → index-D0BSkxYQ.js} +1 -1
- package/src/assets/web-panel/assets/{index-Cao5DZy7.js → index-D5YVopyr.js} +1 -1
- package/src/assets/web-panel/assets/{index-C3TSohzc.js → index-DKUBj36_.js} +1 -1
- package/src/assets/web-panel/assets/{index-BFIFJ5Dr.js → index-DM724NgU.js} +1 -1
- package/src/assets/web-panel/assets/{index-ConjaJro.js → index-DQRsQen0.js} +1 -1
- package/src/assets/web-panel/assets/index-DgoXmwqB.js +1 -0
- package/src/assets/web-panel/assets/{index-C9_48OzU.js → index-DikJ0Qqe.js} +1 -1
- package/src/assets/web-panel/assets/{index-C0k_Nqg9.js → index-Dn2dSdXx.js} +1 -1
- package/src/assets/web-panel/assets/{index-DE-hmI2l.js → index-DyUaFWEk.js} +1 -1
- package/src/assets/web-panel/assets/{index-so8eIIxF.js → index-Hfe_dEGx.js} +1 -1
- package/src/assets/web-panel/assets/{index-FcV8J_Qz.js → index-_JjRLSD0.js} +1 -1
- package/src/assets/web-panel/assets/{index-D9LyiN-L.js → index-frSojpHj.js} +1 -1
- package/src/assets/web-panel/assets/{index-CX78k-qf.js → index-jK3ax6Z6.js} +1 -1
- package/src/assets/web-panel/assets/{index-C8UltbXK.js → index-qMuZ-NRR.js} +1 -1
- package/src/assets/web-panel/assets/{index-CqcLo5WV.js → index-q_fQ94SE.js} +1 -1
- package/src/assets/web-panel/assets/{initDefaultProps-CPYEIdpV.js → initDefaultProps-D4VdhJ9_.js} +1 -1
- package/src/assets/web-panel/assets/{motion-Cjim9pxs.js → motion-CZJA0MQW.js} +1 -1
- package/src/assets/web-panel/assets/{move-DuU-cgz3.js → move-BqEs7Sb1.js} +1 -1
- package/src/assets/web-panel/assets/{mtc-parser-DJHNAkta.js → mtc-parser-BpHEtsu1.js} +1 -1
- package/src/assets/web-panel/assets/{omit-DSQBgdBj.js → omit-BW94tY9W.js} +1 -1
- package/src/assets/web-panel/assets/{pickAttrs-CTmT_j5m.js → pickAttrs-BnBjPWP9.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-Lfm6v-r4.js → placementArrow-uUkjQ_hu.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-CgrcPcDi.js → responsiveObserve-B-klUqXK.js} +1 -1
- package/src/assets/web-panel/assets/{slide-CuE3110i.js → slide-CvY1cNAs.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-DiK5nbpf.js → statusUtils-Ix5sEDT2.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-DPEJdQaZ.js → styleChecker-C8qcXOne.js} +1 -1
- package/src/assets/web-panel/assets/{useFlexGapSupport-CnnodGmp.js → useFlexGapSupport-KNF6Kj8f.js} +1 -1
- package/src/assets/web-panel/assets/{useFs-DWF84Yav.js → useFs-DGJr345n.js} +1 -1
- package/src/assets/web-panel/assets/{usePersonalDataHub-a5b5Dw2f.js → usePersonalDataHub-BboN99rI.js} +1 -1
- package/src/assets/web-panel/assets/{vnode-DAluzXOq.js → vnode-Bgt8Vgte.js} +1 -1
- package/src/assets/web-panel/assets/{zoom-Dokg7uAZ.js → zoom-BhJtErgt.js} +1 -1
- package/src/assets/web-panel/index.html +1 -1
- package/src/command-help-index.json +1 -1
- package/src/commands/artifacts.js +98 -0
- package/src/commands/mcp.js +1 -1
- package/src/commands/review.js +221 -22
- package/src/commands/session-mcp-recovery.js +5 -5
- package/src/data/changelog.json +14 -1
- package/src/gateways/ws/ws-agent-handler.js +492 -14
- package/src/harness/jsonl-session-store.js +39 -1
- package/src/harness/mcp-client.js +172 -29
- package/src/harness/prompt-compressor.js +24 -0
- package/src/harness/provider-backed-compaction.js +205 -0
- package/src/lib/app-preview.js +3 -0
- package/src/lib/command-lifecycle-report.js +1340 -145
- package/src/lib/delivery-coordinator.js +30 -5
- package/src/lib/delivery-production-adapter.js +1777 -0
- package/src/lib/delivery-production-runner.js +240 -0
- package/src/lib/durable-security-store.js +29 -17
- package/src/lib/execution-trace/trace-context.cjs +179 -0
- package/src/lib/execution-trace/trace-context.js +8 -175
- package/src/lib/mcp-call-ledger-store.js +58 -6
- package/src/lib/mcp-host-recovery-runtime.js +2 -0
- package/src/lib/mcp-ledger-recovery-admission.js +39 -3
- package/src/lib/mcp-recovery-adjudication.js +256 -19
- package/src/lib/mcp-sandbox-policy.js +29 -0
- package/src/lib/mcp-stdio-capsule-builder-worker.cjs +495 -0
- package/src/lib/mcp-stdio-executable-identity.js +33 -2
- package/src/lib/mcp-stdio-immutable-vfs-resolver.cjs +830 -0
- package/src/lib/mcp-stdio-package-materialization.js +721 -333
- package/src/lib/observability/index.js +2 -0
- package/src/lib/observability/otlp-exporter.js +2 -2
- package/src/lib/packer/pack-update-applier.js +8 -1
- package/src/lib/packer/pkg-config-generator.js +34 -0
- package/src/lib/process-execution-broker/index.js +34 -5
- package/src/lib/process-execution-broker/platform-sandbox.js +82 -1
- package/src/lib/scheduler-kernel/contract.js +315 -0
- package/src/lib/scheduler-kernel/store.js +1345 -0
- package/src/lib/session-host-lease.js +403 -30
- package/src/lib/session-persistence-failure.js +4 -1
- package/src/lib/sub-agent-context.js +8 -0
- package/src/repl/agent-repl.js +285 -38
- package/src/runtime/agent-core.js +1044 -90
- package/src/runtime/headless-runner.js +260 -166
- package/src/runtime/headless-stream.js +254 -25
- package/src/assets/web-panel/assets/MarkdownRenderer-D53pHiHy.js +0 -1
- package/src/assets/web-panel/assets/Providers-CxC7JuYv.js +0 -1
- package/src/assets/web-panel/assets/devWarning-kB0nCNwN.js +0 -1
- package/src/assets/web-panel/assets/index-Bya64sZE.js +0 -1
- package/src/assets/web-panel/assets/index-D_FWpDZM.js +0 -1
package/src/data/changelog.json
CHANGED
|
@@ -1,6 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"source": "CHANGELOG.md",
|
|
3
3
|
"releases": [
|
|
4
|
+
{
|
|
5
|
+
"productVersion": null,
|
|
6
|
+
"cliVersion": "0.163.4",
|
|
7
|
+
"cliVersions": ["0.163.3", "0.163.4"],
|
|
8
|
+
"date": "2026-08-11",
|
|
9
|
+
"title": "",
|
|
10
|
+
"sections": [
|
|
11
|
+
{
|
|
12
|
+
"heading": "Added — cc CLI 0.163.4: immutable MCP capsules and durable scheduler storage",
|
|
13
|
+
"body": "> `chainlesschain` **0.163.3 → 0.163.4** (candidate; not yet published,\n> 2026-08-11).\n> CLI-only candidate; `@chainlesschain/personal-data-hub` remains **0.4.57**\n> and `@chainlesschain/agent-sdk` remains **0.1.7**.\n\n- **Immutable MCP capsule build inputs**: the capsule builder now executes in a\n bounded worker against an in-memory WASM virtual filesystem populated from\n verified bytes. Package sources and native builder assets are canonicalized,\n identity-bound, and no longer reopened from mutable host paths during the\n build.\n- **Platform-bound live capsule evidence**: materialized stdio MCP capsules are\n exercised through the production Process Broker and child contract on Linux,\n Windows, and macOS. Framed reports, exact asset identity, deferred host-path\n resolution, and shared CJS/ESM trace context prevent warning or path-alias\n drift from weakening the evidence chain.\n- **Bounded failure behavior**: worker memory, output, timeout, and cleanup are\n bounded; partial or malformed child evidence, post-verification replacement,\n unapproved effects, and unsupported strict boundaries fail closed.\n- **Command lifecycle evidence and alias decision**: report v2 binds exact\n coverage, approval, scope, and repository evidence and summarizes command\n telemetry without silently accepting zero-data input. All 25 deprecated\n aliases remain retained until representative opt-in telemetry exists and the\n documented `0.164.0` removal floor is reached.\n- **Scheduler kernel storage foundation**: a versioned SQLite store adds strict\n schema verification, expected-revision CAS, logical-occurrence deduplication,\n durable claims, and two-handle race coverage. This is the first P2-4 storage\n milestone, not completion of the scheduling kernel or orchestration runtime.\n- **Delivery and recovery hardening**: production delivery adapters, durable\n provider-backed compaction, MCP recovery admission, session ownership fences,\n and exact Windows write checks close additional internal consistency gaps.\n- **Native release readback hardening**: release evidence now verifies public\n bytes, checksums, manifests, signatures, and provenance contracts more\n strictly. Signed native distribution is still blocked until real signed\n artifacts and public package-manager readback are available.\n- **Known residuals**: full P2-4 scheduling orchestration, signed native\n distribution, representative alias telemetry, and the remaining documented\n long-soak/host-boundary follow-ups are not claimed by this release.\n- **Release status**: final tag, exact source SHA, workflow run IDs, package\n digest, provenance, and public registry readback are intentionally omitted\n until the exact `0.163.4` release commit passes the Linux, Windows, and macOS\n `CLI CI` and `CLI Strict Sandbox` gates and the npm release/readback workflows\n complete successfully."
|
|
14
|
+
}
|
|
15
|
+
]
|
|
16
|
+
},
|
|
4
17
|
{
|
|
5
18
|
"productVersion": null,
|
|
6
19
|
"cliVersion": "0.163.3",
|
|
@@ -10,7 +23,7 @@
|
|
|
10
23
|
"sections": [
|
|
11
24
|
{
|
|
12
25
|
"heading": "Added — cc CLI 0.163.3: isolated background agents and policy-bound runtimes",
|
|
13
|
-
"body": "> `chainlesschain` **0.163.2 → 0.163.3** (
|
|
26
|
+
"body": "> `chainlesschain` **0.163.2 → 0.163.3** (published from exact SHA\n> `17fcf6aa7917dd0fcc83b3ab5204c196bbb81758`, 2026-08-10).\n> CLI-only release; `@chainlesschain/personal-data-hub` remains **0.4.57**\n> and `@chainlesschain/agent-sdk` remains **0.1.7**.\n\n- **Git background isolation by default**: `cc agent --bg` runs started from a\n clean Git checkout and not using `--input-format stream-json` now create a\n worktree at committed `HEAD`; `--worktree` requests the same path and only\n `--no-worktree` opts into the shared checkout. Foreground runs, runs using\n `--input-format stream-json`, and non-Git runs retain their prior behavior,\n while a dirty Git source is rejected instead of silently omitting uncommitted\n changes.\n- **Generation- and token-fenced ownership**: locked atomic state, immutable\n worktree/profile identity, worker-generation claims, terminal-absorbing\n updates, durable turn intents, and stop/cleanup fences prevent stale\n cooperative workers from reviving or deleting live work. Versioned,\n secret-free launch profiles preserve compatible resume settings.\n- **Grammar-safe detached arguments**: new background launches preserve option\n values and `--` literals, pass prompts as one `--print=<text>` token,\n canonicalize resume/continue/fork to one session, and remap repository\n `--add-dir` roots into the worktree. Canonical external roots remain shared\n and produce a warning.\n- **Policy-bearing stdio MCP sources**: explicit `--mcp-config`, managed and\n registered local/project/user sources, trusted project configuration, Skill,\n and Cowork definitions propagate normalized `filesystem`/`network`\n requirements plus separately validated working-directory/workspace authority\n to the Process Broker. Unprovable requirements fail closed, and invalid named\n higher-precedence entries do not fall through to a weaker source.\n- **Sealed Linux plugin file sets**: strict direct Plugin Node and supported\n narrow native ELF launches snapshot every pinned regular plugin file into\n sealed anonymous data-bind mounts. Dynamic native evidence covers only\n `PT_INTERP` and direct `DT_NEEDED`; tree attestation remains per-file rather\n than one atomic filesystem snapshot.\n- **Contained Windows adapter artifacts**: helper, cache, and test artifacts use\n an attested non-reparse local temporary root, identity/content rechecks,\n randomized materialization, and bounded retirement. Unknown or unverifiable\n leftovers are preserved and make cleanup fail closed.\n- **Fail-closed CI routing**: the generic selector routes the defined Windows\n helper-support paths to their CLI contract tests, supports multi-suite\n execution, and cannot turn selected-test or primary-run failure into a\n fallback/diagnostic pass. Full-suite workflows provision their required\n dependencies explicitly; this routing does not replace the exact-SHA release\n matrices.\n- **Known residuals**: non-Git, `--input-format stream-json`, `--no-worktree`,\n and external `add-dir` roots are not worktree-isolated. Spawn-to-PID\n hard-crash recovery and long-soak closure remain open; Linux native\n dependency evidence is non-transitive and has no `dlopen` closure; Windows\n path operations are\n re-attested but not handle-atomic. macOS atomic runtime execution, arbitrary\n shared-library closure, remote revocation, signed native distribution, and\n alias telemetry/removal remain out of scope, so this release does not claim\n complete P1-2 closure.\n- **Published release evidence**: immutable tag `v-npm-0-163-3` resolves to\n exact source commit `17fcf6aa7917dd0fcc83b3ab5204c196bbb81758`.\n Its Linux, Windows, and macOS `CLI CI` (`31329476135`) and `CLI Strict\nSandbox` (`31329476020`) matrices passed; the formal two-hour\n reliability/malicious-MCP soak (`31329539092`) completed 7/7 jobs with 300\n host cycles, 900 unapproved effects, 100 Linux races, 100 macOS fail-closed\n probes, and zero escapes. The npm release (`31335579227`) and independent\n public readback (`31336362525`) completed the exact-SHA gate, immutable\n tarball/CycloneDX SBOM, Trusted Publishing, SLSA/Sigstore provenance,\n registry byte comparison, and npmmirror synchronization. The public tarball\n SHA-256 is\n `68396c418029fc314403c9882c92fb9bef5ec6e9a61bb186333209884d410a92`."
|
|
14
27
|
}
|
|
15
28
|
]
|
|
16
29
|
},
|
|
@@ -34,12 +34,17 @@ import {
|
|
|
34
34
|
import { createWsApprovalGate } from "./ws-approval-gate.js";
|
|
35
35
|
import { createSessionMcpLedgerSink } from "../../lib/mcp-call-ledger-store.js";
|
|
36
36
|
import { createMcpHostRecoveryRuntime } from "../../lib/mcp-host-recovery-runtime.js";
|
|
37
|
+
import { compactConversationWithProvider } from "../../harness/provider-backed-compaction.js";
|
|
38
|
+
import { projectCanonicalResumeMessages } from "../../lib/session-message-provenance.js";
|
|
39
|
+
import { feature } from "../../lib/feature-flags.js";
|
|
37
40
|
import {
|
|
41
|
+
appendCompactEventIfMessagesMatch,
|
|
38
42
|
claimWsTurnIfHead,
|
|
39
43
|
computeWsTurnInputDigest,
|
|
40
44
|
createWsTurnClaimId,
|
|
41
45
|
normalizeWsTurnRequestId,
|
|
42
46
|
readVerifiedWsTurnState,
|
|
47
|
+
readVerifiedMessages,
|
|
43
48
|
settleWsTurnClaim,
|
|
44
49
|
} from "../../harness/jsonl-session-store.js";
|
|
45
50
|
|
|
@@ -78,6 +83,8 @@ export class WSAgentHandler {
|
|
|
78
83
|
db,
|
|
79
84
|
approvalGate,
|
|
80
85
|
agentLoop: runAgentLoop,
|
|
86
|
+
compactionLlmQuery,
|
|
87
|
+
compactionChatFn,
|
|
81
88
|
canonicalSessionStore,
|
|
82
89
|
sessionHostLease = null,
|
|
83
90
|
}) {
|
|
@@ -122,12 +129,22 @@ export class WSAgentHandler {
|
|
|
122
129
|
this._mcpRecoveryRevision = null;
|
|
123
130
|
this._mcpRecoveryClient = null;
|
|
124
131
|
this._agentLoop = runAgentLoop || agentLoop;
|
|
132
|
+
this._compactionLlmQuery = compactionLlmQuery || null;
|
|
133
|
+
this._compactionSettlementBlock = null;
|
|
134
|
+
this._compactionChatFn =
|
|
135
|
+
compactionChatFn ||
|
|
136
|
+
(async (...args) => {
|
|
137
|
+
const { chatWithTools } = await import("../../runtime/agent-core.js");
|
|
138
|
+
return chatWithTools(...args);
|
|
139
|
+
});
|
|
125
140
|
this._canonicalSessionStore = {
|
|
141
|
+
appendCompactEventIfMessagesMatch,
|
|
126
142
|
claimWsTurnIfHead,
|
|
127
143
|
computeWsTurnInputDigest,
|
|
128
144
|
createWsTurnClaimId,
|
|
129
145
|
normalizeWsTurnRequestId,
|
|
130
146
|
readVerifiedWsTurnState,
|
|
147
|
+
readVerifiedMessages,
|
|
131
148
|
settleWsTurnClaim,
|
|
132
149
|
...(canonicalSessionStore || {}),
|
|
133
150
|
};
|
|
@@ -171,9 +188,56 @@ export class WSAgentHandler {
|
|
|
171
188
|
return this.session.messages;
|
|
172
189
|
}
|
|
173
190
|
|
|
191
|
+
_latchCompactionSettlement({
|
|
192
|
+
code,
|
|
193
|
+
reason,
|
|
194
|
+
commitState = "unknown",
|
|
195
|
+
usageOutcome = null,
|
|
196
|
+
}) {
|
|
197
|
+
this._compactionSettlementBlock = Object.freeze({
|
|
198
|
+
code: code || "CC_COMPACTION_SETTLEMENT_UNKNOWN",
|
|
199
|
+
reason: reason || "canonical_compaction_settlement_failed",
|
|
200
|
+
commitState,
|
|
201
|
+
...(usageOutcome ? { usageOutcome } : {}),
|
|
202
|
+
});
|
|
203
|
+
return this._compactionSettlementBlock;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
_reconcileCompactionSettlementBlock() {
|
|
207
|
+
if (
|
|
208
|
+
this._compactionSettlementBlock?.commitState !== "provider-usage-unknown"
|
|
209
|
+
) {
|
|
210
|
+
this._compactionSettlementBlock = null;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
_emitCompactionUsage(requestId, usageEvent) {
|
|
215
|
+
if (!usageEvent) return;
|
|
216
|
+
this.interaction.emit("token-usage", {
|
|
217
|
+
requestId,
|
|
218
|
+
...usageEvent,
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
_emitCompactionUsageUnknown(requestId, usageUnknownEvent) {
|
|
223
|
+
const block = this._latchCompactionSettlement({
|
|
224
|
+
code: "CC_COMPACTION_USAGE_UNKNOWN",
|
|
225
|
+
reason: usageUnknownEvent?.reason || "provider_transport_outcome_unknown",
|
|
226
|
+
commitState: "provider-usage-unknown",
|
|
227
|
+
usageOutcome: "unknown",
|
|
228
|
+
});
|
|
229
|
+
this.interaction.emit("compaction-usage-unknown", {
|
|
230
|
+
requestId,
|
|
231
|
+
...usageUnknownEvent,
|
|
232
|
+
code: block.code,
|
|
233
|
+
});
|
|
234
|
+
return block;
|
|
235
|
+
}
|
|
236
|
+
|
|
174
237
|
_canonicalTurnFromAuthority(state, requestId, userMessage, inputDigest) {
|
|
175
238
|
const status = state?.status || (state?.turn ? "completed" : "none");
|
|
176
239
|
this._applyCanonicalMessages(state?.messages || []);
|
|
240
|
+
this._reconcileCompactionSettlementBlock();
|
|
177
241
|
if (status === "completed" && state.turn) {
|
|
178
242
|
return {
|
|
179
243
|
requestId,
|
|
@@ -210,6 +274,193 @@ export class WSAgentHandler {
|
|
|
210
274
|
return null;
|
|
211
275
|
}
|
|
212
276
|
|
|
277
|
+
async _compactCanonicalHistoryBeforeClaim(requestId) {
|
|
278
|
+
const { session } = this;
|
|
279
|
+
if (
|
|
280
|
+
session.autoCompact === false ||
|
|
281
|
+
!feature("PROMPT_COMPRESSOR") ||
|
|
282
|
+
this._compactionSettlementBlock?.commitState === "provider-usage-unknown"
|
|
283
|
+
) {
|
|
284
|
+
return true;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
const before = session.messages.length;
|
|
288
|
+
const expectedMessages = [...session.messages];
|
|
289
|
+
let result;
|
|
290
|
+
try {
|
|
291
|
+
this._sessionHostLease?.assert?.();
|
|
292
|
+
result = await compactConversationWithProvider(session.messages, {
|
|
293
|
+
provider: session.provider,
|
|
294
|
+
model: session.model,
|
|
295
|
+
baseUrl: session.baseUrl,
|
|
296
|
+
apiKey: session.apiKey,
|
|
297
|
+
signal: this._sessionHostLease?.signal,
|
|
298
|
+
onlyIfNeeded: true,
|
|
299
|
+
preserveCompletedExchange: true,
|
|
300
|
+
llmQuery: this._compactionLlmQuery,
|
|
301
|
+
chatFn: this._compactionChatFn,
|
|
302
|
+
chatOptions: {
|
|
303
|
+
cwd: session.projectRoot,
|
|
304
|
+
sessionId: session.id,
|
|
305
|
+
},
|
|
306
|
+
maxMessages: session.compactionMaxMessages,
|
|
307
|
+
maxTokens: session.compactionMaxTokens,
|
|
308
|
+
maxOutputTokens: session.compactionMaxOutputTokens,
|
|
309
|
+
summaryInputMaxChars: session.compactionInputMaxChars,
|
|
310
|
+
});
|
|
311
|
+
this._sessionHostLease?.assert?.();
|
|
312
|
+
} catch (error) {
|
|
313
|
+
if (isAbortError(error) || this._sessionHostLease?.signal?.aborted) {
|
|
314
|
+
throw error;
|
|
315
|
+
}
|
|
316
|
+
const block = this._latchCompactionSettlement({
|
|
317
|
+
code: error?.code || "CC_COMPACTION_FAILED",
|
|
318
|
+
reason: `compaction_failed:${String(error?.message || error).slice(0, 240)}`,
|
|
319
|
+
commitState: "provider-outcome-unknown",
|
|
320
|
+
});
|
|
321
|
+
this.interaction.emit("compaction-degraded", {
|
|
322
|
+
requestId,
|
|
323
|
+
reason: block.reason,
|
|
324
|
+
summaryMode: "none",
|
|
325
|
+
code: block.code,
|
|
326
|
+
});
|
|
327
|
+
this.interaction.emit("error", {
|
|
328
|
+
requestId,
|
|
329
|
+
code: block.code,
|
|
330
|
+
message: "Canonical history could not be compacted before turn claim",
|
|
331
|
+
});
|
|
332
|
+
return false;
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
const {
|
|
336
|
+
messages: compacted,
|
|
337
|
+
stats,
|
|
338
|
+
degradedEvent,
|
|
339
|
+
usageEvent,
|
|
340
|
+
usageUnknownEvent,
|
|
341
|
+
} = result;
|
|
342
|
+
if (degradedEvent) {
|
|
343
|
+
this.interaction.emit("compaction-degraded", {
|
|
344
|
+
requestId,
|
|
345
|
+
...degradedEvent,
|
|
346
|
+
});
|
|
347
|
+
}
|
|
348
|
+
if (usageUnknownEvent) {
|
|
349
|
+
const block = this._emitCompactionUsageUnknown(
|
|
350
|
+
requestId,
|
|
351
|
+
usageUnknownEvent,
|
|
352
|
+
);
|
|
353
|
+
this.interaction.emit("error", {
|
|
354
|
+
requestId,
|
|
355
|
+
code: block.code,
|
|
356
|
+
message:
|
|
357
|
+
"Compaction provider usage is unknown; the paid compaction is not retried",
|
|
358
|
+
});
|
|
359
|
+
return false;
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
const messagesChanged =
|
|
363
|
+
session.messages.length !== expectedMessages.length ||
|
|
364
|
+
session.messages.some(
|
|
365
|
+
(message, index) => message !== expectedMessages[index],
|
|
366
|
+
);
|
|
367
|
+
const shouldSettle = stats?.strategy !== "none" && stats?.saved > 0;
|
|
368
|
+
let settlementError = null;
|
|
369
|
+
if (!messagesChanged && shouldSettle) {
|
|
370
|
+
try {
|
|
371
|
+
const settlement =
|
|
372
|
+
this._canonicalSessionStore.appendCompactEventIfMessagesMatch(
|
|
373
|
+
session.id,
|
|
374
|
+
{
|
|
375
|
+
...stats,
|
|
376
|
+
trigger: "auto",
|
|
377
|
+
messages: projectCanonicalResumeMessages(compacted, {
|
|
378
|
+
strict: true,
|
|
379
|
+
}),
|
|
380
|
+
},
|
|
381
|
+
expectedMessages,
|
|
382
|
+
);
|
|
383
|
+
if (settlement && typeof settlement.then === "function") {
|
|
384
|
+
void Promise.resolve(settlement).catch(() => {});
|
|
385
|
+
const error = new TypeError(
|
|
386
|
+
"Canonical compact settlement must be synchronous",
|
|
387
|
+
);
|
|
388
|
+
error.code = "CC_COMPACTION_SETTLEMENT_ASYNC";
|
|
389
|
+
throw error;
|
|
390
|
+
}
|
|
391
|
+
} catch (error) {
|
|
392
|
+
settlementError = error;
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
this._emitCompactionUsage(requestId, usageEvent);
|
|
397
|
+
if (messagesChanged || settlementError) {
|
|
398
|
+
const stale = settlementError?.code === "SESSION_REVISION_STALE";
|
|
399
|
+
let reconciled = false;
|
|
400
|
+
if (stale) {
|
|
401
|
+
try {
|
|
402
|
+
const authoritativeMessages =
|
|
403
|
+
this._canonicalSessionStore.readVerifiedMessages(session.id);
|
|
404
|
+
if (!Array.isArray(authoritativeMessages)) {
|
|
405
|
+
throw new TypeError(
|
|
406
|
+
"Canonical message refresh must be synchronous",
|
|
407
|
+
);
|
|
408
|
+
}
|
|
409
|
+
this._applyCanonicalMessages(authoritativeMessages);
|
|
410
|
+
this._reconcileCompactionSettlementBlock();
|
|
411
|
+
reconciled = true;
|
|
412
|
+
} catch {
|
|
413
|
+
// Latch below until a later verified canonical refresh succeeds.
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
const block =
|
|
417
|
+
reconciled && stale
|
|
418
|
+
? {
|
|
419
|
+
code: "CC_COMPACTION_REVISION_STALE",
|
|
420
|
+
reason: "session_messages_changed_during_compaction",
|
|
421
|
+
commitState: "reconciled-stale",
|
|
422
|
+
}
|
|
423
|
+
: this._latchCompactionSettlement({
|
|
424
|
+
code:
|
|
425
|
+
settlementError?.code ||
|
|
426
|
+
(messagesChanged
|
|
427
|
+
? "CC_COMPACTION_LOCAL_STATE_CHANGED"
|
|
428
|
+
: "CC_COMPACTION_SETTLEMENT_UNKNOWN"),
|
|
429
|
+
reason:
|
|
430
|
+
messagesChanged || stale
|
|
431
|
+
? "session_messages_changed_during_compaction"
|
|
432
|
+
: "canonical_compaction_settlement_failed",
|
|
433
|
+
commitState: "unknown",
|
|
434
|
+
});
|
|
435
|
+
this.interaction.emit("compaction-degraded", {
|
|
436
|
+
requestId,
|
|
437
|
+
reason: block.reason,
|
|
438
|
+
summaryMode: "none",
|
|
439
|
+
code: block.code,
|
|
440
|
+
});
|
|
441
|
+
this.interaction.emit("error", {
|
|
442
|
+
requestId,
|
|
443
|
+
code: block.code,
|
|
444
|
+
message:
|
|
445
|
+
"Canonical compaction did not settle; the paid compaction is not retried",
|
|
446
|
+
});
|
|
447
|
+
return false;
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
if (shouldSettle) {
|
|
451
|
+
session.messages.length = 0;
|
|
452
|
+
session.messages.push(...compacted);
|
|
453
|
+
this.interaction.emit("compaction", {
|
|
454
|
+
requestId,
|
|
455
|
+
stats,
|
|
456
|
+
trigger: "auto",
|
|
457
|
+
messagesBefore: before,
|
|
458
|
+
messagesAfter: session.messages.length,
|
|
459
|
+
});
|
|
460
|
+
}
|
|
461
|
+
return true;
|
|
462
|
+
}
|
|
463
|
+
|
|
213
464
|
_claimCanonicalTurn(userMessage, requestId) {
|
|
214
465
|
const inputDigest =
|
|
215
466
|
this._canonicalSessionStore.computeWsTurnInputDigest(userMessage);
|
|
@@ -396,6 +647,7 @@ export class WSAgentHandler {
|
|
|
396
647
|
sink: this._mcpRecoverySink,
|
|
397
648
|
recovery: session.mcpLedgerRecovery || null,
|
|
398
649
|
controller,
|
|
650
|
+
dispatchAdmission: this._sessionHostLease?.admitMcpDispatch || null,
|
|
399
651
|
});
|
|
400
652
|
this._mcpRecoveryClient = rawClient;
|
|
401
653
|
this._mcpRecoveryRevision = revision;
|
|
@@ -509,7 +761,26 @@ export class WSAgentHandler {
|
|
|
509
761
|
this._sessionHostLease?.assert?.();
|
|
510
762
|
|
|
511
763
|
if (session.canonicalJsonlSession === true) {
|
|
512
|
-
|
|
764
|
+
const inputDigest =
|
|
765
|
+
this._canonicalSessionStore.computeWsTurnInputDigest(userMessage);
|
|
766
|
+
const preflightState =
|
|
767
|
+
this._canonicalSessionStore.readVerifiedWsTurnState(
|
|
768
|
+
session.id,
|
|
769
|
+
requestId,
|
|
770
|
+
{ inputDigest },
|
|
771
|
+
);
|
|
772
|
+
canonicalTurn = this._canonicalTurnFromAuthority(
|
|
773
|
+
preflightState,
|
|
774
|
+
requestId,
|
|
775
|
+
userMessage,
|
|
776
|
+
inputDigest,
|
|
777
|
+
);
|
|
778
|
+
if (!canonicalTurn) {
|
|
779
|
+
const compacted =
|
|
780
|
+
await this._compactCanonicalHistoryBeforeClaim(requestId);
|
|
781
|
+
if (!compacted) return;
|
|
782
|
+
}
|
|
783
|
+
canonicalTurn ||= this._claimCanonicalTurn(userMessage, requestId);
|
|
513
784
|
if (canonicalTurn.status === "completed") {
|
|
514
785
|
this.interaction.emit("response-complete", {
|
|
515
786
|
requestId,
|
|
@@ -601,6 +872,7 @@ export class WSAgentHandler {
|
|
|
601
872
|
// headless and REPL sessions. For unknown/write/destructive effects a
|
|
602
873
|
// failed prewrite blocks the network call inside agent-core.
|
|
603
874
|
mcpCallLedger: mcpRecoveryRuntime.ledger,
|
|
875
|
+
mcpDispatchAdmission: this._sessionHostLease?.admitMcpDispatch || null,
|
|
604
876
|
shellPolicyOverrides: session.shellPolicyOverrides || null,
|
|
605
877
|
slotFiller,
|
|
606
878
|
interaction: this.interaction,
|
|
@@ -608,6 +880,12 @@ export class WSAgentHandler {
|
|
|
608
880
|
// P0 authority: null unless opted in (byte-identical default — agent
|
|
609
881
|
// core already defaults `options.approvalGate || null`).
|
|
610
882
|
approvalGate: await this._ensureApprovalGate(),
|
|
883
|
+
// Canonical WS history is compacted before ws_turn_prepare. Compaction
|
|
884
|
+
// inside agent-core would include the staged pending user, which is not
|
|
885
|
+
// part of the canonical message projection until turn settlement.
|
|
886
|
+
...(session.canonicalJsonlSession === true
|
|
887
|
+
? { autoCompact: false }
|
|
888
|
+
: {}),
|
|
611
889
|
};
|
|
612
890
|
|
|
613
891
|
// P0-2: crash-safe side-effect ledger for the IDE/bridge path — mirrors
|
|
@@ -718,6 +996,37 @@ export class WSAgentHandler {
|
|
|
718
996
|
}
|
|
719
997
|
break;
|
|
720
998
|
|
|
999
|
+
case "compaction-degraded":
|
|
1000
|
+
this.interaction.emit("compaction-degraded", {
|
|
1001
|
+
requestId,
|
|
1002
|
+
reason: event.reason,
|
|
1003
|
+
summaryMode: event.summaryMode,
|
|
1004
|
+
...(event.code ? { code: event.code } : {}),
|
|
1005
|
+
stats: event.stats,
|
|
1006
|
+
});
|
|
1007
|
+
break;
|
|
1008
|
+
|
|
1009
|
+
case "compaction-usage-unknown":
|
|
1010
|
+
this._emitCompactionUsageUnknown(requestId, event);
|
|
1011
|
+
break;
|
|
1012
|
+
|
|
1013
|
+
case "compaction":
|
|
1014
|
+
this.interaction.emit("compaction", {
|
|
1015
|
+
requestId,
|
|
1016
|
+
stats: event.stats,
|
|
1017
|
+
});
|
|
1018
|
+
break;
|
|
1019
|
+
|
|
1020
|
+
case "token-usage":
|
|
1021
|
+
this.interaction.emit("token-usage", {
|
|
1022
|
+
requestId,
|
|
1023
|
+
provider: event.provider,
|
|
1024
|
+
model: event.model,
|
|
1025
|
+
usage: event.usage,
|
|
1026
|
+
...(event.source ? { source: event.source } : {}),
|
|
1027
|
+
});
|
|
1028
|
+
break;
|
|
1029
|
+
|
|
721
1030
|
case "response-complete":
|
|
722
1031
|
if (session.canonicalJsonlSession === true) {
|
|
723
1032
|
const settled = this._settleCanonicalSuccess(
|
|
@@ -983,25 +1292,194 @@ export class WSAgentHandler {
|
|
|
983
1292
|
});
|
|
984
1293
|
break;
|
|
985
1294
|
|
|
986
|
-
case "/compact":
|
|
987
|
-
if (
|
|
988
|
-
const
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
1295
|
+
case "/compact": {
|
|
1296
|
+
if (this._compactionSettlementBlock) {
|
|
1297
|
+
const block = this._compactionSettlementBlock;
|
|
1298
|
+
this.interaction.emit("compaction-degraded", {
|
|
1299
|
+
requestId,
|
|
1300
|
+
reason: block.reason,
|
|
1301
|
+
summaryMode: "none",
|
|
1302
|
+
code: block.code,
|
|
1303
|
+
});
|
|
1304
|
+
this.interaction.emit("command-response", {
|
|
1305
|
+
requestId,
|
|
1306
|
+
command: cmd,
|
|
1307
|
+
result: {
|
|
1308
|
+
messageCount: session.messages.length,
|
|
1309
|
+
error: block,
|
|
1310
|
+
},
|
|
1311
|
+
});
|
|
1312
|
+
break;
|
|
1313
|
+
}
|
|
1314
|
+
|
|
1315
|
+
const before = session.messages.length;
|
|
1316
|
+
const expectedMessages = [...session.messages];
|
|
1317
|
+
let result = null;
|
|
1318
|
+
let commandError = null;
|
|
1319
|
+
try {
|
|
1320
|
+
this._sessionHostLease?.assert?.();
|
|
1321
|
+
result = await compactConversationWithProvider(session.messages, {
|
|
1322
|
+
provider: session.provider,
|
|
1323
|
+
model: session.model,
|
|
1324
|
+
baseUrl: session.baseUrl,
|
|
1325
|
+
apiKey: session.apiKey,
|
|
1326
|
+
signal: this._sessionHostLease?.signal,
|
|
1327
|
+
force: true,
|
|
1328
|
+
preserveCompletedExchange: true,
|
|
1329
|
+
llmQuery: this._compactionLlmQuery,
|
|
1330
|
+
chatFn: this._compactionChatFn,
|
|
1331
|
+
chatOptions: {
|
|
1332
|
+
cwd: session.projectRoot,
|
|
1333
|
+
sessionId: session.id,
|
|
1334
|
+
},
|
|
1335
|
+
maxOutputTokens: session.compactionMaxOutputTokens,
|
|
1336
|
+
summaryInputMaxChars: session.compactionInputMaxChars,
|
|
1337
|
+
});
|
|
1338
|
+
this._sessionHostLease?.assert?.();
|
|
1339
|
+
} catch (error) {
|
|
1340
|
+
if (isAbortError(error) || this._sessionHostLease?.signal?.aborted) {
|
|
1341
|
+
throw error;
|
|
1342
|
+
}
|
|
1343
|
+
commandError = this._latchCompactionSettlement({
|
|
1344
|
+
code: error?.code || "CC_COMPACTION_FAILED",
|
|
1345
|
+
reason: `compaction_failed:${String(error?.message || error).slice(0, 240)}`,
|
|
1346
|
+
commitState: "provider-outcome-unknown",
|
|
1347
|
+
});
|
|
1348
|
+
this.interaction.emit("compaction-degraded", {
|
|
1349
|
+
requestId,
|
|
1350
|
+
reason: commandError.reason,
|
|
1351
|
+
summaryMode: "none",
|
|
1352
|
+
code: commandError.code,
|
|
1353
|
+
});
|
|
1354
|
+
}
|
|
1355
|
+
if (result) {
|
|
1356
|
+
const {
|
|
1357
|
+
messages,
|
|
1358
|
+
stats,
|
|
1359
|
+
degradedEvent,
|
|
1360
|
+
usageEvent,
|
|
1361
|
+
usageUnknownEvent,
|
|
1362
|
+
} = result;
|
|
1363
|
+
if (degradedEvent) {
|
|
1364
|
+
this.interaction.emit("compaction-degraded", {
|
|
1365
|
+
requestId,
|
|
1366
|
+
...degradedEvent,
|
|
1367
|
+
});
|
|
1368
|
+
}
|
|
1369
|
+
if (usageUnknownEvent) {
|
|
1370
|
+
commandError = this._emitCompactionUsageUnknown(
|
|
1371
|
+
requestId,
|
|
1372
|
+
usageUnknownEvent,
|
|
1373
|
+
);
|
|
1374
|
+
}
|
|
1375
|
+
const messagesChanged =
|
|
1376
|
+
session.messages.length !== expectedMessages.length ||
|
|
1377
|
+
session.messages.some(
|
|
1378
|
+
(message, index) => message !== expectedMessages[index],
|
|
1379
|
+
);
|
|
1380
|
+
let settlementError = null;
|
|
1381
|
+
if (
|
|
1382
|
+
!commandError &&
|
|
1383
|
+
!messagesChanged &&
|
|
1384
|
+
session.canonicalJsonlSession === true
|
|
1385
|
+
) {
|
|
1386
|
+
if (stats?.strategy !== "none") {
|
|
1387
|
+
try {
|
|
1388
|
+
const settlement =
|
|
1389
|
+
this._canonicalSessionStore.appendCompactEventIfMessagesMatch(
|
|
1390
|
+
session.id,
|
|
1391
|
+
{
|
|
1392
|
+
...stats,
|
|
1393
|
+
trigger: "manual",
|
|
1394
|
+
messages: projectCanonicalResumeMessages(messages, {
|
|
1395
|
+
strict: true,
|
|
1396
|
+
}),
|
|
1397
|
+
},
|
|
1398
|
+
expectedMessages,
|
|
1399
|
+
);
|
|
1400
|
+
if (settlement && typeof settlement.then === "function") {
|
|
1401
|
+
void Promise.resolve(settlement).catch(() => {});
|
|
1402
|
+
const error = new TypeError(
|
|
1403
|
+
"Canonical compact settlement must be synchronous",
|
|
1404
|
+
);
|
|
1405
|
+
error.code = "CC_COMPACTION_SETTLEMENT_ASYNC";
|
|
1406
|
+
throw error;
|
|
1407
|
+
}
|
|
1408
|
+
} catch (error) {
|
|
1409
|
+
settlementError = error;
|
|
1410
|
+
}
|
|
1411
|
+
}
|
|
1412
|
+
}
|
|
1413
|
+
|
|
1414
|
+
if (!commandError && !messagesChanged && !settlementError) {
|
|
1415
|
+
session.messages.length = 0;
|
|
1416
|
+
session.messages.push(...messages);
|
|
1417
|
+
this.interaction.emit("compaction", {
|
|
1418
|
+
requestId,
|
|
1419
|
+
stats,
|
|
1420
|
+
messagesBefore: before,
|
|
1421
|
+
messagesAfter: session.messages.length,
|
|
1422
|
+
});
|
|
1423
|
+
} else if (!commandError) {
|
|
1424
|
+
const stale = settlementError?.code === "SESSION_REVISION_STALE";
|
|
1425
|
+
let reconciled = false;
|
|
1426
|
+
if (stale) {
|
|
1427
|
+
try {
|
|
1428
|
+
const authoritativeMessages =
|
|
1429
|
+
this._canonicalSessionStore.readVerifiedMessages(session.id);
|
|
1430
|
+
if (!Array.isArray(authoritativeMessages)) {
|
|
1431
|
+
throw new TypeError(
|
|
1432
|
+
"Canonical message refresh must be synchronous",
|
|
1433
|
+
);
|
|
1434
|
+
}
|
|
1435
|
+
this._applyCanonicalMessages(authoritativeMessages);
|
|
1436
|
+
this._reconcileCompactionSettlementBlock();
|
|
1437
|
+
reconciled = true;
|
|
1438
|
+
} catch {
|
|
1439
|
+
// Latch below until a later verified canonical refresh.
|
|
1440
|
+
}
|
|
1441
|
+
}
|
|
1442
|
+
commandError =
|
|
1443
|
+
reconciled && stale
|
|
1444
|
+
? {
|
|
1445
|
+
code: "CC_COMPACTION_REVISION_STALE",
|
|
1446
|
+
reason: "session_messages_changed_during_compaction",
|
|
1447
|
+
commitState: "reconciled-stale",
|
|
1448
|
+
}
|
|
1449
|
+
: this._latchCompactionSettlement({
|
|
1450
|
+
code:
|
|
1451
|
+
settlementError?.code ||
|
|
1452
|
+
(messagesChanged
|
|
1453
|
+
? "CC_COMPACTION_LOCAL_STATE_CHANGED"
|
|
1454
|
+
: "CC_COMPACTION_SETTLEMENT_UNKNOWN"),
|
|
1455
|
+
reason:
|
|
1456
|
+
messagesChanged || stale
|
|
1457
|
+
? "session_messages_changed_during_compaction"
|
|
1458
|
+
: "canonical_compaction_settlement_failed",
|
|
1459
|
+
commitState: "unknown",
|
|
1460
|
+
});
|
|
1461
|
+
this.interaction.emit("compaction-degraded", {
|
|
1462
|
+
requestId,
|
|
1463
|
+
reason: commandError.reason,
|
|
1464
|
+
summaryMode: "none",
|
|
1465
|
+
code: commandError.code,
|
|
1466
|
+
});
|
|
1467
|
+
}
|
|
1468
|
+
// Provider usage is emitted exactly once even when the message CAS
|
|
1469
|
+
// rejects the candidate; the paid request already happened and is
|
|
1470
|
+
// never retried by this command.
|
|
1471
|
+
this._emitCompactionUsage(requestId, usageEvent);
|
|
998
1472
|
}
|
|
999
1473
|
this.interaction.emit("command-response", {
|
|
1000
1474
|
requestId,
|
|
1001
1475
|
command: cmd,
|
|
1002
|
-
result: {
|
|
1476
|
+
result: {
|
|
1477
|
+
messageCount: session.messages.length,
|
|
1478
|
+
...(commandError ? { error: commandError } : {}),
|
|
1479
|
+
},
|
|
1003
1480
|
});
|
|
1004
1481
|
break;
|
|
1482
|
+
}
|
|
1005
1483
|
|
|
1006
1484
|
case "/task":
|
|
1007
1485
|
if (arg === "clear") {
|