chainlesschain 0.166.128 → 0.166.129

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 (167) hide show
  1. package/README.md +18 -4
  2. package/package.json +1 -1
  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-BmGA5zXX.js → AIOps-CjPaaF2r.js} +1 -1
  6. package/src/assets/web-panel/assets/{ActionButton-B7WXwoF0.js → ActionButton-_zlP_Z6z.js} +1 -1
  7. package/src/assets/web-panel/assets/{Analytics-IvJG43B5.js → Analytics-C7X31L8l.js} +2 -2
  8. package/src/assets/web-panel/assets/{AppLayout-DWY017_e.js → AppLayout-BmYa34Se.js} +5 -5
  9. package/src/assets/web-panel/assets/Artifacts-B_YKNjlp.js +1 -0
  10. package/src/assets/web-panel/assets/{Audit-CD9sTnBN.js → Audit-5JsI67XQ.js} +1 -1
  11. package/src/assets/web-panel/assets/{BackgroundAgents-J6gg5z0U.js → BackgroundAgents-BL3QbzvS.js} +1 -1
  12. package/src/assets/web-panel/assets/{Backup-D7ik3lse.js → Backup-BRmg-gTa.js} +1 -1
  13. package/src/assets/web-panel/assets/{BaseInput-MrDd5zcz.js → BaseInput-DNE7mT3K.js} +1 -1
  14. package/src/assets/web-panel/assets/{Chat-DbxRqGiK.js → Chat-OYwAopdM.js} +5 -5
  15. package/src/assets/web-panel/assets/ChatBubbleRenderer-Dtxw3Wgt.js +1 -0
  16. package/src/assets/web-panel/assets/{Checkbox-CditB77B.js → Checkbox-nMgYkH8H.js} +1 -1
  17. package/src/assets/web-panel/assets/{Codegen-Ds0UZWZG.js → Codegen-B9G2ngLI.js} +1 -1
  18. package/src/assets/web-panel/assets/{Col-CZlj1XI2.js → Col-i0owJaGP.js} +1 -1
  19. package/src/assets/web-panel/assets/{Community-j4B2SoT6.js → Community-B3Ta0mI_.js} +1 -1
  20. package/src/assets/web-panel/assets/{Compact-BuKQutaO.js → Compact-DDXrvvm-.js} +1 -1
  21. package/src/assets/web-panel/assets/{Compliance-DAgDyS-p.js → Compliance-Bn4Uq6U1.js} +1 -1
  22. package/src/assets/web-panel/assets/{Cowork-DX2-I6V3.js → Cowork-CO5NKD6r.js} +2 -2
  23. package/src/assets/web-panel/assets/{Cron-dJpc-FxX.js → Cron-ByjNese0.js} +2 -2
  24. package/src/assets/web-panel/assets/{Crosschain-7m8euM3v.js → Crosschain-BN1FUYyi.js} +1 -1
  25. package/src/assets/web-panel/assets/{DID-CLoYoCe1.js → DID-CUFX5RL3.js} +2 -2
  26. package/src/assets/web-panel/assets/{Dashboard-DR1rRMb7.js → Dashboard-D_2FDPBP.js} +2 -2
  27. package/src/assets/web-panel/assets/{Dropdown-BsKhCfvH.js → Dropdown-lGOMtIzb.js} +1 -1
  28. package/src/assets/web-panel/assets/{EmailListRenderer-BAGexzJu.js → EmailListRenderer-DA3Qf1S2.js} +1 -1
  29. package/src/assets/web-panel/assets/EvolutionSettings-DLcnicCr.js +1 -0
  30. package/src/assets/web-panel/assets/{FamilyGuardDashboard-BIpueefy.js → FamilyGuardDashboard-BPOSaIN1.js} +1 -1
  31. package/src/assets/web-panel/assets/{Federation-BluNep6d.js → Federation-DzJUCQq8.js} +1 -1
  32. package/src/assets/web-panel/assets/{FormItemContext-CerdM3am.js → FormItemContext-DVx1XNKx.js} +1 -1
  33. package/src/assets/web-panel/assets/{GenericCardRenderer-DXh4tOjU.js → GenericCardRenderer-BkqzO_lh.js} +1 -1
  34. package/src/assets/web-panel/assets/{Git-CEE0cGmf.js → Git-Dr_rdT_j.js} +2 -2
  35. package/src/assets/web-panel/assets/{Governance-Bc-XNDhM.js → Governance-DyVkZddw.js} +1 -1
  36. package/src/assets/web-panel/assets/{Inference-CiBzXyZ-.js → Inference-IN2YDd4v.js} +1 -1
  37. package/src/assets/web-panel/assets/{KnowledgeGraph-CV2IiyuN.js → KnowledgeGraph-Ceiy4n6N.js} +1 -1
  38. package/src/assets/web-panel/assets/{Logs-fbQYKuSz.js → Logs-d7pIEAX2.js} +2 -2
  39. package/src/assets/web-panel/assets/{MarkdownRenderer-B73ZyMRI.js → MarkdownRenderer-DmSl0MNI.js} +1 -1
  40. package/src/assets/web-panel/assets/{Marketplace-C5utdpxZ.js → Marketplace-uVE7U14g.js} +1 -1
  41. package/src/assets/web-panel/assets/{McpTools-CPE4SaF3.js → McpTools-DUfBM--y.js} +3 -3
  42. package/src/assets/web-panel/assets/{Memory-DTFDszzk.js → Memory-6gkcR02J.js} +2 -2
  43. package/src/assets/web-panel/assets/{MobileBridge-DxqPmTzP.js → MobileBridge-Cl6ys2O9.js} +1 -1
  44. package/src/assets/web-panel/assets/{MobileProjects-CwcK8l2y.js → MobileProjects-5P8jN4gf.js} +1 -1
  45. package/src/assets/web-panel/assets/{Mtc-DrjECLGO.js → Mtc-DtiT1Kol.js} +2 -2
  46. package/src/assets/web-panel/assets/{MtcAudit-4IURCa-3.js → MtcAudit-DZz8iiTE.js} +5 -5
  47. package/src/assets/web-panel/assets/{Multisig-CggLV1Cp.js → Multisig-DFH3-fBJ.js} +3 -3
  48. package/src/assets/web-panel/assets/{NLProgramming-DkOQJT73.js → NLProgramming-BYNuDOt-.js} +1 -1
  49. package/src/assets/web-panel/assets/{Notes-Dodcva6s.js → Notes-BCY4jgYy.js} +3 -3
  50. package/src/assets/web-panel/assets/{NotificationSettings-CQ3HeTs6.js → NotificationSettings-Bk2ltghU.js} +1 -1
  51. package/src/assets/web-panel/assets/OrderTableRenderer-OdeXEGAn.js +1 -0
  52. package/src/assets/web-panel/assets/{Organization-B6HFsIfU.js → Organization-CY4_mSiV.js} +2 -2
  53. package/src/assets/web-panel/assets/{Overflow-G9dju55N.js → Overflow-CaRUAOY_.js} +1 -1
  54. package/src/assets/web-panel/assets/{P2P-C1BCE155.js → P2P-Bd96rBWQ.js} +2 -2
  55. package/src/assets/web-panel/assets/{PdhVaultBrowser-BFAxXn5D.js → PdhVaultBrowser-JjnExxan.js} +3 -3
  56. package/src/assets/web-panel/assets/{Permissions-DWg7cw9Q.js → Permissions-CW1PUJB0.js} +2 -2
  57. package/src/assets/web-panel/assets/{PersonalDataHub-BQxuOQOO.js → PersonalDataHub-BNn9alTk.js} +3 -3
  58. package/src/assets/web-panel/assets/{Pipeline-C3Gse9Ne.js → Pipeline-01_PBiUu.js} +1 -1
  59. package/src/assets/web-panel/assets/{Privacy-Dcsjx6Oi.js → Privacy-BP4DlVGb.js} +1 -1
  60. package/src/assets/web-panel/assets/{ProjectInit-DeYlnXJQ.js → ProjectInit-CAMnQj4n.js} +2 -2
  61. package/src/assets/web-panel/assets/{ProjectSettings-D7kbZ_K7.js → ProjectSettings-DKxV5On_.js} +2 -2
  62. package/src/assets/web-panel/assets/{Projects-C5m3NGzM.js → Projects-B_4kRnM8.js} +1 -1
  63. package/src/assets/web-panel/assets/{Providers-oT6jy83z.js → Providers-DeqqZyUv.js} +1 -1
  64. package/src/assets/web-panel/assets/{QrScannerModal-NZ11GEBa.js → QrScannerModal-fFkycCT4.js} +1 -1
  65. package/src/assets/web-panel/assets/{QuickAsk-CtQU4Tx0.js → QuickAsk-Ln6qQidy.js} +1 -1
  66. package/src/assets/web-panel/assets/{Recommend-3CoXYu3O.js → Recommend-DeENA-y0.js} +1 -1
  67. package/src/assets/web-panel/assets/{RemoteSession-C2d4LzBM.js → RemoteSession-CRxSYxo4.js} +2 -2
  68. package/src/assets/web-panel/assets/{Reputation-WZQHrGwl.js → Reputation-B2kU2F0l.js} +1 -1
  69. package/src/assets/web-panel/assets/{Row-ChiqY7Hg.js → Row-lV_nLlFq.js} +1 -1
  70. package/src/assets/web-panel/assets/{RssFeed-Cjwl2Kum.js → RssFeed-Df21mCdF.js} +2 -2
  71. package/src/assets/web-panel/assets/{Search-DRDMZxTF.js → Search-8_Dz4qU9.js} +1 -1
  72. package/src/assets/web-panel/assets/{Security-D0y4LlQ4.js → Security-Cl5-PEcp.js} +2 -2
  73. package/src/assets/web-panel/assets/{Services-ChpkqWm0.js → Services-C5qgCqA7.js} +2 -2
  74. package/src/assets/web-panel/assets/{Skeleton-D3WGZ8yO.js → Skeleton-ASRgSh_Y.js} +1 -1
  75. package/src/assets/web-panel/assets/{Skills-Bv_7HaUW.js → Skills-DWx01ZJ7.js} +1 -1
  76. package/src/assets/web-panel/assets/{Sla-crZMKyX0.js → Sla-I2gbgtW8.js} +1 -1
  77. package/src/assets/web-panel/assets/{SpeechSettings-ByWn5XDZ.js → SpeechSettings-BqTikzfe.js} +1 -1
  78. package/src/assets/web-panel/assets/{SyncSettings--R55vxvj.js → SyncSettings-D3zCpBFV.js} +2 -2
  79. package/src/assets/web-panel/assets/{Tasks-BZA_Via_.js → Tasks-DjMWII45.js} +1 -1
  80. package/src/assets/web-panel/assets/{Templates-9eJ9yY8Q.js → Templates-Cq7qDnHX.js} +1 -1
  81. package/src/assets/web-panel/assets/{Tenant-CfWX2jqj.js → Tenant-DEasKDpQ.js} +1 -1
  82. package/src/assets/web-panel/assets/{Terminal-CUXUF4kL.js → Terminal-J6fLkTzi.js} +2 -2
  83. package/src/assets/web-panel/assets/{TimelineRenderer-77y9bkYN.js → TimelineRenderer-CNvWrWN-.js} +1 -1
  84. package/src/assets/web-panel/assets/{Tokens-CvyrdLH6.js → Tokens-BSgHJCKH.js} +1 -1
  85. package/src/assets/web-panel/assets/{Trigger-MNRl_YNr.js → Trigger-DgGU_D0o.js} +1 -1
  86. package/src/assets/web-panel/assets/{Trust-BHOXK-Mp.js → Trust-BANlv-uB.js} +1 -1
  87. package/src/assets/web-panel/assets/{UkeySign-Bz1oZNyQ.js → UkeySign-qh8GPRsU.js} +1 -1
  88. package/src/assets/web-panel/assets/{VideoEditing-DlqmXyZv.js → VideoEditing-DBiGTB4H.js} +1 -1
  89. package/src/assets/web-panel/assets/{Wallet-Dg1rnqEG.js → Wallet-DMUFR7cL.js} +2 -2
  90. package/src/assets/web-panel/assets/{WebAuthn-DJtGeaOk.js → WebAuthn-DP9nQQzW.js} +3 -3
  91. package/src/assets/web-panel/assets/{WorkflowEditor-DJPubjX5.js → WorkflowEditor-DT_6jDkL.js} +1 -1
  92. package/src/assets/web-panel/assets/{chat-BWweDuIV.js → chat-C_kELmV6.js} +1 -1
  93. package/src/assets/web-panel/assets/{colors-BX5ViADF.js → colors-DE-ZxAv_.js} +1 -1
  94. package/src/assets/web-panel/assets/{compact-item-Df8MLbXp.js → compact-item-BowulLDi.js} +1 -1
  95. package/src/assets/web-panel/assets/{createContext-C0FDTwdV.js → createContext-DCh8oMBQ.js} +1 -1
  96. package/src/assets/web-panel/assets/devWarning-BVvJAp91.js +1 -0
  97. package/src/assets/web-panel/assets/{hasIn-PpL6GdNk.js → hasIn-Be7mK-iw.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-P1ERNJla.js → index-3Ql7xQLn.js} +1 -1
  99. package/src/assets/web-panel/assets/{index-BF0ERucU.js → index-4KkYmFy5.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-B4UxFB2N.js → index-6OluUVJJ.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-DGLbojjx.js → index-Ao-LXr-d.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-D5Ei75Wt.js → index-B-3EDOlf.js} +1 -1
  103. package/src/assets/web-panel/assets/index-B7IhCfsh.js +1 -0
  104. package/src/assets/web-panel/assets/{index-R0LQ3fgq.js → index-BDIIR8g6.js} +1 -1
  105. package/src/assets/web-panel/assets/index-BMrbe_Ey.js +1 -0
  106. package/src/assets/web-panel/assets/{index-itNn6pW1.js → index-BdzVLz-c.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-Cj00JSqq.js → index-BlzMqaWB.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-Cm7vZvA3.js → index-BwY31W-u.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-UXM5vpt4.js → index-C2pCquZC.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-DBzaRg4E.js → index-CKmC6ugN.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-Beh1kLwx.js → index-CL2hAUWh.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-BMIEWinN.js → index-CUXfwAhF.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-C2JU-gdS.js → index-CXvy8HrM.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-FAZH69my.js → index-C_VnSUjh.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-BeFhy4BX.js → index-CecGCLWI.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-C0PqPK-8.js → index-Ck6MYKVN.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-DxJqyIP8.js → index-Cvy4vdVW.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-DddQd0_V.js → index-CwJfLNqv.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-B3K1uZ7R.js → index-D3lOYd9_.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-iif2A1eL.js → index-DEDVYN7D.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-ChV82mzs.js → index-DLCzaLH4.js} +1 -1
  122. package/src/assets/web-panel/assets/{index-Cf86RSQk.js → index-DMDaGPxG.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-7VyVOEf7.js → index-DMKo49Um.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-NdEUFm32.js → index-DN1AT3FH.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-BWSCphaT.js → index-DOebEvgn.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-D_6XIMVV.js → index-DPX3N4T8.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-DFtzEEYe.js → index-DSRKtgJg.js} +1 -1
  128. package/src/assets/web-panel/assets/{index-B982oUKN.js → index-DSqZBvQM.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-CxY_U5RT.js → index-DbrQO1p9.js} +1 -1
  130. package/src/assets/web-panel/assets/{index-Dy8K2laU.js → index-DjC2TJeH.js} +1 -1
  131. package/src/assets/web-panel/assets/{index-C9N1u8jV.js → index-LVrxqU88.js} +1 -1
  132. package/src/assets/web-panel/assets/{index-C9FOwTgX.js → index-OH54KMLN.js} +1 -1
  133. package/src/assets/web-panel/assets/{index-CmMzB4C-.js → index-Qx8cTReg.js} +3 -3
  134. package/src/assets/web-panel/assets/{index-B8-pSyP7.js → index-_cYsz4df.js} +1 -1
  135. package/src/assets/web-panel/assets/{index-DwZkBGXd.js → index-lN916819.js} +1 -1
  136. package/src/assets/web-panel/assets/{index-C8wl7Ica.js → index-nLHTuHoT.js} +1 -1
  137. package/src/assets/web-panel/assets/{initDefaultProps-DeMthvi4.js → initDefaultProps-BNhziAal.js} +1 -1
  138. package/src/assets/web-panel/assets/{motion-_7kbkzE0.js → motion-fUkbJz38.js} +1 -1
  139. package/src/assets/web-panel/assets/{move-gCI04pLw.js → move-rFx211Cl.js} +1 -1
  140. package/src/assets/web-panel/assets/{mtc-parser-D5UWHv2U.js → mtc-parser-CEP1wN3R.js} +1 -1
  141. package/src/assets/web-panel/assets/{omit-CDCZcqeS.js → omit-DacHd_Zm.js} +1 -1
  142. package/src/assets/web-panel/assets/{pickAttrs-DGMDLi3S.js → pickAttrs-Dqp58Ep2.js} +1 -1
  143. package/src/assets/web-panel/assets/{placementArrow-C-3vC1Vh.js → placementArrow-Cv6Rm0pV.js} +1 -1
  144. package/src/assets/web-panel/assets/{responsiveObserve-vdoYucvi.js → responsiveObserve-rNE0p9ZW.js} +1 -1
  145. package/src/assets/web-panel/assets/{slide-B62FhgyZ.js → slide-C97JxD4S.js} +1 -1
  146. package/src/assets/web-panel/assets/{statusUtils-DCLlfnym.js → statusUtils-Cxk1gV9M.js} +1 -1
  147. package/src/assets/web-panel/assets/{styleChecker-CGvQ4LRR.js → styleChecker-CbtKKsPo.js} +1 -1
  148. package/src/assets/web-panel/assets/{useFlexGapSupport-BqkGoKwe.js → useFlexGapSupport-CQATs2JQ.js} +1 -1
  149. package/src/assets/web-panel/assets/{useFs-Bkr_nU3q.js → useFs-6c7qrpE_.js} +1 -1
  150. package/src/assets/web-panel/assets/{usePersonalDataHub-CYxMIUEq.js → usePersonalDataHub-OjxtBGe7.js} +1 -1
  151. package/src/assets/web-panel/assets/{vnode-sAbcY1FX.js → vnode-CSlXfUSh.js} +1 -1
  152. package/src/assets/web-panel/assets/{zoom-Dm2pLrXi.js → zoom-Cc1qKiSZ.js} +1 -1
  153. package/src/assets/web-panel/index.html +1 -1
  154. package/src/data/changelog.json +13 -0
  155. package/src/lib/codex-app-server-adapter.js +36 -22
  156. package/src/lib/codex-app-server-support.js +91 -0
  157. package/src/lib/coding-change-review-context.js +258 -0
  158. package/src/lib/coding-task-guidance.js +3 -0
  159. package/src/lib/context-memory-kernel/provider-context.js +22 -12
  160. package/src/runtime/agent-core.js +125 -40
  161. package/src/assets/web-panel/assets/Artifacts-BOyohM_-.js +0 -1
  162. package/src/assets/web-panel/assets/ChatBubbleRenderer-DbeJAwMg.js +0 -1
  163. package/src/assets/web-panel/assets/EvolutionSettings-BqYYmC01.js +0 -1
  164. package/src/assets/web-panel/assets/OrderTableRenderer-pT2nzmIO.js +0 -1
  165. package/src/assets/web-panel/assets/devWarning-BgM5vq1s.js +0 -1
  166. package/src/assets/web-panel/assets/index-Bl-HTXWn.js +0 -1
  167. package/src/assets/web-panel/assets/index-Cxf0YfM5.js +0 -1
@@ -1,6 +1,19 @@
1
1
  {
2
2
  "source": "CHANGELOG.md",
3
3
  "releases": [
4
+ {
5
+ "productVersion": null,
6
+ "cliVersion": "0.166.129",
7
+ "cliVersions": ["0.166.129"],
8
+ "date": "2026-10-28",
9
+ "title": "",
10
+ "sections": [
11
+ {
12
+ "heading": "Fixed - cc CLI 0.166.129: independent change review and Codex support evidence (candidate, 2026-10-28)",
13
+ "body": "- Give opted-in hermetic change review its own request context and tool journal, preserving original requirements, shared request limits, permissions and cancellation. Missing review usage blocks further calls; review is not independent task acceptance.\n- Centralize experimental Codex App Server support, versioned schema probes and CI targets. Keep default-off routing and the existing experimental allowlist; probe-only 0.160.0 and 0.164.0 do not imply production admission.\n- Verify concurrent thread recovery with explicit database recency pagination on Linux, Windows and macOS. Retain documented limitations for default rollout scanning and legacy creation-time pagination.\n- Retain published child dependencies. Candidate publication requires exact-commit CLI CI and Strict Sandbox across all configured systems, GitHub Actions OIDC publication and public artifact readback. Historical task and native acceptance remain separately reported."
14
+ }
15
+ ]
16
+ },
4
17
  {
5
18
  "productVersion": null,
6
19
  "cliVersion": "0.166.128",
@@ -1,13 +1,17 @@
1
1
  import { EventEmitter } from "node:events";
2
-
3
- export const CODEX_APP_SERVER_PROTOCOL = "codex-app-server-experimental-v1";
4
- export const CODEX_APP_SERVER_FEATURE_FLAG = "CC_EXPERIMENTAL_CODEX_APP_SERVER";
5
- export const CODEX_APP_SERVER_COMPATIBILITY_MATRIX = Object.freeze([
6
- Object.freeze({ version: "0.149.0" }),
7
- Object.freeze({ version: "0.150.0" }),
8
- Object.freeze({ version: "0.150.1" }),
9
- Object.freeze({ version: "0.154.0" }),
10
- ]);
2
+ import {
3
+ CODEX_APP_SERVER_PROTOCOL,
4
+ CODEX_APP_SERVER_FEATURE_FLAG,
5
+ CODEX_APP_SERVER_FALLBACK_PROTOCOL,
6
+ CODEX_APP_SERVER_COMPATIBILITY_MATRIX,
7
+ getCodexAppServerSupport,
8
+ parseCodexVersion,
9
+ } from "./codex-app-server-support.js";
10
+ export {
11
+ CODEX_APP_SERVER_PROTOCOL,
12
+ CODEX_APP_SERVER_FEATURE_FLAG,
13
+ CODEX_APP_SERVER_COMPATIBILITY_MATRIX,
14
+ } from "./codex-app-server-support.js";
11
15
 
12
16
  function adapterError(code, message, details = {}) {
13
17
  const error = new Error(message);
@@ -17,17 +21,10 @@ function adapterError(code, message, details = {}) {
17
21
  return error;
18
22
  }
19
23
 
20
- function parseVersion(value) {
21
- const match = String(value || "")
22
- .trim()
23
- .match(/^(?:codex(?:-cli)?\s+)?(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)$/u);
24
- return match ? match.slice(1).map(Number).join(".") : null;
25
- }
26
-
27
24
  export function isCodexAppServerVersionCompatible(version, matrix = []) {
28
- const parsed = parseVersion(version);
25
+ const parsed = parseCodexVersion(version);
29
26
  if (!parsed || !Array.isArray(matrix) || matrix.length === 0) return false;
30
- return matrix.some((entry) => parseVersion(entry?.version) === parsed);
27
+ return matrix.some((entry) => parseCodexVersion(entry?.version) === parsed);
31
28
  }
32
29
 
33
30
  function projectNotification(notification) {
@@ -182,11 +179,16 @@ export class CodexAppServerAdapter extends EventEmitter {
182
179
  productionCritical: false,
183
180
  featureFlag: CODEX_APP_SERVER_FEATURE_FLAG,
184
181
  enabled: this.enabled,
182
+ support: getCodexAppServerSupport(this.upstreamVersion),
183
+ compatibilitySource:
184
+ this.compatibilityMatrix === CODEX_APP_SERVER_COMPATIBILITY_MATRIX
185
+ ? "manifest"
186
+ : "override",
185
187
  versionCompatible: isCodexAppServerVersionCompatible(
186
188
  this.upstreamVersion,
187
189
  this.compatibilityMatrix,
188
190
  ),
189
- fallback: "codex-exec-jsonl-v1",
191
+ fallback: CODEX_APP_SERVER_FALLBACK_PROTOCOL,
190
192
  });
191
193
  }
192
194
 
@@ -302,6 +304,7 @@ export class CodexAppServerAdapter extends EventEmitter {
302
304
  const buildResult = (terminalEvent) =>
303
305
  Object.freeze({
304
306
  protocol: CODEX_APP_SERVER_PROTOCOL,
307
+ support: claims.support,
305
308
  threadId: activeThreadId,
306
309
  turnId: activeTurnId,
307
310
  terminal: terminalEvent.terminal,
@@ -388,13 +391,23 @@ export class CodexAppServerAdapter extends EventEmitter {
388
391
  throw adapterError(
389
392
  "CC_CODEX_APP_SERVER_SUBMISSION_UNKNOWN",
390
393
  "Codex App Server turn submission outcome is unknown; fallback was suppressed to prevent duplicate effects",
391
- { cause: error },
394
+ {
395
+ cause: error,
396
+ protocol: CODEX_APP_SERVER_PROTOCOL,
397
+ fallbackSuppressed: true,
398
+ support: claims.support,
399
+ },
392
400
  );
393
401
  }
394
402
  throw adapterError(
395
403
  "CC_CODEX_APP_SERVER_FAILED_AFTER_ADMISSION",
396
404
  "Codex App Server failed after the turn was admitted; fallback was suppressed to prevent duplicate effects",
397
- { cause: error },
405
+ {
406
+ cause: error,
407
+ protocol: CODEX_APP_SERVER_PROTOCOL,
408
+ fallbackSuppressed: true,
409
+ support: claims.support,
410
+ },
398
411
  );
399
412
  } finally {
400
413
  clearTimeout(timer);
@@ -412,7 +425,8 @@ export class CodexAppServerAdapter extends EventEmitter {
412
425
  const result = await this.fallback({ prompt, ...options });
413
426
  return Object.freeze({
414
427
  ...result,
415
- protocol: "codex-exec-jsonl-v1",
428
+ protocol: CODEX_APP_SERVER_FALLBACK_PROTOCOL,
429
+ support: getCodexAppServerSupport(this.upstreamVersion),
416
430
  fallback: true,
417
431
  fallbackReason: reason,
418
432
  authoritative: false,
@@ -0,0 +1,91 @@
1
+ // Configured probe coverage is not evidence that a workflow passed. Admission
2
+ // stays separate from both probe configuration and the experimental allowlist.
3
+ export const CODEX_APP_SERVER_PROTOCOL = "codex-app-server-experimental-v1";
4
+ export const CODEX_APP_SERVER_FEATURE_FLAG = "CC_EXPERIMENTAL_CODEX_APP_SERVER";
5
+ export const CODEX_APP_SERVER_FALLBACK_PROTOCOL = "codex-exec-jsonl-v1";
6
+
7
+ export const CODEX_APP_SERVER_SUPPORT = Object.freeze({
8
+ revision: "2026-10-28",
9
+ defaultEnabled: false,
10
+ productionAdmitted: false,
11
+ platforms: Object.freeze([
12
+ Object.freeze({ platform: "linux", runner: "ubuntu-latest" }),
13
+ Object.freeze({ platform: "windows", runner: "windows-latest" }),
14
+ Object.freeze({ platform: "macos", runner: "macos-latest" }),
15
+ ]),
16
+ versions: Object.freeze([
17
+ ...["0.149.0", "0.150.0", "0.150.1", "0.154.0"].map((version) =>
18
+ Object.freeze({
19
+ version,
20
+ experimentalAllowed: true,
21
+ compatibilityProbeConfigured: true,
22
+ schemaAndTurnProbeConfigured: false,
23
+ }),
24
+ ),
25
+ ...["0.160.0", "0.164.0"].map((version) =>
26
+ Object.freeze({
27
+ version,
28
+ experimentalAllowed: false,
29
+ compatibilityProbeConfigured: false,
30
+ schemaAndTurnProbeConfigured: true,
31
+ }),
32
+ ),
33
+ ]),
34
+ });
35
+
36
+ export const CODEX_APP_SERVER_COMPATIBILITY_MATRIX = Object.freeze(
37
+ CODEX_APP_SERVER_SUPPORT.versions
38
+ .filter((entry) => entry.experimentalAllowed)
39
+ .map(({ version }) => Object.freeze({ version })),
40
+ );
41
+
42
+ export const CODEX_APP_SERVER_SCHEMA_PROBE_VERSIONS = Object.freeze(
43
+ CODEX_APP_SERVER_SUPPORT.versions
44
+ .filter((entry) => entry.schemaAndTurnProbeConfigured)
45
+ .map((entry) => entry.version),
46
+ );
47
+ // Keep the original default for callers that do not specify a probe version.
48
+ export const CODEX_APP_SERVER_SCHEMA_PROBE_VERSION =
49
+ CODEX_APP_SERVER_SCHEMA_PROBE_VERSIONS[0];
50
+
51
+ export function parseCodexVersion(value) {
52
+ const match = String(value || "")
53
+ .trim()
54
+ .match(/^(?:codex(?:-cli)?\s+)?(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)$/u);
55
+ return match ? match.slice(1).join(".") : null;
56
+ }
57
+
58
+ export function getCodexAppServerSupport(version) {
59
+ const upstreamVersion = parseCodexVersion(version);
60
+ const entry = CODEX_APP_SERVER_SUPPORT.versions.find(
61
+ (candidate) => candidate.version === upstreamVersion,
62
+ );
63
+ return Object.freeze({
64
+ manifestRevision: CODEX_APP_SERVER_SUPPORT.revision,
65
+ upstreamVersion,
66
+ knownVersion: Boolean(entry),
67
+ defaultEnabled: CODEX_APP_SERVER_SUPPORT.defaultEnabled,
68
+ productionAdmitted: CODEX_APP_SERVER_SUPPORT.productionAdmitted,
69
+ experimentalAllowed: entry?.experimentalAllowed === true,
70
+ compatibilityProbeConfigured: entry?.compatibilityProbeConfigured === true,
71
+ schemaAndTurnProbeConfigured: entry?.schemaAndTurnProbeConfigured === true,
72
+ });
73
+ }
74
+
75
+ export function codexAppServerCiMatrices() {
76
+ const entries = (predicate) => ({
77
+ include: CODEX_APP_SERVER_SUPPORT.versions
78
+ .filter(predicate)
79
+ .flatMap(({ version }) =>
80
+ CODEX_APP_SERVER_SUPPORT.platforms.map(({ platform, runner }) => ({
81
+ platform,
82
+ runner,
83
+ codex_version: version,
84
+ })),
85
+ ),
86
+ });
87
+ return {
88
+ compatibility: entries((entry) => entry.compatibilityProbeConfigured),
89
+ schema: entries((entry) => entry.schemaAndTurnProbeConfigured),
90
+ };
91
+ }
@@ -0,0 +1,258 @@
1
+ import { isDeepStrictEqual } from "node:util";
2
+ import {
3
+ DURABLE_SYSTEM_MESSAGE_KINDS,
4
+ SESSION_MESSAGE_PROVENANCE_FIELD,
5
+ encodePersistedMessage,
6
+ getDurableSystemMessageProvenance,
7
+ isRuntimeOnlySessionMessage,
8
+ } from "./session-message-provenance.js";
9
+
10
+ function snapshot(message) {
11
+ const copy = encodePersistedMessage(message);
12
+ if (!copy || typeof copy !== "object" || Array.isArray(copy)) {
13
+ throw new TypeError("Review context requires plain message objects");
14
+ }
15
+ return copy;
16
+ }
17
+
18
+ function hasContent(message) {
19
+ return (
20
+ (typeof message.content === "string" &&
21
+ message.content.trim().length > 0) ||
22
+ (Array.isArray(message.content) && message.content.length > 0)
23
+ );
24
+ }
25
+
26
+ function mergeAdjacentUsers(messages) {
27
+ const projected = [];
28
+ for (const message of messages) {
29
+ const previous = projected.at(-1);
30
+ if (previous?.role !== "user" || message.role !== "user") {
31
+ projected.push(message);
32
+ continue;
33
+ }
34
+ // Message-level metadata can have provider-specific scope. Dropping it or
35
+ // attaching it to a larger user turn could change meaning or authority.
36
+ if (
37
+ [previous, message].some((entry) =>
38
+ Object.keys(entry).some((key) => !["role", "content"].includes(key)),
39
+ )
40
+ ) {
41
+ throw new TypeError("Cannot safely merge review user message metadata");
42
+ }
43
+ const left = previous.content;
44
+ const right = message.content;
45
+ if (
46
+ ![left, right].every(
47
+ (content) => typeof content === "string" || Array.isArray(content),
48
+ )
49
+ ) {
50
+ throw new TypeError("Cannot safely merge review user message content");
51
+ }
52
+ const blocks = (content) =>
53
+ Array.isArray(content) ? content : [{ type: "text", text: content }];
54
+ previous.content =
55
+ typeof left === "string" && typeof right === "string"
56
+ ? `${left}\n\n${right}`
57
+ : [...blocks(left), ...blocks(right)];
58
+ }
59
+ return projected;
60
+ }
61
+
62
+ function contentSegments(content) {
63
+ const blocks =
64
+ typeof content === "string" ? [{ type: "text", text: content }] : content;
65
+ if (!Array.isArray(blocks))
66
+ throw new TypeError("Invalid review requirement content");
67
+ const segments = [];
68
+ for (const block of blocks) {
69
+ // Blocks with provider metadata are not interchangeable with plain text.
70
+ if (
71
+ block?.type === "text" &&
72
+ typeof block.text === "string" &&
73
+ Object.keys(block).every((key) => ["type", "text"].includes(key))
74
+ ) {
75
+ if (typeof segments.at(-1) === "string")
76
+ segments[segments.length - 1] += block.text;
77
+ else segments.push(block.text);
78
+ } else segments.push(block);
79
+ }
80
+ return segments;
81
+ }
82
+
83
+ function preservesContent(expected, actual, allowSuffix) {
84
+ const required = contentSegments(expected);
85
+ const supplied = contentSegments(actual);
86
+ if (
87
+ supplied.length < required.length ||
88
+ (!allowSuffix && supplied.length !== required.length)
89
+ )
90
+ return false;
91
+ return required.every((segment, index) => {
92
+ if (
93
+ allowSuffix &&
94
+ index === required.length - 1 &&
95
+ typeof segment === "string"
96
+ ) {
97
+ return (
98
+ typeof supplied[index] === "string" &&
99
+ supplied[index].startsWith(segment)
100
+ );
101
+ }
102
+ return isDeepStrictEqual(segment, supplied[index]);
103
+ });
104
+ }
105
+
106
+ function pendingCalls(messages) {
107
+ const pending = new Set();
108
+ for (const message of messages) {
109
+ if (message.role === "tool") {
110
+ if (!pending.delete(message.tool_call_id)) {
111
+ throw new TypeError("Review tool result has no pending call");
112
+ }
113
+ continue;
114
+ }
115
+ if (pending.size) {
116
+ throw new TypeError("Review tool call group is incomplete");
117
+ }
118
+ if (message.tool_calls !== undefined) {
119
+ if (message.role !== "assistant" || !Array.isArray(message.tool_calls)) {
120
+ throw new TypeError("Invalid review tool calls");
121
+ }
122
+ // Provider IDs are scoped to a tool batch, matching agentLoop. A fully
123
+ // settled later batch may reuse an ID without making its result orphaned.
124
+ const seen = new Set();
125
+ for (const call of message.tool_calls) {
126
+ if (typeof call?.id !== "string" || !call.id || seen.has(call.id)) {
127
+ throw new TypeError("Review tool call IDs must be unique strings");
128
+ }
129
+ seen.add(call.id);
130
+ pending.add(call.id);
131
+ }
132
+ }
133
+ }
134
+ return pending;
135
+ }
136
+
137
+ /**
138
+ * Request-only context for one independent review within the existing loop.
139
+ * The caller supplies pristine host-built task messages before compaction;
140
+ * unmarked system messages must already be trusted host instructions.
141
+ * This journal neither replaces durable history nor grants any authority.
142
+ */
143
+ export class CodingChangeReviewContext {
144
+ #initial;
145
+ #journal = [];
146
+ #active = false;
147
+
148
+ constructor(initialMessages) {
149
+ // Validate the entire input without invoking accessors before inspecting it.
150
+ const validated = snapshot({ messages: initialMessages }).messages;
151
+ if (!Array.isArray(validated)) {
152
+ throw new TypeError("Review context requires initial task messages");
153
+ }
154
+ this.#initial = [];
155
+ for (const message of initialMessages) {
156
+ const copy = snapshot(message);
157
+ if (isRuntimeOnlySessionMessage(message)) continue;
158
+ const provenance = getDurableSystemMessageProvenance(message);
159
+ if (provenance) {
160
+ if (provenance.kind === DURABLE_SYSTEM_MESSAGE_KINDS.FORK_LINEAGE) {
161
+ continue;
162
+ }
163
+ throw new TypeError(
164
+ "Review requires original requirements before summarization",
165
+ );
166
+ }
167
+ if (Object.hasOwn(message, SESSION_MESSAGE_PROVENANCE_FIELD)) {
168
+ throw new TypeError(
169
+ "Review context cannot trust serialized provenance",
170
+ );
171
+ }
172
+ if (!["system", "user"].includes(copy.role)) continue;
173
+ if (!hasContent(copy) || copy.tool_calls || copy.tool_call_id) {
174
+ throw new TypeError("Review requirements must have valid content");
175
+ }
176
+ this.#initial.push(copy);
177
+ }
178
+ if (!this.#initial.some((message) => message.role === "user")) {
179
+ throw new TypeError("Review requires original user requirements");
180
+ }
181
+ }
182
+
183
+ get active() {
184
+ return this.#active;
185
+ }
186
+
187
+ activate(reviewPromptMessage) {
188
+ if (this.#active) return false;
189
+ const prompt = snapshot(reviewPromptMessage);
190
+ if (
191
+ prompt.role !== "user" ||
192
+ !hasContent(prompt) ||
193
+ prompt.tool_calls ||
194
+ prompt.tool_call_id
195
+ ) {
196
+ throw new TypeError("Review prompt must be a user-role instruction");
197
+ }
198
+ this.#journal = [prompt];
199
+ this.#active = true;
200
+ return true;
201
+ }
202
+
203
+ record(...messages) {
204
+ if (!this.#active) return;
205
+ const copies = messages.map((message) => {
206
+ const copy = snapshot(message);
207
+ if (
208
+ !["assistant", "tool"].includes(copy.role) &&
209
+ !(copy.role === "user" && isRuntimeOnlySessionMessage(message))
210
+ ) {
211
+ throw new TypeError(
212
+ "Review journal accepts only review responses and runtime nudges",
213
+ );
214
+ }
215
+ return copy;
216
+ });
217
+ const next = [...this.#journal, ...copies];
218
+ pendingCalls(next);
219
+ this.#journal = next;
220
+ }
221
+
222
+ /** Fail closed if request normalization or context planning dropped scope. */
223
+ assertRequirementsPreserved(projectedMessages) {
224
+ if (!this.#active) throw new TypeError("Review context is not active");
225
+ const supplied = snapshot({ messages: projectedMessages }).messages;
226
+ if (!Array.isArray(supplied))
227
+ throw new TypeError("Invalid review provider messages");
228
+ const required = mergeAdjacentUsers(this.#initial.map(snapshot));
229
+ for (let index = 0; index < required.length; index++) {
230
+ const expected = required[index];
231
+ const actual = supplied[index];
232
+ if (
233
+ !actual ||
234
+ actual.role !== expected.role ||
235
+ !preservesContent(
236
+ expected.content,
237
+ actual.content,
238
+ expected.role === "user",
239
+ )
240
+ ) {
241
+ throw new TypeError(
242
+ "Review provider context did not preserve original requirements",
243
+ );
244
+ }
245
+ }
246
+ return true;
247
+ }
248
+
249
+ project() {
250
+ if (!this.#active) throw new TypeError("Review context is not active");
251
+ if (pendingCalls(this.#journal).size) {
252
+ throw new TypeError("Review tool call group is incomplete");
253
+ }
254
+ return mergeAdjacentUsers(
255
+ [...this.#initial, ...this.#journal].map(snapshot),
256
+ );
257
+ }
258
+ }
@@ -4,6 +4,7 @@ export const CODING_TASK_QUALITY_GUIDANCE = `Coding task quality:
4
4
  - Keep progress explanations to one or two sentences. Once the relevant API and behavior are clear, make the next tool call; resolve a remaining uncertainty with a targeted read. Put implementation code directly in write/edit tool arguments instead of rehearsing the code or repeatedly analyzing the same source in ordinary assistant text.
5
5
  - Resolve each relative import from the destination file's directory. Read back the completed file and fix newDiagnostics from write/edit results before finishing. A successful write confirms persistence, not syntax, test execution or acceptance.
6
6
  - Before finishing a regression task, map each explicit acceptance requirement to a concrete fixture, production call path and observable assertion in the deliverable. Positive and negative controls must exercise the same requested behavior and differ in the intended condition. Resolve uncovered requirements with permitted tools, or report the specific gap. Avoid mocks or alternate calls that bypass the behavior under test. Complete the current worker/request when testing cancellation and replacement.
7
+ - Allocate limited test cases from the user's explicit requirements, not from the tests already written. A test-count cap is a prioritization budget, not permission to omit a requirement. Merge or replace equivalent cases that reach the same decision so uncovered requirements take priority. Repair known coverage gaps within the authorized scope and remaining budgets; if a gap cannot be resolved, report the task as incomplete.
7
8
  - For boundary regressions, derive expected defaults, computed values and rejection rules from the implementation or the explicit requested contract. Inject mismatched, tampered or stale input through the real entry point while keeping other prerequisites valid; verify that the fixture reaches the intended check rather than failing during setup. Compare observable results with independent expected values or authoritative state, not a helper that merely recomputes the same result.
8
9
  - Trace rejection before asserting its aftermath: a request can be rejected before registration or persistence. Check whether state stays unchanged, a failed record is saved, or an event is emitted; do not assume every rejection creates a failed task. When testing attribution, verify independently recorded identities and provenance as well as message contents; identical text can still be attributed to the wrong source.
9
10
  - Use available execution tools for a focused check when permitted. When execution tools are unavailable, inspect imports, API contracts and fixtures using the available file tools, and clearly say that tests were not run. Never describe a read-back or static check as a passing test or end-to-end verification.
@@ -17,5 +18,7 @@ Return a concise, evidence-based completion message within these tool limits.`;
17
18
 
18
19
  /** Optional runtime follow-up; contains no task-specific acceptance information. */
19
20
  export const CODING_CHANGE_REVIEW_PROMPT = `Runtime change review: the original user task, authorized scope, tools and remaining budgets still apply; this message grants no new permissions.
21
+ Inspect the current deliverable and relevant source with the permitted tools. Build your own requirement-to-assertion account before accepting the existing implementation; earlier completion explanations are not evidence. For a negative control, keep unrelated rejection conditions valid so another guard cannot mask a missing check. Check the actual order of observable effects when an operation throws.
20
22
  Before finishing, check the changed deliverable against each explicit requirement. For regression tests, identify the concrete fixture, actual production call path and observable assertion for each requirement. Confirm that positive and negative controls reach the intended behavior with valid prerequisites and differ in the intended condition. Similar field names and unrelated rejection paths do not establish coverage.
23
+ Derive that requirement list from the original task, not from the tests already written. If a test-count cap is reached, merge or replace redundant cases reaching the same decision to cover missing requirements within that cap. Use the remaining budget to repair an identified gap rather than treating the count cap as a scope exemption. A reported missing requirement means the task remains incomplete.
21
24
  Use permitted tools to inspect and repair any gap. Run focused checks only when execution tools are available. If a requirement remains uncovered or a check cannot be run, report that specific limitation. This review is not evidence that tests or independent acceptance passed. Give a concise final answer when finished.`;
@@ -189,7 +189,12 @@ export async function prepareCanonicalProviderContext(
189
189
  };
190
190
  }
191
191
 
192
- const candidateProvider = semanticCandidateProvider(options);
192
+ // Review can exclude recalled author/session data while retaining the exact
193
+ // canonical context, tool and output-token planning boundary.
194
+ const recallEnabled = options.contextMemoryRecall !== false;
195
+ const candidateProvider = recallEnabled
196
+ ? semanticCandidateProvider(options)
197
+ : null;
193
198
  const sink = String(options.contextMemorySink || `provider.${provider}`);
194
199
  const scopeAdmissions = defaultAdmissions(sessionId, options);
195
200
  const lastUser = [...messages]
@@ -211,17 +216,22 @@ export async function prepareCanonicalProviderContext(
211
216
  scopeAdmissions,
212
217
  limit: recallLimit,
213
218
  });
214
- const recall = await runtime.kernel.recallMemory({
215
- query,
216
- sink,
217
- scopeAdmissions,
218
- limit: recallLimit,
219
- tokenBudget: Math.max(
220
- 1,
221
- Math.min(32_768, Number(options.contextMemoryRecallTokens) || 4096),
222
- ),
223
- ...(semanticCandidates === undefined ? {} : { semanticCandidates }),
224
- });
219
+ const recall = recallEnabled
220
+ ? await runtime.kernel.recallMemory({
221
+ query,
222
+ sink,
223
+ scopeAdmissions,
224
+ limit: recallLimit,
225
+ tokenBudget: Math.max(
226
+ 1,
227
+ Math.min(32_768, Number(options.contextMemoryRecallTokens) || 4096),
228
+ ),
229
+ ...(semanticCandidates === undefined ? {} : { semanticCandidates }),
230
+ })
231
+ : {
232
+ results: [],
233
+ memoryRevision: await runtime.memoryPort.getRevision(),
234
+ };
225
235
  const imageTransport = captureContextImageTransport(messages);
226
236
  const messageItems = adjustContextImageTokenEstimates(
227
237
  messagesToContextItems(imageTransport.messages, {