chainlesschain 0.166.71 → 0.166.74

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 (164) hide show
  1. package/README.md +26 -4
  2. package/package.json +2 -1
  3. package/scripts/pm-exploration-effect.mjs +188 -0
  4. package/src/assets/web-panel/assets/{AIOps-6n6RPfD2.js → AIOps-BlIvP3k1.js} +1 -1
  5. package/src/assets/web-panel/assets/{ActionButton-BRlz1g77.js → ActionButton-DYF7atSV.js} +1 -1
  6. package/src/assets/web-panel/assets/{Analytics-BFx6_nNR.js → Analytics-LZYaYek6.js} +3 -3
  7. package/src/assets/web-panel/assets/{AppLayout-CcbKe_m4.js → AppLayout-BJxrjNbj.js} +5 -5
  8. package/src/assets/web-panel/assets/{Artifacts-DlBMxBaf.js → Artifacts-gEDhxhmE.js} +1 -1
  9. package/src/assets/web-panel/assets/{Audit-aqQRi1IW.js → Audit-B0MR950Q.js} +1 -1
  10. package/src/assets/web-panel/assets/{BackgroundAgents-tzAQeiAS.js → BackgroundAgents-3e6Os_Kl.js} +1 -1
  11. package/src/assets/web-panel/assets/{Backup-C3sLPZvj.js → Backup-DB_X8KUg.js} +1 -1
  12. package/src/assets/web-panel/assets/{BaseInput-BdqG7xax.js → BaseInput-DTNcvNeG.js} +1 -1
  13. package/src/assets/web-panel/assets/{Chat-DXjdkR-r.js → Chat-SnqdA62j.js} +6 -6
  14. package/src/assets/web-panel/assets/{ChatBubbleRenderer-B-3SVP-4.js → ChatBubbleRenderer-BaiWNH_V.js} +1 -1
  15. package/src/assets/web-panel/assets/{Checkbox-CACOSDhS.js → Checkbox-Dj0O4dyP.js} +1 -1
  16. package/src/assets/web-panel/assets/{Codegen-ZY0zbHvS.js → Codegen-BeelW3dx.js} +1 -1
  17. package/src/assets/web-panel/assets/{Col-C511kzpa.js → Col-BmstiyBM.js} +1 -1
  18. package/src/assets/web-panel/assets/{Community-CIM5EtmR.js → Community-CrbmFk3f.js} +1 -1
  19. package/src/assets/web-panel/assets/{Compact-DpTxu8E7.js → Compact-DCg5ZPIw.js} +1 -1
  20. package/src/assets/web-panel/assets/{Compliance-Cu42ksf-.js → Compliance-B3sajhq7.js} +1 -1
  21. package/src/assets/web-panel/assets/{Cowork-BqUbCW9U.js → Cowork-DWcdvrDK.js} +4 -4
  22. package/src/assets/web-panel/assets/{Cron-OXYE4gRs.js → Cron-Bjwp_NDf.js} +2 -2
  23. package/src/assets/web-panel/assets/{Crosschain-DPqmhSi6.js → Crosschain-BXTLC9o8.js} +1 -1
  24. package/src/assets/web-panel/assets/{DID-CPp_yj85.js → DID-Di62M46b.js} +2 -2
  25. package/src/assets/web-panel/assets/{Dashboard-pki3T5PE.js → Dashboard-BQED8Rkt.js} +2 -2
  26. package/src/assets/web-panel/assets/{Dropdown-IyL1RsjP.js → Dropdown-DEf9VYaj.js} +1 -1
  27. package/src/assets/web-panel/assets/{EmailListRenderer-6Kbwb4Ux.js → EmailListRenderer-DhFpPMAM.js} +1 -1
  28. package/src/assets/web-panel/assets/{EvolutionSettings-DGBMs24I.js → EvolutionSettings-BOqmzkpS.js} +1 -1
  29. package/src/assets/web-panel/assets/{FamilyGuardDashboard-CLz3KJvw.js → FamilyGuardDashboard-BxBnJ4fe.js} +1 -1
  30. package/src/assets/web-panel/assets/{Federation-gMDCbNjS.js → Federation-BN9Q8nsZ.js} +1 -1
  31. package/src/assets/web-panel/assets/{FormItemContext-bSzQnHE6.js → FormItemContext-CGeqFEd-.js} +1 -1
  32. package/src/assets/web-panel/assets/{GenericCardRenderer-DCyBnm6B.js → GenericCardRenderer-DElmWQTc.js} +1 -1
  33. package/src/assets/web-panel/assets/{Git-BKqZtZMD.js → Git-BHBSgKck.js} +2 -2
  34. package/src/assets/web-panel/assets/{Governance-nZDU4Gz2.js → Governance-Breo3NTU.js} +1 -1
  35. package/src/assets/web-panel/assets/{Inference-VodzHgdz.js → Inference-CCABy4E0.js} +1 -1
  36. package/src/assets/web-panel/assets/{KnowledgeGraph-DHjlnyh4.js → KnowledgeGraph-B6_ryn-X.js} +1 -1
  37. package/src/assets/web-panel/assets/{Logs-CPsAssGM.js → Logs-CkmJjJok.js} +2 -2
  38. package/src/assets/web-panel/assets/{MarkdownRenderer-ChogLgLv.js → MarkdownRenderer-DQEQBaRu.js} +1 -1
  39. package/src/assets/web-panel/assets/{Marketplace-Df7Cr8cW.js → Marketplace-iip65jxv.js} +1 -1
  40. package/src/assets/web-panel/assets/{McpTools-Dy_V6M2q.js → McpTools-DDwp_QLb.js} +2 -2
  41. package/src/assets/web-panel/assets/{Memory-DjYWvH5O.js → Memory-2ZmNDRkC.js} +2 -2
  42. package/src/assets/web-panel/assets/{MobileBridge-qYw4QwQh.js → MobileBridge-C6HilwZl.js} +1 -1
  43. package/src/assets/web-panel/assets/MobileProjects-BeMtYRhx.js +1 -0
  44. package/src/assets/web-panel/assets/{Mtc-BQ2fg2aQ.js → Mtc-Bp-FEcoo.js} +5 -5
  45. package/src/assets/web-panel/assets/{MtcAudit-CaBVA8Cu.js → MtcAudit-DNdkTCe5.js} +2 -2
  46. package/src/assets/web-panel/assets/{Multisig-DsTt5nuM.js → Multisig-PnKg2_Eo.js} +3 -3
  47. package/src/assets/web-panel/assets/{NLProgramming-CqpsGgiz.js → NLProgramming-DDp4lZeG.js} +1 -1
  48. package/src/assets/web-panel/assets/{Notes-DpRTGRs9.js → Notes-DEjFktcO.js} +4 -4
  49. package/src/assets/web-panel/assets/{NotificationSettings-CmHeyjUS.js → NotificationSettings-FR8fJDAn.js} +1 -1
  50. package/src/assets/web-panel/assets/{OrderTableRenderer-D-JBdzGf.js → OrderTableRenderer-Cyc-XI0L.js} +1 -1
  51. package/src/assets/web-panel/assets/{Organization-QL01Gu7d.js → Organization-DNW2E_JU.js} +4 -4
  52. package/src/assets/web-panel/assets/{Overflow-DjUeTZ69.js → Overflow-BHfd6wk6.js} +1 -1
  53. package/src/assets/web-panel/assets/{P2P-DuM6UaEh.js → P2P-COIkaXH4.js} +2 -2
  54. package/src/assets/web-panel/assets/{PdhVaultBrowser-BsL5CbMs.js → PdhVaultBrowser-DuRP0UeX.js} +3 -3
  55. package/src/assets/web-panel/assets/{Permissions-Cfu4vMf9.js → Permissions-BfVRGMy8.js} +4 -4
  56. package/src/assets/web-panel/assets/{PersonalDataHub-HvEGAMl5.js → PersonalDataHub-BWYjO6Aa.js} +5 -5
  57. package/src/assets/web-panel/assets/{Pipeline-_CZIYXJs.js → Pipeline-C0e0fPBW.js} +1 -1
  58. package/src/assets/web-panel/assets/{Privacy-C6bTNjwi.js → Privacy-CnId4Jv-.js} +1 -1
  59. package/src/assets/web-panel/assets/{ProjectInit-D64UJRfZ.js → ProjectInit-CYf1grXg.js} +2 -2
  60. package/src/assets/web-panel/assets/{ProjectSettings-CSTAzKVe.js → ProjectSettings-HsXgJdiH.js} +2 -2
  61. package/src/assets/web-panel/assets/{Projects-BudNMgcm.js → Projects-Bi0r9QcC.js} +1 -1
  62. package/src/assets/web-panel/assets/{Providers-C7ddN75H.js → Providers-B-Tu_-_4.js} +1 -1
  63. package/src/assets/web-panel/assets/{QrScannerModal-CtsMC0eH.js → QrScannerModal-CPDqYT2F.js} +1 -1
  64. package/src/assets/web-panel/assets/{QuickAsk-iE7xKI4P.js → QuickAsk-Df6qcjXy.js} +1 -1
  65. package/src/assets/web-panel/assets/{Recommend-5FCqoy3g.js → Recommend-dP6sfGSY.js} +1 -1
  66. package/src/assets/web-panel/assets/{RemoteSession-DtX0VARB.js → RemoteSession-VAt9-tM3.js} +2 -2
  67. package/src/assets/web-panel/assets/{Reputation-Hd4dH5ci.js → Reputation-DtRVRiLI.js} +1 -1
  68. package/src/assets/web-panel/assets/{Row-CnLRjeGC.js → Row-B6Ukqvli.js} +1 -1
  69. package/src/assets/web-panel/assets/{RssFeed-Ds43ubF9.js → RssFeed-DfVRQMrZ.js} +3 -3
  70. package/src/assets/web-panel/assets/{Search-BmXOdvpt.js → Search-CyncAiqQ.js} +1 -1
  71. package/src/assets/web-panel/assets/{Security--yQqv9yt.js → Security-DEO7nrkb.js} +4 -4
  72. package/src/assets/web-panel/assets/{Services-CNNPxlyA.js → Services-CkusQEhN.js} +2 -2
  73. package/src/assets/web-panel/assets/{Skeleton-DPmZAdDN.js → Skeleton-CbGtO3kc.js} +1 -1
  74. package/src/assets/web-panel/assets/{Skills-Va_WxW7s.js → Skills-diOh0gAr.js} +1 -1
  75. package/src/assets/web-panel/assets/{Sla-BZoRsy3v.js → Sla-CIu9Ahak.js} +1 -1
  76. package/src/assets/web-panel/assets/{SpeechSettings-XgRV95VE.js → SpeechSettings-_Nzyi4K9.js} +1 -1
  77. package/src/assets/web-panel/assets/{SyncSettings-Dr7NXCEw.js → SyncSettings-BAOLFlRq.js} +2 -2
  78. package/src/assets/web-panel/assets/{Tasks-j-xRo5_-.js → Tasks-BpmvL1Eq.js} +1 -1
  79. package/src/assets/web-panel/assets/{Templates-BJSqGQuB.js → Templates-Dkr_vRdJ.js} +1 -1
  80. package/src/assets/web-panel/assets/{Tenant-zuVl_JY7.js → Tenant-kM7lHUFR.js} +1 -1
  81. package/src/assets/web-panel/assets/{Terminal-B-xNbgfG.js → Terminal-9zfc41aU.js} +2 -2
  82. package/src/assets/web-panel/assets/{TimelineRenderer-BtZQpa0b.js → TimelineRenderer-Cg_7j6cj.js} +1 -1
  83. package/src/assets/web-panel/assets/{Tokens-CXGqGXWd.js → Tokens-Cs1aikaM.js} +1 -1
  84. package/src/assets/web-panel/assets/{Trigger-CtDmejyH.js → Trigger-DKYPJ9gl.js} +1 -1
  85. package/src/assets/web-panel/assets/{Trust-BfDvBu2B.js → Trust-BFy1Sm8B.js} +1 -1
  86. package/src/assets/web-panel/assets/{UkeySign-CgHq72xW.js → UkeySign-B31L9NBH.js} +1 -1
  87. package/src/assets/web-panel/assets/{VideoEditing-pRBMqiGT.js → VideoEditing-OMmUYdIC.js} +1 -1
  88. package/src/assets/web-panel/assets/{Wallet-DHhZSHFo.js → Wallet-y3aE7oru.js} +4 -4
  89. package/src/assets/web-panel/assets/{WebAuthn-C-PDGO1-.js → WebAuthn-C0ICKvpu.js} +4 -4
  90. package/src/assets/web-panel/assets/{WorkflowEditor-Dqrh4ooE.js → WorkflowEditor-Cq5UYbr5.js} +1 -1
  91. package/src/assets/web-panel/assets/{chat-Du4rhkgo.js → chat-B1ijaKFv.js} +1 -1
  92. package/src/assets/web-panel/assets/{colors-CVVon0Yw.js → colors-CHkI8PDg.js} +1 -1
  93. package/src/assets/web-panel/assets/{compact-item-zcQv_R_9.js → compact-item-1BYvgWEs.js} +1 -1
  94. package/src/assets/web-panel/assets/{createContext-UfW2PpZM.js → createContext-BGti56u4.js} +1 -1
  95. package/src/assets/web-panel/assets/devWarning-Isft1nEX.js +1 -0
  96. package/src/assets/web-panel/assets/{hasIn-Dko6kq4D.js → hasIn-Cr87Fph1.js} +1 -1
  97. package/src/assets/web-panel/assets/{index-DMdBtncl.js → index-1WxCzqYq.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-DwXm_6Df.js → index-6Ta8Pg47.js} +1 -1
  99. package/src/assets/web-panel/assets/{index-Dgu3vko5.js → index-B1yur8MU.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-jjgfplWj.js → index-B4BSM3BK.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-ija7mc1b.js → index-B8Jb_cGt.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-Cs4qAz6z.js → index-BA0FMuDX.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-BwcE8uKT.js → index-BKb16YKp.js} +1 -1
  104. package/src/assets/web-panel/assets/{index-5UfwyzQV.js → index-BOjTRSHE.js} +3 -3
  105. package/src/assets/web-panel/assets/{index-BPE8w-x1.js → index-BYpqBWlt.js} +1 -1
  106. package/src/assets/web-panel/assets/index-B_T9NUk7.js +1 -0
  107. package/src/assets/web-panel/assets/{index-DMxhURG4.js → index-Bdkrut2A.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-CJ72HeXg.js → index-BjgtiMdY.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-BoQJIWkq.js → index-BkFXPrdx.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-BolCTH1Q.js → index-Bni5GodE.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-DqQhty7h.js → index-CDTNnQDz.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-BEOOJevs.js → index-CQWMHlY7.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-CoXowCMA.js → index-CS0MIE2C.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-7aNfa1q3.js → index-C_lEztok.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-DhYE_jVw.js → index-CbkGda_k.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-CV8kORgq.js → index-CevUJTXd.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-DIFh_pNy.js → index-CjBkVrq9.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-CrURt95p.js → index-CkcWhgLB.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-BXqsNksk.js → index-CmmSJBNi.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-Dkc1L9vQ.js → index-CvcpesEZ.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-Dviw8PsD.js → index-Cvu95WPI.js} +1 -1
  122. package/src/assets/web-panel/assets/{index-Dh1USRx7.js → index-D6g4jxdE.js} +1 -1
  123. package/src/assets/web-panel/assets/index-DBqUxaat.js +1 -0
  124. package/src/assets/web-panel/assets/{index-BR5eNU_w.js → index-DCkvhzaY.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-CPqtDZE1.js → index-DHJtAEx8.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-0d3V2fKV.js → index-DJjnXDAD.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-4YoVVwaY.js → index-Dam-LB_J.js} +1 -1
  128. package/src/assets/web-panel/assets/{index-BHq5RTAk.js → index-DcoI3ENn.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-CrbxgYRx.js → index-Dnp-4yPc.js} +1 -1
  130. package/src/assets/web-panel/assets/{index-ubMuGX5r.js → index-Duv0TfJa.js} +1 -1
  131. package/src/assets/web-panel/assets/{index-B8nu6_LV.js → index-DzevrmLK.js} +1 -1
  132. package/src/assets/web-panel/assets/{index-UzXoeYbz.js → index-fhpMyq0u.js} +1 -1
  133. package/src/assets/web-panel/assets/{index-BPTQ-SUp.js → index-rO6VKJv5.js} +1 -1
  134. package/src/assets/web-panel/assets/{index-D4-E1s34.js → index-rVnXNFST.js} +1 -1
  135. package/src/assets/web-panel/assets/{index-DKAB6MRs.js → index-tY479EoQ.js} +1 -1
  136. package/src/assets/web-panel/assets/{initDefaultProps-DvSMOW2m.js → initDefaultProps-DAGtnwoX.js} +1 -1
  137. package/src/assets/web-panel/assets/{motion-C7PjuFda.js → motion-02FXBi5C.js} +1 -1
  138. package/src/assets/web-panel/assets/{move-qsgDmMqu.js → move-BLf7rhzJ.js} +1 -1
  139. package/src/assets/web-panel/assets/{mtc-parser-D7qHulCC.js → mtc-parser-Ct6i1vqQ.js} +1 -1
  140. package/src/assets/web-panel/assets/{omit-g_tGmcIM.js → omit-DKvTU8IT.js} +1 -1
  141. package/src/assets/web-panel/assets/{pickAttrs-DGs-br4p.js → pickAttrs-DqDsKoMe.js} +1 -1
  142. package/src/assets/web-panel/assets/{placementArrow-A1KZT5yH.js → placementArrow-kae6Cnwx.js} +1 -1
  143. package/src/assets/web-panel/assets/{responsiveObserve-B98U6Yi5.js → responsiveObserve-DzFM_TQf.js} +1 -1
  144. package/src/assets/web-panel/assets/{slide-Y5Q6ixV9.js → slide-qDjNFPuM.js} +1 -1
  145. package/src/assets/web-panel/assets/{statusUtils-CVC7D579.js → statusUtils-BihSr7G3.js} +1 -1
  146. package/src/assets/web-panel/assets/{styleChecker-CDWAgZKa.js → styleChecker-BzoT0TfJ.js} +1 -1
  147. package/src/assets/web-panel/assets/{useFlexGapSupport-C0UFofSm.js → useFlexGapSupport-CjXXcU1j.js} +1 -1
  148. package/src/assets/web-panel/assets/{useFs-BHEf6SSo.js → useFs-DrWcbDJ1.js} +1 -1
  149. package/src/assets/web-panel/assets/{usePersonalDataHub-Bb2M_BPj.js → usePersonalDataHub-DO1oBNTE.js} +1 -1
  150. package/src/assets/web-panel/assets/{vnode-DENyLaXR.js → vnode-BR6crWko.js} +1 -1
  151. package/src/assets/web-panel/assets/{zoom-BUOUP8-I.js → zoom-DmKLfw6W.js} +1 -1
  152. package/src/assets/web-panel/index.html +1 -1
  153. package/src/data/changelog.json +39 -0
  154. package/src/lib/decision-layer/benchmark.js +64 -3
  155. package/src/lib/decision-layer/runtime.js +18 -5
  156. package/src/lib/evolution/evolution-eval-gate.js +289 -32
  157. package/src/lib/evolution/pm-exploration-benchmark.js +2014 -49
  158. package/src/lib/evolution/skill-writer-inventory-manifest.js +4 -1
  159. package/src/lib/task-progress-tracker.js +47 -4
  160. package/src/runtime/agent-core.js +18 -7
  161. package/src/assets/web-panel/assets/MobileProjects-DDA7pzJd.js +0 -1
  162. package/src/assets/web-panel/assets/devWarning-CoA1apwL.js +0 -1
  163. package/src/assets/web-panel/assets/index-CsR4S29Z.js +0 -1
  164. package/src/assets/web-panel/assets/index-DvcAyRFh.js +0 -1
@@ -3,9 +3,46 @@ import { performance } from "node:perf_hooks";
3
3
  import { decisionDigest } from "./contracts.js";
4
4
 
5
5
  export const SKILL_DECISION_BENCHMARK_SCHEMA =
6
- "chainlesschain.skill-decision-benchmark/v1";
6
+ "chainlesschain.skill-decision-benchmark/v2";
7
7
 
8
8
  const DIGEST = /^sha256:[a-f0-9]{64}$/u;
9
+ const ONE_SIDED_ALPHA = 0.05;
10
+
11
+ // Exact Clopper-Pearson upper bound: find p where P(Binomial(n, p) <= k)
12
+ // equals alpha. Keep zero-denominator metrics inconclusive.
13
+ function binomialUpperBound(errors, trials) {
14
+ if (trials === 0) return null;
15
+ if (errors === trials) return 1;
16
+ if (errors === 0) return -Math.expm1(Math.log(ONE_SIDED_ALPHA) / trials);
17
+
18
+ const logFactorials = [0];
19
+ for (let i = 1; i <= trials; i += 1) {
20
+ logFactorials.push(logFactorials[i - 1] + Math.log(i));
21
+ }
22
+ const logCombination =
23
+ logFactorials[trials] -
24
+ logFactorials[errors] -
25
+ logFactorials[trials - errors];
26
+ let lower = errors / trials;
27
+ let upper = 1;
28
+ for (let iteration = 0; iteration < 60; iteration += 1) {
29
+ const probability = (lower + upper) / 2;
30
+ let term = Math.exp(
31
+ logCombination +
32
+ errors * Math.log(probability) +
33
+ (trials - errors) * Math.log1p(-probability),
34
+ );
35
+ let cumulative = term;
36
+ for (let count = errors; count > 0; count -= 1) {
37
+ term *=
38
+ (count / (trials - count + 1)) * ((1 - probability) / probability);
39
+ cumulative += term;
40
+ }
41
+ if (cumulative > ONE_SIDED_ALPHA) lower = probability;
42
+ else upper = probability;
43
+ }
44
+ return (lower + upper) / 2;
45
+ }
9
46
 
10
47
  function ratio(value, label) {
11
48
  const number = Number(value);
@@ -141,6 +178,23 @@ export async function runSkillDecisionBenchmark({
141
178
  unavailableRate: unavailable / normalizedCases.length,
142
179
  p95Ms: latencies[Math.max(0, Math.ceil(latencies.length * 0.95) - 1)],
143
180
  });
181
+ const counts = Object.freeze({
182
+ accepted,
183
+ acceptedErrors,
184
+ positives,
185
+ affirmative,
186
+ noMatches,
187
+ noMatchFalseSuggestions,
188
+ abstentions,
189
+ unavailable,
190
+ });
191
+ const oneSided95Upper = Object.freeze({
192
+ acceptedSuggestionErrorRate: binomialUpperBound(acceptedErrors, accepted),
193
+ noMatchFalseSuggestionRate: binomialUpperBound(
194
+ noMatchFalseSuggestions,
195
+ noMatches,
196
+ ),
197
+ });
144
198
  const core = {
145
199
  schema: SKILL_DECISION_BENCHMARK_SCHEMA,
146
200
  caseCount: normalizedCases.length,
@@ -150,9 +204,16 @@ export async function runSkillDecisionBenchmark({
150
204
  ),
151
205
  thresholds: gate,
152
206
  metrics,
207
+ counts,
208
+ oneSided95Upper,
153
209
  passed:
154
- metrics.acceptedSuggestionErrorRate <= gate.acceptedSuggestionErrorRate &&
155
- metrics.noMatchFalseSuggestionRate <= gate.noMatchFalseSuggestionRate &&
210
+ oneSided95Upper.acceptedSuggestionErrorRate !== null &&
211
+ oneSided95Upper.acceptedSuggestionErrorRate <=
212
+ gate.acceptedSuggestionErrorRate &&
213
+ oneSided95Upper.noMatchFalseSuggestionRate !== null &&
214
+ oneSided95Upper.noMatchFalseSuggestionRate <=
215
+ gate.noMatchFalseSuggestionRate &&
216
+ positives > 0 &&
156
217
  metrics.affirmativeCoverage >= gate.affirmativeCoverage &&
157
218
  metrics.p95Ms <= gate.p95Ms,
158
219
  rows: Object.freeze(rows),
@@ -143,6 +143,7 @@ export function createSkillDecisionRuntime({
143
143
  throw new TypeError("decision runtime clock returned an invalid date");
144
144
  }
145
145
  let outcome;
146
+ let requestSignal = null;
146
147
  try {
147
148
  const raw = await runMeteredDirectModelCall({
148
149
  sessionId: boundSessionId,
@@ -152,10 +153,12 @@ export function createSkillDecisionRuntime({
152
153
  source: "model",
153
154
  operationId: `decision:${decisionId}`,
154
155
  sessionBudget,
155
- call: () =>
156
- providerAuthority.decide(request, {
157
- signal: timeoutSignal(signal, timeoutMs),
158
- }),
156
+ call: () => {
157
+ requestSignal = timeoutSignal(signal, timeoutMs);
158
+ return providerAuthority.decide(request, {
159
+ signal: requestSignal,
160
+ });
161
+ },
159
162
  });
160
163
  const normalized = normalizeSkillDecisionProviderResult(request, raw);
161
164
  const resolved = resolveSkillDecision(request, normalized, thresholds);
@@ -170,7 +173,17 @@ export function createSkillDecisionRuntime({
170
173
  resultDigest: resolved.resultDigest,
171
174
  };
172
175
  } catch (error) {
173
- if (signal?.aborted || isTerminalModelFailure(error)) throw error;
176
+ const localTimeout =
177
+ !signal?.aborted &&
178
+ requestSignal?.aborted &&
179
+ requestSignal.reason === error &&
180
+ error?.name === "TimeoutError";
181
+ if (
182
+ signal?.aborted ||
183
+ (isTerminalModelFailure(error) && !localTimeout)
184
+ ) {
185
+ throw error;
186
+ }
174
187
  outcome = {
175
188
  status: "unavailable",
176
189
  reasonCode: projectUnavailable(error),
@@ -18,6 +18,8 @@ export const EVOLUTION_EVAL_POLICY_SCHEMA =
18
18
  "chainlesschain.evolution-eval-policy/v2";
19
19
  export const EVOLUTION_EVAL_RECEIPT_SCHEMA =
20
20
  "chainlesschain.evolution-eval-receipt/v4";
21
+ export const EVOLUTION_EVAL_RESULT_EVIDENCE_SCHEMA =
22
+ "chainlesschain.evolution-eval-result-evidence/v1";
21
23
  export const EVOLUTION_EVAL_SUITE_AUTHORITY_SCHEMA =
22
24
  "chainlesschain.evolution-eval-suite-authority-receipt/v1";
23
25
  export const EVOLUTION_EVAL_ENVIRONMENT_SCHEMA =
@@ -2647,6 +2649,27 @@ function comparisonSummary(results, confidenceZ, seedCount) {
2647
2649
  });
2648
2650
  }
2649
2651
 
2652
+ function resultEvidenceCore(receipt, results) {
2653
+ return {
2654
+ schema: EVOLUTION_EVAL_RESULT_EVIDENCE_SCHEMA,
2655
+ receiptDigest: receipt.receiptDigest,
2656
+ validation: results.validation,
2657
+ test: results.test,
2658
+ qualifiesForPromotion: false,
2659
+ };
2660
+ }
2661
+
2662
+ function buildResultEvidence(receipt, results) {
2663
+ const core = resultEvidenceCore(receipt, results);
2664
+ const evidence = {
2665
+ ...core,
2666
+ evidenceDigest: digest(core, EVOLUTION_EVAL_RESULT_EVIDENCE_SCHEMA),
2667
+ };
2668
+ // Include the digest envelope in the same bound used by the readback path.
2669
+ canonicalJson(evidence);
2670
+ return deepFreeze(evidence);
2671
+ }
2672
+
2650
2673
  function decideSplit(summary, policy) {
2651
2674
  const { baseline, candidate } = summary;
2652
2675
  if (candidate.securityViolations > 0 || candidate.permissionViolations > 0) {
@@ -5149,6 +5172,7 @@ export class EvolutionEvalGate {
5149
5172
  this.#policy.confidenceZ,
5150
5173
  this.#policy.seeds.length,
5151
5174
  ),
5175
+ ...(run.includeResultEvidence ? { results } : {}),
5152
5176
  });
5153
5177
  }
5154
5178
 
@@ -5271,10 +5295,46 @@ export class EvolutionEvalGate {
5271
5295
  signedReceipt.receiptDigest,
5272
5296
  "receiptDigest",
5273
5297
  );
5298
+ if (run.includeResultEvidence) {
5299
+ // Export only completed validation + test sets, after the final receipt
5300
+ // was independently signed and verified. No observer runs during grading.
5301
+ const resultEvidence = run.results
5302
+ ? buildResultEvidence(signedReceipt, run.results)
5303
+ : null;
5304
+ const exportedAt = readClock(this.#clock).milliseconds;
5305
+ if (
5306
+ exportedAt >= run.deadlineMs ||
5307
+ NATIVE_MONOTONIC_NOW() >= run.runLocalDeadlineMs ||
5308
+ Date.parse(signedReceipt.expiresAt) <= exportedAt ||
5309
+ run.portExpiries.some(
5310
+ (expiresAt) => Date.parse(expiresAt) <= exportedAt,
5311
+ )
5312
+ ) {
5313
+ throw evalError(
5314
+ EVOLUTION_EVAL_EXECUTION_FAILED_CODE,
5315
+ "evaluation evidence export crossed the evaluation deadline",
5316
+ );
5317
+ }
5318
+ return deepFreeze({ receipt: signedReceipt, resultEvidence });
5319
+ }
5274
5320
  return signedReceipt;
5275
5321
  }
5276
5322
 
5277
5323
  async run(request) {
5324
+ return this.#run(request, false);
5325
+ }
5326
+
5327
+ /** Trusted evaluator host only. Never expose hidden-test rows to the Actor. */
5328
+ async runWithEvidence(request) {
5329
+ return this.#run(request, true);
5330
+ }
5331
+
5332
+ /** Trusted host opt-in: best-effort signed rejection after measured execution. */
5333
+ async runWithFailureEvidence(request) {
5334
+ return this.#run(request, true, true);
5335
+ }
5336
+
5337
+ async #run(request, includeResultEvidence, signRuntimeFailures = false) {
5278
5338
  const runLocalDeadlineMs =
5279
5339
  NATIVE_MONOTONIC_NOW() + this.#policy.maxWallClockMs;
5280
5340
  assertExactRecord(request, RUN_REQUEST_KEYS, "evaluation run request");
@@ -5628,6 +5688,7 @@ export class EvolutionEvalGate {
5628
5688
  const run = {
5629
5689
  runId,
5630
5690
  runNonce,
5691
+ includeResultEvidence,
5631
5692
  deadlineAt,
5632
5693
  deadlineMs,
5633
5694
  runLocalDeadlineMs,
@@ -5713,43 +5774,13 @@ export class EvolutionEvalGate {
5713
5774
  }
5714
5775
 
5715
5776
  const sandboxInstances = new Set();
5777
+ let evaluated;
5716
5778
  try {
5717
- const evaluated = await this.#evaluateBlindedWorkPlan(
5779
+ evaluated = await this.#evaluateBlindedWorkPlan(
5718
5780
  run,
5719
5781
  usage,
5720
5782
  sandboxInstances,
5721
5783
  );
5722
- const { validation, test } = evaluated;
5723
- const validationDecision = decideSplit(validation, this.#policy);
5724
- if (!validationDecision.accepted) {
5725
- return this.#buildReceipt(run, {
5726
- decision: "rejected",
5727
- reasonCodes: [`validation-${validationDecision.reason}`],
5728
- validation,
5729
- test,
5730
- usage,
5731
- });
5732
- }
5733
- const testDecision = decideSplit(test, this.#policy);
5734
- if (!testDecision.accepted) {
5735
- return this.#buildReceipt(run, {
5736
- decision: "rejected",
5737
- reasonCodes: [`test-${testDecision.reason}`],
5738
- validation,
5739
- test,
5740
- usage,
5741
- });
5742
- }
5743
- return this.#buildReceipt(run, {
5744
- decision: "accepted",
5745
- reasonCodes: [
5746
- `validation-${validationDecision.reason}`,
5747
- `test-${testDecision.reason}`,
5748
- ],
5749
- validation,
5750
- test,
5751
- usage,
5752
- });
5753
5784
  } catch (cause) {
5754
5785
  if (cause instanceof EvaluationBudgetExceeded) {
5755
5786
  return this.#buildReceipt(run, {
@@ -5760,8 +5791,65 @@ export class EvolutionEvalGate {
5760
5791
  usage: cause.usage,
5761
5792
  });
5762
5793
  }
5794
+ const failureReason =
5795
+ cause instanceof EvolutionEvalGateError
5796
+ ? new Map([
5797
+ [
5798
+ EVOLUTION_EVAL_EXECUTION_FAILED_CODE,
5799
+ "runtime-execution-failed",
5800
+ ],
5801
+ [EVOLUTION_EVAL_GRADER_FAILED_CODE, "runtime-grader-failed"],
5802
+ [EVOLUTION_EVAL_SAFETY_FAILED_CODE, "runtime-safety-failed"],
5803
+ ]).get(cause.code)
5804
+ : undefined;
5805
+ if (signRuntimeFailures && failureReason && usage.executionCount > 0) {
5806
+ try {
5807
+ return await this.#buildReceipt(run, {
5808
+ decision: "rejected",
5809
+ reasonCodes: [failureReason],
5810
+ validation: null,
5811
+ test: null,
5812
+ usage,
5813
+ });
5814
+ } catch {
5815
+ // A deadline, expired authority, or signer failure cannot be
5816
+ // represented as authenticated outcome evidence.
5817
+ }
5818
+ }
5763
5819
  throw cause;
5764
5820
  }
5821
+ const { validation, test } = evaluated;
5822
+ if (includeResultEvidence) run.results = evaluated.results;
5823
+ const validationDecision = decideSplit(validation, this.#policy);
5824
+ if (!validationDecision.accepted) {
5825
+ return this.#buildReceipt(run, {
5826
+ decision: "rejected",
5827
+ reasonCodes: [`validation-${validationDecision.reason}`],
5828
+ validation,
5829
+ test,
5830
+ usage,
5831
+ });
5832
+ }
5833
+ const testDecision = decideSplit(test, this.#policy);
5834
+ if (!testDecision.accepted) {
5835
+ return this.#buildReceipt(run, {
5836
+ decision: "rejected",
5837
+ reasonCodes: [`test-${testDecision.reason}`],
5838
+ validation,
5839
+ test,
5840
+ usage,
5841
+ });
5842
+ }
5843
+ return this.#buildReceipt(run, {
5844
+ decision: "accepted",
5845
+ reasonCodes: [
5846
+ `validation-${validationDecision.reason}`,
5847
+ `test-${testDecision.reason}`,
5848
+ ],
5849
+ validation,
5850
+ test,
5851
+ usage,
5852
+ });
5765
5853
  }
5766
5854
  }
5767
5855
 
@@ -6461,6 +6549,28 @@ export async function runEvolutionEvalGate(gate, request) {
6461
6549
  return EvolutionEvalGate.prototype.run.call(gate, request);
6462
6550
  }
6463
6551
 
6552
+ /** Opt-in export for the trusted evaluation host, after the whole run settles. */
6553
+ export async function runEvolutionEvalGateWithEvidence(gate, request) {
6554
+ if (!GATE_INSTANCES.has(gate)) {
6555
+ throw evalError(
6556
+ EVOLUTION_EVAL_INVALID_CODE,
6557
+ "result evidence export requires a trusted EvolutionEvalGate instance",
6558
+ );
6559
+ }
6560
+ return EvolutionEvalGate.prototype.runWithEvidence.call(gate, request);
6561
+ }
6562
+
6563
+ /** Opt-in for trusted hosts; an unsigned failure still rejects the promise. */
6564
+ export async function runEvolutionEvalGateWithFailureEvidence(gate, request) {
6565
+ if (!GATE_INSTANCES.has(gate)) {
6566
+ throw evalError(
6567
+ EVOLUTION_EVAL_INVALID_CODE,
6568
+ "failure evidence export requires a trusted EvolutionEvalGate instance",
6569
+ );
6570
+ }
6571
+ return EvolutionEvalGate.prototype.runWithFailureEvidence.call(gate, request);
6572
+ }
6573
+
6464
6574
  export async function verifyEvolutionEvalReceipt(verifier, value, expected) {
6465
6575
  if (!RECEIPT_VERIFIER_INSTANCES.has(verifier)) {
6466
6576
  throw evalError(
@@ -6474,3 +6584,150 @@ export async function verifyEvolutionEvalReceipt(verifier, value, expected) {
6474
6584
  expected,
6475
6585
  );
6476
6586
  }
6587
+
6588
+ const RESULT_ROW_KEYS = new Set([
6589
+ "taskDigest",
6590
+ "seed",
6591
+ "pass",
6592
+ "qualityScore",
6593
+ "securityViolations",
6594
+ "permissionViolations",
6595
+ "outputArtifactDigest",
6596
+ "subjectBindingDigest",
6597
+ "subjectReservationDigest",
6598
+ "executionDigest",
6599
+ "gradeDigest",
6600
+ "safetyDigest",
6601
+ "metrics",
6602
+ ]);
6603
+
6604
+ function verifyResultRows(rows, tasks, seeds) {
6605
+ if (!Array.isArray(rows) || rows.length !== tasks.size * seeds.size) {
6606
+ throw evalError(
6607
+ EVOLUTION_EVAL_INVALID_CODE,
6608
+ "result evidence must cover every task and seed in each arm",
6609
+ );
6610
+ }
6611
+ const seen = new Set();
6612
+ for (const row of rows) {
6613
+ assertExactRecord(row, RESULT_ROW_KEYS, "evaluation result row");
6614
+ for (const field of RESULT_ROW_KEYS) {
6615
+ if (field.endsWith("Digest")) normalizeDigest(row[field], field);
6616
+ }
6617
+ normalizeInteger(row.seed, "result seed", { maximum: 0x7fffffff });
6618
+ const pair = `${row.taskDigest}\0${row.seed}`;
6619
+ if (!tasks.has(row.taskDigest) || !seeds.has(row.seed) || seen.has(pair)) {
6620
+ throw evalError(
6621
+ EVOLUTION_EVAL_INVALID_CODE,
6622
+ "result evidence contains a foreign or duplicate task/seed pair",
6623
+ );
6624
+ }
6625
+ seen.add(pair);
6626
+ if (typeof row.pass !== "boolean") {
6627
+ throw evalError(
6628
+ EVOLUTION_EVAL_INVALID_CODE,
6629
+ "result pass must be boolean",
6630
+ );
6631
+ }
6632
+ normalizeRatio(row.qualityScore, "result qualityScore");
6633
+ normalizeInteger(row.securityViolations, "result securityViolations");
6634
+ normalizeInteger(row.permissionViolations, "result permissionViolations");
6635
+ normalizeMetrics(row.metrics);
6636
+ }
6637
+ }
6638
+
6639
+ /**
6640
+ * Authenticate raw rows through the existing final receipt's signed result
6641
+ * digests. This does not fetch/reverify the underlying execution/grader/safety
6642
+ * receipts, attest preparation costs, or turn the rows into promotion approval.
6643
+ * `expected` must come from the trusted host's registered run context.
6644
+ */
6645
+ export async function verifyEvolutionEvalResultEvidence(
6646
+ verifier,
6647
+ input,
6648
+ expected,
6649
+ ) {
6650
+ assertExactRecord(
6651
+ input,
6652
+ new Set(["receipt", "resultEvidence", "suite", "policy"]),
6653
+ "evaluation result evidence input",
6654
+ );
6655
+ // Capture every graph before invoking any asynchronous authority, using the
6656
+ // existing independent bounds for each canonical document.
6657
+ const receipt = deepFreeze(cloneCanonical(input.receipt));
6658
+ const evidence = deepFreeze(cloneCanonical(input.resultEvidence));
6659
+ const suite = verifyEvolutionEvalSuite(input.suite);
6660
+ const policy = verifyEvolutionEvalPolicy(input.policy);
6661
+ const expectedSnapshot = deepFreeze(cloneCanonical(expected));
6662
+ assertExactRecord(
6663
+ evidence,
6664
+ new Set([
6665
+ "schema",
6666
+ "receiptDigest",
6667
+ "validation",
6668
+ "test",
6669
+ "qualifiesForPromotion",
6670
+ "evidenceDigest",
6671
+ ]),
6672
+ "evaluation result evidence",
6673
+ );
6674
+ if (
6675
+ evidence.schema !== EVOLUTION_EVAL_RESULT_EVIDENCE_SCHEMA ||
6676
+ evidence.qualifiesForPromotion !== false ||
6677
+ evidence.receiptDigest !== receipt.receiptDigest ||
6678
+ receipt.suiteDigest !== suite.suiteDigest ||
6679
+ receipt.policyDigest !== policy.policyDigest ||
6680
+ receipt.confidenceZ !== policy.confidenceZ ||
6681
+ !receipt.validation ||
6682
+ !receipt.test ||
6683
+ digest(receipt.splitCounts, "split-counts") !==
6684
+ digest(countSplits(suite.tasks), "split-counts")
6685
+ ) {
6686
+ throw evalError(
6687
+ EVOLUTION_EVAL_INVALID_CODE,
6688
+ "result evidence differs from its receipt, suite, or policy",
6689
+ );
6690
+ }
6691
+ const seeds = new Set(policy.seeds);
6692
+ for (const split of ["validation", "test"]) {
6693
+ const results = evidence[split];
6694
+ assertExactRecord(
6695
+ results,
6696
+ new Set(["baseline", "candidate"]),
6697
+ "split results",
6698
+ );
6699
+ const tasks = new Set(
6700
+ suite.tasks
6701
+ .filter((task) => task.split === split)
6702
+ .map((task) => task.taskDigest),
6703
+ );
6704
+ for (const arm of ["baseline", "candidate"]) {
6705
+ verifyResultRows(results[arm], tasks, seeds);
6706
+ }
6707
+ const recomputed = comparisonSummary(
6708
+ results,
6709
+ policy.confidenceZ,
6710
+ seeds.size,
6711
+ );
6712
+ if (
6713
+ digest(recomputed, "chainlesschain.evolution-eval-comparison/v2") !==
6714
+ digest(receipt[split], "chainlesschain.evolution-eval-comparison/v2")
6715
+ ) {
6716
+ throw evalError(
6717
+ EVOLUTION_EVAL_INVALID_CODE,
6718
+ "result rows do not reproduce the signed comparison",
6719
+ );
6720
+ }
6721
+ }
6722
+ const rebuilt = buildResultEvidence(receipt, evidence);
6723
+ if (rebuilt.evidenceDigest !== evidence.evidenceDigest) {
6724
+ throw evalError(
6725
+ EVOLUTION_EVAL_INVALID_CODE,
6726
+ "result evidence digest mismatch",
6727
+ );
6728
+ }
6729
+ // Verify freshness last so a receipt that expires during recomputation cannot
6730
+ // be returned as verified. The same check authenticates signature and context.
6731
+ await verifyEvolutionEvalReceipt(verifier, receipt, expectedSnapshot);
6732
+ return evidence;
6733
+ }