@tangle-network/agent-eval 0.144.11 → 0.144.13
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/CHANGELOG.md +11 -0
- package/dist/agent-profile-B9_GGsG8.d.ts +84 -0
- package/dist/agent-profile-B9_GGsG8.d.ts.map +1 -0
- package/dist/{agent-profile-cell-BOP-iA9Q.d.ts → agent-profile-cell-BkcRDikH.d.ts} +2 -2
- package/dist/{agent-profile-cell-BOP-iA9Q.d.ts.map → agent-profile-cell-BkcRDikH.d.ts.map} +1 -1
- package/dist/analyst/index.d.ts +134 -16
- package/dist/analyst/index.d.ts.map +1 -1
- package/dist/analyst/index.js +364 -10
- package/dist/analyst/index.js.map +1 -1
- package/dist/backend-integrity-CsVin_Wb.d.ts +280 -0
- package/dist/backend-integrity-CsVin_Wb.d.ts.map +1 -0
- package/dist/{baseline-C-GocmIW.js → baseline-BhPRQBVn.js} +3 -2
- package/dist/{baseline-C-GocmIW.js.map → baseline-BhPRQBVn.js.map} +1 -1
- package/dist/{benchmark-CWeqGl7x.js → benchmark-BhT16ep9.js} +2 -2
- package/dist/{benchmark-CWeqGl7x.js.map → benchmark-BhT16ep9.js.map} +1 -1
- package/dist/{agent-profile-DPi7IZg7.d.ts → benchmark-Ceoan7vk.d.ts} +4 -91
- package/dist/benchmark-Ceoan7vk.d.ts.map +1 -0
- package/dist/{benchmark-command-BteMFN62.js → benchmark-command-CY6cbhOB.js} +36 -79
- package/dist/benchmark-command-CY6cbhOB.js.map +1 -0
- package/dist/benchmarks/index.d.ts +244 -2
- package/dist/benchmarks/index.d.ts.map +1 -0
- package/dist/benchmarks/index.js +733 -1
- package/dist/benchmarks/index.js.map +1 -0
- package/dist/builder-eval/index.d.ts +23 -2
- package/dist/builder-eval/index.d.ts.map +1 -1
- package/dist/builder-eval/index.js +227 -3
- package/dist/builder-eval/index.js.map +1 -1
- package/dist/campaign/index.d.ts +10 -8
- package/dist/campaign/index.js +9 -6
- package/dist/{campaign-C2TTzQII.js → campaign-BYjBAypg.js} +21 -634
- package/dist/campaign-BYjBAypg.js.map +1 -0
- package/dist/{canonical-D011XM8r.js → canonical-D-XsTQ6_.js} +2 -2
- package/dist/{canonical-D011XM8r.js.map → canonical-D-XsTQ6_.js.map} +1 -1
- package/dist/{index-CQTZ-4XN.d.ts → capture-fetch-DDvpjVRU.d.ts} +3 -3
- package/dist/capture-fetch-DDvpjVRU.d.ts.map +1 -0
- package/dist/{default-registry-BmktKy8r.js → chat-client-Bp4Ebuuc.js} +1276 -1276
- package/dist/chat-client-Bp4Ebuuc.js.map +1 -0
- package/dist/cli.js +2 -2
- package/dist/{client-C9gzZE59.d.ts → client-KUbGulm_.d.ts} +4 -4
- package/dist/{client-C9gzZE59.d.ts.map → client-KUbGulm_.d.ts.map} +1 -1
- package/dist/contract/index.d.ts +13 -390
- package/dist/contract/index.d.ts.map +1 -1
- package/dist/contract/index.js +18 -542
- package/dist/contract/index.js.map +1 -1
- package/dist/{cost-ledger-DMFxsLKr.js → cost-ledger-BSe92yAV.js} +3 -3
- package/dist/{cost-ledger-DMFxsLKr.js.map → cost-ledger-BSe92yAV.js.map} +1 -1
- package/dist/{cost-ledger-Bv_e8XHY.d.ts → cost-ledger-DbQdN3nO.d.ts} +2 -2
- package/dist/{cost-ledger-Bv_e8XHY.d.ts.map → cost-ledger-DbQdN3nO.d.ts.map} +1 -1
- package/dist/{counterfactual-CxmxAONP.d.ts → counterfactual--bpysZF0.d.ts} +2 -14
- package/dist/{counterfactual-CxmxAONP.d.ts.map → counterfactual--bpysZF0.d.ts.map} +1 -1
- package/dist/{counterfactual-CWPTrMH7.js → counterfactual-lDfCx0Uz.js} +3 -31
- package/dist/{counterfactual-CWPTrMH7.js.map → counterfactual-lDfCx0Uz.js.map} +1 -1
- package/dist/{dataset-C8xaLXdY.d.ts → dataset-CJjKqQfA.d.ts} +2 -8
- package/dist/dataset-CJjKqQfA.d.ts.map +1 -0
- package/dist/{default-registry-Bf8Woqmq.d.ts → default-registry-Di6HP6pG.d.ts} +7 -12
- package/dist/default-registry-Di6HP6pG.d.ts.map +1 -0
- package/dist/{analyze-runs-C30yljDJ.js → define-agent-eval-iqjT--ZZ.js} +542 -130
- package/dist/define-agent-eval-iqjT--ZZ.js.map +1 -0
- package/dist/define-agent-eval-sH24zBfM.d.ts +388 -0
- package/dist/define-agent-eval-sH24zBfM.d.ts.map +1 -0
- package/dist/descriptive-B5MwKfbf.js +144 -0
- package/dist/descriptive-B5MwKfbf.js.map +1 -0
- package/dist/{dspy-rlm-engine-DbTk4JdR.js → dspy-rlm-engine-B_qhSc21.js} +4 -4
- package/dist/{dspy-rlm-engine-DbTk4JdR.js.map → dspy-rlm-engine-B_qhSc21.js.map} +1 -1
- package/dist/effect-sizes-DiH8MGOH.js +82 -0
- package/dist/effect-sizes-DiH8MGOH.js.map +1 -0
- package/dist/{engine-3hL-XqwJ.d.ts → engine-otFpE2gF.d.ts} +10 -38
- package/dist/engine-otFpE2gF.d.ts.map +1 -0
- package/dist/{errors-CKPfb2aH.d.ts → errors-DEE6u6ot.d.ts} +2 -14
- package/dist/{errors-CKPfb2aH.d.ts.map → errors-DEE6u6ot.d.ts.map} +1 -1
- package/dist/{errors-D-LKuDhb.js → errors-Dngq5h35.js} +2 -8
- package/dist/{errors-D-LKuDhb.js.map → errors-Dngq5h35.js.map} +1 -1
- package/dist/{eval-campaign-B_7wcnav.js → eval-campaign-UB-usSQ2.js} +6 -6
- package/dist/{eval-campaign-B_7wcnav.js.map → eval-campaign-UB-usSQ2.js.map} +1 -1
- package/dist/{exact-types-DSFFpLLI.d.ts → exact-types-BH1twmAJ.d.ts} +2 -2
- package/dist/{exact-types-DSFFpLLI.d.ts.map → exact-types-BH1twmAJ.d.ts.map} +1 -1
- package/dist/experiment/index.d.ts +9 -6
- package/dist/experiment/index.d.ts.map +1 -1
- package/dist/experiment/index.js +11 -7
- package/dist/experiment/index.js.map +1 -1
- package/dist/experiment-tracker-C29gXM4B.js +269 -0
- package/dist/experiment-tracker-C29gXM4B.js.map +1 -0
- package/dist/{experiment-tracker-IMntXr6J.d.ts → experiment-tracker-DWHZBAYL.d.ts} +77 -121
- package/dist/experiment-tracker-DWHZBAYL.d.ts.map +1 -0
- package/dist/{external-optimizer-contracts-CZuJNcT5.d.ts → external-optimizer-contracts-lixrOZdX.d.ts} +3 -3
- package/dist/{external-optimizer-contracts-CZuJNcT5.d.ts.map → external-optimizer-contracts-lixrOZdX.d.ts.map} +1 -1
- package/dist/external-optimizer-process-BTiNB-RH.js +301 -0
- package/dist/external-optimizer-process-BTiNB-RH.js.map +1 -0
- package/dist/{single-run-lock-DFWHEB09.js → external-optimizer-subprocess-DrJ9hR8u.js} +144 -438
- package/dist/external-optimizer-subprocess-DrJ9hR8u.js.map +1 -0
- package/dist/extract-usage-BrQ8mCLX.js +155 -0
- package/dist/extract-usage-BrQ8mCLX.js.map +1 -0
- package/dist/{failure-cluster-CqcvCcdR.d.ts → failure-cluster-BLURuWG4.d.ts} +2 -3
- package/dist/failure-cluster-BLURuWG4.d.ts.map +1 -0
- package/dist/{feedback-trajectory-CacHpxsp.d.ts → feedback-trajectory-juOozjAc.d.ts} +5 -36
- package/dist/feedback-trajectory-juOozjAc.d.ts.map +1 -0
- package/dist/fuzz.d.ts +2 -2
- package/dist/fuzz.js +2 -2
- package/dist/hosted/index.d.ts +3 -3
- package/dist/{index-CvSN3IG1.d.ts → index-B8Ui1mr1.d.ts} +2 -2
- package/dist/{index-CvSN3IG1.d.ts.map → index-B8Ui1mr1.d.ts.map} +1 -1
- package/dist/{skill-usage-CO9OLRBx.d.ts → index-BWDrSVfw.d.ts} +11 -136
- package/dist/index-BWDrSVfw.d.ts.map +1 -0
- package/dist/index-Ba3YrbAL.d.ts +1 -0
- package/dist/{index-BnEuDAK2.d.ts → index-COQYtuRF.d.ts} +3 -3
- package/dist/{index-BnEuDAK2.d.ts.map → index-COQYtuRF.d.ts.map} +1 -1
- package/dist/{index-C3ssXVLv.d.ts → index-CvjYbU0D.d.ts} +2 -2
- package/dist/{index-C3ssXVLv.d.ts.map → index-CvjYbU0D.d.ts.map} +1 -1
- package/dist/{index-DPPGNJ_R.d.ts → index-DSmEylT9.d.ts} +17 -115
- package/dist/index-DSmEylT9.d.ts.map +1 -0
- package/dist/index.d.ts +2397 -5308
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5914 -10496
- package/dist/index.js.map +1 -1
- package/dist/{insight-report-CgX_s0Ez.d.ts → insight-report-CRi-Ufrj.d.ts} +4 -4
- package/dist/{insight-report-CgX_s0Ez.d.ts.map → insight-report-CRi-Ufrj.d.ts.map} +1 -1
- package/dist/{integrity-MLzHOfV9.js → integrity-Cy9WHAtb.js} +2 -2
- package/dist/{integrity-MLzHOfV9.js.map → integrity-Cy9WHAtb.js.map} +1 -1
- package/dist/{integrity-DY6tIbl0.js → integrity-DysDBWDu.js} +2 -2
- package/dist/{integrity-DY6tIbl0.js.map → integrity-DysDBWDu.js.map} +1 -1
- package/dist/{integrity-BuqEKu-x.d.ts → integrity-OrcI9Nau.d.ts} +3 -3
- package/dist/{integrity-BuqEKu-x.d.ts.map → integrity-OrcI9Nau.d.ts.map} +1 -1
- package/dist/internal-BDHPCnjk.js +230 -0
- package/dist/internal-BDHPCnjk.js.map +1 -0
- package/dist/judge-calibration-C5CbMYce.d.ts +117 -0
- package/dist/judge-calibration-C5CbMYce.d.ts.map +1 -0
- package/dist/judge-calibration-DZkWrm5H.js +317 -0
- package/dist/judge-calibration-DZkWrm5H.js.map +1 -0
- package/dist/{kind-factory-B8-r8-y8.js → kind-factory-CPmSd58s.js} +208 -208
- package/dist/{kind-factory-B8-r8-y8.js.map → kind-factory-CPmSd58s.js.map} +1 -1
- package/dist/ledger-core/index.d.ts +1 -1
- package/dist/ledger-core/index.js +2 -2
- package/dist/{ledger-core-DXZIqu17.js → ledger-core-BmZt19oQ.js} +110 -110
- package/dist/{ledger-core-DXZIqu17.js.map → ledger-core-BmZt19oQ.js.map} +1 -1
- package/dist/{llm-client-DzvMUsS_.js → llm-client-d0-2TT1g.js} +4 -64
- package/dist/{llm-client-DzvMUsS_.js.map → llm-client-d0-2TT1g.js.map} +1 -1
- package/dist/{skillopt-optimization-method-CQdVeM8k.js → llm-judge-dZ8P6nGI.js} +3349 -5401
- package/dist/llm-judge-dZ8P6nGI.js.map +1 -0
- package/dist/matrix/index.d.ts +2 -2
- package/dist/meta-eval/index.d.ts +3 -3
- package/dist/meta-eval/index.js +3 -3
- package/dist/{metrics-C9YY1OcL.js → metrics-Cl0L1KUy.js} +2 -108
- package/dist/{metrics-C9YY1OcL.js.map → metrics-Cl0L1KUy.js.map} +1 -1
- package/dist/{mint-B2O60ACG.js → mint-Dj9Ww_3I.js} +4 -4
- package/dist/{mint-B2O60ACG.js.map → mint-Dj9Ww_3I.js.map} +1 -1
- package/dist/{multi-layer-verifier-DnAqwl0h.d.ts → multi-layer-verifier-DIguZc8Z.d.ts} +3 -3
- package/dist/{multi-layer-verifier-DnAqwl0h.d.ts.map → multi-layer-verifier-DIguZc8Z.d.ts.map} +1 -1
- package/dist/multiplicity-DIWHvysC.d.ts +43 -0
- package/dist/multiplicity-DIWHvysC.d.ts.map +1 -0
- package/dist/multishot/index.d.ts +3 -3
- package/dist/multishot/index.js +1 -1
- package/dist/openapi.json +1 -1
- package/dist/{opencode-sqlite-8r6WUfHc.js → opencode-sqlite-DJWAXLms.js} +2 -2
- package/dist/{opencode-sqlite-8r6WUfHc.js.map → opencode-sqlite-DJWAXLms.js.map} +1 -1
- package/dist/package-version-D7lQHt_-.js +34 -0
- package/dist/package-version-D7lQHt_-.js.map +1 -0
- package/dist/paired-arms-D-XRF_fy.js +1045 -0
- package/dist/paired-arms-D-XRF_fy.js.map +1 -0
- package/dist/paired-promotion-decision-CGzg0cI_.d.ts +251 -0
- package/dist/paired-promotion-decision-CGzg0cI_.d.ts.map +1 -0
- package/dist/paired-tests-BHIhYVdu.js +213 -0
- package/dist/paired-tests-BHIhYVdu.js.map +1 -0
- package/dist/pareto-BqNW3LJR.d.ts +117 -0
- package/dist/pareto-BqNW3LJR.d.ts.map +1 -0
- package/dist/pipelines/index.d.ts +3 -64
- package/dist/pipelines/index.d.ts.map +1 -1
- package/dist/pipelines/index.js +4 -284
- package/dist/pipelines/index.js.map +1 -1
- package/dist/power-and-mde-CHIrXJll.js +195 -0
- package/dist/power-and-mde-CHIrXJll.js.map +1 -0
- package/dist/{promotion-policy-CrLrmys8.js → power-preflight-DEw-uC7q.js} +4 -184
- package/dist/power-preflight-DEw-uC7q.js.map +1 -0
- package/dist/pre-registration-CZwSFQS4.d.ts +577 -0
- package/dist/pre-registration-CZwSFQS4.d.ts.map +1 -0
- package/dist/{prime-protocol-BfSalTfR.js → prime-protocol-6tZTVsWm.js} +72 -21
- package/dist/prime-protocol-6tZTVsWm.js.map +1 -0
- package/dist/produced-state-DU79a81m.js +586 -0
- package/dist/produced-state-DU79a81m.js.map +1 -0
- package/dist/profile-cell.d.ts +1 -1
- package/dist/profile-cell.js +1 -1
- package/dist/promotion-policy-D0nPhkSy.d.ts +134 -0
- package/dist/promotion-policy-D0nPhkSy.d.ts.map +1 -0
- package/dist/promotion-policy-xzA40Evo.js +186 -0
- package/dist/promotion-policy-xzA40Evo.js.map +1 -0
- package/dist/{skillopt-optimization-method-USDKhxSA.d.ts → provenance-CCdxgLDT.d.ts} +57 -478
- package/dist/provenance-CCdxgLDT.d.ts.map +1 -0
- package/dist/registry-oJeeI4-a.d.ts +178 -0
- package/dist/registry-oJeeI4-a.d.ts.map +1 -0
- package/dist/{release-report-DA2BCu5a.d.ts → release-confidence-BFRE5WSp.d.ts} +180 -112
- package/dist/release-confidence-BFRE5WSp.d.ts.map +1 -0
- package/dist/{release-report-BUYmoKo2.js → release-confidence-CxDuiAev.js} +125 -217
- package/dist/release-confidence-CxDuiAev.js.map +1 -0
- package/dist/reporting.d.ts +6 -5
- package/dist/reporting.js +7 -5
- package/dist/{researcher-BchpD55R.d.ts → researcher-DaN4GST-.d.ts} +7 -40
- package/dist/{researcher-BchpD55R.d.ts.map → researcher-DaN4GST-.d.ts.map} +1 -1
- package/dist/{reward-hacking-BDToousL.js → reward-hacking-DNgjilrV.js} +3 -3
- package/dist/reward-hacking-DNgjilrV.js.map +1 -0
- package/dist/{reward-hacking-BI0OMAlo.d.ts → reward-hacking-DSSTuI9r.d.ts} +5 -5
- package/dist/{reward-hacking-BI0OMAlo.d.ts.map → reward-hacking-DSSTuI9r.d.ts.map} +1 -1
- package/dist/rl.d.ts +7 -7
- package/dist/rl.js +11 -10
- package/dist/rl.js.map +1 -1
- package/dist/rollout/index.d.ts +2 -2
- package/dist/rollout/index.js +4 -4
- package/dist/{rollout-DRrksrcV.js → rollout-BWtw0I_6.js} +3 -3
- package/dist/{rollout-DRrksrcV.js.map → rollout-BWtw0I_6.js.map} +1 -1
- package/dist/{rubric-predictive-validity-DvkjPYCe.d.ts → rubric-predictive-validity-BgxtKe4G.d.ts} +2 -2
- package/dist/{rubric-predictive-validity-DvkjPYCe.d.ts.map → rubric-predictive-validity-BgxtKe4G.d.ts.map} +1 -1
- package/dist/{rubric-predictive-validity-BRR632r1.js → rubric-predictive-validity-Cwwyd7ah.js} +2 -2
- package/dist/{rubric-predictive-validity-BRR632r1.js.map → rubric-predictive-validity-Cwwyd7ah.js.map} +1 -1
- package/dist/{run-record-BmSPWXJR.js → run-record-BvHPVS-i.js} +3 -3
- package/dist/{run-record-BmSPWXJR.js.map → run-record-BvHPVS-i.js.map} +1 -1
- package/dist/{run-record-CF4Dwpxr.d.ts → run-record-CKiihE6f.d.ts} +4 -4
- package/dist/{run-record-CF4Dwpxr.d.ts.map → run-record-CKiihE6f.d.ts.map} +1 -1
- package/dist/{proposal-findings-2GIUo1et.js → run-score-lDzV0X8j.js} +31 -31
- package/dist/run-score-lDzV0X8j.js.map +1 -0
- package/dist/sandbox-harness-BlSOu4LX.d.ts +70 -0
- package/dist/sandbox-harness-BlSOu4LX.d.ts.map +1 -0
- package/dist/{schema-Cef2cFmb2.d.ts → schema-Cef2cFmb.d.ts} +1 -1
- package/dist/schema-Cef2cFmb.d.ts.map +1 -0
- package/dist/semantic-concept-judge-BiJxScqe.js +406 -0
- package/dist/semantic-concept-judge-BiJxScqe.js.map +1 -0
- package/dist/{sequential-D-BLJBKU.js → sequential-C458DXNf.js} +4 -3
- package/dist/{sequential-D-BLJBKU.js.map → sequential-C458DXNf.js.map} +1 -1
- package/dist/sequential-eprocess-CbUt2htw.js +83 -0
- package/dist/sequential-eprocess-CbUt2htw.js.map +1 -0
- package/dist/series-convergence-D1cL1f-4.d.ts +129 -0
- package/dist/series-convergence-D1cL1f-4.d.ts.map +1 -0
- package/dist/{server-iu0ede49.js → server-ulsOdrTI.js} +5 -21
- package/dist/server-ulsOdrTI.js.map +1 -0
- package/dist/skillopt-optimization-method-C5cotF4E.d.ts +427 -0
- package/dist/skillopt-optimization-method-C5cotF4E.d.ts.map +1 -0
- package/dist/skillopt-optimization-method-jjdnc3YK.js +1999 -0
- package/dist/skillopt-optimization-method-jjdnc3YK.js.map +1 -0
- package/dist/{statistical-heldout-TQ-4CYiN.d.ts → statistical-heldout-DoFF5KJX.d.ts} +5 -278
- package/dist/statistical-heldout-DoFF5KJX.d.ts.map +1 -0
- package/dist/{store-otlp-Dw8PPIlL.js → store-otlp-CsptLYpN.js} +3 -3
- package/dist/{store-otlp-Dw8PPIlL.js.map → store-otlp-CsptLYpN.js.map} +1 -1
- package/dist/store-tool-spans-Cq9mFd-q.js +667 -0
- package/dist/store-tool-spans-Cq9mFd-q.js.map +1 -0
- package/dist/store-tool-spans-DbDLOBOb.d.ts +342 -0
- package/dist/store-tool-spans-DbDLOBOb.d.ts.map +1 -0
- package/dist/student-t-CvBq2mve.js +38 -0
- package/dist/student-t-CvBq2mve.js.map +1 -0
- package/dist/{summary-report-Lf-5I7xh.js → summary-report-Blysd6Z2.js} +6 -3
- package/dist/{summary-report-Lf-5I7xh.js.map → summary-report-Blysd6Z2.js.map} +1 -1
- package/dist/{summary-report-BNR7DWTj.d.ts → summary-report-CaL-Hnxt.d.ts} +5 -5
- package/dist/{summary-report-BNR7DWTj.d.ts.map → summary-report-CaL-Hnxt.d.ts.map} +1 -1
- package/dist/supervisor-run/index.d.ts +391 -3
- package/dist/supervisor-run/index.d.ts.map +1 -0
- package/dist/supervisor-run/index.js +1689 -2
- package/dist/{supervisor-run-D_sokXcO.js.map → supervisor-run/index.js.map} +1 -1
- package/dist/{extract-usage-CdZdoj1s.js → task-failure-attributes-CpQ4y5RD.js} +5 -157
- package/dist/task-failure-attributes-CpQ4y5RD.js.map +1 -0
- package/dist/{tool-groups-CZPGGlHf.d.ts → tool-groups-Cteb03Ps.d.ts} +3 -3
- package/dist/tool-groups-Cteb03Ps.d.ts.map +1 -0
- package/dist/tool-waste-BDdBZG1F.js +803 -0
- package/dist/tool-waste-BDdBZG1F.js.map +1 -0
- package/dist/tool-waste-DjRDEsuI.d.ts +128 -0
- package/dist/tool-waste-DjRDEsuI.d.ts.map +1 -0
- package/dist/trace-repair/index.d.ts +14 -5
- package/dist/trace-repair/index.d.ts.map +1 -1
- package/dist/trace-repair/index.js +35 -7
- package/dist/trace-repair/index.js.map +1 -1
- package/dist/traces.d.ts +406 -7
- package/dist/traces.d.ts.map +1 -0
- package/dist/traces.js +1011 -10
- package/dist/traces.js.map +1 -0
- package/dist/trajectory-replay/index.d.ts +16 -3
- package/dist/trajectory-replay/index.d.ts.map +1 -1
- package/dist/trajectory-replay/index.js +52 -5
- package/dist/trajectory-replay/index.js.map +1 -1
- package/dist/types-BEPZc6eo.d.ts +93 -0
- package/dist/types-BEPZc6eo.d.ts.map +1 -0
- package/dist/{usage-receipt-t7vAzCRQ.js → types-BI4fT3HN.js} +67 -67
- package/dist/types-BI4fT3HN.js.map +1 -0
- package/dist/{types-BnjdJ70P.d.ts → types-BZ59Ahr8.d.ts} +5 -5
- package/dist/{types-BnjdJ70P.d.ts.map → types-BZ59Ahr8.d.ts.map} +1 -1
- package/dist/{types-D216SgwM.d.ts → types-Cx3YUh2r.d.ts} +4 -241
- package/dist/types-Cx3YUh2r.d.ts.map +1 -0
- package/dist/{types-BvDKaULh.d.ts → types-DLQx4mKU.d.ts} +4 -4
- package/dist/{types-BvDKaULh.d.ts.map → types-DLQx4mKU.d.ts.map} +1 -1
- package/dist/{types-D4mog56g.d.ts → types-yLK8gXE9.d.ts} +2 -2
- package/dist/{types-D4mog56g.d.ts.map → types-yLK8gXE9.d.ts.map} +1 -1
- package/dist/verdict-BndeTAh_.js +61 -0
- package/dist/verdict-BndeTAh_.js.map +1 -0
- package/dist/verdict-E4eRNf7-.d.ts +392 -0
- package/dist/verdict-E4eRNf7-.d.ts.map +1 -0
- package/dist/{verdict-cache-BCcOh0kF.js → verdict-cache-mZf5FEiY.js} +3 -55
- package/dist/{verdict-cache-BCcOh0kF.js.map → verdict-cache-mZf5FEiY.js.map} +1 -1
- package/dist/wire/index.d.ts +3 -3
- package/dist/wire/index.d.ts.map +1 -1
- package/dist/wire/index.js +1 -1
- package/docs/charter.md +3 -3
- package/docs/control-runtime.md +3 -42
- package/docs/experiment.md +0 -1
- package/docs/feature-guide.md +2 -2
- package/docs/trace-repair-grader.md +1 -0
- package/docs/trajectory-replay.md +1 -0
- package/docs/verdicts.md +43 -0
- package/docs/verification-strategies.md +3 -2
- package/package.json +6 -11
- package/dist/agent-profile-DPi7IZg7.d.ts.map +0 -1
- package/dist/analyze-runs-C30yljDJ.js.map +0 -1
- package/dist/baseline-CavEbRyH.d.ts +0 -136
- package/dist/baseline-CavEbRyH.d.ts.map +0 -1
- package/dist/benchmark-command-BteMFN62.js.map +0 -1
- package/dist/benchmarks-Dzs8CKb1.js +0 -755
- package/dist/benchmarks-Dzs8CKb1.js.map +0 -1
- package/dist/campaign-C2TTzQII.js.map +0 -1
- package/dist/completion-verifier-DJA5BhPb.d.ts +0 -414
- package/dist/completion-verifier-DJA5BhPb.d.ts.map +0 -1
- package/dist/control.d.ts +0 -3
- package/dist/control.js +0 -2
- package/dist/dataset-C8xaLXdY.d.ts.map +0 -1
- package/dist/default-registry-Bf8Woqmq.d.ts.map +0 -1
- package/dist/default-registry-BmktKy8r.js.map +0 -1
- package/dist/engine-3hL-XqwJ.d.ts.map +0 -1
- package/dist/experiment-tracker-CnRICnMl.js +0 -500
- package/dist/experiment-tracker-CnRICnMl.js.map +0 -1
- package/dist/experiment-tracker-IMntXr6J.d.ts.map +0 -1
- package/dist/extract-usage-CdZdoj1s.js.map +0 -1
- package/dist/failure-cluster-CqcvCcdR.d.ts.map +0 -1
- package/dist/feedback-trajectory-CacHpxsp.d.ts.map +0 -1
- package/dist/index-BZ3-y4YL.d.ts +0 -391
- package/dist/index-BZ3-y4YL.d.ts.map +0 -1
- package/dist/index-CQTZ-4XN.d.ts.map +0 -1
- package/dist/index-DPPGNJ_R.d.ts.map +0 -1
- package/dist/index-YE4KdKbO2.d.ts +0 -335
- package/dist/index-YE4KdKbO2.d.ts.map +0 -1
- package/dist/paired-arms-iZ08VFMN.js +0 -260
- package/dist/paired-arms-iZ08VFMN.js.map +0 -1
- package/dist/paired-promotion-decision-B6zJ3gYM.d.ts +0 -114
- package/dist/paired-promotion-decision-B6zJ3gYM.d.ts.map +0 -1
- package/dist/prime-protocol-BfSalTfR.js.map +0 -1
- package/dist/promotion-policy-Ckjhzg_4.d.ts +0 -289
- package/dist/promotion-policy-Ckjhzg_4.d.ts.map +0 -1
- package/dist/promotion-policy-CrLrmys8.js.map +0 -1
- package/dist/proposal-findings-2GIUo1et.js.map +0 -1
- package/dist/propose-review-control-dSNPjFUH.js +0 -1458
- package/dist/propose-review-control-dSNPjFUH.js.map +0 -1
- package/dist/release-report-BUYmoKo2.js.map +0 -1
- package/dist/release-report-DA2BCu5a.d.ts.map +0 -1
- package/dist/replay-CohS93nE.js +0 -1859
- package/dist/replay-CohS93nE.js.map +0 -1
- package/dist/replay-DbhZ4Ked.d.ts +0 -834
- package/dist/replay-DbhZ4Ked.d.ts.map +0 -1
- package/dist/reward-hacking-BDToousL.js.map +0 -1
- package/dist/run-evidence-Dhi3C81V.d.ts +0 -225
- package/dist/run-evidence-Dhi3C81V.d.ts.map +0 -1
- package/dist/schema-Cef2cFmb2.d.ts.map +0 -1
- package/dist/semantic-concept-judge-D1z-KepS.js +0 -767
- package/dist/semantic-concept-judge-D1z-KepS.js.map +0 -1
- package/dist/series-convergence-ofsqPWhs.d.ts +0 -35
- package/dist/series-convergence-ofsqPWhs.d.ts.map +0 -1
- package/dist/server-iu0ede49.js.map +0 -1
- package/dist/single-run-lock-DFWHEB09.js.map +0 -1
- package/dist/skill-usage-CO9OLRBx.d.ts.map +0 -1
- package/dist/skillopt-optimization-method-CQdVeM8k.js.map +0 -1
- package/dist/skillopt-optimization-method-USDKhxSA.d.ts.map +0 -1
- package/dist/statistical-heldout-TQ-4CYiN.d.ts.map +0 -1
- package/dist/statistics-ByxzSiOM.js +0 -2212
- package/dist/statistics-ByxzSiOM.js.map +0 -1
- package/dist/statistics-D6Uebe_4.d.ts +0 -968
- package/dist/statistics-D6Uebe_4.d.ts.map +0 -1
- package/dist/supervisor-run-D_sokXcO.js +0 -1690
- package/dist/test-graded-scenario-D1TaI2va.d.ts +0 -141
- package/dist/test-graded-scenario-D1TaI2va.d.ts.map +0 -1
- package/dist/test-graded-scenario-JHcKQNpq.js +0 -318
- package/dist/test-graded-scenario-JHcKQNpq.js.map +0 -1
- package/dist/tool-groups-CZPGGlHf.d.ts.map +0 -1
- package/dist/tool-use-metrics-DEGMKycK.js +0 -370
- package/dist/tool-use-metrics-DEGMKycK.js.map +0 -1
- package/dist/types-D216SgwM.d.ts.map +0 -1
- package/dist/usage-receipt-t7vAzCRQ.js.map +0 -1
- package/dist/verdict-DExhxfgR.d.ts +0 -201
- package/dist/verdict-DExhxfgR.d.ts.map +0 -1
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["canonicalize","stripSlash","clamp01","sum","mean","mean","mean","isObject","defaultExtract","groupBy","fsConstants","clamp01","sum","runScore","inferCandidateId","fs","clamp01"],"sources":["../src/auto-pr.ts","../src/executor.ts","../src/benchmark.ts","../src/capability-headroom.ts","../src/deprecation.ts","../src/client.ts","../src/convergence.ts","../src/driver.ts","../src/feedback-trajectory.ts","../src/integrity/preflight.ts","../src/integrity/single-backend.ts","../src/knowledge/readiness.ts","../src/live-proof.ts","../src/pr-review-benchmark.ts","../src/registry.ts","../src/reporter.ts","../src/treatment-gate.ts","../src/worker-driver-seed.ts","../src/anti-slop.ts","../src/artifact-validator.ts","../src/dual-agent-bench.ts","../src/eval-tools.ts","../src/harness-optimizer.ts","../src/judge-ensemble.ts","../src/judge-retry.ts","../src/judge-panel.ts","../src/judge-runner.ts","../src/playbook.ts","../src/prompt-registry.ts","../src/steering.ts","../src/steering-optimizer.ts","../src/workspace-inspector.ts","../src/budget-guard.ts","../src/hidden-criteria-grading.ts","../src/runtime-trajectory.ts","../src/cost-tracker.ts","../src/eval-trace-store.ts","../src/leaderboard.ts","../src/muffled-gate-scanner.ts","../src/oracle.ts","../src/partition-held-out.ts","../src/scorecard.ts","../src/slo.ts","../src/state-continuity.ts","../src/verification-strategy.ts","../src/equivalence-check.ts","../src/ui-finding.ts","../src/trace-contracts.ts","../src/behavior-dsl.ts","../src/ci-gate.ts","../src/observability.ts","../src/paraphrase.ts","../src/visual-diff.ts","../src/bisector.ts","../src/cross-trace-diff.ts","../src/active-learning.ts","../src/causal-attribution.ts","../src/prm/training-export.ts","../src/reward-model-export.ts","../src/self-play.ts","../src/command-runner.ts","../src/deploy-gate-layer.ts","../src/error-count-extractor.ts","../src/flow-layer.ts","../src/intent-match-judge.ts","../src/keyword-coverage-judge.ts","../src/multi-layer-verifier.ts","../src/multi-toolchain-layer.ts","../src/reference-replay.ts","../src/reviewer.ts","../src/description-length-gate.ts","../src/discover-personas.ts","../src/golden-matcher.ts","../src/held-out-gate.ts","../src/orthogonality.ts","../src/reference-replay-steering.ts","../src/researcher.ts","../src/sandbox-pool.ts","../src/otel-pipeline.ts","../src/profile/baselines.ts","../src/profile/index.ts","../src/traced-analyst.ts","../src/traced-judges.ts","../src/cost-report.ts","../src/model-seats.ts","../src/attestation.ts","../src/product-benchmark/export.ts","../src/product-benchmark/index.ts"],"sourcesContent":["/**\n * Automated pull-request transports for the production loop.\n *\n * A consumer's `runProductionLoop` ships a promoted surface diff as a\n * reviewable code change by handing one of these clients to its\n * `ProductionShipConfig.client`. Each `AutoPrClient.proposeChange`:\n *\n * 1. Stage a branch off `baseBranch`.\n * 2. Write each `fileChange` into the worktree.\n * 3. Commit + push.\n * 4. Open a PR via the GitHub API.\n *\n * (The campaign-loop `autoOnPromote: 'pr'` path uses `openAutoPr` in\n * `src/campaign/auto-pr.ts`, a self-contained `gh pr create` shell-out.)\n *\n * Two transports ship in core:\n *\n * - `ghCliClient(opts)` — shells out to the `gh` CLI. No extra deps,\n * re-uses the developer machine's `gh auth` state, works with both\n * github.com and GitHub Enterprise. This is the recommended default.\n * - `httpGithubClient(opts)` — direct `fetch` against `api.github.com`\n * with a bearer token. Useful in CI where `gh` may not be installed.\n *\n * Both implement the small `AutoPrClient` interface, so tests substitute\n * a fake without spinning a process or network.\n */\n\nimport { ConfigError, ValidationError } from './errors'\n\nexport interface FileChange {\n /** Repo-relative path. Forward slashes; no `..`. */\n path: string\n /** New file contents. UTF-8. */\n contents: string\n /** Optional explanatory comment shown in the commit body. */\n rationale?: string\n}\n\nexport interface RepoRef {\n owner: string\n name: string\n}\n\nexport interface ProposeAutomatedPullRequestInput {\n repo: RepoRef\n /** Branch to base the PR on. Default `'main'`. */\n baseBranch?: string\n /** New branch name. Use a prefix + a short stable id; no spaces. */\n branchName: string\n fileChanges: FileChange[]\n title: string\n body: string\n /** Optional GitHub usernames to request review from. */\n reviewers?: string[]\n /** Optional labels to apply. */\n labels?: string[]\n /** Commit author name. Default: derived from the GitHub client. */\n authorName?: string\n /** Commit author email. Default: derived from the GitHub client. */\n authorEmail?: string\n /** Dry-run — do not push or open a PR; just return the would-be plan. */\n dryRun?: boolean\n}\n\nexport interface ProposeAutomatedPullRequestResult {\n prUrl: string\n branchName: string\n headSha: string\n dryRun: boolean\n}\n\n/** Pluggable transport for the auto-PR pipeline. */\nexport interface AutoPrClient {\n /**\n * Create a branch from `baseBranch`, write file changes, commit, push,\n * and open a PR. Returns the PR's HTML url and head SHA.\n *\n * Implementations must be idempotent on `branchName`: if the branch\n * already exists with the same head SHA as the would-be commit, return\n * the existing PR rather than failing. This makes the production loop\n * safe to retry on transient errors.\n */\n proposeChange(input: ProposeAutomatedPullRequestInput): Promise<ProposeAutomatedPullRequestResult>\n}\n\n/**\n * Validate a proposed change before any transport touches the network. Each\n * `AutoPrClient.proposeChange` runs this at its boundary so a malformed input\n * (path traversal, duplicate path, branch == base, empty title) fails loud\n * locally instead of producing a broken commit on the remote.\n */\nfunction validateProposeInput(input: ProposeAutomatedPullRequestInput): void {\n if (!input.repo.owner.trim() || !input.repo.name.trim()) {\n throw new ValidationError('proposeChange: repo.owner and repo.name required')\n }\n if (!input.branchName.trim() || /\\s/.test(input.branchName)) {\n throw new ValidationError(\n 'proposeChange: branchName must be non-empty and contain no whitespace',\n )\n }\n if (input.branchName === (input.baseBranch ?? 'main')) {\n throw new ValidationError('proposeChange: branchName must differ from baseBranch')\n }\n if (input.fileChanges.length === 0) {\n throw new ValidationError('proposeChange: fileChanges must not be empty')\n }\n const seenPaths = new Set<string>()\n for (const change of input.fileChanges) {\n if (!change.path.trim() || change.path.includes('..') || change.path.startsWith('/')) {\n throw new ValidationError(\n `proposeChange: invalid file path \"${change.path}\" (no '..' or leading '/')`,\n )\n }\n if (seenPaths.has(change.path)) {\n throw new ValidationError(`proposeChange: duplicate file path \"${change.path}\"`)\n }\n seenPaths.add(change.path)\n }\n if (!input.title.trim()) {\n throw new ValidationError('proposeChange: title must not be empty')\n }\n}\n\n// ── HTTP transport (uses `fetch` against api.github.com) ─────────────\n\nexport interface HttpGithubClientOptions {\n /** Personal access token, GitHub App token, or `GITHUB_TOKEN` from Actions. */\n token: string\n /** Override for GitHub Enterprise. Default `'https://api.github.com'`. */\n apiBase?: string\n /** Test seam — defaults to global `fetch`. */\n fetchImpl?: typeof fetch\n /** Test seam — clock for commit timestamps. */\n now?: () => Date\n}\n\ninterface GhRef {\n ref: string\n object: { sha: string }\n}\n\ninterface GhCommit {\n sha: string\n tree: { sha: string }\n}\n\ninterface GhBlob {\n sha: string\n}\n\ninterface GhTree {\n sha: string\n}\n\ninterface GhPullRequest {\n html_url: string\n number: number\n}\n\n/**\n * Direct REST-API GitHub client. No external deps.\n *\n * Idempotency strategy: before creating refs/commits/PRs, check whether\n * the branch already exists at the desired tree. If so, return the\n * existing PR (or open one if missing). Errors from concurrent runs\n * (`Reference already exists`) are caught and treated as success.\n */\nexport function httpGithubClient(opts: HttpGithubClientOptions): AutoPrClient {\n const fetchImpl = opts.fetchImpl ?? fetch\n const apiBase = (opts.apiBase ?? 'https://api.github.com').replace(/\\/+$/, '')\n const now = opts.now ?? (() => new Date())\n\n async function api<T>(\n method: string,\n path: string,\n body?: unknown,\n accept404 = false,\n ): Promise<T | null> {\n const res = await fetchImpl(`${apiBase}${path}`, {\n method,\n headers: {\n accept: 'application/vnd.github+json',\n 'content-type': 'application/json',\n authorization: `Bearer ${opts.token}`,\n 'x-github-api-version': '2022-11-28',\n },\n body: body === undefined ? undefined : JSON.stringify(body),\n })\n if (accept404 && res.status === 404) return null\n if (!res.ok) {\n const text = await res.text().catch(() => '')\n throw new ConfigError(\n `proposeChange: GitHub ${method} ${path} → ${res.status} ${text.slice(0, 400)}`,\n )\n }\n return (await res.json()) as T\n }\n\n return {\n async proposeChange(input) {\n validateProposeInput(input)\n const baseBranch = input.baseBranch ?? 'main'\n const repoPath = `/repos/${input.repo.owner}/${input.repo.name}`\n\n if (input.dryRun) {\n return {\n prUrl: `https://github.com/${input.repo.owner}/${input.repo.name}/compare/${baseBranch}...${input.branchName}`,\n branchName: input.branchName,\n headSha: 'dry-run',\n dryRun: true,\n }\n }\n\n // 1. Find base SHA\n const baseRef = await api<GhRef>('GET', `${repoPath}/git/ref/heads/${baseBranch}`)\n if (!baseRef) {\n throw new ConfigError(`proposeChange: base branch \"${baseBranch}\" not found`)\n }\n const baseSha = baseRef.object.sha\n const baseCommit = await api<GhCommit>('GET', `${repoPath}/git/commits/${baseSha}`)\n if (!baseCommit) {\n throw new ConfigError(`proposeChange: base commit ${baseSha} not found (race condition?)`)\n }\n\n // 2. Create blobs for each file\n const treeEntries = []\n for (const change of input.fileChanges) {\n const blob = await api<GhBlob>('POST', `${repoPath}/git/blobs`, {\n content: change.contents,\n encoding: 'utf-8',\n })\n if (!blob) throw new ConfigError('proposeChange: blob creation returned null')\n treeEntries.push({\n path: change.path,\n mode: '100644',\n type: 'blob',\n sha: blob.sha,\n })\n }\n\n // 3. Create tree\n const tree = await api<GhTree>('POST', `${repoPath}/git/trees`, {\n base_tree: baseCommit.tree.sha,\n tree: treeEntries,\n })\n if (!tree) throw new ConfigError('proposeChange: tree creation returned null')\n\n // 4. Create commit\n const author =\n input.authorName && input.authorEmail\n ? { name: input.authorName, email: input.authorEmail, date: now().toISOString() }\n : undefined\n const commitMessage = renderCommitMessage(input)\n const commit = await api<GhCommit>('POST', `${repoPath}/git/commits`, {\n message: commitMessage,\n tree: tree.sha,\n parents: [baseSha],\n ...(author ? { author, committer: author } : {}),\n })\n if (!commit) throw new ConfigError('proposeChange: commit creation returned null')\n\n // 5. Create or fast-forward branch ref (idempotent on existing branch).\n const existing = await api<GhRef>(\n 'GET',\n `${repoPath}/git/ref/heads/${input.branchName}`,\n undefined,\n true,\n )\n if (!existing) {\n await api('POST', `${repoPath}/git/refs`, {\n ref: `refs/heads/${input.branchName}`,\n sha: commit.sha,\n })\n } else if (existing.object.sha !== commit.sha) {\n await api('PATCH', `${repoPath}/git/refs/heads/${input.branchName}`, {\n sha: commit.sha,\n force: true,\n })\n }\n\n // 6. Open PR (or find an existing open one for the same branch).\n const openPrs = await api<GhPullRequest[]>(\n 'GET',\n `${repoPath}/pulls?state=open&head=${encodeURIComponent(`${input.repo.owner}:${input.branchName}`)}`,\n )\n let pr: GhPullRequest\n if (openPrs && openPrs.length > 0) {\n pr = openPrs[0] as GhPullRequest\n } else {\n const created = await api<GhPullRequest>('POST', `${repoPath}/pulls`, {\n title: input.title,\n body: input.body,\n head: input.branchName,\n base: baseBranch,\n })\n if (!created) throw new ConfigError('proposeChange: PR creation returned null')\n pr = created\n }\n\n if (input.reviewers && input.reviewers.length > 0) {\n await api(\n 'POST',\n `${repoPath}/pulls/${pr.number}/requested_reviewers`,\n { reviewers: input.reviewers },\n true,\n ).catch(() => {\n /* reviewer assignment is best-effort */\n })\n }\n if (input.labels && input.labels.length > 0) {\n await api(\n 'POST',\n `${repoPath}/issues/${pr.number}/labels`,\n { labels: input.labels },\n true,\n ).catch(() => {\n /* label assignment is best-effort */\n })\n }\n\n return {\n prUrl: pr.html_url,\n branchName: input.branchName,\n headSha: commit.sha,\n dryRun: false,\n }\n },\n }\n}\n\n// ── gh CLI transport (no fetch needed, re-uses developer auth) ──────\n\nexport interface GhCliClientOptions {\n /** Override the CLI binary (`gh`). For testing. */\n bin?: string\n /** Working directory containing a clone of `repo`. Default: process cwd. */\n cwd?: string\n /** Test seam: process spawner. Default: node:child_process spawn. */\n exec?: (\n bin: string,\n args: string[],\n opts: { cwd: string; stdin?: string },\n ) => Promise<{ stdout: string; stderr: string; exitCode: number }>\n}\n\n/**\n * `gh` CLI transport. Requires:\n * - `gh` installed and authenticated (`gh auth status`).\n * - A local clone of the repo with a clean working tree.\n * - `git` on PATH.\n *\n * Uses `gh api` for repo metadata and `gh pr create` for the PR. The\n * actual commit lands via `git`, which keeps `gh`'s footprint minimal.\n */\nexport function ghCliClient(opts: GhCliClientOptions = {}): AutoPrClient {\n const bin = opts.bin ?? 'gh'\n const cwd = opts.cwd ?? process.cwd()\n const exec = opts.exec ?? defaultExec\n\n async function run(\n cmd: string,\n args: string[],\n stdin?: string,\n ): Promise<{ stdout: string; stderr: string }> {\n const r = await exec(cmd, args, { cwd, stdin })\n if (r.exitCode !== 0) {\n throw new ConfigError(\n `proposeChange: ${cmd} ${args.join(' ')} failed (${r.exitCode}): ${r.stderr.trim() || r.stdout.trim()}`,\n )\n }\n return r\n }\n\n return {\n async proposeChange(input) {\n validateProposeInput(input)\n const baseBranch = input.baseBranch ?? 'main'\n if (input.dryRun) {\n return {\n prUrl: `https://github.com/${input.repo.owner}/${input.repo.name}/compare/${baseBranch}...${input.branchName}`,\n branchName: input.branchName,\n headSha: 'dry-run',\n dryRun: true,\n }\n }\n\n // Ensure we're working in a clean tree on the base branch.\n await run('git', ['fetch', 'origin', baseBranch])\n await run('git', ['checkout', baseBranch])\n await run('git', ['reset', '--hard', `origin/${baseBranch}`])\n\n // Branch (idempotent: delete if exists, then re-create from base).\n await exec('git', ['branch', '-D', input.branchName], { cwd })\n await run('git', ['checkout', '-b', input.branchName])\n\n // Write file changes.\n const { mkdir, writeFile } = await import('node:fs/promises')\n const { dirname, join, resolve } = await import('node:path')\n for (const change of input.fileChanges) {\n const abs = resolve(cwd, change.path)\n await mkdir(dirname(abs), { recursive: true })\n await writeFile(abs, change.contents, 'utf8')\n await run('git', ['add', join(change.path)])\n }\n\n // Commit.\n const env: Record<string, string> = {}\n if (input.authorName) env.GIT_AUTHOR_NAME = input.authorName\n if (input.authorEmail) env.GIT_AUTHOR_EMAIL = input.authorEmail\n if (input.authorName) env.GIT_COMMITTER_NAME = input.authorName\n if (input.authorEmail) env.GIT_COMMITTER_EMAIL = input.authorEmail\n const message = renderCommitMessage(input)\n await run('git', ['commit', '-m', message])\n\n const headRes = await run('git', ['rev-parse', 'HEAD'])\n const headSha = headRes.stdout.trim()\n\n // Push.\n await run('git', ['push', '-f', 'origin', input.branchName])\n\n // Open PR (idempotent: `gh pr create` errors if one exists).\n const existing = await exec(\n bin,\n [\n 'pr',\n 'list',\n '--state',\n 'open',\n '--head',\n input.branchName,\n '--json',\n 'url,number',\n '--limit',\n '1',\n ],\n { cwd },\n )\n let prUrl = ''\n if (existing.exitCode === 0 && existing.stdout.trim()) {\n const parsed = JSON.parse(existing.stdout) as Array<{ url: string }>\n if (parsed.length > 0 && parsed[0]) prUrl = parsed[0].url\n }\n if (!prUrl) {\n const args = [\n 'pr',\n 'create',\n '--title',\n input.title,\n '--body',\n input.body,\n '--base',\n baseBranch,\n ]\n if (input.reviewers && input.reviewers.length > 0) {\n args.push('--reviewer', input.reviewers.join(','))\n }\n if (input.labels && input.labels.length > 0) {\n args.push('--label', input.labels.join(','))\n }\n const r = await run(bin, args)\n const match = r.stdout.match(/https?:\\/\\/\\S+/)\n prUrl = match ? match[0] : r.stdout.trim()\n }\n\n return { prUrl, branchName: input.branchName, headSha, dryRun: false }\n },\n }\n}\n\nasync function defaultExec(\n bin: string,\n args: string[],\n opts: { cwd: string; stdin?: string },\n): Promise<{ stdout: string; stderr: string; exitCode: number }> {\n const { spawn } = await import('node:child_process')\n return new Promise((resolveExec) => {\n const child = spawn(bin, args, { cwd: opts.cwd })\n let stdout = ''\n let stderr = ''\n child.stdout.on('data', (d) => {\n stdout += d.toString()\n })\n child.stderr.on('data', (d) => {\n stderr += d.toString()\n })\n if (opts.stdin) child.stdin.end(opts.stdin)\n child.on('error', (err) => {\n resolveExec({ stdout, stderr: `${stderr}${err.message}`, exitCode: 1 })\n })\n child.on('close', (code) => {\n resolveExec({ stdout, stderr, exitCode: code ?? 1 })\n })\n })\n}\n\nfunction renderCommitMessage(input: ProposeAutomatedPullRequestInput): string {\n const lines = [input.title, '']\n for (const change of input.fileChanges) {\n if (change.rationale) lines.push(`- ${change.path}: ${change.rationale}`)\n }\n if (lines[lines.length - 1] !== '') lines.push('')\n lines.push(input.body.trim())\n return lines.join('\\n').trim()\n}\n","import type { ChatClient, ChatRequest } from './analyst/chat-client'\nimport { CostLedger, type CostLedgerHandle } from './cost-ledger'\nimport { CaptureIntegrityError } from './errors'\nimport { assertServedModel } from './integrity/served-model'\nimport { JudgeParseError } from './judges'\nimport {\n costReceiptFromLlm,\n costReceiptFromLlmError,\n isTransientLlmError,\n maximumChargeForLlmRequest,\n} from './llm-client'\nimport { normalizeScores, weightedMean } from './statistics'\nimport type {\n CollectedArtifacts,\n JudgeFn,\n JudgeScore,\n Scenario,\n ScenarioResult,\n TurnResult,\n} from './types'\n\ninterface ChatMessage {\n role: 'system' | 'user' | 'assistant'\n content: string\n}\n\nexport interface ExecutorConfig {\n /** System prompt for the agent under test */\n systemPrompt: string\n /** Model to use for the agent */\n model?: string\n /** Judges to run after execution */\n judges: JudgeFn[]\n /** Shared ledger for paid built-in judges. */\n costLedger?: CostLedgerHandle\n costPhase?: string\n costTags?: Record<string, string>\n signal?: AbortSignal\n /** Regex patterns for detecting tool/API calls in responses */\n toolCallPatterns?: RegExp[]\n /** Block delimiter pattern (default: :::type\\n...\\n:::) */\n blockPattern?: RegExp\n /** Custom artifact checker for domain-specific checks */\n artifactChecker?: (\n check: Scenario['artifactChecks'][0],\n artifacts: CollectedArtifacts,\n ) => { passed: boolean; detail: string } | null\n /**\n * Sleep used between judge retries and after a judge succeeds. Defaults to\n * real `setTimeout`. Injectable so tests exercise the retry policy without\n * the real multi-second backoff.\n */\n sleep?: (ms: number) => Promise<void>\n}\n\nfunction errMessage(err: unknown): string {\n if (err instanceof Error) return `${err.name}: ${err.message}`\n return String(err)\n}\n\n/** Per-judge failure diagnostic, recorded additively on `ScenarioResult`. */\nexport interface JudgeFailure {\n judge: string\n attempts: number\n reason: string\n}\n\n/**\n * Execute a scenario against an injected chat client.\n *\n * Runs multi-turn conversation, extracts artifacts, runs judges.\n */\nexport async function executeScenario(\n chat: ChatClient,\n scenario: Scenario,\n config: ExecutorConfig,\n): Promise<ScenarioResult> {\n const startTime = Date.now()\n const model = config.model ?? 'gpt-4o'\n const costLedger = config.costLedger ?? new CostLedger()\n const costTags = {\n ...config.costTags,\n scenarioId: scenario.id,\n executionId: globalThis.crypto.randomUUID(),\n }\n\n const systemPrompt = [config.systemPrompt, scenario.systemPromptAppend ?? '']\n .filter(Boolean)\n .join('\\n\\n')\n\n const messages: ChatMessage[] = [{ role: 'system', content: systemPrompt }]\n\n const turns: TurnResult[] = []\n const allCodeBlocks: { language: string; code: string }[] = []\n const allBlocks: { type: string; fields: Record<string, string> }[] = []\n const allToolCalls: string[] = []\n\n const blockRe = config.blockPattern ?? /:::(\\w+)\\s*\\n([\\s\\S]*?)\\n\\s*:::/g\n\n for (let i = 0; i < scenario.turns.length; i++) {\n const turn = scenario.turns[i]!\n const turnStart = Date.now()\n\n messages.push({ role: 'user', content: turn.user })\n\n const request = {\n model,\n messages,\n temperature: 0.4,\n maxTokens: 3000,\n } satisfies ChatRequest\n const paid = await costLedger.runPaidCall({\n channel: 'agent',\n phase: config.costPhase ?? 'benchmark.agent',\n actor: 'scenario-agent',\n model,\n maximumCharge:\n chat.maximumAttempts === undefined\n ? undefined\n : maximumChargeForLlmRequest(request, { maximumAttempts: chat.maximumAttempts }),\n tags: costTags,\n signal: config.signal,\n execute: (signal, callId) => chat.chat(request, { signal, idempotencyKey: callId }),\n receipt: costReceiptFromLlm,\n receiptFromError: costReceiptFromLlmError,\n })\n if (!paid.succeeded) throw paid.error\n // Hold the transport to its own word: when it names the model that\n // answered, that name must be the model this scenario requested, or every\n // per-model number below is about a model we never called. A transport that\n // names nothing (mock, CLI bridge) cannot be made to prove identity from\n // here — callers needing that proof enable it at the client\n // (`LlmClientOptions.assertServedModel`) or gate the run on\n // `assertModelsServed`.\n assertServedModel(model, (paid.value as { servedModel?: string | null }).servedModel, {\n allowUnreported: true,\n context: `executeScenario \"${scenario.id}\" turn ${i}`,\n })\n const rawContent = (paid.value as { content?: unknown }).content\n if (typeof rawContent !== 'string') {\n throw new CaptureIntegrityError(\n `chat response for scenario \"${scenario.id}\" turn ${i} is malformed: ` +\n `expected content to be a string, got ${\n rawContent === null ? 'null' : typeof rawContent\n }`,\n )\n }\n const content = rawContent\n\n messages.push({ role: 'assistant', content })\n\n // Extract code blocks\n const codeRe = /```(\\w+)?\\n([\\s\\S]*?)```/g\n let codeMatch: RegExpExecArray | null = codeRe.exec(content)\n while (codeMatch !== null) {\n allCodeBlocks.push({ language: codeMatch[1] ?? 'text', code: codeMatch[2] ?? '' })\n codeMatch = codeRe.exec(content)\n }\n\n // Extract structured blocks\n const turnBlocks: { type: string; title: string }[] = []\n const blockReLocal = new RegExp(blockRe.source, blockRe.flags)\n let blockMatch: RegExpExecArray | null = blockReLocal.exec(content)\n while (blockMatch !== null) {\n const fields: Record<string, string> = {}\n for (const line of (blockMatch[2] ?? '').split('\\n')) {\n const idx = line.indexOf(':')\n if (idx > 0) fields[line.slice(0, idx).trim()] = line.slice(idx + 1).trim()\n }\n const blockType = blockMatch[1] ?? ''\n allBlocks.push({ type: blockType, fields })\n turnBlocks.push({ type: blockType, title: fields.title ?? '' })\n blockMatch = blockReLocal.exec(content)\n }\n\n // Detect tool calls via configurable patterns\n let hasToolCall = false\n if (config.toolCallPatterns) {\n for (const pattern of config.toolCallPatterns) {\n const re = new RegExp(pattern.source, pattern.flags)\n let toolMatch: RegExpExecArray | null = re.exec(content)\n while (toolMatch !== null) {\n allToolCalls.push(toolMatch[0])\n hasToolCall = true\n toolMatch = re.exec(content)\n }\n }\n }\n\n turns.push({\n turnIndex: i,\n userMessage: turn.user,\n agentResponse: content,\n durationMs: Date.now() - turnStart,\n blocksExtracted: turnBlocks,\n containsCode: allCodeBlocks.length > 0,\n containsToolCall: hasToolCall,\n })\n }\n\n const artifacts: CollectedArtifacts = {\n vaultFiles: [],\n blocksExtracted: allBlocks,\n codeBlocks: allCodeBlocks,\n toolCalls: allToolCalls,\n }\n\n // Run artifact checks\n const artifactResults = scenario.artifactChecks.map((check) => {\n // Try custom checker first\n if (config.artifactChecker) {\n const custom = config.artifactChecker(check, artifacts)\n if (custom) return { check, ...custom }\n }\n\n switch (check.type) {\n case 'block_extracted': {\n const count = allBlocks.filter((b) => b.type === check.target).length\n return {\n check,\n passed: count >= (check.minCount ?? 1),\n detail: `Found ${count} ${check.target} blocks (need ${check.minCount ?? 1})`,\n }\n }\n case 'code_valid': {\n const hasCode = allCodeBlocks.some(\n (b) => b.language === check.target || b.code.includes(check.target),\n )\n return { check, passed: hasCode, detail: hasCode ? 'Code block found' : 'No matching code' }\n }\n default:\n return {\n check,\n passed: false,\n detail: `Check type \"${check.type}\" requires live environment`,\n }\n }\n })\n\n // Run judges sequentially with retry. A judge that fails — unparseable\n // output (JudgeParseError, non-retryable) or errors across every attempt —\n // is COUNTED as a failed judge, never folded into the scores as a fake\n // zero row: a synthetic zero is indistinguishable from a real low score.\n const judgeInput = {\n scenario,\n turns,\n artifacts,\n costLedger,\n costPhase: config.costPhase ?? 'benchmark.judge',\n costTags,\n signal: config.signal,\n }\n const judgeResults: JudgeScore[][] = []\n let failedJudges = 0\n const judgeFailures: JudgeFailure[] = []\n const sleep = config.sleep ?? ((ms: number) => new Promise<void>((r) => setTimeout(r, ms)))\n\n for (let j = 0; j < config.judges.length; j++) {\n const judge = config.judges[j]!\n const judgeName = judge.name || `judge[${j}]`\n let lastError: unknown\n let madeAttempts = 0\n for (let attempt = 0; attempt < 3; attempt++) {\n madeAttempts = attempt + 1\n try {\n if (attempt > 0) {\n const wait = attempt * 10_000\n console.log(` ${judgeName} retry ${attempt}/2 (waiting ${wait / 1000}s)`)\n await sleep(wait)\n }\n const scores = await judge(chat, judgeInput)\n judgeResults.push(scores)\n await sleep(3000)\n lastError = undefined\n break\n } catch (err) {\n lastError = err\n if (err instanceof JudgeParseError) {\n // The model answered but unparseably — another identical prompt\n // won't fix it. Record the failure and move to the next judge.\n console.error(` ${judgeName} unparseable (no retry): ${errMessage(err)}`)\n break\n }\n console.error(` ${judgeName} attempt ${attempt} failed: ${errMessage(err)}`)\n // Deterministic errors (bad rubric, auth, 4xx) won't change on retry —\n // only retry connection/rate-limit class faults. Stop the loop now so a\n // permanent error is not masked by two pointless waits.\n if (!isTransientLlmError(err)) break\n }\n }\n if (lastError !== undefined) {\n failedJudges++\n judgeFailures.push({\n judge: judgeName,\n attempts: madeAttempts,\n reason: errMessage(lastError),\n })\n }\n }\n\n const allScores = judgeResults.flat()\n // Defensive: custom JudgeFns may still emit error-shaped rows.\n const errorScores = allScores.filter(\n (s) => s.dimension === 'parse_error' || s.dimension === 'error',\n )\n const validScores = allScores.filter(\n (s) => s.dimension !== 'parse_error' && s.dimension !== 'error',\n )\n const normalized = normalizeScores(validScores)\n\n // Build weight map from scenario rubric dimensions\n const weightMap = new Map<string, number>()\n for (const dim of scenario.dimensions) {\n weightMap.set(dim, 1)\n }\n\n const overallScore = weightedMean(\n normalized.map((s) => ({\n score: s.score,\n weight: weightMap.get(s.dimension) ?? 1,\n })),\n )\n\n // judgeFailures is additive diagnostic context (WHY each judge errored),\n // recorded alongside the existing judgeErrors count without widening the\n // shared ScenarioResult contract. Absent when every judge succeeded.\n const result: ScenarioResult & { judgeFailures?: JudgeFailure[] } = {\n scenarioId: scenario.id,\n persona: scenario.persona,\n turns,\n artifactResults,\n judgeScores: allScores,\n judgeErrors: errorScores.length + failedJudges,\n overallScore,\n totalDurationMs: Date.now() - startTime,\n artifacts,\n cost: costLedger.summary({ tags: costTags }),\n }\n if (judgeFailures.length > 0) result.judgeFailures = judgeFailures\n return result\n}\n","import type { ChatClient } from './analyst/chat-client'\nimport { CostLedger } from './cost-ledger'\nimport { executeScenario } from './executor'\nimport type { BenchmarkReport, BenchmarkRunnerConfig, Scenario, ScenarioResult } from './types'\n\n/**\n * BenchmarkRunner — orchestrates scenarios, executor, judges, and scoring.\n *\n * Domain-agnostic. Each agent provides its own scenarios, judges, and system prompt.\n */\nexport class BenchmarkRunner {\n private chat: ChatClient\n private config: BenchmarkRunnerConfig\n\n constructor(chat: ChatClient, config: BenchmarkRunnerConfig) {\n this.chat = chat\n this.config = config\n }\n\n async run(scenarios?: Scenario[]): Promise<BenchmarkReport> {\n const toRun = scenarios ?? this.config.scenarios\n const passThreshold = this.config.passThreshold ?? 6.0\n const costLedger = this.config.costLedger ?? new CostLedger()\n const costTags = { benchmarkRunId: globalThis.crypto.randomUUID() }\n\n console.log('='.repeat(70))\n console.log(' AGENT EVAL — BENCHMARK')\n console.log(' Multi-turn scenarios x Multi-judge panel')\n console.log('='.repeat(70))\n console.log(`Scenarios: ${toRun.length}`)\n console.log(`Judges: ${this.config.judges.length}`)\n console.log(`Model: ${this.config.model ?? 'gpt-4o'}`)\n console.log()\n\n const results: ScenarioResult[] = []\n\n for (let i = 0; i < toRun.length; i++) {\n const scenario = toRun[i]!\n console.log(`[${i + 1}/${toRun.length}] ${scenario.id} (${scenario.persona})`)\n console.log(` thesis: ${scenario.thesis}`)\n console.log(` turns: ${scenario.turns.length}`)\n\n const result = await executeScenario(this.chat, scenario, {\n systemPrompt: this.config.systemPrompt,\n model: this.config.model,\n judges: this.config.judges,\n costLedger,\n costTags,\n })\n results.push(result)\n\n // Print turn summaries\n for (const turn of result.turns) {\n const codeIcon = turn.containsCode ? '[code]' : ''\n const toolIcon = turn.containsToolCall ? '[tool]' : ''\n const blockCount = turn.blocksExtracted.length\n const blockIcon = blockCount > 0 ? `[blocks:${blockCount}]` : ''\n console.log(\n ` turn ${turn.turnIndex + 1}: ${(turn.durationMs / 1000).toFixed(1)}s ${codeIcon} ${toolIcon} ${blockIcon} (${turn.agentResponse.length} chars)`,\n )\n }\n\n // Print artifact results\n for (const ar of result.artifactResults) {\n const icon = ar.passed ? '+' : 'X'\n console.log(` artifact: [${icon}] ${ar.check.description} — ${ar.detail}`)\n }\n\n // Print judge scores\n console.log(` judges:`)\n const byJudge: Record<string, { scores: number[]; dimensions: string[] }> = {}\n for (const js of result.judgeScores) {\n const entry = byJudge[js.judgeName] ?? { scores: [], dimensions: [] }\n entry.scores.push(js.score)\n entry.dimensions.push(`${js.dimension}=${js.score}`)\n byJudge[js.judgeName] = entry\n }\n for (const [name, data] of Object.entries(byJudge)) {\n const avg = (data.scores.reduce((a, b) => a + b, 0) / data.scores.length).toFixed(1)\n console.log(` ${name.padEnd(16)} avg=${avg} [${data.dimensions.join(', ')}]`)\n }\n\n console.log(\n ` OVERALL: ${result.overallScore.toFixed(1)}/10 (${(result.totalDurationMs / 1000).toFixed(0)}s)`,\n )\n console.log()\n }\n\n // Build summary\n const byPersona: Record<string, { avg: number; passed: number; total: number }> = {}\n const byDimension: Record<string, { avg: number; scores: number[] }> = {}\n\n for (const r of results) {\n const personaEntry = byPersona[r.persona] ?? { avg: 0, passed: 0, total: 0 }\n personaEntry.total++\n personaEntry.avg += r.overallScore\n if (r.overallScore >= passThreshold) personaEntry.passed++\n byPersona[r.persona] = personaEntry\n\n for (const js of r.judgeScores) {\n const dimEntry = byDimension[js.dimension] ?? { avg: 0, scores: [] }\n dimEntry.scores.push(js.score)\n byDimension[js.dimension] = dimEntry\n }\n }\n\n for (const p of Object.values(byPersona)) {\n p.avg = p.total > 0 ? p.avg / p.total : 0\n }\n for (const d of Object.values(byDimension)) {\n d.avg = d.scores.length > 0 ? d.scores.reduce((a, b) => a + b, 0) / d.scores.length : 0\n }\n\n const sorted = [...results].sort((a, b) => a.overallScore - b.overallScore)\n const weakest = sorted.slice(0, 3).map((r) => ({\n scenario: r.scenarioId,\n score: r.overallScore,\n reason:\n r.judgeScores\n .filter((s) => s.score < passThreshold)\n .map((s) => `${s.dimension}=${s.score}`)\n .join(', ') || 'close to threshold',\n }))\n const strongest = sorted\n .slice(-3)\n .reverse()\n .map((r) => ({\n scenario: r.scenarioId,\n score: r.overallScore,\n reason:\n r.judgeScores\n .filter((s) => s.score >= 9)\n .map((s) => `${s.dimension}=${s.score}`)\n .join(', ') || 'consistently strong',\n }))\n\n // Print final summary\n console.log('='.repeat(70))\n console.log(' RESULTS')\n console.log('='.repeat(70))\n\n const overallAvg =\n results.length > 0 ? results.reduce((s, r) => s + r.overallScore, 0) / results.length : 0\n\n console.log(`Overall: ${overallAvg.toFixed(1)}/10`)\n console.log()\n\n console.log('By persona:')\n for (const [name, data] of Object.entries(byPersona)) {\n console.log(\n ` ${name.padEnd(20)} ${data.avg.toFixed(1)}/10 (${data.passed}/${data.total} passed)`,\n )\n }\n console.log()\n\n console.log('By dimension:')\n const dimEntries = Object.entries(byDimension).sort((a, b) => a[1].avg - b[1].avg)\n for (const [name, data] of dimEntries) {\n const min = Math.min(...data.scores)\n const max = Math.max(...data.scores)\n console.log(\n ` ${name.padEnd(24)} avg=${data.avg.toFixed(1)} range=[${min}-${max}] n=${data.scores.length}`,\n )\n }\n console.log()\n\n if (weakest.length > 0) {\n console.log('Weakest:')\n for (const w of weakest) {\n console.log(` ${w.scenario}: ${w.score.toFixed(1)} — ${w.reason}`)\n }\n console.log()\n }\n\n return {\n timestamp: new Date().toISOString(),\n generation: this.config.generation ?? 1,\n promptVersion: this.config.promptVersion ?? 'v1',\n scenarioCount: toRun.length,\n results,\n cost: costLedger.summary({ tags: costTags }),\n summary: { overallAvg, byPersona, byDimension, weakest, strongest },\n }\n }\n}\n","/**\n * Capability-headroom gate — \"can this task set even SEE the capability\n * you're about to A/B?\"\n *\n * A capability A/B (grant one arm a tool, a skill, extra context — anything)\n * can only detect the capability on tasks the capability-ABSENT baseline\n * FAILS. A task the baseline already passes is saturated: the treatment arm\n * has no headroom to demonstrate anything, and averaging saturated tasks into\n * the comparison dilutes a real effect toward a false null. Calibrate before\n * measuring: run the baseline arm first, classify every task's headroom, and\n * refuse to run the comparison when no task has a gap.\n *\n * Fail-closed on unknown outcomes: a baseline run whose outcome could not be\n * determined (infra loss, unverified, missing) NEVER counts as a failure —\n * treating \"couldn't tell\" as \"failed\" would manufacture headroom out of\n * telemetry gaps and launder infra noise into a treatment effect.\n *\n * Domain-free by construction: the capability under test never appears here.\n * Callers decide what the baseline arm lacks; this module only classifies\n * baseline outcomes per task.\n */\n\nimport { ValidationError } from './errors'\n\n/** One baseline-arm (capability-absent) observation of one task. */\nexport interface HeadroomInput {\n /** Stable task identity; multiple rows per task are multiple baseline reps. */\n taskId: string\n /** Baseline outcome. 'unknown' = the outcome could not be determined —\n * distinct from 'fail' and never counted as one. */\n baselineOutcome: 'pass' | 'fail' | 'unknown'\n}\n\n/** Headroom classification for one task.\n * - 'gap': the baseline fails it — the comparison can see the capability here.\n * - 'saturated': the baseline already passes it — no headroom.\n * - 'unknown': every baseline outcome is unknown — fail-closed, not a gap. */\nexport type HeadroomClass = 'gap' | 'saturated' | 'unknown'\n\nexport interface TaskHeadroom {\n taskId: string\n /** Total baseline observations for this task (known + unknown). */\n n: number\n /** Observations with a known ('pass' | 'fail') outcome — the evidence the\n * classification actually rests on. A large `n` with a small `nKnown`\n * means the headroom verdict is thin, not well-replicated. */\n nKnown: number\n /** Pass rate over KNOWN outcomes only; NaN when every outcome is unknown\n * (no data ≠ measured zero). */\n baselinePassRate: number\n headroom: HeadroomClass\n}\n\nexport interface CapabilityHeadroomOptions {\n /** A task counts as 'gap' when its baseline pass rate is ≤ this. Default 0\n * (the baseline must fail every known rep). Must be in [0, 1) — a\n * threshold of 1 would classify a fully-saturated task as a gap. */\n keepThreshold?: number\n}\n\nexport interface CapabilityHeadroomResult {\n /** Per-task classification, sorted by `taskId`. */\n tasks: TaskHeadroom[]\n summary: {\n tasksWithGap: number\n tasksSaturated: number\n tasksUnknown: number\n /** Total unknown-outcome reps across ALL tasks (including tasks that\n * still classified via their known reps) — the size of the telemetry\n * hole behind the classifications. */\n repsUnknown: number\n }\n}\n\n/**\n * Classify every task's baseline headroom from capability-absent baseline\n * outcomes.\n *\n * A task is 'gap' when it has ≥ 1 known outcome and its pass rate over known\n * outcomes is ≤ `keepThreshold`; 'saturated' when the rate exceeds the\n * threshold; 'unknown' when every outcome is unknown. Unknown reps never\n * count toward the rate in either direction (fail-closed — see the module\n * doc), and evidence strength stays visible: each task reports `nKnown`\n * alongside `n`, and the summary totals the unknown reps in `repsUnknown`.\n * Throws on empty input, an out-of-range `keepThreshold`, or an\n * unrecognized outcome value (rows are often projected from untyped records).\n */\nexport function capabilityHeadroom(\n rows: readonly HeadroomInput[],\n opts: CapabilityHeadroomOptions = {},\n): CapabilityHeadroomResult {\n const keepThreshold = opts.keepThreshold ?? 0\n if (!Number.isFinite(keepThreshold) || keepThreshold < 0 || keepThreshold >= 1) {\n throw new ValidationError(\n `capabilityHeadroom: keepThreshold must be in [0, 1), got ${keepThreshold}`,\n )\n }\n if (rows.length === 0) {\n throw new ValidationError(\n 'capabilityHeadroom: no baseline rows supplied — run the capability-absent baseline arm first',\n )\n }\n\n // taskId → { n, passes, known }\n const byTask = new Map<string, { n: number; passes: number; known: number }>()\n for (const row of rows) {\n if (\n row.baselineOutcome !== 'pass' &&\n row.baselineOutcome !== 'fail' &&\n row.baselineOutcome !== 'unknown'\n ) {\n throw new ValidationError(\n `capabilityHeadroom: unrecognized baselineOutcome '${row.baselineOutcome}' for task '${row.taskId}' (expected 'pass' | 'fail' | 'unknown')`,\n )\n }\n const agg = byTask.get(row.taskId) ?? { n: 0, passes: 0, known: 0 }\n agg.n++\n if (row.baselineOutcome !== 'unknown') {\n agg.known++\n if (row.baselineOutcome === 'pass') agg.passes++\n }\n byTask.set(row.taskId, agg)\n }\n\n const tasks: TaskHeadroom[] = [...byTask.entries()]\n .sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0))\n .map(([taskId, agg]) => {\n if (agg.known === 0) {\n return {\n taskId,\n n: agg.n,\n nKnown: 0,\n baselinePassRate: Number.NaN,\n headroom: 'unknown' as const,\n }\n }\n const baselinePassRate = agg.passes / agg.known\n return {\n taskId,\n n: agg.n,\n nKnown: agg.known,\n baselinePassRate,\n headroom: baselinePassRate <= keepThreshold ? ('gap' as const) : ('saturated' as const),\n }\n })\n\n const summary = {\n tasksWithGap: tasks.filter((t) => t.headroom === 'gap').length,\n tasksSaturated: tasks.filter((t) => t.headroom === 'saturated').length,\n tasksUnknown: tasks.filter((t) => t.headroom === 'unknown').length,\n repsUnknown: tasks.reduce((sum, t) => sum + (t.n - t.nKnown), 0),\n }\n return { tasks, summary }\n}\n\nexport interface AssertCapabilityHeadroomOptions {\n /** Minimum tasks classified 'gap' for the comparison to proceed. Default 1. */\n minTasksWithGap?: number\n}\n\n/**\n * The go/no-go guard: throws when fewer than `minTasksWithGap` tasks have\n * baseline headroom — i.e. the benchmark cannot see the capability, so any\n * comparison run on it would measure noise. Call between the baseline\n * calibration run and the treatment run.\n */\nexport function assertCapabilityHeadroom(\n result: CapabilityHeadroomResult,\n opts: AssertCapabilityHeadroomOptions = {},\n): void {\n const minTasksWithGap = opts.minTasksWithGap ?? 1\n if (!Number.isInteger(minTasksWithGap) || minTasksWithGap < 1) {\n throw new ValidationError(\n `assertCapabilityHeadroom: minTasksWithGap must be an integer ≥ 1, got ${minTasksWithGap}`,\n )\n }\n const { tasksWithGap, tasksSaturated, tasksUnknown } = result.summary\n if (tasksWithGap < minTasksWithGap) {\n const total = result.tasks.length\n throw new ValidationError(\n `assertCapabilityHeadroom: only ${tasksWithGap} of ${total} task(s) have baseline headroom ` +\n `(need ≥ ${minTasksWithGap}). ${tasksSaturated} saturated (baseline already passes), ` +\n `${tasksUnknown} unknown (no determinable baseline outcome). A capability A/B on this ` +\n `task set cannot detect the capability — add tasks the baseline fails, or fix baseline ` +\n `outcome capture, before measuring.`,\n )\n }\n}\n","/**\n * One-shot deprecation warnings. A deprecated surface warns the FIRST time it\n * is used in a process — loud enough to be seen, quiet enough not to flood a\n * matrix run that constructs it per cell.\n */\n\nconst warned = new Set<string>()\n\n/** Emit `message` on console.warn once per process per `key`. */\nexport function warnDeprecatedOnce(key: string, message: string): void {\n if (warned.has(key)) return\n warned.add(key)\n console.warn(`[agent-eval deprecation] ${message}`)\n}\n\n/** Test seam: forget prior warnings so once-semantics can be asserted. */\nexport function resetDeprecationWarnings(): void {\n warned.clear()\n}\n","import { warnDeprecatedOnce } from './deprecation'\nimport type { CheckResult, ProductClientConfig, RouteMap, TestResult } from './types'\n\nconst DEFAULT_REQUEST_TIMEOUT_MS = 30_000\n\n/**\n * ProductClient — configurable HTTP client for exercising any agent's APIs.\n *\n * Routes are config, not hardcoded. Each agent provides its own RouteMap.\n *\n * @deprecated A one-product REST client does not belong in the generic\n * substrate. Moves to the product repo in the next major\n * (tangle-network/agent-runtime#694); vendor it if you construct it directly.\n */\nexport class ProductClient {\n private baseUrl: string\n private routes: RouteMap\n private cookies: string = ''\n private timeoutMs: number\n\n constructor(config: ProductClientConfig) {\n warnDeprecatedOnce(\n 'ProductClient',\n 'ProductClient is deprecated and moves to the product repo in the next major (tangle-network/agent-runtime#694).',\n )\n this.baseUrl = config.baseUrl.replace(/\\/+$/, '')\n this.routes = config.routes\n this.timeoutMs = config.timeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS\n }\n\n private route(name: keyof RouteMap): string {\n const path = this.routes[name]\n if (!path) throw new Error(`Route \"${name}\" not configured`)\n return path\n }\n\n /**\n * Single HTTP boundary for every JSON request. Aborts after `timeoutMs`,\n * checks `res.ok` BEFORE parsing, and throws `${method} ${path} failed:\n * HTTP ${status} — ${body}` on a non-ok response so a 4xx/5xx error body\n * can never be parsed as a success shape. Callers inspect the resolved\n * value only after a successful return.\n */\n private async request(\n method: string,\n path: string,\n body?: Record<string, unknown>,\n ): Promise<Record<string, unknown>> {\n const controller = new AbortController()\n const timeout = setTimeout(() => controller.abort(), this.timeoutMs)\n let res: Response\n try {\n res = await fetch(`${this.baseUrl}${path}`, {\n method,\n headers: {\n ...(body ? { 'Content-Type': 'application/json' } : {}),\n Origin: this.baseUrl,\n Cookie: this.cookies,\n },\n ...(body ? { body: JSON.stringify(body) } : {}),\n signal: controller.signal,\n })\n } finally {\n clearTimeout(timeout)\n }\n if (!res.ok) {\n const text = await res.text().catch(() => '')\n throw new Error(`${method} ${path} failed: HTTP ${res.status} — ${text.slice(0, 500)}`)\n }\n return res.json() as Promise<Record<string, unknown>>\n }\n\n /**\n * Read a required collection field. A missing/non-array field is a contract\n * violation (wrong route, drift, partial body) — surface it loud instead of\n * masking it as a healthy empty set. A genuinely empty `[]` passes through.\n */\n private requireArray<T>(res: Record<string, unknown>, field: string): T[] {\n const value = res[field]\n if (!Array.isArray(value)) {\n throw new Error(\n `Response missing array field \"${field}\" (got ${typeof value}: ${JSON.stringify(value)?.slice(0, 200)})`,\n )\n }\n return value as T[]\n }\n\n async signup(name: string, email: string, password: string): Promise<{ userId: string }> {\n const res = await this.post(this.route('signup'), { name, email, password })\n const user = res.user as Record<string, unknown> | undefined\n if (!user?.id) throw new Error(`Signup failed: ${JSON.stringify(res)}`)\n return { userId: user.id as string }\n }\n\n async login(email: string, password: string): Promise<void> {\n const res = await fetch(`${this.baseUrl}${this.route('login')}`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', Origin: this.baseUrl },\n body: JSON.stringify({ email, password }),\n redirect: 'manual',\n })\n const setCookie = res.headers.get('set-cookie')\n if (setCookie) {\n this.cookies = setCookie.split(';')[0] ?? ''\n }\n const body = (await res.json()) as Record<string, unknown>\n if (!body.user) throw new Error(`Login failed: ${JSON.stringify(body)}`)\n }\n\n async createWorkspace(name: string, type = 'project'): Promise<string> {\n const res = await this.post(this.route('workspaces'), { name, type })\n const ws = res.workspace as Record<string, unknown> | undefined\n if (!ws?.id) throw new Error(`Workspace creation failed: ${JSON.stringify(res)}`)\n return ws.id as string\n }\n\n async createThread(workspaceId: string): Promise<string> {\n const res = await this.post(this.route('threads'), { workspaceId })\n const thread = res.thread as Record<string, unknown> | undefined\n if (!thread?.id) throw new Error(`Thread creation failed: ${JSON.stringify(res)}`)\n return thread.id as string\n }\n\n async chat(\n workspaceId: string,\n threadId: string,\n content: string,\n _opts?: { blockPatterns?: RegExp[] },\n ): Promise<{ text: string; blocks: { type: string; title: string }[] }> {\n const res = await fetch(`${this.baseUrl}${this.route('chat')}`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Origin: this.baseUrl,\n Cookie: this.cookies,\n },\n body: JSON.stringify({ workspaceId, threadId, content }),\n })\n\n if (!res.ok || !res.body) throw new Error(`Chat failed: ${res.status}`)\n\n // Parse NDJSON stream\n const reader = res.body.getReader()\n const decoder = new TextDecoder()\n let buf = ''\n let text = ''\n const blocks: { type: string; title: string }[] = []\n\n while (true) {\n const { done, value } = await reader.read()\n if (done) break\n buf += decoder.decode(value, { stream: true })\n const lines = buf.split('\\n')\n buf = lines.pop() ?? ''\n for (const line of lines) {\n if (!line.trim()) continue\n try {\n const event = JSON.parse(line) as { type?: string; data?: { delta?: string } }\n if (event.type === 'message.part.updated' && event.data?.delta) {\n text += event.data.delta\n }\n } catch {\n /* skip non-JSON lines */\n }\n }\n }\n\n // Extract :::blocks from text\n const blockRe = /:::(\\w+)\\s*\\n([\\s\\S]*?)\\n\\s*:::/g\n let match: RegExpExecArray | null = blockRe.exec(text)\n while (match !== null) {\n const fields: Record<string, string> = {}\n for (const line of match[2]!.split('\\n')) {\n const idx = line.indexOf(':')\n if (idx > 0) fields[line.slice(0, idx).trim()] = line.slice(idx + 1).trim()\n }\n blocks.push({ type: match[1]!, title: fields.title ?? '' })\n match = blockRe.exec(text)\n }\n\n return { text, blocks }\n }\n\n async getTasks(\n workspaceId: string,\n ): Promise<{ id: string; title: string; status: string; priority: string }[]> {\n const res = await this.get(`${this.route('tasks')}?workspaceId=${workspaceId}`)\n return this.requireArray<{ id: string; title: string; status: string; priority: string }>(\n res,\n 'tasks',\n )\n }\n\n async getEvents(workspaceId: string): Promise<{ id: string; title: string; type: string }[]> {\n const res = await this.get(`${this.route('events')}?workspaceId=${workspaceId}`)\n return this.requireArray<{ id: string; title: string; type: string }>(res, 'events')\n }\n\n async getApprovals(\n workspaceId: string,\n ): Promise<{ id: string; title: string; status: string; type: string }[]> {\n const res = await this.get(`${this.route('approvals')}?workspaceId=${workspaceId}`)\n return this.requireArray<{ id: string; title: string; status: string; type: string }>(\n res,\n 'actions',\n )\n }\n\n async getVaultTree(workspaceId: string): Promise<string[]> {\n const res = await this.get(`${this.route('vault')}?workspaceId=${workspaceId}`)\n const paths: string[] = []\n function extract(nodes: unknown[]) {\n for (const n of nodes) {\n const node = n as { path?: string; type?: string; children?: unknown[] }\n if (node.type === 'file' && node.path) paths.push(node.path)\n if (node.children) extract(node.children)\n }\n }\n extract(this.requireArray<unknown>(res, 'tree'))\n return paths\n }\n\n async approveAction(workspaceId: string, id: string): Promise<void> {\n await this.patch(this.route('approvals'), { workspaceId, id, status: 'approved' })\n }\n\n async rejectAction(workspaceId: string, id: string, reason: string): Promise<void> {\n await this.patch(this.route('approvals'), { workspaceId, id, status: 'rejected', reason })\n }\n\n async getGenerations(\n workspaceId: string,\n ): Promise<{ id: string; type: string; prompt: string }[]> {\n const res = await this.get(`${this.route('generations')}?workspaceId=${workspaceId}`)\n return this.requireArray<{ id: string; type: string; prompt: string }>(res, 'generations')\n }\n\n /** Generic GET for custom routes */\n async get(path: string): Promise<Record<string, unknown>> {\n return this.request('GET', path)\n }\n\n /** Generic POST for custom routes */\n async post(path: string, body: Record<string, unknown>): Promise<Record<string, unknown>> {\n return this.request('POST', path, body)\n }\n\n /** Generic PATCH for custom routes */\n async patch(path: string, body: Record<string, unknown>): Promise<Record<string, unknown>> {\n return this.request('PATCH', path, body)\n }\n}\n\n/**\n * Run a full e2e workflow test against a live product.\n *\n * The `workflow` callback receives a ProductClient and returns CheckResults.\n * This is the generic harness — each agent defines its own workflow steps.\n */\nexport async function runE2EWorkflow(\n client: ProductClient,\n name: string,\n workflow: (client: ProductClient) => Promise<CheckResult[]>,\n): Promise<TestResult> {\n const start = Date.now()\n const checks: CheckResult[] = []\n\n try {\n const results = await workflow(client)\n checks.push(...results)\n } catch (err) {\n checks.push({\n name: 'fatal_error',\n passed: false,\n expected: 'no crash',\n actual: err instanceof Error ? err.message : String(err),\n })\n }\n\n return {\n name,\n passed: checks.every((c) => c.passed),\n duration: Date.now() - start,\n detail: `${checks.filter((c) => c.passed).length}/${checks.length} checks passed`,\n checks,\n }\n}\n","import type { CompletionCriterion, DriverState } from './types'\n\n/**\n * ConvergenceTracker — tracks completion percentage over turns.\n *\n * Produces convergence curves showing how quickly the agent reaches\n * completion criteria.\n */\nexport class ConvergenceTracker {\n private criteria: CompletionCriterion[]\n private history: {\n turn: number\n completionPercent: number\n criteriaStatus: Record<string, boolean | number>\n }[] = []\n\n constructor(criteria: CompletionCriterion[]) {\n this.criteria = criteria\n }\n\n /** Evaluate criteria against current state, record result */\n record(\n turn: number,\n state: DriverState,\n ): {\n completionPercent: number\n complete: boolean\n criteriaStatus: Record<string, boolean | number>\n } {\n const criteriaStatus: Record<string, boolean | number> = {}\n let totalCredit = 0\n\n for (const criterion of this.criteria) {\n if (criterion.progress) {\n const credit = Math.min(1, Math.max(0, criterion.progress(state)))\n criteriaStatus[criterion.name] = credit\n totalCredit += credit\n } else {\n const passed = criterion.check(state)\n criteriaStatus[criterion.name] = passed\n totalCredit += passed ? 1 : 0\n }\n }\n\n const completionPercent =\n this.criteria.length > 0 ? (totalCredit / this.criteria.length) * 100 : 100\n\n this.history.push({ turn, completionPercent, criteriaStatus })\n\n return {\n completionPercent,\n complete: totalCredit >= this.criteria.length,\n criteriaStatus,\n }\n }\n\n /** Get convergence curve */\n getCurve(): number[] {\n return this.history.map((h) => h.completionPercent)\n }\n\n /** Get full history with per-criterion status */\n getHistory() {\n return [...this.history]\n }\n\n /** Find the turn where completion first reached 100% (or null) */\n getTurnToCompletion(): number | null {\n const entry = this.history.find((h) => h.completionPercent === 100)\n return entry?.turn ?? null\n }\n}\n","import type { ChatClient, ChatRequest } from './analyst/chat-client'\nimport type { ProductClient } from './client'\nimport { ConvergenceTracker } from './convergence'\nimport { CostLedger, type CostLedgerHandle } from './cost-ledger'\nimport { warnDeprecatedOnce } from './deprecation'\nimport { assertServedModel } from './integrity/served-model'\nimport {\n costReceiptFromLlm,\n costReceiptFromLlmError,\n maximumChargeForLlmRequest,\n} from './llm-client'\nimport { MetricsCollector } from './metrics'\nimport type { DriverResult, DriverState, PersonaConfig, PersonaRigor, TurnMetrics } from './types'\n\nexport interface AgentDriverConfig {\n client: ProductClient\n driverModel?: string\n /** System prompt context for the driver LLM to understand the product */\n productContext?: string\n /** Shared account for driver-model calls. */\n costLedger?: CostLedgerHandle\n}\n\n/**\n * Per-rigor stance the driver LLM adopts. Scales how hard the simulated\n * user interrogates the agent — see `PersonaConfig.rigor`.\n */\nconst RIGOR_STANCE: Record<PersonaRigor, string> = {\n cooperative:\n 'Your stance: a pragmatic early adopter. You accept reasonable answers and only push back on clear gaps or outright errors.',\n demanding:\n 'Your stance: an experienced professional with no time to waste. You do not accept vague, hedged, or generic answers — you expect specifics, and you say so plainly when you do not get them.',\n relentless:\n 'Your stance: a senior partner reviewing this work for a client who will litigate if it is wrong. You interrogate every claim. You accept nothing undefended. You find the single weakest point in every answer and attack it. Courteous, never satisfied.',\n}\n\n/**\n * AgentDriver — meta-agent that plays a persona against the real product.\n *\n * Uses a driver LLM (Claude/GPT-4o) to decide what to say each turn.\n * Not scripted — the driver gets the current product state and decides\n * the next realistic user message.\n *\n * @deprecated A one-product driver welded to `ProductClient` does not belong\n * in the generic substrate. Moves to the product repo in the next major\n * (tangle-network/agent-runtime#694). A driver is an `AgentProfile` on a\n * graph edge; use the agent-graph path once it lands, or vendor this class.\n */\nexport class AgentDriver {\n private chat: ChatClient\n private client: ProductClient\n private driverModel: string\n private productContext: string\n private costLedger: CostLedgerHandle\n\n constructor(chat: ChatClient, config: AgentDriverConfig) {\n warnDeprecatedOnce(\n 'AgentDriver',\n 'AgentDriver is deprecated and moves to the product repo in the next major (tangle-network/agent-runtime#694).',\n )\n this.chat = chat\n this.client = config.client\n this.driverModel = config.driverModel ?? 'claude-sonnet-4-6'\n this.productContext = config.productContext ?? ''\n this.costLedger = config.costLedger ?? new CostLedger()\n }\n\n /**\n * Run a persona through the product.\n *\n * Returns metrics on how many turns to completion, cost curve,\n * quality curve, and convergence curve.\n */\n async run(persona: PersonaConfig): Promise<DriverResult> {\n const costTags = { driverRunId: globalThis.crypto.randomUUID() }\n // Setup: create workspace + thread\n const email = `eval-driver-${Date.now()}@test.agent-eval.local`\n await this.client.signup(`Driver ${persona.role}`, email, 'eval-driver-pass')\n await this.client.login(email, 'eval-driver-pass')\n const workspaceId = await this.client.createWorkspace(`${persona.role} Eval`)\n const threadId = await this.client.createThread(workspaceId)\n\n const metrics = new MetricsCollector(this.client, workspaceId)\n const convergence = new ConvergenceTracker(persona.completionCriteria)\n const turnMetrics: TurnMetrics[] = []\n const conversationHistory: { role: string; content: string }[] = []\n\n let completed = false\n let turnsToCompletion: number | null = null\n let criteriaMetAtTurn: number | null = null\n\n for (let turn = 1; turn <= persona.maxTurns; turn++) {\n // Get current product state\n const state = await metrics.getState()\n\n // Ask driver LLM what to say\n const userMessage = await this.decideNextMessage(\n persona,\n state,\n conversationHistory,\n costTags,\n )\n\n if (userMessage === 'DONE') {\n completed = true\n turnsToCompletion = turn - 1\n console.log(` SIGNED OFF by simulated ${persona.role} after turn ${turn - 1}`)\n break\n }\n\n // Send to product\n const turnStart = Date.now()\n const response = await this.client.chat(workspaceId, threadId, userMessage)\n const latency = Date.now() - turnStart\n\n conversationHistory.push(\n { role: 'user', content: userMessage },\n { role: 'assistant', content: response.text },\n )\n\n // Wait for post-processor\n await new Promise((r) => setTimeout(r, 2000))\n\n // Handle pending approvals\n await this.handleApprovals(persona, workspaceId, state)\n\n // Check convergence\n const postState = await metrics.getState()\n const conv = convergence.record(turn, postState)\n\n // Collect metrics\n const codeBlockCount = (response.text.match(/```\\w+\\n/g) || []).length\n const m = await metrics.collect(\n turn,\n latency,\n response.text.length,\n codeBlockCount,\n response.blocks.length,\n Object.values(conv.criteriaStatus).filter(Boolean).length,\n persona.completionCriteria.length,\n )\n turnMetrics.push(m)\n\n // Print turn status\n const criteriaStr = Object.entries(conv.criteriaStatus)\n .map(([k, v]) => `${k}:${v ? '+' : '-'}`)\n .join(' ')\n console.log(\n ` [turn ${turn}] ${conv.completionPercent.toFixed(0)}% — ${criteriaStr} (${(latency / 1000).toFixed(1)}s)`,\n )\n\n // Nominal criteria met is recorded, not a stop condition. The\n // simulated professional keeps pressure-testing until genuinely\n // satisfied — a criteria-met-but-sloppy answer must still be defended.\n if (conv.complete && criteriaMetAtTurn === null) {\n criteriaMetAtTurn = turn\n console.log(` criteria met at turn ${turn} — driver continues pressure-testing`)\n }\n }\n\n const finalState = await metrics.getState()\n\n return {\n personaId: persona.id,\n completed,\n turnsToCompletion,\n criteriaMetAtTurn,\n totalTurns: turnMetrics.length,\n metrics: turnMetrics,\n finalState,\n convergenceCurve: convergence.getCurve(),\n totalCostUsd: this.costLedger.summary({ tags: costTags }).totalCostUsd,\n finalQualityScore: null,\n }\n }\n\n /** Use the driver LLM to decide what the \"user\" says next */\n private async decideNextMessage(\n persona: PersonaConfig,\n state: DriverState,\n history: { role: string; content: string }[],\n costTags: Record<string, string>,\n ): Promise<string> {\n return decideNextUserTurn(this.chat, {\n persona,\n state,\n history,\n productContext: this.productContext,\n model: this.driverModel,\n costLedger: this.costLedger,\n costTags,\n })\n }\n\n /** Handle pending approvals based on persona feedback patterns */\n private async handleApprovals(\n persona: PersonaConfig,\n workspaceId: string,\n _state: DriverState,\n ): Promise<void> {\n const approvals = await this.client.getApprovals(workspaceId)\n const pending = approvals.filter((a) => a.status === 'pending')\n\n for (const action of pending) {\n // Check if any feedback pattern triggers a rejection\n const rejection = persona.feedbackPatterns?.find((fp) => {\n const title = action.title.toLowerCase()\n return title.includes(fp.trigger.toLowerCase())\n })\n\n if (rejection) {\n await this.client.rejectAction(workspaceId, action.id, rejection.response)\n console.log(` rejected: ${action.title} — ${rejection.response.slice(0, 60)}`)\n } else {\n await this.client.approveAction(workspaceId, action.id)\n console.log(` approved: ${action.title}`)\n }\n }\n }\n}\n\n/** Describe which nominal completion criteria are met, for the driver prompt. */\nfunction describeCompletion(persona: PersonaConfig, state: DriverState): string {\n const results = persona.completionCriteria.map((c) => {\n const met = c.check(state)\n return `${c.name}: ${met ? 'MET' : 'NOT MET'}`\n })\n const metCount = results.filter((r) => r.includes('MET') && !r.includes('NOT')).length\n return `${metCount}/${persona.completionCriteria.length} — ${results.join(', ')}`\n}\n\n/**\n * Build the driver LLM's system prompt. The simulated user is an\n * adversarial senior professional: it judges the agent's last response by a\n * professional standard, refuses vague answers, challenges undefended\n * claims, probes the persona's pressure points without revealing them, and\n * signs off (DONE) only when a real practitioner would act on the work\n * unmodified. Pure function of persona, product state, and product context\n * — exported so harness authors can inspect and regression-test it.\n *\n * @deprecated A role expressed as a code function can never be optimized.\n * Removal is a major; until then, treat this output as SEED data for a\n * registry-backed directive prompt (tangle-network/agent-runtime#694).\n */\nexport function buildDriverSystemPrompt(\n persona: PersonaConfig,\n state: DriverState,\n productContext = '',\n): string {\n warnDeprecatedOnce(\n 'buildDriverSystemPrompt',\n 'buildDriverSystemPrompt is deprecated: roles belong in registry-backed prompt data, not code (tangle-network/agent-runtime#694).',\n )\n const rigor: PersonaRigor = persona.rigor ?? 'demanding'\n const expertise = persona.expertise ? ` You are ${persona.expertise}.` : ''\n\n const pressure =\n persona.pressurePoints && persona.pressurePoints.length > 0\n ? `\\nA competent ${persona.role} here MUST get the agent to address each of:\\n${persona.pressurePoints\n .map((p) => ` - ${p}`)\n .join(\n '\\n',\n )}\\nDo NOT hand these to the agent. Probe whether it surfaces them itself. If it misses one, press on exactly that gap until it delivers or demonstrably fails.\\n`\n : ''\n\n const curveballs =\n persona.curveballs && persona.curveballs.length > 0\n ? `\\nOnce the agent is coasting on easy answers, introduce ONE of these as a genuine new development — never as a quiz:\\n${persona.curveballs\n .map((c) => ` - ${c}`)\n .join('\\n')}\\n`\n : ''\n\n return `You are role-playing a real ${persona.role} putting an AI agent through its paces.${expertise}\nYour objective: ${persona.goal}\nYou are deciding whether this agent's work is good enough to stake your professional reputation on. Assume it is not — until it proves otherwise.\n\n${RIGOR_STANCE[rigor]}\n${productContext ? `Product context:\\n${productContext}\\n` : ''}Current workspace state:\n- Tasks: ${state.tasks} | Events: ${state.events}\n- Proposals: pending=${state.proposals.pending}, approved=${state.proposals.approved}, rejected=${state.proposals.rejected}\n- Vault files (${state.vaultFiles.length}): ${state.vaultFiles.slice(0, 10).join(', ')}${state.vaultFiles.length > 10 ? ' …' : ''}\n- Nominal task criteria: ${describeCompletion(persona, state)}\n${pressure}${curveballs}\nHow to choose your next message:\n1. Silently judge the agent's last response the way a ${persona.role} would. Is every claim defended with a specific authority, figure, or mechanism? Or is it vague, hedged, or generic?\n2. If it is vague or hand-waved — do NOT move on. Name the gap and demand the specific authority / figure / mechanism. \"It depends\" is not an answer; force the decision.\n3. If it makes a claim you can challenge — challenge it. Make the agent defend or correct it.\n4. If it missed something a ${persona.role} would catch — press on exactly that, without naming it for the agent.\n5. If it is genuinely solid — escalate: go a layer deeper, or introduce a curveball.\n6. First message — state your situation as you really would: realistic, specific, with the messy detail, but do not coach the agent.\n\nSign-off: respond with exactly \"DONE\" only when a ${persona.role} would act on this work without redoing it. Nominal task completion is NOT sign-off — sloppy-but-complete still fails. If the agent never gets there, keep pushing; never sign off on weak work.\n\nOutput ONLY your next message to the agent — in character, first person, no meta-commentary, no stage directions.`\n}\n\nexport interface DecideNextUserTurnOpts {\n persona: PersonaConfig\n state: DriverState\n /** Conversation so far — alternating user/assistant messages, oldest first. */\n history: { role: string; content: string }[]\n /** Optional product context woven into the driver prompt. */\n productContext?: string\n /** Driver LLM model. Defaults to claude-sonnet-4-6. */\n model?: string\n /** Shared account for the paid driver-model call. */\n costLedger?: CostLedgerHandle\n /** Attribution tags merged into the paid-call receipt. */\n costTags?: Record<string, string>\n}\n\n/**\n * Decide the simulated user's next turn — the reactive, adversarial\n * turn-generation core of `AgentDriver`, exposed standalone so an in-process\n * eval harness can drive multi-shot conversations without the `ProductClient`\n * workspace machinery. Returns the next user message, or the literal \"DONE\"\n * when the simulated professional would sign off.\n *\n * @deprecated The persona-driver loop becomes a 2-node agent graph (driver\n * profile + delegates edge); removal is a major\n * (tangle-network/agent-runtime#694).\n */\nexport async function decideNextUserTurn(\n chat: ChatClient,\n opts: DecideNextUserTurnOpts,\n): Promise<string> {\n warnDeprecatedOnce(\n 'decideNextUserTurn',\n 'decideNextUserTurn is deprecated: the persona-driver loop becomes a 2-node agent graph (tangle-network/agent-runtime#694).',\n )\n const { persona, state, history, productContext = '', model = 'claude-sonnet-4-6' } = opts\n\n const lastResponse =\n history.length > 0\n ? history[history.length - 1]!.content.slice(0, 2000)\n : '(no conversation yet — this is the first message)'\n\n const recentHistory = history\n .slice(-6)\n .map((h) => `${h.role}: ${h.content.slice(0, 500)}`)\n .join('\\n\\n')\n\n const request = {\n model,\n messages: [\n { role: 'system', content: buildDriverSystemPrompt(persona, state, productContext) },\n {\n role: 'user',\n content: recentHistory\n ? `Recent conversation:\\n${recentHistory}\\n\\nThe agent's latest response:\\n${lastResponse}`\n : 'No conversation yet. Send your opening message — in character, phrased as this person actually would.',\n },\n ],\n temperature: 0.5,\n maxTokens: 700,\n } satisfies ChatRequest\n const paid = await (opts.costLedger ?? new CostLedger()).runPaidCall({\n channel: 'driver',\n phase: 'driver-turn',\n actor: 'decideNextUserTurn',\n model,\n tags: opts.costTags,\n maximumCharge:\n chat.maximumAttempts === undefined\n ? undefined\n : maximumChargeForLlmRequest(request, { maximumAttempts: chat.maximumAttempts }),\n execute: (signal, callId) => chat.chat(request, { signal, idempotencyKey: callId }),\n receipt: costReceiptFromLlm,\n receiptFromError: costReceiptFromLlmError,\n })\n if (!paid.succeeded) throw paid.error\n // Hold the transport to its own word: a persona turn written by a different\n // model is not this driver model's behaviour. A transport that echoes no id\n // cannot be made to prove identity here — callers needing that proof enable\n // it at the client (`LlmClientOptions.assertServedModel`).\n assertServedModel(model, paid.value.servedModel, {\n allowUnreported: true,\n context: 'decideNextUserTurn',\n })\n return paid.value.content.trim()\n}\n","import type { AnalystFinding, AnalystRunResult } from './analyst/types'\nimport type { ControlEvalResult, ControlRunResult, ControlStep } from './control-runtime'\nimport type { DatasetScenario, DatasetSplit } from './dataset'\nimport {\n type AnalystReviewDecision,\n analystFindingDigest,\n analystRunDigest,\n assertUniqueFindingIds,\n completedAnalystReviewQuality,\n readAnalystReview,\n snapshotAnalystRun,\n validateAnalystReviewDecisions,\n} from './feedback-trajectory-review'\n\nexport type {\n AnalystFindingDigest,\n AnalystMissedIssue,\n AnalystReviewCounts,\n AnalystReviewDecision,\n AnalystReviewQuality,\n AnalystReviewSource,\n AnalystRunDigest,\n} from './feedback-trajectory-review'\nexport { analystFindingDigest, analystRunDigest } from './feedback-trajectory-review'\n\nexport type FeedbackArtifactType =\n | 'text'\n | 'code'\n | 'plan'\n | 'research'\n | 'action'\n | 'ui'\n | 'decision'\n | 'data'\n | 'other'\n\nexport type FeedbackLabelSource = 'user' | 'judge' | 'environment' | 'metric' | 'policy' | 'system'\n\nexport type FeedbackLabelKind =\n | 'approve'\n | 'reject'\n | 'select'\n | 'edit'\n | 'rank'\n | 'rate'\n | 'comment'\n | 'metric_outcome'\n | 'policy_block'\n | 'revision_request'\n\nexport type FeedbackSeverity = 'info' | 'warning' | 'error' | 'critical'\n\nexport interface FeedbackTask {\n intent: string\n context?: unknown\n}\n\nexport interface ProposedSideEffect {\n type: string\n risk?: 'low' | 'medium' | 'high'\n costUsd?: number\n externalSideEffect?: boolean\n requiresApproval?: boolean\n metadata?: Record<string, unknown>\n}\n\nexport interface FeedbackLabel {\n id?: string\n source: FeedbackLabelSource\n kind: FeedbackLabelKind\n value: unknown\n reason?: string\n severity?: FeedbackSeverity\n createdAt: string\n metadata?: Record<string, unknown>\n}\n\nexport interface FeedbackAttempt {\n id: string\n stepIndex: number\n artifactType: FeedbackArtifactType\n artifact: unknown\n options?: unknown[]\n proposedAction?: ProposedSideEffect\n evals?: ControlEvalResult[]\n feedback?: FeedbackLabel[]\n createdAt: string\n metadata?: Record<string, unknown>\n}\n\nexport interface FeedbackOutcome {\n success?: boolean\n score?: number\n metrics?: Record<string, number>\n costUsd?: number\n detail?: string\n observedAt?: string\n metadata?: Record<string, unknown>\n}\n\nexport interface FeedbackTrajectory {\n id: string\n projectId?: string\n scenarioId?: string\n task: FeedbackTask\n attempts: FeedbackAttempt[]\n labels: FeedbackLabel[]\n outcome?: FeedbackOutcome\n split?: DatasetSplit\n tags?: Record<string, string>\n createdAt: string\n updatedAt?: string\n metadata?: Record<string, unknown>\n}\n\nexport interface FeedbackTrajectoryStore {\n save(trajectory: FeedbackTrajectory): Promise<void>\n get(id: string): Promise<FeedbackTrajectory | null>\n list(filter?: FeedbackTrajectoryFilter): Promise<FeedbackTrajectory[]>\n appendAttempt(id: string, attempt: FeedbackAttempt): Promise<FeedbackTrajectory>\n appendLabel(id: string, label: FeedbackLabel, attemptId?: string): Promise<FeedbackTrajectory>\n}\n\nexport interface FeedbackTrajectoryFilter {\n projectId?: string\n scenarioId?: string\n split?: DatasetSplit\n tag?: [string, string]\n}\n\nexport interface FeedbackSplitPolicy {\n trainPct?: number\n devPct?: number\n testPct?: number\n holdoutPct?: number\n}\n\nexport interface PreferenceMemoryEntry {\n instruction: string\n rationale: string\n weight: number\n sourceTrajectoryId: string\n sourceLabelId?: string\n category?: string\n}\n\nexport interface FeedbackOptimizerRow {\n scenarioId: string\n trajectoryId: string\n labelKinds: FeedbackLabelKind[]\n score?: number\n metadata?: Record<string, unknown>\n}\n\nexport interface FeedbackReplayResult {\n trajectoryId: string\n pass: boolean\n score?: number\n labels: FeedbackLabel[]\n outcome?: FeedbackOutcome\n metadata?: Record<string, unknown>\n}\n\nexport interface FeedbackReplayAdapter {\n replay(\n trajectory: FeedbackTrajectory,\n ):\n | Promise<Omit<FeedbackReplayResult, 'trajectoryId'>>\n | Omit<FeedbackReplayResult, 'trajectoryId'>\n}\n\nexport interface AnalystFeedbackTrajectoryOptions {\n task: FeedbackTask\n labels?: readonly FeedbackLabel[]\n reviewRequests?: readonly AnalystReviewRequest[]\n reviewDecisions?: readonly AnalystReviewDecision[]\n outcome?: FeedbackOutcome\n id?: string\n projectId?: string\n scenarioId?: string\n split?: DatasetSplit\n tags?: Record<string, string>\n createdAt?: string\n trace?: {\n source?: string\n traceIds?: readonly string[]\n artifactUri?: string\n }\n metadata?: Record<string, unknown>\n}\n\nexport interface AnalystReviewRequest {\n id: string\n runId: string\n runDigest: `sha256:${string}`\n findingId: string\n findingDigest: `sha256:${string}`\n analystId: string\n area: string\n claim: string\n evidence: AnalystFinding['evidence_refs']\n recommendedAction?: string\n validationPlan?: string\n severity: FeedbackSeverity\n confidence: number\n createdAt: string\n}\n\nconst DEFAULT_SPLIT_POLICY: Required<FeedbackSplitPolicy> = {\n trainPct: 70,\n devPct: 15,\n testPct: 10,\n holdoutPct: 5,\n}\n\nexport class InMemoryFeedbackTrajectoryStore implements FeedbackTrajectoryStore {\n private readonly trajectories = new Map<string, FeedbackTrajectory>()\n\n async save(trajectory: FeedbackTrajectory): Promise<void> {\n this.trajectories.set(trajectory.id, cloneTrajectory(trajectory))\n }\n\n async get(id: string): Promise<FeedbackTrajectory | null> {\n const trajectory = this.trajectories.get(id)\n return trajectory ? cloneTrajectory(trajectory) : null\n }\n\n async list(filter: FeedbackTrajectoryFilter = {}): Promise<FeedbackTrajectory[]> {\n return [...this.trajectories.values()]\n .filter((trajectory) => matchesFilter(trajectory, filter))\n .map(cloneTrajectory)\n }\n\n async appendAttempt(id: string, attempt: FeedbackAttempt): Promise<FeedbackTrajectory> {\n const trajectory = this.trajectories.get(id)\n if (!trajectory)\n throw new Error(`FeedbackTrajectoryStore.appendAttempt: unknown trajectory \"${id}\"`)\n const next = cloneTrajectory({\n ...trajectory,\n attempts: [...trajectory.attempts, attempt],\n updatedAt: attempt.createdAt,\n })\n this.trajectories.set(id, next)\n return cloneTrajectory(next)\n }\n\n async appendLabel(\n id: string,\n label: FeedbackLabel,\n attemptId?: string,\n ): Promise<FeedbackTrajectory> {\n const trajectory = this.trajectories.get(id)\n if (!trajectory)\n throw new Error(`FeedbackTrajectoryStore.appendLabel: unknown trajectory \"${id}\"`)\n const attempts = attemptId\n ? trajectory.attempts.map((attempt) =>\n attempt.id === attemptId\n ? { ...attempt, feedback: [...(attempt.feedback ?? []), label] }\n : attempt,\n )\n : trajectory.attempts\n const next = cloneTrajectory({\n ...trajectory,\n attempts,\n labels: attemptId ? trajectory.labels : [...trajectory.labels, label],\n updatedAt: label.createdAt,\n })\n this.trajectories.set(id, next)\n return cloneTrajectory(next)\n }\n}\n\nexport class FileSystemFeedbackTrajectoryStore implements FeedbackTrajectoryStore {\n private readonly dir: string\n private readonly memory = new InMemoryFeedbackTrajectoryStore()\n private loaded = false\n\n constructor(options: { dir: string }) {\n this.dir = options.dir\n }\n\n async save(trajectory: FeedbackTrajectory): Promise<void> {\n await this.load()\n await this.memory.save(trajectory)\n await this.append({ op: 'save', trajectory })\n }\n\n async get(id: string): Promise<FeedbackTrajectory | null> {\n await this.load()\n return this.memory.get(id)\n }\n\n async list(filter: FeedbackTrajectoryFilter = {}): Promise<FeedbackTrajectory[]> {\n await this.load()\n return this.memory.list(filter)\n }\n\n async appendAttempt(id: string, attempt: FeedbackAttempt): Promise<FeedbackTrajectory> {\n await this.load()\n const next = await this.memory.appendAttempt(id, attempt)\n await this.append({ op: 'appendAttempt', id, attempt })\n return next\n }\n\n async appendLabel(\n id: string,\n label: FeedbackLabel,\n attemptId?: string,\n ): Promise<FeedbackTrajectory> {\n await this.load()\n const next = await this.memory.appendLabel(id, label, attemptId)\n await this.append({ op: 'appendLabel', id, label, attemptId })\n return next\n }\n\n private async append(record: unknown): Promise<void> {\n const { appendFile, mkdir } = await import('node:fs/promises')\n const { join } = await import('node:path')\n await mkdir(this.dir, { recursive: true })\n await appendFile(\n join(this.dir, 'feedback-trajectories.ndjson'),\n `${JSON.stringify(record)}\\n`,\n 'utf8',\n )\n }\n\n private async load(): Promise<void> {\n if (this.loaded) return\n const { readFile } = await import('node:fs/promises')\n const { join } = await import('node:path')\n const file = join(this.dir, 'feedback-trajectories.ndjson')\n try {\n const raw = await readFile(file, 'utf8')\n for (const line of raw.split('\\n')) {\n if (!line.trim()) continue\n try {\n const record = JSON.parse(line) as\n | { op: 'save'; trajectory: FeedbackTrajectory }\n | { op: 'appendAttempt'; id: string; attempt: FeedbackAttempt }\n | { op: 'appendLabel'; id: string; label: FeedbackLabel; attemptId?: string }\n if (record.op === 'save') await this.memory.save(record.trajectory)\n if (record.op === 'appendAttempt')\n await this.memory.appendAttempt(record.id, record.attempt)\n if (record.op === 'appendLabel')\n await this.memory.appendLabel(record.id, record.label, record.attemptId)\n } catch {\n /* corrupt records are skipped so one bad line does not discard the corpus */\n }\n }\n } catch {\n /* first run */\n }\n this.loaded = true\n }\n}\n\nexport function createFeedbackTrajectory(input: {\n id?: string\n projectId?: string\n scenarioId?: string\n task: FeedbackTask\n attempts?: FeedbackAttempt[]\n labels?: FeedbackLabel[]\n outcome?: FeedbackOutcome\n split?: DatasetSplit\n tags?: Record<string, string>\n createdAt?: string\n metadata?: Record<string, unknown>\n}): FeedbackTrajectory {\n const createdAt = input.createdAt ?? new Date().toISOString()\n const id =\n input.id ??\n `ft_${stableHash(`${input.projectId ?? ''}|${input.scenarioId ?? ''}|${input.task.intent}|${createdAt}`).toString(16)}`\n return {\n id,\n projectId: input.projectId,\n scenarioId: input.scenarioId,\n task: input.task,\n attempts: input.attempts ?? [],\n labels: input.labels ?? [],\n outcome: input.outcome,\n split: input.split,\n tags: input.tags,\n createdAt,\n metadata: input.metadata,\n }\n}\n\n/** Preserve a trace-analysis run for review, whether or not review is complete. */\nexport function analystRunToFeedbackTrajectory(\n run: AnalystRunResult,\n options: AnalystFeedbackTrajectoryOptions,\n): FeedbackTrajectory {\n const archivedRun = snapshotAnalystRun(run, `analyst run \"${run.run_id}\"`)\n const runDigest = analystRunDigest(archivedRun)\n const findings = archivedRun.findings\n const findingIds = findings.map((finding) => finding.finding_id)\n assertUniqueFindingIds(findingIds)\n const analystIds = [\n ...new Set([\n ...findings.map((finding) => finding.analyst_id),\n ...archivedRun.per_analyst.map((summary) => summary.analyst_id),\n ]),\n ]\n const reviewDecisions = validateAnalystReviewDecisions({\n runId: archivedRun.run_id,\n runDigest,\n findings,\n analystIds,\n decisions: options.reviewDecisions ?? [],\n })\n const reviewRequests =\n options.reviewRequests === undefined\n ? undefined\n : validateAnalystReviewRequests(archivedRun, options.reviewRequests)\n const createdAt = options.createdAt ?? archivedRun.started_at\n const knownCostUsd = archivedRun.total_cost_usd\n const capturedCost =\n archivedRun.total_cost_provenance?.kind === 'uncaptured'\n ? undefined\n : archivedRun.total_cost_usd\n return createFeedbackTrajectory({\n id: options.id,\n projectId: options.projectId,\n scenarioId: options.scenarioId,\n task: options.task,\n attempts: [\n {\n id: `analysis:${archivedRun.run_id}`,\n stepIndex: 0,\n artifactType: 'research',\n artifact: {\n type: 'analyst-run',\n analystRunId: archivedRun.run_id,\n runDigest,\n correlationId: archivedRun.correlation_id,\n analystIds,\n findings,\n ...('execution_plan' in archivedRun ? { executionPlan: archivedRun.execution_plan } : {}),\n ...('completion' in archivedRun ? { completion: archivedRun.completion } : {}),\n },\n createdAt,\n metadata: {\n perAnalyst: archivedRun.per_analyst,\n trace: options.trace,\n reviewRequests,\n },\n },\n ],\n labels: [...(options.labels ?? [])],\n outcome: options.outcome\n ? {\n ...options.outcome,\n costUsd: options.outcome.costUsd ?? capturedCost,\n }\n : capturedCost === undefined\n ? undefined\n : { costUsd: capturedCost, observedAt: archivedRun.ended_at },\n split: options.split,\n tags: options.tags,\n createdAt,\n metadata: {\n ...options.metadata,\n analysis: {\n kind: 'analyst-run',\n runId: archivedRun.run_id,\n runDigest,\n startedAt: archivedRun.started_at,\n endedAt: archivedRun.ended_at,\n reviewDecisions,\n costProvenance: archivedRun.total_cost_provenance,\n knownCostUsd,\n },\n },\n })\n}\n\n/** Convert one immutable analyst run into revision requests for an independent reviewer. */\nexport function analystRunToReviewRequests(\n run: AnalystRunResult,\n options: { createdAt?: string } = {},\n): AnalystReviewRequest[] {\n const archivedRun = snapshotAnalystRun(run, `analyst run \"${run.run_id}\"`)\n const runDigest = analystRunDigest(archivedRun)\n const createdAt = options.createdAt ?? new Date().toISOString()\n return archivedRun.findings.map((finding) => ({\n id: analystReviewRequestId(runDigest, finding.finding_id),\n runId: archivedRun.run_id,\n runDigest,\n findingId: finding.finding_id,\n findingDigest: analystFindingDigest(finding),\n analystId: finding.analyst_id,\n area: finding.area,\n claim: finding.claim,\n evidence: finding.evidence_refs,\n recommendedAction: finding.recommended_action,\n validationPlan: finding.validation_plan,\n severity: feedbackSeverityFromFinding(finding),\n confidence: finding.confidence,\n createdAt,\n }))\n}\n\nfunction validateAnalystReviewRequests(\n run: AnalystRunResult,\n requests: readonly AnalystReviewRequest[],\n): AnalystReviewRequest[] {\n const runDigest = analystRunDigest(run)\n const findingsById = new Map(run.findings.map((finding) => [finding.finding_id, finding]))\n const seenFindingIds = new Set<string>()\n return requests.map((request, index) => {\n if (request.runId !== run.run_id) {\n throw new TypeError(`analyst review request ${index} run id mismatch`)\n }\n if (request.runDigest !== runDigest) {\n throw new TypeError(`analyst review request ${index} run digest mismatch`)\n }\n const finding = findingsById.get(request.findingId)\n if (!finding) {\n throw new TypeError(\n `analyst review request ${index} references unknown finding id \"${request.findingId}\"`,\n )\n }\n if (seenFindingIds.has(request.findingId)) {\n throw new TypeError(`duplicate analyst review request for finding id \"${request.findingId}\"`)\n }\n seenFindingIds.add(request.findingId)\n if (request.findingDigest !== analystFindingDigest(finding)) {\n throw new TypeError(`analyst review request ${index} finding digest mismatch`)\n }\n if (request.id !== analystReviewRequestId(runDigest, request.findingId)) {\n throw new TypeError(`analyst review request ${index} id mismatch`)\n }\n return request\n })\n}\n\nfunction analystReviewRequestId(runDigest: `sha256:${string}`, findingId: string): string {\n return `analyst:${runDigest}:${findingId}`\n}\n\nexport function assignFeedbackSplit(\n trajectory: Pick<FeedbackTrajectory, 'id' | 'projectId' | 'scenarioId' | 'task'>,\n policy: FeedbackSplitPolicy = {},\n): DatasetSplit {\n const split = { ...DEFAULT_SPLIT_POLICY, ...policy }\n const total = split.trainPct + split.devPct + split.testPct + split.holdoutPct\n if (total <= 0) throw new Error('assignFeedbackSplit: split percentages must sum above zero')\n const bucket =\n stableHash(\n `${trajectory.projectId ?? ''}|${trajectory.scenarioId ?? ''}|${trajectory.id}|${trajectory.task.intent}`,\n ) % total\n if (bucket < split.trainPct) return 'train'\n if (bucket < split.trainPct + split.devPct) return 'dev'\n if (bucket < split.trainPct + split.devPct + split.testPct) return 'test'\n return 'holdout'\n}\n\nexport function withAssignedFeedbackSplit(\n trajectory: FeedbackTrajectory,\n policy?: FeedbackSplitPolicy,\n): FeedbackTrajectory {\n return {\n ...trajectory,\n split: trajectory.split ?? assignFeedbackSplit(trajectory, policy),\n }\n}\n\nexport function feedbackTrajectoryToDatasetScenario(\n trajectory: FeedbackTrajectory,\n): DatasetScenario {\n const withSplit = withAssignedFeedbackSplit(trajectory)\n return {\n id: withSplit.scenarioId ?? withSplit.id,\n split: withSplit.split,\n payload: withSplit,\n tags: {\n ...(withSplit.projectId ? { projectId: withSplit.projectId } : {}),\n ...(withSplit.tags ?? {}),\n source: 'feedback-trajectory',\n },\n }\n}\n\nexport function feedbackTrajectoriesToDatasetScenarios(\n trajectories: FeedbackTrajectory[],\n): DatasetScenario[] {\n return trajectories.map(feedbackTrajectoryToDatasetScenario)\n}\n\nexport function feedbackTrajectoryToOptimizerRow(\n trajectory: FeedbackTrajectory,\n): FeedbackOptimizerRow {\n const labels = allLabels(trajectory)\n const analystReview = readAnalystReview(trajectory)\n const analystQuality = analystReview ? completedAnalystReviewQuality(analystReview) : undefined\n const reviewLabelKinds = analystReview\n ? analystReview.reviewDecisions.map((decision): FeedbackLabelKind => {\n if (decision.verdict === 'rejected') return 'reject'\n if (decision.verdict === 'completeness_assessed' && decision.missedIssues.length > 0) {\n return 'revision_request'\n }\n return 'approve'\n })\n : []\n return {\n scenarioId: trajectory.scenarioId ?? trajectory.id,\n trajectoryId: trajectory.id,\n labelKinds: [...new Set([...labels.map((label) => label.kind), ...reviewLabelKinds])],\n score: analystQuality?.f1 ?? trajectory.outcome?.score ?? scoreFromLabels(labels),\n metadata: {\n projectId: trajectory.projectId,\n split: trajectory.split,\n intent: trajectory.task.intent,\n attempts: trajectory.attempts.length,\n outcome: trajectory.outcome,\n labels,\n ...(analystReview\n ? {\n analystReview: {\n findingIds: analystReview.findingIds,\n findingDigests: analystReview.findings.map((finding) => ({\n findingId: finding.finding_id,\n findingDigest: analystFindingDigest(finding),\n })),\n decisions: analystReview.reviewDecisions,\n precision: analystQuality?.precision,\n recall: analystQuality?.recall,\n f1: analystQuality?.f1,\n counts: analystQuality?.counts,\n },\n }\n : {}),\n },\n }\n}\n\nexport function feedbackTrajectoriesToOptimizerRows(\n trajectories: FeedbackTrajectory[],\n): FeedbackOptimizerRow[] {\n return trajectories.map(feedbackTrajectoryToOptimizerRow)\n}\n\nexport async function replayFeedbackTrajectory(\n trajectory: FeedbackTrajectory,\n adapter: FeedbackReplayAdapter,\n): Promise<FeedbackReplayResult> {\n try {\n const result = await adapter.replay(trajectory)\n return {\n trajectoryId: trajectory.id,\n ...result,\n }\n } catch (err) {\n const createdAt = new Date().toISOString()\n const message = err instanceof Error ? err.message : String(err)\n return {\n trajectoryId: trajectory.id,\n pass: false,\n labels: [\n {\n source: 'system',\n kind: 'reject',\n value: false,\n reason: message,\n severity: 'error',\n createdAt,\n },\n ],\n outcome: {\n success: false,\n score: 0,\n detail: message,\n observedAt: createdAt,\n },\n metadata: { replayError: true },\n }\n }\n}\n\nexport async function replayFeedbackTrajectories(\n trajectories: FeedbackTrajectory[],\n adapter: FeedbackReplayAdapter,\n): Promise<FeedbackReplayResult[]> {\n const results: FeedbackReplayResult[] = []\n for (const trajectory of trajectories) {\n results.push(await replayFeedbackTrajectory(trajectory, adapter))\n }\n return results\n}\n\nexport function summarizePreferenceMemory(\n trajectories: FeedbackTrajectory[],\n options: { maxEntries?: number } = {},\n): PreferenceMemoryEntry[] {\n const maxEntries = options.maxEntries ?? 20\n const entries: PreferenceMemoryEntry[] = []\n for (const trajectory of trajectories) {\n for (const label of allLabels(trajectory)) {\n const instruction = instructionFromLabel(trajectory, label)\n if (!instruction) continue\n entries.push({\n instruction,\n rationale: label.reason ?? `${label.kind} label from ${label.source}`,\n weight: weightForLabel(label),\n sourceTrajectoryId: trajectory.id,\n sourceLabelId: label.id,\n category: label.kind,\n })\n }\n }\n\n const byInstruction = new Map<string, PreferenceMemoryEntry>()\n for (const entry of entries) {\n const key = entry.instruction.toLowerCase().replace(/\\s+/g, ' ').trim()\n const existing = byInstruction.get(key)\n if (!existing || entry.weight > existing.weight) byInstruction.set(key, entry)\n }\n return [...byInstruction.values()].sort((a, b) => b.weight - a.weight).slice(0, maxEntries)\n}\n\nexport function renderPreferenceMemoryMarkdown(entries: PreferenceMemoryEntry[]): string {\n const lines = ['# Preference Memory', '']\n for (const entry of entries) {\n lines.push(`- ${entry.instruction}`)\n lines.push(` Rationale: ${entry.rationale}`)\n lines.push(` Source: ${entry.sourceTrajectoryId}`)\n lines.push('')\n }\n return `${lines.join('\\n').trim()}\\n`\n}\n\nexport function serializeFeedbackTrajectoriesJsonl(trajectories: FeedbackTrajectory[]): string {\n return `${trajectories\n .slice()\n .sort((a, b) => a.id.localeCompare(b.id))\n .map((trajectory) => JSON.stringify(canonicalize(trajectory)))\n .join('\\n')}\\n`\n}\n\nexport function parseFeedbackTrajectoriesJsonl(jsonl: string): FeedbackTrajectory[] {\n const trajectories: FeedbackTrajectory[] = []\n for (const line of jsonl.split('\\n')) {\n if (!line.trim()) continue\n trajectories.push(JSON.parse(line) as FeedbackTrajectory)\n }\n return trajectories\n}\n\nexport function controlRunToFeedbackTrajectory<TState, TAction, TActionResult>(\n run: ControlRunResult<TState, TAction, TActionResult>,\n options: {\n projectId?: string\n scenarioId?: string\n artifactType?: FeedbackArtifactType\n artifactFromStep?: (step: ControlStep<TState, TAction, TActionResult>) => unknown\n proposedActionFromStep?: (\n step: ControlStep<TState, TAction, TActionResult>,\n ) => ProposedSideEffect | undefined\n createdAt?: string\n } = {},\n): FeedbackTrajectory {\n const createdAt = options.createdAt ?? new Date().toISOString()\n const trajectoryId =\n run.runId ?? `ft_control_${stableHash(`${run.intent}|${createdAt}`).toString(16)}`\n return createFeedbackTrajectory({\n id: trajectoryId,\n projectId: options.projectId,\n scenarioId: options.scenarioId,\n task: { intent: run.intent },\n createdAt,\n attempts: run.steps.map((step) => ({\n id: `${trajectoryId}_step_${step.index}`,\n stepIndex: step.index,\n artifactType: options.artifactType ?? 'action',\n artifact: options.artifactFromStep?.(step) ?? step.actionOutcome?.result ?? step.decision,\n proposedAction: options.proposedActionFromStep?.(step),\n evals: step.evalsAfter,\n createdAt: step.startedAt,\n metadata: {\n decision: step.decision,\n actionOutcome: step.actionOutcome,\n },\n })),\n labels: [\n {\n source: 'system',\n kind: run.pass ? 'approve' : 'reject',\n value: run.pass,\n reason: run.reason,\n severity: run.pass ? 'info' : 'error',\n createdAt,\n },\n ],\n outcome: {\n success: run.pass,\n score: run.score,\n costUsd: run.spentCostUsd,\n detail: run.reason,\n observedAt: createdAt,\n metadata: {\n stoppedBy: run.stoppedBy,\n failureClass: run.failureClass,\n },\n },\n })\n}\n\nfunction allLabels(trajectory: FeedbackTrajectory): FeedbackLabel[] {\n const labels = [\n ...trajectory.labels,\n ...trajectory.attempts.flatMap((attempt) => attempt.feedback ?? []),\n ]\n const seen = new Set<string>()\n return labels.filter((label) => {\n const key =\n label.id ?? `${label.source}|${label.kind}|${label.createdAt}|${JSON.stringify(label.value)}`\n if (seen.has(key)) return false\n seen.add(key)\n return true\n })\n}\n\nfunction feedbackSeverityFromFinding(finding: AnalystFinding): FeedbackSeverity {\n switch (finding.severity) {\n case 'critical':\n return 'critical'\n case 'high':\n return 'error'\n case 'medium':\n return 'warning'\n default:\n return 'info'\n }\n}\n\nfunction scoreFromLabels(labels: FeedbackLabel[]): number | undefined {\n if (!labels.length) return undefined\n const scored = labels\n .map((label) => {\n if (label.kind === 'approve' || label.kind === 'select') return 1\n if (label.kind === 'reject' || label.kind === 'policy_block') return 0\n if (label.kind === 'rate' && typeof label.value === 'number')\n return Math.max(0, Math.min(1, label.value))\n return undefined\n })\n .filter((value): value is number => typeof value === 'number')\n if (!scored.length) return undefined\n return Math.round((scored.reduce((sum, value) => sum + value, 0) / scored.length) * 1000) / 1000\n}\n\nfunction instructionFromLabel(\n trajectory: FeedbackTrajectory,\n label: FeedbackLabel,\n): string | undefined {\n if (label.kind === 'reject' && label.reason)\n return `Avoid outputs like \"${compact(trajectory.task.intent, 80)}\" when: ${label.reason}`\n if (label.kind === 'revision_request' && label.reason)\n return `Revise similar work by applying: ${label.reason}`\n if (label.kind === 'select' && label.reason)\n return `Prefer selected options for \"${compact(trajectory.task.intent, 80)}\" because: ${label.reason}`\n if (label.kind === 'approve' && label.reason)\n return `Repeat the pattern approved for \"${compact(trajectory.task.intent, 80)}\": ${label.reason}`\n if (label.kind === 'comment' && label.reason) return label.reason\n return undefined\n}\n\nfunction weightForLabel(label: FeedbackLabel): number {\n const severity =\n label.severity === 'critical'\n ? 4\n : label.severity === 'error'\n ? 3\n : label.severity === 'warning'\n ? 2\n : 1\n const source =\n label.source === 'user'\n ? 3\n : label.source === 'metric' || label.source === 'environment'\n ? 2\n : 1\n return severity * source\n}\n\nfunction matchesFilter(trajectory: FeedbackTrajectory, filter: FeedbackTrajectoryFilter): boolean {\n if (filter.projectId && trajectory.projectId !== filter.projectId) return false\n if (filter.scenarioId && trajectory.scenarioId !== filter.scenarioId) return false\n if (filter.split && trajectory.split !== filter.split) return false\n if (filter.tag) {\n const [key, value] = filter.tag\n if (trajectory.tags?.[key] !== value) return false\n }\n return true\n}\n\nfunction cloneTrajectory(trajectory: FeedbackTrajectory): FeedbackTrajectory {\n return JSON.parse(JSON.stringify(trajectory)) as FeedbackTrajectory\n}\n\nfunction compact(value: string, max: number): string {\n const normalized = value.replace(/\\s+/g, ' ').trim()\n return normalized.length > max ? `${normalized.slice(0, max).trim()}...` : normalized\n}\n\nfunction stableHash(input: string): number {\n let hash = 2166136261\n for (let i = 0; i < input.length; i += 1) {\n hash ^= input.charCodeAt(i)\n hash = Math.imul(hash, 16777619)\n }\n return hash >>> 0\n}\n\nfunction canonicalize(value: unknown): unknown {\n if (value === null || typeof value !== 'object') return value\n if (Array.isArray(value)) return value.map(canonicalize)\n const out: Record<string, unknown> = {}\n for (const key of Object.keys(value as Record<string, unknown>).sort()) {\n out[key] = canonicalize((value as Record<string, unknown>)[key])\n }\n return out\n}\n","/**\n * Backend preflight: verify the models a campaign is about to spend tokens\n * against are actually served by the router BEFORE the run starts. The PRE-hoc\n * complement to `assertRealBackend` (which inspects RunRecords AFTER the run to\n * catch a stub/unconfigured backend).\n *\n * Two checks, increasing in cost:\n * - membership (free): GET `{baseUrl}/models` once; a model is `listed` when\n * its id is in the served set.\n * - probe (spends a tiny number of tokens): POST `{baseUrl}/chat/completions`\n * per model with a 1-message, `PROBE_MAX_TOKENS`-token request; `served` is\n * whether the router reached a provider, with the HTTP `status` and the\n * body's `error.message` captured in `detail`, and `servedModel` recording\n * WHICH model answered.\n *\n * A 2xx is not proof the requested model answered — a gateway can accept one\n * id and route to another. The probe therefore compares the echoed id against\n * the requested one and reports `substitution`; `assertModelsServed` fails on\n * a substituted id exactly as it fails on a dead one, because a campaign that\n * runs on a silently-swapped model produces per-model numbers about a model it\n * never called.\n *\n * A default model the router cannot serve is a config bug. Gate a campaign on\n * `assertModelsServed` and it surfaces every dead or substituted id with its\n * status + detail instead of silently producing a stub or mislabelled run.\n */\n\nimport { AgentEvalError, ConfigError } from '../errors'\nimport {\n checkServedModel,\n PROBE_MAX_TOKENS,\n type ServedModelCheck,\n servedModelAcceptable,\n} from './served-model'\n\n/**\n * Provider signature for \"the budget ran out before an answer\". The model is\n * alive — a provider took the request and consumed the budget — so this must\n * never be scored as a dead id.\n */\nconst REASONING_BUDGET_EXHAUSTED = /reasoning[\\s_-]?budget[\\s_-]?exhausted/i\n\nexport interface ModelPreflight {\n /** The model id as supplied by the caller. */\n model: string\n /** Membership in the `{baseUrl}/models` served set. */\n listed: boolean\n /**\n * The router reached a provider for this model. `null` when `probe` was not\n * requested. True on a 2xx, and also when the provider answered by\n * exhausting its reasoning budget — that proves reachability while leaving\n * identity unproven (see `budgetExhausted`).\n */\n served: boolean | null\n /** HTTP status of the probe. `null` when not probed. */\n status: number | null\n /** Probe body's `error.message` when present, else `null`. */\n detail: string | null\n /**\n * The probe died on the token budget rather than on the model. Identity is\n * unproven, not refuted: raise `probeMaxTokens` to resolve it.\n */\n budgetExhausted: boolean\n /**\n * Identity of the model that answered the probe, compared against `model`.\n * `null` when the model was not probed or the probe failed.\n */\n substitution: ServedModelCheck | null\n}\n\nexport interface PreflightModelsOptions {\n /** Router base URL, e.g. `https://router.tangle.tools/v1`. Trailing slash tolerated. */\n baseUrl: string\n /** Bearer token sent as `Authorization: Bearer <apiKey>`. */\n apiKey: string\n /** Model ids to check. */\n models: string[]\n /** When true, additionally spend a small chat probe per model. Default false. */\n probe?: boolean\n /**\n * Output-token budget per probe. Default `PROBE_MAX_TOKENS`. Lowering it\n * below the reasoning floor makes healthy reasoning models report\n * `budgetExhausted` instead of proving their identity.\n */\n probeMaxTokens?: number\n /** Injectable fetch for tests; defaults to the global. */\n fetchImpl?: typeof fetch\n}\n\nexport interface PreflightOutcome {\n succeeded: boolean\n value: ModelPreflight[] | null\n error: string | null\n}\n\ninterface ModelsListBody {\n data?: ReadonlyArray<{ id?: unknown }>\n}\n\ninterface ChatErrorBody {\n error?: { message?: unknown }\n message?: unknown\n}\n\ninterface ChatProbeBody {\n model?: unknown\n}\n\nfunction stripSlash(url: string): string {\n return url.replace(/\\/+$/, '')\n}\n\n/** Extract `error.message` (then top-level `message`) from a chat-completions error body. */\nfunction errorMessage(body: unknown): string | null {\n if (body == null || typeof body !== 'object') return null\n const b = body as ChatErrorBody\n if (b.error && typeof b.error.message === 'string') return b.error.message\n if (typeof b.message === 'string') return b.message\n return null\n}\n\n/**\n * Check that `models` are reachable on the router. Returns a typed outcome —\n * a network failure yields `{ succeeded: false, error }`, never a throw and\n * never a partial result silently reported as success. No retries, no\n * fallbacks.\n *\n * The membership check (one GET) always runs. When `probe` is true, each model\n * additionally gets a small chat probe so a model that is listed but\n * unconfigured (a 401 `model_not_found` from the router) is caught.\n */\nexport async function preflightModels(opts: PreflightModelsOptions): Promise<PreflightOutcome> {\n const fetchImpl = opts.fetchImpl ?? fetch\n const baseUrl = stripSlash(opts.baseUrl)\n const authHeaders = { authorization: `Bearer ${opts.apiKey}` }\n const maxTokens = opts.probeMaxTokens ?? PROBE_MAX_TOKENS\n if (!Number.isInteger(maxTokens) || maxTokens <= 0) {\n return {\n succeeded: false,\n value: null,\n error: `preflightModels: probeMaxTokens must be a positive integer, got ${maxTokens}`,\n }\n }\n\n let served: Set<string>\n try {\n const res = await fetchImpl(`${baseUrl}/models`, { method: 'GET', headers: authHeaders })\n if (!res.ok) {\n const text = await res.text().catch(() => '')\n return {\n succeeded: false,\n value: null,\n error: `preflightModels: GET ${baseUrl}/models → ${res.status} ${text.slice(0, 400)}`,\n }\n }\n const body = (await res.json()) as ModelsListBody\n const ids = Array.isArray(body.data) ? body.data : []\n served = new Set(ids.map((m) => m.id).filter((id): id is string => typeof id === 'string'))\n } catch (err) {\n return {\n succeeded: false,\n value: null,\n error: `preflightModels: GET ${baseUrl}/models failed — ${err instanceof Error ? err.message : String(err)}`,\n }\n }\n\n const results: ModelPreflight[] = []\n for (const model of opts.models) {\n const listed = served.has(model)\n if (!opts.probe) {\n results.push({\n model,\n listed,\n served: null,\n status: null,\n detail: null,\n budgetExhausted: false,\n substitution: null,\n })\n continue\n }\n try {\n const res = await fetchImpl(`${baseUrl}/chat/completions`, {\n method: 'POST',\n headers: { ...authHeaders, 'content-type': 'application/json' },\n body: JSON.stringify({\n model,\n messages: [{ role: 'user', content: 'ping' }],\n max_tokens: maxTokens,\n }),\n })\n let detail: string | null = null\n let substitution: ServedModelCheck | null = null\n let budgetExhausted = false\n const body = await res.json().catch(() => null)\n if (res.ok) {\n const echoed = (body as ChatProbeBody | null)?.model\n substitution = checkServedModel(\n model,\n typeof echoed === 'string' && echoed.trim() !== '' ? echoed : null,\n )\n } else {\n detail = errorMessage(body)\n budgetExhausted = detail !== null && REASONING_BUDGET_EXHAUSTED.test(detail)\n // The provider took the request and burned the budget, so the id is\n // live. It echoed no model, so identity stays unproven and the default\n // `allowUnreported: false` still refuses the run.\n if (budgetExhausted) substitution = checkServedModel(model, null)\n }\n results.push({\n model,\n listed,\n served: res.ok || budgetExhausted,\n status: res.status,\n detail,\n budgetExhausted,\n substitution,\n })\n } catch (err) {\n return {\n succeeded: false,\n value: null,\n error: `preflightModels: probe POST ${baseUrl}/chat/completions (model ${model}) failed — ${err instanceof Error ? err.message : String(err)}`,\n }\n }\n }\n\n return { succeeded: true, value: results, error: null }\n}\n\nexport class ModelsUnreachableError extends AgentEvalError {\n constructor(\n message: string,\n public readonly results: ReadonlyArray<ModelPreflight>,\n ) {\n super('config', message)\n this.name = 'ModelsUnreachableError'\n }\n}\n\nfunction describeFailure(r: ModelPreflight): string {\n if (!r.listed) {\n const probeNote =\n r.served === false ? ` (probe ${r.status}${r.detail ? `: ${r.detail}` : ''})` : ''\n return `${r.model}: not in /models${probeNote}`\n }\n if (r.served === false) {\n return `${r.model}: listed but probe ${r.status}${r.detail ? ` — ${r.detail}` : ''}`\n }\n if (r.budgetExhausted) {\n return (\n `${r.model}: alive but the probe ran out of reasoning budget (status ${r.status}` +\n `${r.detail ? `: ${r.detail}` : ''}) — it echoed no model id, so identity is unproven. ` +\n 'Raise probeMaxTokens, or pass allowUnreported to accept reachability without identity.'\n )\n }\n // listed, probe 2xx — but a different model answered\n const s = r.substitution\n if (s?.verdict === 'unreported') {\n return `${r.model}: probe answered without echoing a model id — identity unproven`\n }\n return `${r.model}: probe answered by ${s?.served} (${s?.verdict})`\n}\n\nexport interface AssertModelsServedOptions extends PreflightModelsOptions {\n /**\n * Accept a probe answered by a different model of the same provider family.\n * Default false. Only meaningful with `probe: true`.\n */\n allowWithinFamily?: boolean\n /**\n * Accept a probe whose response echoed no model id. Default false — an\n * unidentified response cannot prove the requested model is the one running.\n */\n allowUnreported?: boolean\n}\n\n/**\n * Throw `ModelsUnreachableError` naming EVERY model that is unusable for a\n * measured run — with status, detail, and served identity per model. A model\n * is unusable when it is unlisted, when its probe fails, or when its probe is\n * answered by a different model than the one requested. Callers gate a\n * campaign on this before spending tokens. When the network call itself fails\n * the underlying outcome error is rethrown — there is no partial silent pass.\n *\n * Substitution is only detectable with `probe: true`; a membership-only check\n * proves an id is in the catalogue, never that the catalogue entry answers.\n */\nexport async function assertModelsServed(\n opts: AssertModelsServedOptions,\n): Promise<ModelPreflight[]> {\n const outcome = await preflightModels(opts)\n if (!outcome.succeeded || outcome.value === null) {\n throw new ConfigError(\n outcome.error ?? 'assertModelsServed: preflight failed without an error message',\n )\n }\n const bad = outcome.value.filter(\n (r) =>\n !r.listed ||\n r.served === false ||\n (r.substitution !== null && !servedModelAcceptable(r.substitution, opts)),\n )\n if (bad.length > 0) {\n throw new ModelsUnreachableError(\n `assertModelsServed: ${bad.length}/${outcome.value.length} model(s) unusable on the router — ${bad\n .map(describeFailure)\n .join('; ')}`,\n outcome.value,\n )\n }\n return outcome.value\n}\n","/**\n * Single-backend guard: assert the agent and the rubric judge run through the\n * SAME backend config, so the judge can't silently re-route through a\n * different (often paid) backend than the agent.\n *\n * The bug class: `--backend cli-bridge` rewires the agent, but the judge still\n * reads `process.env.TANGLE_API_KEY` → router. Cost is billed against the\n * router, the eval reports the cli-bridge model, and the data is unusable.\n * Four consumers hand-roll this comparison (legal at `canonical.ts:702-795`);\n * this is the one substrate copy.\n *\n * Complements `assertRealBackend` (records → stub vs real) and\n * `assertCrossFamily` (judge-ensemble family diversity): this one compares two\n * backend *configs* before the run.\n */\n\nimport { AgentEvalError } from '../errors'\n\n/**\n * Minimal backend-config shape the assertion reads. Consumers may pass richer\n * types — only these five fields are inspected.\n */\nexport interface BackendDescriptor {\n /** Backend route — e.g. `'tcloud' | 'cli-bridge' | 'sandbox' | 'direct-provider'`;\n * free-form for consumer extensibility. */\n kind: string\n /** Resolved base URL. Compared lexically (trailing slash stripped). */\n baseUrl: string\n /** Model id (with snapshot suffix). Compared lexically. */\n model: string\n /** Optional provider override. Compared when both set; flagged when only\n * one side sets it. */\n provider?: string\n /** Bearer token. Values are NEVER compared (security) — only that EITHER\n * both are set OR both are empty. Mismatched presence is a divergence. */\n apiKey?: string\n}\n\nexport interface AssertSingleBackendOptions {\n /** When true, ANY field divergence fails. When false (default), only\n * `kind` / `baseUrl` / `provider` / `apiKeyPresence` divergence throws —\n * a different judge `model` on the same route is allowed (the legal\n * pattern: a cheaper judge model). */\n strict?: boolean\n agentLabel?: string\n judgeLabel?: string\n}\n\nexport type SingleBackendField = 'kind' | 'baseUrl' | 'model' | 'provider' | 'apiKeyPresence'\n\nexport interface SingleBackendDivergence {\n field: SingleBackendField\n agent: string | undefined\n judge: string | undefined\n}\n\nexport interface SingleBackendReport {\n /** True when agent + judge agree per the configured strictness. */\n ok: boolean\n /** Every divergence detected (includes `model` even when non-blocking). */\n divergences: ReadonlyArray<SingleBackendDivergence>\n}\n\nexport class SingleBackendError extends AgentEvalError {\n constructor(\n message: string,\n public readonly report: SingleBackendReport,\n ) {\n super('backend_integrity', message)\n this.name = 'SingleBackendError'\n }\n}\n\nfunction stripSlash(url: string): string {\n return url.replace(/\\/+$/, '')\n}\n\n/**\n * Throw `SingleBackendError` when the agent and judge backends diverge in a\n * way that would re-route the judge through a different backend than the\n * agent. Returns the report so callers can log it in either case.\n */\nexport function assertSingleBackend(\n agent: BackendDescriptor,\n judge: BackendDescriptor,\n opts: AssertSingleBackendOptions = {},\n): SingleBackendReport {\n const divergences: SingleBackendDivergence[] = []\n\n if (agent.kind !== judge.kind) {\n divergences.push({ field: 'kind', agent: agent.kind, judge: judge.kind })\n }\n if (stripSlash(agent.baseUrl) !== stripSlash(judge.baseUrl)) {\n divergences.push({ field: 'baseUrl', agent: agent.baseUrl, judge: judge.baseUrl })\n }\n if (agent.model !== judge.model) {\n divergences.push({ field: 'model', agent: agent.model, judge: judge.model })\n }\n // provider: compare when both set; flag when exactly one is set.\n if (agent.provider !== judge.provider) {\n divergences.push({ field: 'provider', agent: agent.provider, judge: judge.provider })\n }\n // apiKey: presence only, never the value.\n const agentHasKey = Boolean(agent.apiKey)\n const judgeHasKey = Boolean(judge.apiKey)\n if (agentHasKey !== judgeHasKey) {\n divergences.push({\n field: 'apiKeyPresence',\n agent: agentHasKey ? 'set' : 'empty',\n judge: judgeHasKey ? 'set' : 'empty',\n })\n }\n\n const blocking = opts.strict ? divergences : divergences.filter((d) => d.field !== 'model')\n const ok = blocking.length === 0\n const report: SingleBackendReport = { ok, divergences }\n\n if (!ok) {\n const agentLabel = opts.agentLabel ?? 'agent'\n const judgeLabel = opts.judgeLabel ?? 'judge'\n const detail = blocking\n .map((d) => `${d.field}: ${agentLabel}=${d.agent ?? '∅'} vs ${judgeLabel}=${d.judge ?? '∅'}`)\n .join('; ')\n throw new SingleBackendError(\n `single-backend: ${agentLabel} and ${judgeLabel} backends diverge — the judge would ` +\n `re-route through a different backend than the agent (${detail})`,\n report,\n )\n }\n\n return report\n}\n","import { type ControlEvalResult, objectiveEval } from '../control-runtime'\nimport type { TraceEmitter } from '../trace/emitter'\nimport type {\n DataAcquisitionPlan,\n KnowledgeAcquisitionMode,\n KnowledgeBundle,\n KnowledgeImportance,\n KnowledgeReadinessReport,\n KnowledgeRecommendedAction,\n KnowledgeRequirement,\n UserQuestion,\n} from './types'\n\nexport interface ScoreKnowledgeReadinessOptions {\n taskId: string\n requirements: KnowledgeRequirement[]\n evidenceIds?: string[]\n claimIds?: string[]\n wikiPageIds?: string[]\n userAnswers?: Record<string, string>\n metadata?: Record<string, unknown>\n now?: Date\n}\n\nexport function scoreKnowledgeReadiness(\n options: ScoreKnowledgeReadinessOptions,\n): KnowledgeReadinessReport {\n const now = options.now ?? new Date()\n const requirements = options.requirements.map(normalizeRequirement)\n const missing = requirements.filter((requirement) => isRequirementMissing(requirement, now))\n const blockingMissingRequirements = missing.filter(isBlockingGap)\n const nonBlockingGaps = missing.filter((requirement) => !isBlockingGap(requirement))\n const readinessScore = weightedReadinessAt(requirements, now)\n const bundle: KnowledgeBundle = {\n taskId: options.taskId,\n requirements,\n evidenceIds: unique([\n ...(options.evidenceIds ?? []),\n ...requirements.flatMap((r) => r.evidenceIds),\n ]),\n claimIds: unique(options.claimIds ?? []),\n wikiPageIds: unique(options.wikiPageIds ?? []),\n userAnswers: options.userAnswers ?? {},\n missing,\n readinessScore,\n metadata: options.metadata,\n }\n const recommendedAction = chooseRecommendedAction(blockingMissingRequirements, nonBlockingGaps)\n const severity =\n blockingMissingRequirements.length > 0\n ? 'critical'\n : nonBlockingGaps.some((gap) => gap.importance === 'high')\n ? 'warning'\n : 'info'\n const reason =\n blockingMissingRequirements.length > 0\n ? `${blockingMissingRequirements.length} blocking knowledge requirement(s) are missing.`\n : nonBlockingGaps.length > 0\n ? `${nonBlockingGaps.length} non-blocking knowledge gap(s) remain.`\n : 'All declared knowledge requirements are ready.'\n\n return {\n taskId: options.taskId,\n readinessScore,\n blockingMissingRequirements,\n nonBlockingGaps,\n recommendedAction,\n bundle,\n severity,\n reason,\n }\n}\n\nexport function blockingKnowledgeEval(\n report: KnowledgeReadinessReport,\n options: { id?: string; minimumScore?: number; emitter?: TraceEmitter } = {},\n): ControlEvalResult {\n const minimumScore = options.minimumScore ?? 0.7\n const passed =\n report.blockingMissingRequirements.length === 0 && report.readinessScore >= minimumScore\n if (options.emitter) {\n void options.emitter\n .emit({\n kind: 'custom',\n payload: knowledgeReadinessTracePayload(report, { passed, minimumScore }),\n })\n .catch(() => undefined)\n }\n return objectiveEval({\n id: options.id ?? 'knowledge-ready',\n passed,\n score: report.readinessScore,\n severity: passed ? 'info' : report.severity,\n detail: report.reason,\n evidence: report.blockingMissingRequirements.map((r) => r.id).join(', ') || undefined,\n metadata: { knowledgeReadiness: report },\n })\n}\n\nexport function knowledgeReadinessTracePayload(\n report: KnowledgeReadinessReport,\n options: { passed?: boolean; minimumScore?: number } = {},\n): Record<string, unknown> {\n return {\n kind: 'readiness_scored',\n taskId: report.taskId,\n passed: options.passed ?? report.blockingMissingRequirements.length === 0,\n readinessScore: report.readinessScore,\n minimumScore: options.minimumScore,\n blockingRequirementIds: report.blockingMissingRequirements.map((r) => r.id),\n nonBlockingRequirementIds: report.nonBlockingGaps.map((r) => r.id),\n recommendedAction: report.recommendedAction,\n severity: report.severity,\n reason: report.reason,\n }\n}\n\nexport function userQuestionsForKnowledgeGaps(gaps: KnowledgeRequirement[]): UserQuestion[] {\n return gaps\n .filter((gap) => gap.acquisitionMode === 'ask_user' || gap.fallbackPolicy === 'ask')\n .map((gap) => ({\n id: `question_${gap.id}`,\n question: `Please provide: ${gap.description}`,\n reason: `Required for ${gap.requiredFor.join(', ') || 'the task'}.`,\n requirementId: gap.id,\n importance: gap.importance,\n answerType: gap.sensitivity === 'secret' ? 'credential' : 'free_text',\n impactIfUnknown: impactFor(gap),\n }))\n}\n\nexport function acquisitionPlansForKnowledgeGaps(\n gaps: KnowledgeRequirement[],\n): DataAcquisitionPlan[] {\n const byMode = new Map<string, KnowledgeRequirement[]>()\n for (const gap of gaps) {\n const mode = planMode(gap.acquisitionMode)\n if (!mode) continue\n const bucket = byMode.get(mode) ?? []\n bucket.push(gap)\n byMode.set(mode, bucket)\n }\n return [...byMode.entries()].map(([mode, requirements]) => ({\n id: `acquire_${mode}`,\n requirementIds: requirements.map((r) => r.id),\n mode: mode as DataAcquisitionPlan['mode'],\n description: descriptionForPlan(mode as DataAcquisitionPlan['mode'], requirements),\n priority: maxImportance(requirements.map((r) => r.importance)),\n questions: mode === 'ask_user' ? userQuestionsForKnowledgeGaps(requirements) : undefined,\n }))\n}\n\nfunction normalizeRequirement(requirement: KnowledgeRequirement): KnowledgeRequirement {\n return {\n ...requirement,\n confidenceNeeded: clamp01(requirement.confidenceNeeded),\n currentConfidence: clamp01(requirement.currentConfidence),\n evidenceIds: unique(requirement.evidenceIds),\n }\n}\n\nfunction weightedReadinessAt(requirements: KnowledgeRequirement[], now: Date): number {\n if (requirements.length === 0) return 1\n let weightSum = 0\n let scoreSum = 0\n for (const requirement of requirements) {\n const weight = importanceWeight(requirement.importance)\n const score = isExpired(requirement, now)\n ? 0\n : requirement.confidenceNeeded <= 0\n ? 1\n : Math.min(1, requirement.currentConfidence / requirement.confidenceNeeded)\n weightSum += weight\n scoreSum += weight * score\n }\n return clamp01(scoreSum / weightSum)\n}\n\nfunction isRequirementMissing(requirement: KnowledgeRequirement, now: Date): boolean {\n return isExpired(requirement, now) || requirement.currentConfidence < requirement.confidenceNeeded\n}\n\nfunction isExpired(requirement: KnowledgeRequirement, now: Date): boolean {\n if (!requirement.validUntil) return false\n const deadline = Date.parse(requirement.validUntil)\n if (!Number.isFinite(deadline)) return true\n return deadline <= now.getTime()\n}\n\nfunction isBlockingGap(requirement: KnowledgeRequirement): boolean {\n return (\n requirement.importance === 'blocking' ||\n requirement.fallbackPolicy === 'block' ||\n requirement.sensitivity === 'secret'\n )\n}\n\nfunction chooseRecommendedAction(\n blocking: KnowledgeRequirement[],\n nonBlocking: KnowledgeRequirement[],\n): KnowledgeRecommendedAction {\n const gaps = blocking.length > 0 ? blocking : nonBlocking\n if (gaps.length === 0) return 'run_agent'\n if (gaps.some((gap) => gap.acquisitionMode === 'ask_user' || gap.fallbackPolicy === 'ask'))\n return 'ask_user'\n if (gaps.some((gap) => gap.acquisitionMode === 'query_connector')) return 'query_connectors'\n if (\n gaps.some(\n (gap) => gap.acquisitionMode === 'inspect_repo' || gap.acquisitionMode === 'run_command',\n )\n )\n return 'inspect_repo'\n if (gaps.some((gap) => gap.acquisitionMode === 'search_web')) return 'collect_web_data'\n if (gaps.some((gap) => gap.acquisitionMode === 'not_available')) return 'abort_or_rescope'\n if (nonBlocking.some((gap) => gap.importance === 'high')) return 'build_domain_wiki'\n return 'continue_with_caveat'\n}\n\nfunction planMode(mode: KnowledgeAcquisitionMode): DataAcquisitionPlan['mode'] | null {\n if (mode === 'infer_low_confidence' || mode === 'not_available') return null\n return mode\n}\n\nfunction descriptionForPlan(\n mode: DataAcquisitionPlan['mode'],\n requirements: KnowledgeRequirement[],\n): string {\n const labels = requirements.map((r) => r.description).join('; ')\n if (mode === 'ask_user') return `Ask the user for: ${labels}`\n if (mode === 'search_web') return `Search web or documentation sources for: ${labels}`\n if (mode === 'query_connector') return `Query configured connectors for: ${labels}`\n if (mode === 'inspect_repo') return `Inspect repository context for: ${labels}`\n if (mode === 'run_command') return `Run local commands to collect: ${labels}`\n return `Build domain wiki evidence for: ${labels}`\n}\n\nfunction impactFor(requirement: KnowledgeRequirement): string {\n if (requirement.fallbackPolicy === 'block') return 'The agent should not run until this is known.'\n if (requirement.fallbackPolicy === 'continue_with_caveat')\n return 'The agent may continue, but must disclose uncertainty.'\n if (requirement.fallbackPolicy === 'use_default')\n return 'The agent will use the configured default if skipped.'\n return 'The agent should ask before continuing.'\n}\n\nfunction maxImportance(values: KnowledgeImportance[]): KnowledgeImportance {\n const order: KnowledgeImportance[] = ['blocking', 'high', 'medium', 'low']\n return order.find((value) => values.includes(value)) ?? 'low'\n}\n\nfunction importanceWeight(importance: KnowledgeImportance): number {\n if (importance === 'blocking') return 8\n if (importance === 'high') return 4\n if (importance === 'medium') return 2\n return 1\n}\n\nfunction clamp01(value: number): number {\n if (!Number.isFinite(value)) return 0\n return Math.max(0, Math.min(1, value))\n}\n\nfunction unique<T>(items: T[]): T[] {\n return [...new Set(items)]\n}\n","import {\n createFeedbackTrajectory,\n type FeedbackLabel,\n type FeedbackTrajectory,\n type FeedbackTrajectoryStore,\n} from './feedback-trajectory'\nimport type {\n ReleaseConfidenceScorecard,\n ReleaseConfidenceThresholds,\n ReleaseTraceEvidence,\n} from './release-confidence'\nimport { evaluateReleaseConfidence } from './release-confidence'\nimport type { CheckResult, TestResult } from './types'\n\nexport interface LiveProofArtifact {\n kind: string\n id?: string\n path?: string\n url?: string\n metadata?: Record<string, unknown>\n}\n\nexport interface LiveProofContext {\n projectId: string\n scenarioId: string\n task: string\n checks: CheckResult[]\n artifacts: LiveProofArtifact[]\n labels: FeedbackLabel[]\n metadata: Record<string, unknown>\n transcript: { role: 'user' | 'assistant' | 'system' | 'tool'; content: string; at: string }[]\n addCheck(check: CheckResult): void\n addArtifact(artifact: LiveProofArtifact): void\n addLabel(label: Omit<FeedbackLabel, 'createdAt'> & { createdAt?: string }): void\n addTurn(turn: {\n role: 'user' | 'assistant' | 'system' | 'tool'\n content: string\n at?: string\n }): void\n}\n\nexport interface LiveProofConfig {\n projectId: string\n scenarioId: string\n task: string\n drive(context: LiveProofContext): Promise<void> | void\n validate?(\n context: LiveProofContext,\n ): Promise<CheckResult[] | undefined> | CheckResult[] | undefined\n requiredArtifacts?: string[]\n minPassRate?: number\n trajectoryStore?: FeedbackTrajectoryStore\n releaseConfidence?: {\n target: string\n candidateId?: string\n baselineId?: string\n thresholds?: ReleaseConfidenceThresholds\n }\n metadata?: Record<string, unknown>\n}\n\nexport interface LiveProofResult extends TestResult {\n projectId: string\n scenarioId: string\n artifacts: LiveProofArtifact[]\n labels: FeedbackLabel[]\n transcript: LiveProofContext['transcript']\n trajectory: FeedbackTrajectory\n releaseConfidence?: ReleaseConfidenceScorecard\n}\n\nexport async function runLiveProof(config: LiveProofConfig): Promise<LiveProofResult> {\n const startedAt = Date.now()\n const checks: CheckResult[] = []\n const artifacts: LiveProofArtifact[] = []\n const labels: FeedbackLabel[] = []\n const transcript: LiveProofContext['transcript'] = []\n const metadata = { ...(config.metadata ?? {}), live: true }\n const context: LiveProofContext = {\n projectId: config.projectId,\n scenarioId: config.scenarioId,\n task: config.task,\n checks,\n artifacts,\n labels,\n metadata,\n transcript,\n addCheck: (check) => checks.push(check),\n addArtifact: (artifact) => artifacts.push(artifact),\n addLabel: (label) =>\n labels.push({ ...label, createdAt: label.createdAt ?? new Date().toISOString() }),\n addTurn: (turn) => transcript.push({ ...turn, at: turn.at ?? new Date().toISOString() }),\n }\n\n try {\n await config.drive(context)\n const validationChecks = await config.validate?.(context)\n if (validationChecks) checks.push(...validationChecks)\n } catch (err) {\n checks.push({\n name: 'live_proof_runtime',\n passed: false,\n expected: 'live proof completes without runtime failure',\n actual: err instanceof Error ? err.message : String(err),\n })\n }\n\n for (const kind of config.requiredArtifacts ?? []) {\n checks.push({\n name: `artifact:${kind}`,\n passed: artifacts.some((artifact) => artifact.kind === kind),\n expected: `artifact kind ${kind}`,\n actual: artifacts.map((artifact) => artifact.kind).join(', ') || 'none',\n })\n }\n\n const passRate =\n checks.length === 0 ? 0 : checks.filter((check) => check.passed).length / checks.length\n if (config.minPassRate !== undefined) {\n checks.push({\n name: 'min_pass_rate',\n passed: passRate >= config.minPassRate,\n expected: `pass rate >= ${config.minPassRate}`,\n actual: passRate.toFixed(3),\n })\n }\n\n const passed = checks.length > 0 && checks.every((check) => check.passed)\n const duration = Date.now() - startedAt\n const trajectory = createFeedbackTrajectory({\n projectId: config.projectId,\n scenarioId: config.scenarioId,\n task: { intent: config.task },\n labels,\n outcome: {\n success: passed,\n score:\n checks.length === 0 ? 0 : checks.filter((check) => check.passed).length / checks.length,\n detail: `${checks.filter((check) => check.passed).length}/${checks.length} checks passed`,\n observedAt: new Date().toISOString(),\n metadata: {\n artifacts,\n transcript,\n },\n },\n metadata,\n })\n await config.trajectoryStore?.save(trajectory)\n\n const releaseConfidence = config.releaseConfidence\n ? evaluateReleaseConfidence({\n ...config.releaseConfidence,\n traces: [liveProofToReleaseTrace(config, trajectory, duration)],\n thresholds: {\n requireCorpus: false,\n requireHoldout: false,\n minScenarioCount: 0,\n minSearchRuns: 0,\n minHoldoutRuns: 0,\n requireAsiForFailures: false,\n ...(config.releaseConfidence.thresholds ?? {}),\n },\n })\n : undefined\n\n return {\n name: config.scenarioId,\n passed: passed && (releaseConfidence ? releaseConfidence.status !== 'fail' : true),\n duration,\n detail: `${checks.filter((check) => check.passed).length}/${checks.length} checks passed`,\n checks,\n projectId: config.projectId,\n scenarioId: config.scenarioId,\n artifacts,\n labels,\n transcript,\n trajectory,\n releaseConfidence,\n }\n}\n\nfunction liveProofToReleaseTrace(\n config: LiveProofConfig,\n trajectory: FeedbackTrajectory,\n durationMs: number,\n): ReleaseTraceEvidence {\n return {\n scenarioId: config.scenarioId,\n candidateId: config.releaseConfidence?.candidateId,\n split:\n trajectory.split === 'holdout' ? 'holdout' : trajectory.split === 'dev' ? 'dev' : 'search',\n score: trajectory.outcome?.score,\n ok: trajectory.outcome?.success,\n turnCount: Array.isArray(trajectory.outcome?.metadata?.transcript)\n ? trajectory.outcome.metadata.transcript.length\n : undefined,\n durationMs,\n metadata: {\n projectId: config.projectId,\n artifacts: trajectory.outcome?.metadata?.artifacts,\n },\n }\n}\n","import { clamp01 } from './run-score'\n\nexport type PrReviewSource =\n | 'drew'\n | 'donovan'\n | 'shady'\n | 'codex'\n | 'claude-code'\n | 'gpt-5.5-high'\n | 'claude-opus-4.7-high'\n | 'kimi'\n | 'opencode'\n | (string & {})\n\nexport type PrReviewSeverity = 'critical' | 'high' | 'medium' | 'low' | 'nit'\n\nexport type PrReviewOutcome = 'accepted' | 'fixed' | 'rejected' | 'duplicate' | 'noise' | 'unknown'\n\nexport interface PrReviewComment {\n id: string\n source: PrReviewSource\n body: string\n model?: string\n author?: string\n path?: string\n line?: number\n severity?: PrReviewSeverity\n outcome?: PrReviewOutcome\n createdAt?: string\n metadata?: Record<string, unknown>\n}\n\nexport interface PrReviewReferenceFinding {\n id: string\n title: string\n severity: PrReviewSeverity\n path?: string\n line?: number\n /**\n * Stable terms that should appear in a useful finding. Keep these\n * factual: API names, invariant names, table names, error classes.\n */\n keywords?: string[]\n fixedByCommit?: string\n sourceCommentIds?: string[]\n metadata?: Record<string, unknown>\n}\n\nexport interface PrReviewAuditCase {\n id: string\n repo: string\n prNumber?: number\n baseSha?: string\n headSha?: string\n title?: string\n diff?: string\n split?: 'train' | 'validation' | 'test' | 'holdout' | (string & {})\n comments: PrReviewComment[]\n referenceFindings: PrReviewReferenceFinding[]\n metadata?: Record<string, unknown>\n}\n\nexport interface PrReviewScoreWeights {\n recall: number\n precision: number\n actionability: number\n severityCalibration: number\n lowNoise: number\n}\n\nexport interface PrReviewMatchedFinding {\n referenceId: string\n commentId: string\n score: number\n}\n\nexport interface PrReviewScore {\n caseId: string\n source: PrReviewSource\n commentCount: number\n referenceCount: number\n matchedFindings: PrReviewMatchedFinding[]\n recall: number\n precision: number\n actionability: number\n severityCalibration: number\n lowNoise: number\n aggregate: number\n notes: string[]\n}\n\nexport interface PrReviewBenchmarkSummary {\n source: PrReviewSource\n caseCount: number\n commentCount: number\n aggregateMean: number\n recallMean: number\n precisionMean: number\n actionabilityMean: number\n severityCalibrationMean: number\n lowNoiseMean: number\n}\n\nexport const DEFAULT_PR_REVIEW_SCORE_WEIGHTS: PrReviewScoreWeights = {\n recall: 4,\n precision: 2,\n actionability: 1.5,\n severityCalibration: 1,\n lowNoise: 1,\n}\n\nexport function commentsForSource(\n auditCase: PrReviewAuditCase,\n source: PrReviewSource,\n): PrReviewComment[] {\n return auditCase.comments.filter((comment) => comment.source === source)\n}\n\nexport function scorePrReviewSource(\n auditCase: PrReviewAuditCase,\n source: PrReviewSource,\n weights: Partial<PrReviewScoreWeights> = {},\n): PrReviewScore {\n return scorePrReviewComments(auditCase, commentsForSource(auditCase, source), source, weights)\n}\n\nexport function scorePrReviewComments(\n auditCase: PrReviewAuditCase,\n comments: PrReviewComment[],\n source: PrReviewSource,\n weights: Partial<PrReviewScoreWeights> = {},\n): PrReviewScore {\n const matchedFindings = matchReferenceFindings(auditCase.referenceFindings, comments)\n const matchedCommentIds = new Set(matchedFindings.map((match) => match.commentId))\n const positiveComments = comments.filter((comment) => isPositiveOutcome(comment.outcome))\n const negativeComments = comments.filter((comment) => isNegativeOutcome(comment.outcome))\n const actionableComments = comments.filter(isActionableComment)\n const severityComments = comments.filter((comment) => comment.severity)\n const severityAligned = severityComments.filter((comment) =>\n isSeverityAligned(comment, auditCase.referenceFindings, matchedFindings),\n )\n\n const recall = auditCase.referenceFindings.length\n ? matchedFindings.length / auditCase.referenceFindings.length\n : comments.length === 0\n ? 1\n : 0\n\n const precisionDenominator = positiveComments.length + negativeComments.length\n const precision =\n precisionDenominator > 0\n ? positiveComments.length / precisionDenominator\n : comments.length > 0\n ? matchedCommentIds.size / comments.length\n : auditCase.referenceFindings.length === 0\n ? 1\n : 0\n\n const actionability = comments.length ? actionableComments.length / comments.length : 1\n const severityCalibration = severityComments.length\n ? severityAligned.length / severityComments.length\n : matchedFindings.length\n ? 0.5\n : 1\n const lowNoise = comments.length ? 1 - negativeComments.length / comments.length : 1\n const aggregate = aggregatePrReviewScore(\n { recall, precision, actionability, severityCalibration, lowNoise },\n weights,\n )\n\n return {\n caseId: auditCase.id,\n source,\n commentCount: comments.length,\n referenceCount: auditCase.referenceFindings.length,\n matchedFindings,\n recall,\n precision,\n actionability,\n severityCalibration,\n lowNoise,\n aggregate,\n notes: buildScoreNotes({\n comments,\n referenceCount: auditCase.referenceFindings.length,\n matchedFindings,\n negativeComments,\n actionableComments,\n }),\n }\n}\n\nexport function summarizePrReviewBenchmark(scores: PrReviewScore[]): PrReviewBenchmarkSummary[] {\n const bySource = new Map<PrReviewSource, PrReviewScore[]>()\n for (const score of scores) {\n bySource.set(score.source, [...(bySource.get(score.source) ?? []), score])\n }\n return [...bySource.entries()]\n .map(([source, sourceScores]) => ({\n source,\n caseCount: sourceScores.length,\n commentCount: sum(sourceScores.map((score) => score.commentCount)),\n aggregateMean: mean(sourceScores.map((score) => score.aggregate)),\n recallMean: mean(sourceScores.map((score) => score.recall)),\n precisionMean: mean(sourceScores.map((score) => score.precision)),\n actionabilityMean: mean(sourceScores.map((score) => score.actionability)),\n severityCalibrationMean: mean(sourceScores.map((score) => score.severityCalibration)),\n lowNoiseMean: mean(sourceScores.map((score) => score.lowNoise)),\n }))\n .sort((a, b) => b.aggregateMean - a.aggregateMean)\n}\n\nexport function aggregatePrReviewScore(\n dimensions: Pick<\n PrReviewScore,\n 'recall' | 'precision' | 'actionability' | 'severityCalibration' | 'lowNoise'\n >,\n weights: Partial<PrReviewScoreWeights> = {},\n): number {\n const merged = { ...DEFAULT_PR_REVIEW_SCORE_WEIGHTS, ...weights }\n const weightSum = Object.values(merged).reduce((total, value) => total + Math.max(0, value), 0)\n if (weightSum <= 0) return 0\n return (\n (merged.recall * clamp01(dimensions.recall) +\n merged.precision * clamp01(dimensions.precision) +\n merged.actionability * clamp01(dimensions.actionability) +\n merged.severityCalibration * clamp01(dimensions.severityCalibration) +\n merged.lowNoise * clamp01(dimensions.lowNoise)) /\n weightSum\n )\n}\n\nfunction matchReferenceFindings(\n references: PrReviewReferenceFinding[],\n comments: PrReviewComment[],\n): PrReviewMatchedFinding[] {\n const matches: PrReviewMatchedFinding[] = []\n const usedCommentIds = new Set<string>()\n\n for (const reference of references) {\n const candidates = comments\n .filter((comment) => !usedCommentIds.has(comment.id))\n .map((comment) => ({ comment, score: matchScore(reference, comment) }))\n .filter(({ score }) => score >= 0.55)\n .sort((a, b) => b.score - a.score)\n const best = candidates[0]\n if (!best) continue\n usedCommentIds.add(best.comment.id)\n matches.push({ referenceId: reference.id, commentId: best.comment.id, score: best.score })\n }\n\n return matches\n}\n\nfunction matchScore(reference: PrReviewReferenceFinding, comment: PrReviewComment): number {\n let score = 0\n if (reference.sourceCommentIds?.includes(comment.id)) score += 1\n if (\n reference.path &&\n comment.path &&\n normalizePath(reference.path) === normalizePath(comment.path)\n ) {\n score += 0.35\n }\n if (reference.line && comment.line && Math.abs(reference.line - comment.line) <= 3) score += 0.15\n\n const terms = [...(reference.keywords ?? []), ...tokenize(reference.title)]\n const uniqueTerms = [...new Set(terms.map(normalizeTerm).filter((term) => term.length >= 3))]\n if (uniqueTerms.length > 0) {\n const bodyTerms = new Set(tokenize(comment.body).map(normalizeTerm))\n const overlap = uniqueTerms.filter((term) => bodyTerms.has(term)).length\n score += 0.5 * (overlap / uniqueTerms.length)\n }\n\n return clamp01(score)\n}\n\nfunction isActionableComment(comment: PrReviewComment): boolean {\n const body = comment.body.trim()\n if (!comment.path && !/\\b(file|line|function|method|class|module|test|migration)\\b/i.test(body)) {\n return false\n }\n return /\\b(fix|change|add|remove|guard|check|reject|validate|test|assert|return|throw|fail|block)\\b/i.test(\n body,\n )\n}\n\nfunction isSeverityAligned(\n comment: PrReviewComment,\n references: PrReviewReferenceFinding[],\n matches: PrReviewMatchedFinding[],\n): boolean {\n if (!comment.severity) return false\n const match = matches.find((candidate) => candidate.commentId === comment.id)\n if (!match) return comment.severity === 'nit' || comment.severity === 'low'\n const reference = references.find((candidate) => candidate.id === match.referenceId)\n if (!reference) return false\n return Math.abs(severityRank(comment.severity) - severityRank(reference.severity)) <= 1\n}\n\nfunction buildScoreNotes(input: {\n comments: PrReviewComment[]\n referenceCount: number\n matchedFindings: PrReviewMatchedFinding[]\n negativeComments: PrReviewComment[]\n actionableComments: PrReviewComment[]\n}): string[] {\n const notes: string[] = []\n if (input.referenceCount > 0 && input.matchedFindings.length === 0) {\n notes.push('no reference findings matched')\n }\n if (input.negativeComments.length > 0) {\n notes.push(`${input.negativeComments.length} comment(s) labelled rejected/duplicate/noise`)\n }\n if (input.comments.length > 0 && input.actionableComments.length === 0) {\n notes.push('comments were not actionable enough for a PR reviewer benchmark')\n }\n return notes\n}\n\nfunction isPositiveOutcome(outcome: PrReviewOutcome | undefined): boolean {\n return outcome === 'accepted' || outcome === 'fixed'\n}\n\nfunction isNegativeOutcome(outcome: PrReviewOutcome | undefined): boolean {\n return outcome === 'rejected' || outcome === 'duplicate' || outcome === 'noise'\n}\n\nfunction severityRank(severity: PrReviewSeverity): number {\n switch (severity) {\n case 'critical':\n return 5\n case 'high':\n return 4\n case 'medium':\n return 3\n case 'low':\n return 2\n case 'nit':\n return 1\n }\n}\n\nfunction tokenize(input: string): string[] {\n return input.match(/[a-zA-Z0-9_.$/-]+/g) ?? []\n}\n\nfunction normalizeTerm(input: string): string {\n return input.toLowerCase().replace(/^[^a-z0-9_]+|[^a-z0-9_]+$/g, '')\n}\n\nfunction normalizePath(input: string): string {\n return input.replace(/^\\.\\/+/, '')\n}\n\nfunction mean(values: number[]): number {\n return values.length ? sum(values) / values.length : 0\n}\n\nfunction sum(values: number[]): number {\n return values.reduce((total, value) => total + value, 0)\n}\n","import type { Scenario, ScenarioFile } from './types'\n\n/**\n * ScenarioRegistry — manages scenario discovery and filtering.\n *\n * Each agent registers its scenarios. The registry handles conversion\n * from ScenarioFile format to the framework's Scenario type.\n */\nexport class ScenarioRegistry {\n private scenarios: Scenario[] = []\n private scenarioFiles: ScenarioFile[] = []\n\n /** Register scenarios from ScenarioFile format */\n registerFiles(files: ScenarioFile[]): void {\n this.scenarioFiles.push(...files)\n this.scenarios.push(...files.map(toScenario))\n }\n\n /** Register pre-built Scenario objects directly */\n register(scenarios: Scenario[]): void {\n this.scenarios.push(...scenarios)\n }\n\n /** Get all scenarios */\n all(): Scenario[] {\n return [...this.scenarios]\n }\n\n /** Get scenarios filtered by category */\n byCategory(category: string): Scenario[] {\n const fromFiles = this.scenarioFiles.filter((sf) => sf.category === category).map(toScenario)\n return fromFiles\n }\n\n /** List all categories with counts */\n listCategories(): { category: string; count: number }[] {\n const counts: Record<string, number> = {}\n for (const sf of this.scenarioFiles) {\n counts[sf.category] = (counts[sf.category] ?? 0) + 1\n }\n return Object.entries(counts).map(([category, count]) => ({ category, count }))\n }\n\n /** Get scenarios filtered by persona */\n byPersona(persona: string): Scenario[] {\n return this.scenarios.filter((s) => s.persona === persona)\n }\n\n /** Get a single scenario by ID */\n byId(id: string): Scenario | undefined {\n return this.scenarios.find((s) => s.id === id)\n }\n\n /** Count total scenarios */\n get count(): number {\n return this.scenarios.length\n }\n}\n\n/** Convert ScenarioFile to the framework's Scenario type */\nfunction toScenario(sf: ScenarioFile): Scenario {\n return {\n id: sf.id,\n persona: sf.persona,\n label: sf.label,\n thesis: sf.thesis,\n dimensions: [],\n turns: sf.turns,\n artifactChecks: sf.artifactChecks,\n systemPromptAppend: sf.isControl ? 'You are a helpful AI assistant.' : undefined,\n }\n}\n","import type { BenchmarkReport, DriverResult } from './types'\n\n/**\n * Report generation utilities.\n *\n * Outputs convergence curves, cost curves, quality curves,\n * and per-persona summaries in markdown format.\n */\n\n/** Generate a markdown report from benchmark results */\nexport function formatBenchmarkReport(report: BenchmarkReport): string {\n const lines: string[] = []\n\n lines.push(`# Benchmark Report`)\n lines.push(``)\n lines.push(`**Date:** ${report.timestamp}`)\n lines.push(`**Generation:** ${report.generation}`)\n lines.push(`**Prompt Version:** ${report.promptVersion}`)\n lines.push(`**Scenarios:** ${report.scenarioCount}`)\n lines.push(`**Overall Score:** ${report.summary.overallAvg.toFixed(1)}/10`)\n lines.push(``)\n\n // By persona\n lines.push(`## By Persona`)\n lines.push(``)\n lines.push(`| Persona | Avg | Passed | Total |`)\n lines.push(`|---------|-----|--------|-------|`)\n for (const [name, data] of Object.entries(report.summary.byPersona)) {\n lines.push(`| ${name} | ${data.avg.toFixed(1)} | ${data.passed} | ${data.total} |`)\n }\n lines.push(``)\n\n // By dimension\n lines.push(`## By Dimension`)\n lines.push(``)\n lines.push(`| Dimension | Avg | Range | N |`)\n lines.push(`|-----------|-----|-------|---|`)\n const dimEntries = Object.entries(report.summary.byDimension).sort((a, b) => a[1].avg - b[1].avg)\n for (const [name, data] of dimEntries) {\n const min = Math.min(...data.scores)\n const max = Math.max(...data.scores)\n lines.push(`| ${name} | ${data.avg.toFixed(1)} | ${min}-${max} | ${data.scores.length} |`)\n }\n lines.push(``)\n\n // Weakest\n if (report.summary.weakest.length > 0) {\n lines.push(`## Weakest Scenarios`)\n lines.push(``)\n for (const w of report.summary.weakest) {\n lines.push(`- **${w.scenario}** (${w.score.toFixed(1)}): ${w.reason}`)\n }\n lines.push(``)\n }\n\n // Strongest\n if (report.summary.strongest.length > 0) {\n lines.push(`## Strongest Scenarios`)\n lines.push(``)\n for (const s of report.summary.strongest) {\n lines.push(`- **${s.scenario}** (${s.score.toFixed(1)}): ${s.reason}`)\n }\n lines.push(``)\n }\n\n return lines.join('\\n')\n}\n\n/** Generate a markdown report from agent driver results */\nexport function formatDriverReport(results: DriverResult[]): string {\n const lines: string[] = []\n\n lines.push(`# Agent Driver Report`)\n lines.push(``)\n\n for (const r of results) {\n lines.push(`## Persona: ${r.personaId}`)\n lines.push(``)\n lines.push(`- **Completed:** ${r.completed ? 'Yes' : 'No'}`)\n lines.push(`- **Turns to completion:** ${r.turnsToCompletion ?? 'N/A'}`)\n lines.push(`- **Total turns:** ${r.totalTurns}`)\n lines.push(\n `- **Final state:** ${r.finalState.tasks} tasks, ${r.finalState.events} events, ${r.finalState.vaultFiles.length} vault files`,\n )\n lines.push(``)\n\n // Convergence curve (ASCII)\n lines.push(`### Convergence`)\n lines.push(``)\n lines.push('```')\n for (let i = 0; i < r.convergenceCurve.length; i++) {\n const pct = r.convergenceCurve[i]!\n const bar = '#'.repeat(Math.round(pct / 2))\n lines.push(` turn ${String(i + 1).padStart(2)}: ${bar} ${pct.toFixed(0)}%`)\n }\n lines.push('```')\n lines.push(``)\n\n // Per-turn metrics table\n if (r.metrics.length > 0) {\n lines.push(`### Per-Turn Metrics`)\n lines.push(``)\n lines.push(`| Turn | Tasks | Events | Vault | Latency | Completion |`)\n lines.push(`|------|-------|--------|-------|---------|------------|`)\n for (const m of r.metrics) {\n lines.push(\n `| ${m.turn} | ${m.tasks} | ${m.events} | ${m.vaultFiles} | ${(m.responseLatencyMs / 1000).toFixed(1)}s | ${m.completionPercent.toFixed(0)}% |`,\n )\n }\n lines.push(``)\n }\n }\n\n return lines.join('\\n')\n}\n\n/** Print a compact summary to console */\nexport function printDriverSummary(results: DriverResult[]): void {\n console.log('='.repeat(70))\n console.log(' AGENT DRIVER — RESULTS')\n console.log('='.repeat(70))\n\n for (const r of results) {\n const status = r.completed ? 'COMPLETE' : 'INCOMPLETE'\n const turns = r.turnsToCompletion ?? r.totalTurns\n console.log(\n ` ${r.personaId.padEnd(20)} ${status.padEnd(12)} turns=${turns} tasks=${r.finalState.tasks} events=${r.finalState.events} vault=${r.finalState.vaultFiles.length}`,\n )\n }\n\n console.log()\n const completedCount = results.filter((r) => r.completed).length\n console.log(`${completedCount}/${results.length} personas completed`)\n}\n","/**\n * Treatment-applied gate — \"did the treatment's tool actually fire this run?\"\n *\n * A tool-treatment A/B (mount a search provider, a browser, a code-exec\n * sandbox, a retrieval MCP — anything one arm gets and the other doesn't) only\n * means something on the treatment arm if that arm actually EXERCISED the tool.\n * A treatment run that never called the mounted tool is not a weak data point\n * — it is a NON-data-point: the manipulation never happened, so the run cannot\n * speak to the treatment and must be excluded from the objective, the same way\n * an infra-tainted run is excluded.\n *\n * This is the manipulation/validity precondition that protects the paired A/B\n * tests downstream (`mcnemar`, `pairedRiskDifference`): they must only ever see\n * runs where the treatment was applied, or they measure noise and report it as\n * an effect.\n *\n * Shape mirrors `authenticity`'s `gateRealness`: a pure predicate over already-\n * computed signals, with explicit fail-open/fail-closed discipline. It is not a\n * trace parser — the tool-call telemetry it reads is the deterministic\n * `toolHistogram` that `computeTraceMetrics(spans)` already produces (OTLP\n * tool-name extraction via `TOOL_NAME_ATTR_KEYS`), or the `ToolSpan[]` a\n * `toolSpans(store, runId)` query returns. The gate never re-derives either.\n *\n * General by construction:\n * - The \"which tool counts as the treatment\" decision is a `matches` PARAMETER\n * — a `(toolName: string) => boolean`. There is no `search`/`web`/`fetch`\n * literal anywhere in this module; a search A/B passes its own matcher.\n * - The \"is THIS run a treatment arm (vs a control)\" decision is the caller's\n * policy and stays at the call site. The gate only answers the narrower,\n * domain-free question: \"given this run's telemetry, did a matching tool\n * fire?\" — so it generalizes to any tool-treatment, not search.\n *\n * Fail-open on telemetry absence: when NO tool calls were captured at all\n * (`sum(toolHistogram) === 0`), the gate cannot distinguish \"the agent used no\n * tools\" from \"this harness's tool calls weren't recorded\". Quarantining on a\n * telemetry gap would silently delete real runs, so the default is\n * applied=true / gated=false. Pass `failOpenWhenNoTelemetry: false` to flip to\n * fail-closed for harnesses where tool capture is guaranteed.\n */\n\nimport type { RunRecord } from './run-record'\nimport type { ToolSpan } from './trace/schema'\nimport type { BehavioralMetrics } from './trace-analyst/behavioral-metrics'\nimport { computeTraceMetrics } from './trace-analyst/behavioral-metrics'\nimport type { TraceAnalystSpan } from './trace-analyst/types'\n\n/** A tool-name matcher: does this tool name belong to the treatment under test?\n * The caller supplies it — the substrate ships no `search` (or any) literal. */\nexport type ToolMatcher = (toolName: string) => boolean\n\nexport interface TreatmentGateInput {\n /** Tool-call counts by tool name — exactly `computeTraceMetrics(spans).toolHistogram`.\n * The gate consumes this; it does not parse spans itself. */\n toolHistogram: Readonly<Record<string, number>>\n /** Which tool names count as the treatment firing. A parameter, never baked in. */\n matches: ToolMatcher\n}\n\nexport interface TreatmentGateOptions {\n /** When the histogram is empty (no tool telemetry captured), treat the run as\n * applied rather than quarantining it. Default true — a telemetry gap must\n * never be mistaken for \"treatment not applied\". Set false only when tool\n * capture is guaranteed for this harness. */\n failOpenWhenNoTelemetry?: boolean\n}\n\nexport interface TreatmentGate {\n /** True iff the treatment's tool is considered to have fired this run. False\n * ONLY when telemetry was present and no matching call appears. */\n applied: boolean\n /** Objective-exclusion flag, parallel to `outcome.realness.gated`: a gated run\n * is dropped from the objective denominator and reported as\n * treatment-not-applied (like infra-loss). `gated === !applied`. */\n gated: boolean\n reason?: string\n /** How many recorded tool calls matched the treatment matcher. */\n matchedCalls: number\n /** Total recorded tool calls (`sum(toolHistogram)`) — 0 means no telemetry. */\n observedTools: number\n}\n\n/**\n * Core predicate. Gated (treatment-not-applied) ONLY when telemetry was\n * captured AND zero matching calls appear; an empty histogram fails open.\n */\nexport function gateTreatmentApplied(\n input: TreatmentGateInput,\n opts: TreatmentGateOptions = {},\n): TreatmentGate {\n const failOpen = opts.failOpenWhenNoTelemetry ?? true\n\n let observedTools = 0\n let matchedCalls = 0\n for (const [tool, count] of Object.entries(input.toolHistogram)) {\n const n = Number.isFinite(count) && count > 0 ? count : 0\n observedTools += n\n if (n > 0 && input.matches(tool)) matchedCalls += n\n }\n\n if (observedTools === 0) {\n return failOpen\n ? {\n applied: true,\n gated: false,\n reason: 'no tool telemetry captured — fail-open (not quarantined)',\n matchedCalls: 0,\n observedTools: 0,\n }\n : {\n applied: false,\n gated: true,\n reason: 'no tool telemetry captured — fail-closed',\n matchedCalls: 0,\n observedTools: 0,\n }\n }\n\n if (matchedCalls === 0) {\n return {\n applied: false,\n gated: true,\n reason: `treatment tool never fired (${observedTools} tool calls, 0 matched)`,\n matchedCalls: 0,\n observedTools,\n }\n }\n\n return { applied: true, gated: false, matchedCalls, observedTools }\n}\n\n/**\n * Convenience: gate from an already-computed `BehavioralMetrics` (the common\n * case — analysts already hold `computeTraceMetrics(spans)` for the run). Reads\n * the metrics' `toolHistogram`; does no re-derivation.\n */\nexport function gateTreatmentFromMetrics(\n metrics: Pick<BehavioralMetrics, 'toolHistogram'>,\n matches: ToolMatcher,\n opts?: TreatmentGateOptions,\n): TreatmentGate {\n return gateTreatmentApplied({ toolHistogram: metrics.toolHistogram, matches }, opts)\n}\n\n/**\n * Convenience: gate directly from analyst spans, reusing the substrate's\n * deterministic histogram builder. For callers holding the trace store's typed\n * `ToolSpan[]` instead, see {@link gateTreatmentFromToolSpans}.\n */\nexport function gateTreatmentFromSpans(\n spans: readonly TraceAnalystSpan[],\n matches: ToolMatcher,\n opts?: TreatmentGateOptions,\n): TreatmentGate {\n return gateTreatmentFromMetrics(computeTraceMetrics(spans), matches, opts)\n}\n\n/**\n * Convenience: gate from the trace store's canonical `ToolSpan[]` (e.g. the\n * result of `toolSpans(store, runId)`). Counts by `toolName` — the typed\n * tool-call field — so it needs no OTLP attribute extraction.\n */\nexport function gateTreatmentFromToolSpans(\n toolSpans: readonly ToolSpan[],\n matches: ToolMatcher,\n opts?: TreatmentGateOptions,\n): TreatmentGate {\n const toolHistogram: Record<string, number> = {}\n for (const s of toolSpans) {\n if (s.toolName) toolHistogram[s.toolName] = (toolHistogram[s.toolName] ?? 0) + 1\n }\n return gateTreatmentApplied({ toolHistogram, matches }, opts)\n}\n\n/** Measurable runs count toward the objective; treatment-not-applied runs are\n * excluded (like infra-loss), NOT counted as treatment failures. This is a\n * partition over the existing exclusion-flag pattern — it adds no new\n * classification enum. */\nexport type TreatmentClass = 'measurable' | 'treatment-not-applied'\n\n/**\n * Map a gate verdict onto a single measurable-vs-excluded label keyed on a\n * `RunRecord`, so consumers (paired A/B filters, reporters) read the partition\n * in one place instead of re-implementing the fail-open guard inline. The\n * `RunRecord` is accepted so callers key on the canonical run row, mirroring\n * how `outcome.realness.gated` rides along on the record; the verdict itself is\n * the gate's, not re-derived here.\n */\nexport function classifyTreatment(_record: RunRecord, gate: TreatmentGate): TreatmentClass {\n return gate.gated ? 'treatment-not-applied' : 'measurable'\n}\n","/**\n * Worker-driver seed DATA — the knowledge that used to be hardcoded inside\n * `buildWorkerDriverSystemPrompt` (deleted; zero callers), re-expressed as\n * plain data so a driver PROFILE can seed its directive prompt from it and an\n * optimizer (GEPA/DSPy) can then improve on it. A role expressed as a code\n * function can never improve; a role expressed as versionable prompt data can\n * (tangle-network/agent-runtime#694).\n *\n * Two exports:\n * - `WORKER_DRIVER_DOCTRINE` — the \"never write a thin steer\" driving\n * contract: the bar for every instruction a driver sends a worker.\n * - `HARNESS_BRIEFS` — per-harness capability + caveat briefs the driver\n * weaves into its instructions so it drives the worker to exploit what\n * THAT harness can actually do, and never asks for a capability it lacks.\n *\n * Both are seeds, not law: a consumer copies them into its directive prompt\n * registry (e.g. `prompts/<surface>/v0.md`) and optimizes from there.\n */\n\n/**\n * The driving contract a worker-driver directive seeds from. Every message the\n * driver writes is held to this bar; a thin steer is the driver's failure, not\n * the worker's.\n */\nexport const WORKER_DRIVER_DOCTRINE = `You are a DRIVER: a meta-agent whose entire job is to drive a capable coding worker to ACHIEVE A GOAL by writing it precise, high-signal instructions. You do not do the work yourself — you direct the worker to do it, brilliantly, and you hold it to a standard it would not hold itself to.\n\nTHE BAR — non-negotiable. Every instruction you write is dense, specific, and complete. You write the message a world-class engineering lead writes to a strong report: the exact next objective, the concrete sub-steps, what to do in parallel vs in sequence, what to verify and how, what \"done\" looks like, and the failure modes to avoid. A thin steer — \"try again\", \"fix the issues\", a single vague sentence — is a failure on YOUR part, not the worker's. Out-drive a human power-user.\n\nHOW to drive (each turn):\n1. Read what the worker actually did (its trace/state), not what it claims. Find the real gap between here and the goal.\n2. Decide the next objective — the largest correct step the worker can take now.\n3. Decompose it: name the sub-tasks that can run IN PARALLEL (independent files/checks/searches) and tell the worker to fan them out (sub-agents / parallel tool calls where its harness allows); name what must run in SEQUENCE and why.\n4. Make it exploit the harness: drive it to run to completion under its own autonomy, spawn sub-agents for separable work, use its tools/MCP, and not stop at the first plausible stopping point.\n5. Specify verification: the exact command / test / check that proves the step landed, and tell it to run that and report the result — never accept \"done\" without the check.\n6. Name the traps: the specific failure modes for THIS step (editing the wrong file, a check that passes vacuously, scope creep) and forbid them.\n7. As the task gets harder, decompose MORE, not less — more parallel branches, deeper sub-agent trees, tighter verification.\n\nCOMPLETION: drive toward the goal's real acceptance check. Do not declare done — the deliverable's checker does. If the worker claims it is done, drive it to PROVE it with the check; if the check fails, drive the fix.\n\nOutput ONLY your next instruction to the worker — direct, detailed, actionable, in the first person as the driver. No meta-commentary, no preamble.`\n\n/**\n * Capability + caveat briefs per harness, keyed by harness id. Free text so\n * the substrate stays decoupled from any runtime harness type — the keys are\n * the conventional harness ids, but the record accepts any string so a\n * consumer can extend it with its own.\n */\nexport const HARNESS_BRIEFS: Record<string, string> = {\n 'claude-code': [\n '- parallel tool calls in a single turn (batch independent reads/greps/commands)',\n '- parallel Task sub-agents (~10 concurrent) for separable investigation or bulk work; sub-agents cannot spawn sub-agents',\n '- native WebSearch/WebFetch plus MCP servers when configured',\n '- skills, hooks, and slash commands when installed in the workspace',\n '- runs to completion under its own autonomy; drive it NOT to stop at the first plausible stopping point',\n ].join('\\n'),\n codex: [\n '- long-horizon autonomous runs (strong run-to-completion; suited to hours-long missions)',\n '- sandboxed exec with full shell access; MCP servers when configured',\n '- no native sub-agent fan-out: express parallelism as explicit backgrounded commands or sequential decomposition',\n '- structured output via --output-schema when a machine-parsed result is needed',\n ].join('\\n'),\n opencode: [\n '- router-backed: any model the router serves; model choice is a live lever',\n '- tool calls and MCP servers when configured',\n '- no native sub-agent tree; decompose into sequential objectives with explicit verification between them',\n ].join('\\n'),\n 'router-tools': [\n '- a plain tool loop over router chat completions: no autonomy, no sub-agents, no workspace',\n '- every capability must be driven explicitly, one tool call at a time',\n '- keep objectives small and verification immediate; never assume it will continue on its own',\n ].join('\\n'),\n}\n","/**\n * Anti-slop quality judge.\n *\n * Deterministic pattern-based quality check — no LLM call. Catches the\n * 80% of AI slop that every production agent leaks:\n * - Banned phrases (voice-specific: \"delve\", \"it's worth noting\", etc.)\n * - N-gram repetition (same phrase over and over)\n * - Hedging overuse (\"I could be wrong, but...\")\n * - Apology padding (\"I'm so sorry for the confusion...\")\n * - Unused opening formulas (\"Great question!\")\n * - Length bounds (too short to be useful, too long to be read)\n *\n * Produces a JudgeScore in the same shape as LLM judges so it composes into\n * `BenchmarkRunner`'s judge array transparently.\n */\n\nimport type { JudgeFn, JudgeInput, JudgeScore } from './types'\n\nexport interface AntiSlopConfig {\n /** Domain label — appears in the JudgeScore output */\n domain?: string\n\n /** Case-insensitive substrings that must not appear. Each occurrence = penalty. */\n bannedPhrases?: string[]\n\n /** Regexes matching opening formulas to penalize (e.g. /^great question/i). */\n bannedOpenings?: RegExp[]\n\n /** Regexes matching hedges (e.g. /i could be wrong/i). Ratio of hedged sentences drives score. */\n hedgingPatterns?: RegExp[]\n\n /** Regexes matching apology padding. */\n apologyPatterns?: RegExp[]\n\n /** Fraction of sentences that can be duplicates before penalty (default 0.15 = 15%). */\n repetitionThreshold?: number\n\n /** Min output length in chars; below this the turn is deemed too terse. */\n minLength?: number\n\n /** Max output length in chars; above this the turn is deemed too verbose. */\n maxLength?: number\n\n /** How heavily each violation class reduces the score (default 1). */\n penaltyWeights?: Partial<Record<SlopCategory, number>>\n}\n\nexport type SlopCategory =\n | 'banned_phrase'\n | 'banned_opening'\n | 'hedging'\n | 'apology'\n | 'repetition'\n | 'length'\n\nconst DEFAULT_HEDGES: RegExp[] = [\n /\\bi\\s+could\\s+be\\s+wrong\\b/i,\n /\\bi\\s+think\\s+maybe\\b/i,\n /\\bit\\s+might\\s+be\\s+that\\b/i,\n /\\bperhaps\\s+(?:you\\s+)?could\\b/i,\n]\n\nconst DEFAULT_APOLOGIES: RegExp[] = [\n /\\bi\\s+(?:apologize|apologise)\\s+(?:for|if)\\b/i,\n /\\bi'?m\\s+(?:so\\s+|really\\s+)?sorry\\s+(?:for|if|about)\\b/i,\n /\\bmy\\s+apologies\\b/i,\n]\n\n/** Create a reusable Judge function from an anti-slop config. */\nexport function createAntiSlopJudge(config: AntiSlopConfig = {}): JudgeFn {\n const conf: Required<Omit<AntiSlopConfig, 'penaltyWeights'>> & {\n penaltyWeights: Record<SlopCategory, number>\n } = {\n domain: config.domain ?? 'general',\n bannedPhrases: config.bannedPhrases ?? [],\n bannedOpenings: config.bannedOpenings ?? [],\n hedgingPatterns: config.hedgingPatterns ?? DEFAULT_HEDGES,\n apologyPatterns: config.apologyPatterns ?? DEFAULT_APOLOGIES,\n repetitionThreshold: config.repetitionThreshold ?? 0.15,\n minLength: config.minLength ?? 20,\n maxLength: config.maxLength ?? 8000,\n penaltyWeights: {\n banned_phrase: 1,\n banned_opening: 1,\n hedging: 0.5,\n apology: 0.5,\n repetition: 0.75,\n length: 0.5,\n ...config.penaltyWeights,\n },\n }\n\n const judge: JudgeFn = async (_tc, input: JudgeInput): Promise<JudgeScore[]> => {\n const outputs = input.turns.map((t) => t.agentResponse ?? '')\n const report = analyzeAntiSlop(outputs, conf)\n return [\n {\n judgeName: `anti-slop(${conf.domain})`,\n dimension: 'anti_slop',\n score: report.score,\n reasoning: report.issues.length\n ? report.issues\n .slice(0, 5)\n .map((i) => `${i.category}: ${i.detail}`)\n .join('; ')\n : 'No slop patterns detected.',\n evidence: report.issues[0]?.example,\n },\n ]\n }\n return judge\n}\n\nexport interface AntiSlopIssue {\n category: SlopCategory\n detail: string\n example?: string\n}\n\nexport interface AntiSlopReport {\n /** 0–10 score; 10 is clean, lower values mean more slop. */\n score: number\n issues: AntiSlopIssue[]\n /** Count of each category for programmatic aggregation. */\n counts: Record<SlopCategory, number>\n}\n\n/**\n * Pure function — analyze one or more outputs against the config. Exposed\n * separately so consumers can build their own reporters on top.\n */\nexport function analyzeAntiSlop(\n outputs: string[],\n config: Omit<Required<AntiSlopConfig>, 'domain'> & {\n penaltyWeights: Record<SlopCategory, number>\n },\n): AntiSlopReport {\n const issues: AntiSlopIssue[] = []\n const counts: Record<SlopCategory, number> = {\n banned_phrase: 0,\n banned_opening: 0,\n hedging: 0,\n apology: 0,\n repetition: 0,\n length: 0,\n }\n\n for (const output of outputs) {\n if (!output) continue\n const lower = output.toLowerCase()\n\n for (const phrase of config.bannedPhrases) {\n const needle = phrase.toLowerCase()\n let idx = lower.indexOf(needle, 0)\n while (idx !== -1) {\n counts.banned_phrase += 1\n if (issues.length < 20) {\n issues.push({\n category: 'banned_phrase',\n detail: `\"${phrase}\"`,\n example: snippet(output, idx, phrase.length),\n })\n }\n idx = lower.indexOf(needle, idx + needle.length)\n }\n }\n\n for (const re of config.bannedOpenings) {\n if (re.test(output)) {\n counts.banned_opening += 1\n issues.push({ category: 'banned_opening', detail: re.source, example: output.slice(0, 80) })\n }\n }\n\n for (const re of config.hedgingPatterns) {\n const matches = output.match(\n new RegExp(re, re.flags.includes('g') ? re.flags : `${re.flags}g`),\n )\n if (matches) {\n counts.hedging += matches.length\n issues.push({\n category: 'hedging',\n detail: `${matches.length}x ${re.source}`,\n example: matches[0],\n })\n }\n }\n\n for (const re of config.apologyPatterns) {\n const matches = output.match(\n new RegExp(re, re.flags.includes('g') ? re.flags : `${re.flags}g`),\n )\n if (matches) {\n counts.apology += matches.length\n issues.push({\n category: 'apology',\n detail: `${matches.length}x ${re.source}`,\n example: matches[0],\n })\n }\n }\n\n // Repetition: compare sentence-level dupes\n const sentences = splitSentences(output)\n if (sentences.length >= 4) {\n const seen = new Map<string, number>()\n for (const s of sentences) {\n const key = normalizeForDupe(s)\n if (!key) continue\n seen.set(key, (seen.get(key) ?? 0) + 1)\n }\n let dupes = 0\n for (const n of seen.values()) if (n > 1) dupes += n - 1\n const ratio = dupes / sentences.length\n if (ratio > config.repetitionThreshold) {\n counts.repetition += 1\n issues.push({\n category: 'repetition',\n detail: `${(ratio * 100).toFixed(0)}% duplicated (threshold ${(config.repetitionThreshold * 100).toFixed(0)}%)`,\n })\n }\n }\n\n // Length\n if (output.length < config.minLength) {\n counts.length += 1\n issues.push({\n category: 'length',\n detail: `too short (${output.length} < ${config.minLength})`,\n })\n } else if (output.length > config.maxLength) {\n counts.length += 1\n issues.push({\n category: 'length',\n detail: `too long (${output.length} > ${config.maxLength})`,\n })\n }\n }\n\n // Score: 10 minus weighted violations, clamped. Each violation of category c\n // subtracts `penaltyWeights[c]` points. Violations beyond 10/weight saturate.\n let penalty = 0\n for (const cat of Object.keys(counts) as SlopCategory[]) {\n penalty += counts[cat] * (config.penaltyWeights[cat] ?? 1)\n }\n const score = Math.max(0, Math.min(10, 10 - penalty))\n\n return { score, issues, counts }\n}\n\nfunction snippet(source: string, at: number, len: number): string {\n const pad = 24\n const start = Math.max(0, at - pad)\n const end = Math.min(source.length, at + len + pad)\n return (start > 0 ? '…' : '') + source.slice(start, end) + (end < source.length ? '…' : '')\n}\n\nfunction splitSentences(text: string): string[] {\n // Simple sentence split — good enough for slop detection; not linguistically perfect.\n return text\n .split(/[.!?\\n]+/)\n .map((s) => s.trim())\n .filter((s) => s.length > 0)\n}\n\nfunction normalizeForDupe(s: string): string {\n return s\n .toLowerCase()\n .replace(/\\s+/g, ' ')\n .replace(/[^a-z0-9 ]/g, '')\n .trim()\n}\n","/**\n * Artifact validators.\n *\n * Generic \"score a produced artifact\" primitive. Tax uses it for PDF form\n * correctness, research for sourced briefs, browser for task assertions, coding\n * for social posts. One interface, many validators; all plug into\n * `BenchmarkRunner` the same way.\n *\n * A validator receives an `Artifact` (file on disk, JSON blob, text, binary)\n * plus a `ValidationContext` (scenario id, the turns that produced it) and\n * returns a `ValidationResult` with pass/fail + 0..1 score + structured\n * issues.\n */\n\nexport interface Artifact {\n /** Logical kind — validators type-guard on this */\n kind: 'file' | 'json' | 'text' | 'binary' | string\n /** Filesystem-style path, optional */\n path?: string\n /** String content for text/json/file kinds */\n content?: string\n /** Binary content (if kind === 'binary') */\n bytes?: Uint8Array\n /** Caller-supplied metadata (mimeType, sha256, size, etc.) */\n metadata?: Record<string, unknown>\n}\n\nexport interface ValidationContext {\n scenarioId: string\n turnIndex?: number\n /** Prior artifacts for multi-artifact scenarios */\n priorArtifacts?: Artifact[]\n /** Free-form hints the validator uses for domain-specific checks */\n hints?: Record<string, unknown>\n}\n\nexport interface ValidationIssue {\n severity: 'error' | 'warning' | 'info'\n message: string\n /** Optional path into the artifact (e.g. JSON path or byte offset) */\n locus?: string\n}\n\nexport interface ValidationResult {\n pass: boolean\n /** 0–1 normalized score. Validators should be monotonic in pass-ness. */\n score: number\n issues: ValidationIssue[]\n /** Diagnostic payload for reporters */\n evidence?: Record<string, unknown>\n}\n\nexport interface ArtifactValidator {\n /** Stable identifier for the validator; appears in reports. */\n name: string\n /** Optional description for human-facing reports. */\n description?: string\n /** Called once per artifact; validators are expected to be pure + idempotent. */\n validate(artifact: Artifact, context: ValidationContext): Promise<ValidationResult>\n}\n\n// ---------------------------------------------------------------------------\n// Composable validators\n// ---------------------------------------------------------------------------\n\n/**\n * Run every validator on the same artifact; aggregate pass as AND, score as\n * (weighted) mean, issues concatenated. Weights default to 1 each.\n */\nexport function composeValidators(\n validators: ArtifactValidator[],\n options?: { name?: string; weights?: number[] },\n): ArtifactValidator {\n const weights = options?.weights ?? validators.map(() => 1)\n if (weights.length !== validators.length) {\n throw new Error('composeValidators: weights length mismatch')\n }\n const totalWeight = weights.reduce((a, b) => a + b, 0) || 1\n return {\n name: options?.name ?? validators.map((v) => v.name).join('+'),\n async validate(artifact, ctx) {\n const results = await Promise.all(validators.map((v) => v.validate(artifact, ctx)))\n const pass = results.every((r) => r.pass)\n const score = results.reduce((acc, r, i) => acc + r.score * weights[i]!, 0) / totalWeight\n return {\n pass,\n score,\n issues: results.flatMap((r, i) =>\n r.issues.map((issue) => ({\n ...issue,\n locus: issue.locus ? `${validators[i]!.name}:${issue.locus}` : validators[i]!.name,\n })),\n ),\n evidence: Object.fromEntries(results.map((r, i) => [validators[i]!.name, r.evidence])),\n }\n },\n }\n}\n\n// ---------------------------------------------------------------------------\n// Built-in validators\n// ---------------------------------------------------------------------------\n\n/** Pass if the artifact body matches a provided regex. */\nexport function regexMatch(name: string, pattern: RegExp): ArtifactValidator {\n return {\n name,\n async validate(artifact) {\n const body = artifact.content ?? ''\n const ok = pattern.test(body)\n return {\n pass: ok,\n score: ok ? 1 : 0,\n issues: ok\n ? []\n : [{ severity: 'error', message: `Artifact content did not match ${pattern}` }],\n }\n },\n }\n}\n\n/** Pass if JSON parses and every required key is present. */\nexport function jsonHasKeys(name: string, requiredPaths: string[]): ArtifactValidator {\n return {\n name,\n async validate(artifact) {\n const body = artifact.content ?? ''\n let parsed: unknown\n try {\n parsed = JSON.parse(body) as unknown\n } catch (err) {\n return {\n pass: false,\n score: 0,\n issues: [\n {\n severity: 'error',\n message: `Invalid JSON: ${err instanceof Error ? err.message : err}`,\n },\n ],\n }\n }\n const missing: string[] = []\n for (const path of requiredPaths) {\n if (!pathExists(parsed, path)) missing.push(path)\n }\n const pass = missing.length === 0\n return {\n pass,\n score: 1 - missing.length / Math.max(1, requiredPaths.length),\n issues: missing.map((p) => ({\n severity: 'error' as const,\n message: `Missing path: ${p}`,\n locus: p,\n })),\n }\n },\n }\n}\n\n/** Pass if min ≤ byte length ≤ max. */\nexport function byteLengthRange(name: string, min: number, max: number): ArtifactValidator {\n return {\n name,\n async validate(artifact) {\n const size =\n artifact.bytes?.byteLength ?? new TextEncoder().encode(artifact.content ?? '').byteLength\n const pass = size >= min && size <= max\n const score = pass ? 1 : size < min ? Math.max(0, size / min) : Math.max(0, max / size)\n return {\n pass,\n score,\n issues: pass\n ? []\n : [{ severity: 'error', message: `Size ${size} outside [${min}, ${max}]` }],\n }\n },\n }\n}\n\n/** Pass if the artifact contains every required substring (case-insensitive by default). */\nexport function containsAll(\n name: string,\n required: string[],\n options?: { caseSensitive?: boolean },\n): ArtifactValidator {\n const cs = options?.caseSensitive ?? false\n return {\n name,\n async validate(artifact) {\n const body = cs ? (artifact.content ?? '') : (artifact.content ?? '').toLowerCase()\n const missing: string[] = []\n for (const needle of required) {\n const probe = cs ? needle : needle.toLowerCase()\n if (!body.includes(probe)) missing.push(needle)\n }\n const pass = missing.length === 0\n return {\n pass,\n score: 1 - missing.length / Math.max(1, required.length),\n issues: missing.map((m) => ({\n severity: 'error' as const,\n message: `Missing substring: ${m}`,\n })),\n }\n },\n }\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction pathExists(obj: unknown, path: string): boolean {\n const parts = path.split('.')\n let current: unknown = obj\n for (const part of parts) {\n if (current === null || typeof current !== 'object') return false\n const key = /^\\d+$/.test(part) ? Number(part) : part\n current = (current as Record<string, unknown>)[key as unknown as string]\n if (current === undefined) return false\n }\n return true\n}\n","/**\n * Dual-agent convergence bench.\n *\n * Pattern lifted from dual-worker review loops: two agents take turns until\n * they converge on a consensus artifact. One proposes, the other critiques;\n * the proposer revises; repeat until a score threshold is hit or max rounds.\n *\n * Generalized so any two \"agents\" (gateways, local functions, anything with\n * `propose` + `critique`) compose in. Returns convergence rounds per\n * scenario + whether convergence happened.\n */\n\nexport interface DualAgentScenario {\n id: string\n initialPrompt: string\n /** Optional context the agents can read (e.g. source documents). */\n context?: Record<string, unknown>\n}\n\nexport interface DualAgentRound {\n roundIndex: number\n proposal: string\n critique: string\n convergenceScore: number // 0..1 — how close to convergence\n}\n\nexport interface DualAgentScenarioResult {\n scenarioId: string\n converged: boolean\n roundsToConverge: number | null\n finalProposal: string\n history: DualAgentRound[]\n finalScore: number\n}\n\nexport interface DualAgentBenchConfig {\n scenarios: DualAgentScenario[]\n maxRounds?: number\n /** Convergence threshold in 0..1 (default 0.85). */\n convergenceThreshold?: number\n /**\n * Propose an answer given the scenario + the critic's prior critique (if any).\n * Returns the proposal string.\n */\n propose: (args: {\n scenario: DualAgentScenario\n roundIndex: number\n priorProposal?: string\n priorCritique?: string\n }) => Promise<string>\n /**\n * Critique the proposer's current output. Returns a structured critique\n * (free text) plus a convergence score: how close the proposal is to\n * acceptable. 1.0 = accept, 0.0 = totally off.\n */\n critique: (args: {\n scenario: DualAgentScenario\n roundIndex: number\n proposal: string\n }) => Promise<{ critique: string; convergenceScore: number }>\n /** Optional per-round hook for progress + tracing. */\n onRoundComplete?: (info: { scenarioId: string; round: DualAgentRound }) => void\n}\n\nexport interface DualAgentReport {\n scenarios: DualAgentScenarioResult[]\n aggregate: {\n convergenceRate: number // fraction of scenarios that converged within maxRounds\n avgRoundsToConverge: number | null // over scenarios that DID converge\n avgFinalScore: number\n }\n config: {\n maxRounds: number\n convergenceThreshold: number\n }\n}\n\nexport class DualAgentBench {\n async run(config: DualAgentBenchConfig): Promise<DualAgentReport> {\n const maxRounds = config.maxRounds ?? 5\n const threshold = config.convergenceThreshold ?? 0.85\n\n if (config.scenarios.length === 0) {\n throw new Error('DualAgentBench requires at least 1 scenario')\n }\n\n const results: DualAgentScenarioResult[] = []\n\n for (const scenario of config.scenarios) {\n const history: DualAgentRound[] = []\n let converged = false\n let roundsToConverge: number | null = null\n let finalProposal = ''\n let lastScore = 0\n let priorCritique: string | undefined\n\n for (let r = 0; r < maxRounds; r++) {\n const priorProposal = history[history.length - 1]?.proposal\n const proposal = await config.propose({\n scenario,\n roundIndex: r,\n priorProposal,\n priorCritique,\n })\n const { critique, convergenceScore } = await config.critique({\n scenario,\n roundIndex: r,\n proposal,\n })\n\n if (!Number.isFinite(convergenceScore) || convergenceScore < 0 || convergenceScore > 1) {\n throw new Error(\n `critique must return convergenceScore in [0,1]; got ${convergenceScore} for scenario ${scenario.id} round ${r}`,\n )\n }\n\n const round: DualAgentRound = {\n roundIndex: r,\n proposal,\n critique,\n convergenceScore,\n }\n history.push(round)\n config.onRoundComplete?.({ scenarioId: scenario.id, round })\n\n finalProposal = proposal\n lastScore = convergenceScore\n priorCritique = critique\n\n if (convergenceScore >= threshold) {\n converged = true\n roundsToConverge = r + 1\n break\n }\n }\n\n results.push({\n scenarioId: scenario.id,\n converged,\n roundsToConverge,\n finalProposal,\n history,\n finalScore: lastScore,\n })\n }\n\n const convergedResults = results.filter((r) => r.converged)\n const convergenceRate = results.length ? convergedResults.length / results.length : 0\n const avgRoundsToConverge = convergedResults.length\n ? convergedResults.reduce((acc, r) => acc + (r.roundsToConverge ?? 0), 0) /\n convergedResults.length\n : null\n const avgFinalScore = results.length\n ? results.reduce((acc, r) => acc + r.finalScore, 0) / results.length\n : 0\n\n return {\n scenarios: results,\n aggregate: { convergenceRate, avgRoundsToConverge, avgFinalScore },\n config: { maxRounds, convergenceThreshold: threshold },\n }\n }\n}\n","/**\n * Eval primitives as agent tools — `makeEvalTools` packages the substrate's\n * judge / completion / analysis entry points as JSON-Schema tool definitions\n * an LLM agent loop can call. The host closes over the live config (judge\n * panels, the correctness checker, analyst registry); the agent passes only\n * data over the wire.\n *\n * Three tools, each present only when its config section is supplied:\n * - `run_judges` — score an artifact with the configured `JudgeConfig`s\n * - `verify_completion` — gold-spec requirement check → `CompletionVerdict`\n * - `analyze_runs` — `RunRecord[]` (inline or from a file) → `InsightReport`\n *\n * `toOpenAiTool` converts a definition to the OpenAI function-tool wire shape.\n */\n\nimport { readFile } from 'node:fs/promises'\nimport type { JudgeConfig, JudgeScore, Scenario } from './campaign/types'\nimport {\n type CompletionVerdict,\n type CorrectnessChecker,\n type ProducedState,\n type TaskGold,\n verifyCompletion,\n} from './completion-verifier'\nimport { type AnalyzeRunsOptions, analyzeRuns } from './contract/analyze-runs'\nimport type { RunRecord } from './run-record'\n\n/** One agent-callable tool. `parameters` is a JSON Schema (draft-07+) object. */\nexport interface EvalToolDef {\n name: string\n description: string\n parameters: Record<string, unknown>\n handler: (args: unknown, ctx?: { signal?: AbortSignal }) => Promise<unknown>\n}\n\nexport interface MakeEvalToolsConfig {\n /** Judges available to `run_judges`. Omit to exclude the tool. */\n judges?: Array<JudgeConfig<unknown>>\n /** Host-side correctness checker for `verify_completion` (the third\n * `verifyCompletion` argument — a function, so it cannot cross the wire).\n * Omit to exclude the tool. */\n completion?: { checkCorrectness: CorrectnessChecker }\n /** `analyzeRuns` options minus `runs` (runs arrive as tool args, inline or\n * via `path`). Omit to exclude the tool. */\n analyze?: Omit<AnalyzeRunsOptions, 'runs'>\n}\n\n/** OpenAI function-tool wire shape for an `EvalToolDef`. */\nexport function toOpenAiTool(def: EvalToolDef): {\n type: 'function'\n function: { name: string; description: string; parameters: Record<string, unknown> }\n} {\n return {\n type: 'function',\n function: { name: def.name, description: def.description, parameters: def.parameters },\n }\n}\n\n/**\n * Build the eval toolset for the supplied config. Only sections present in\n * `cfg` produce tools, so the agent's tool list mirrors what the host\n * actually wired. Handlers fail loud on malformed args — no silent defaults.\n */\nexport function makeEvalTools(cfg: MakeEvalToolsConfig): EvalToolDef[] {\n const tools: EvalToolDef[] = []\n if (cfg.judges) tools.push(runJudgesTool(cfg.judges))\n if (cfg.completion) tools.push(verifyCompletionTool(cfg.completion.checkCorrectness))\n if (cfg.analyze) tools.push(analyzeRunsTool(cfg.analyze))\n return tools\n}\n\n// ── run_judges ───────────────────────────────────────────────────────────\n\nfunction runJudgesTool(judges: Array<JudgeConfig<unknown>>): EvalToolDef {\n if (judges.length === 0) {\n throw new Error('makeEvalTools: cfg.judges is empty — supply judges or omit the section')\n }\n const names = judges.map((j) => j.name)\n return {\n name: 'run_judges',\n description:\n `Score an artifact with the configured judges (${names.join(', ')}). ` +\n 'Pass `judge` to run one judge by name; omit it to run all. ' +\n 'Returns per-judge scores keyed by judge name.',\n parameters: {\n type: 'object',\n properties: {\n judge: {\n type: 'string',\n enum: names,\n description: 'Run only this judge. Omit to run every configured judge.',\n },\n artifact: {\n description: 'The artifact to score — any JSON value the judges understand.',\n },\n scenario: {\n description: 'Optional scenario context forwarded to the judges.',\n },\n },\n required: ['artifact'],\n additionalProperties: false,\n },\n handler: async (args, ctx) => {\n const a = requireObjectArgs('run_judges', args)\n if (!('artifact' in a)) {\n throw new Error('run_judges: args.artifact is required')\n }\n let selected = judges\n if (a.judge !== undefined) {\n if (typeof a.judge !== 'string') throw new Error('run_judges: args.judge must be a string')\n selected = judges.filter((j) => j.name === a.judge)\n if (selected.length === 0) {\n throw new Error(\n `run_judges: unknown judge '${a.judge}' — configured: ${names.join(', ')}`,\n )\n }\n }\n const signal = ctx?.signal ?? new AbortController().signal\n const scenario = a.scenario as Scenario\n const scores: Record<string, JudgeScore> = {}\n for (const judge of selected) {\n if (scenario !== undefined && judge.appliesTo && !judge.appliesTo(scenario)) continue\n scores[judge.name] = await judge.score({ artifact: a.artifact, scenario, signal })\n }\n return { scores }\n },\n }\n}\n\n// ── verify_completion ────────────────────────────────────────────────────\n\nfunction verifyCompletionTool(checkCorrectness: CorrectnessChecker): EvalToolDef {\n return {\n name: 'verify_completion',\n description:\n 'Verify produced state against a gold task spec: each gold requirement is ' +\n 'matched to at most one produced artifact/proposal/tool-call, correctness-checked ' +\n 'by the host, and reduced to a CompletionVerdict (completionRate, fullyComplete, ' +\n 'per-requirement checks).',\n parameters: {\n type: 'object',\n properties: {\n gold: {\n type: 'object',\n description: 'TaskGold — taskId + requirements the produced state must satisfy.',\n },\n state: {\n type: 'object',\n description: 'ProducedState — artifacts, proposals, and tool calls the agent produced.',\n },\n },\n required: ['gold', 'state'],\n additionalProperties: false,\n },\n handler: async (args): Promise<CompletionVerdict> => {\n const a = requireObjectArgs('verify_completion', args)\n if (typeof a.gold !== 'object' || a.gold === null) {\n throw new Error('verify_completion: args.gold (TaskGold) is required')\n }\n if (typeof a.state !== 'object' || a.state === null) {\n throw new Error('verify_completion: args.state (ProducedState) is required')\n }\n return verifyCompletion(a.gold as TaskGold, a.state as ProducedState, checkCorrectness)\n },\n }\n}\n\n// ── analyze_runs ─────────────────────────────────────────────────────────\n\nfunction analyzeRunsTool(analyzeOpts: Omit<AnalyzeRunsOptions, 'runs'>): EvalToolDef {\n return {\n name: 'analyze_runs',\n description:\n 'Run analyzeRuns over a set of RunRecords and return the InsightReport ' +\n '(composite distribution, per-dimension stats, lift, failure clusters, ' +\n 'recommendations). Pass the records inline via `runs`, or `path` to a ' +\n '.json (array) or .jsonl (one record per line) file on the host.',\n parameters: {\n type: 'object',\n properties: {\n runs: {\n type: 'array',\n items: { type: 'object' },\n description: 'RunRecord[] inline.',\n },\n path: {\n type: 'string',\n description: 'Host path to a JSON array or JSONL file of RunRecords.',\n },\n },\n additionalProperties: false,\n },\n handler: async (args) => {\n const a = requireObjectArgs('analyze_runs', args)\n const hasRuns = Array.isArray(a.runs)\n const hasPath = typeof a.path === 'string' && a.path.length > 0\n if (hasRuns === hasPath) {\n throw new Error('analyze_runs: pass exactly one of args.runs (array) or args.path (string)')\n }\n const runs = hasRuns ? (a.runs as RunRecord[]) : await loadRunRecords(a.path as string)\n if (runs.length === 0) {\n throw new Error('analyze_runs: no runs to analyze')\n }\n return analyzeRuns({ ...analyzeOpts, runs })\n },\n }\n}\n\nasync function loadRunRecords(path: string): Promise<RunRecord[]> {\n const text = await readFile(path, 'utf8')\n const trimmed = text.trim()\n if (trimmed.length === 0) {\n throw new Error(`analyze_runs: file '${path}' is empty`)\n }\n if (trimmed.startsWith('[')) {\n const parsed = JSON.parse(trimmed) as unknown\n if (!Array.isArray(parsed)) {\n throw new Error(`analyze_runs: file '${path}' did not parse to an array`)\n }\n return parsed as RunRecord[]\n }\n // JSONL: one record per non-empty line. A malformed line throws with its\n // line number rather than being skipped.\n return trimmed.split('\\n').flatMap((line, i) => {\n const l = line.trim()\n if (l.length === 0) return []\n try {\n return [JSON.parse(l) as RunRecord]\n } catch (err) {\n throw new Error(\n `analyze_runs: file '${path}' line ${i + 1} is not valid JSON: ${err instanceof Error ? err.message : String(err)}`,\n )\n }\n })\n}\n\nfunction requireObjectArgs(tool: string, args: unknown): Record<string, unknown> {\n if (typeof args !== 'object' || args === null || Array.isArray(args)) {\n throw new Error(`${tool}: args must be an object`)\n }\n return args as Record<string, unknown>\n}\n","import { type Objective, type ParetoResult, paretoFrontier } from './pareto'\nimport { RunCritic, type RunTrace } from './run-critic'\nimport { aggregateRunScore, type RunScore, type RunScoreWeights } from './run-score'\nimport type { SteeringBundle } from './steering'\n\nexport type HarnessIntervention =\n | 'continue'\n | 'plan'\n | 'audit'\n | 'recover'\n | 'repair'\n | 'verify'\n | 'final_gate'\n | 'wait_for_measurement'\n | 'abort'\n\nexport interface WorkflowTopology {\n id: string\n interventions: HarnessIntervention[]\n maxParallelBranches?: number\n metadata?: Record<string, unknown>\n}\n\nexport interface MeasurementPolicy {\n required: string[]\n optional?: string[]\n promoteOn?: Array<keyof RunScore | 'aggregate'>\n}\n\nexport interface HarnessVariant {\n id: string\n steering?: SteeringBundle\n topology?: WorkflowTopology\n measurement?: MeasurementPolicy\n budgets?: Record<string, number>\n models?: Record<string, string>\n reviewers?: Record<string, string>\n metadata?: Record<string, unknown>\n}\n\nexport interface HarnessScenario {\n id: string\n task: string\n split?: 'train' | 'validation' | 'test' | string\n metadata?: Record<string, unknown>\n}\n\nexport interface HarnessRunRequest {\n variant: HarnessVariant\n scenario: HarnessScenario\n trialIndex: number\n}\n\nexport interface HarnessAdapter {\n run(request: HarnessRunRequest): Promise<RunTrace>\n}\n\nexport interface HarnessRunResult {\n variant: HarnessVariant\n scenario: HarnessScenario\n trialIndex: number\n trace: RunTrace\n score: RunScore\n aggregate: number\n}\n\nexport interface HarnessVariantReport {\n variant: HarnessVariant\n runs: HarnessRunResult[]\n aggregateMean: number\n passRate: number\n costUsdMean: number\n wallSecondsMean: number\n scoreMean: RunScore\n}\n\nexport interface HarnessSelection {\n winner: HarnessVariantReport\n frontier: ParetoResult<HarnessVariantReport>\n reports: HarnessVariantReport[]\n}\n\nexport interface HarnessExperimentResult {\n results: HarnessRunResult[]\n selection: HarnessSelection\n}\n\nexport interface HarnessExperimentConfig {\n adapter: HarnessAdapter\n variants: HarnessVariant[]\n scenarios: HarnessScenario[]\n trialsPerScenario?: number\n parallelism?: number\n weights?: Partial<RunScoreWeights>\n objectives?: Array<Objective<HarnessVariantReport>>\n score?: (trace: RunTrace, request: HarnessRunRequest) => RunScore | Promise<RunScore>\n onResult?: (result: HarnessRunResult) => void | Promise<void>\n}\n\nexport const DEFAULT_HARNESS_OBJECTIVES: Array<Objective<HarnessVariantReport>> = [\n { name: 'aggregate', direction: 'maximize', value: (r) => r.aggregateMean },\n { name: 'pass_rate', direction: 'maximize', value: (r) => r.passRate },\n { name: 'cost', direction: 'minimize', value: (r) => r.costUsdMean },\n { name: 'wall', direction: 'minimize', value: (r) => r.wallSecondsMean },\n]\n\nexport async function runHarnessExperiment(\n config: HarnessExperimentConfig,\n): Promise<HarnessExperimentResult> {\n const jobs = buildJobs(config)\n const critic = new RunCritic({ weights: config.weights })\n const score = config.score ?? ((trace: RunTrace) => critic.scoreTrace(trace))\n const results = await mapLimit(jobs, config.parallelism ?? 1, async (request) => {\n const trace = await config.adapter.run(request)\n const runScore = await score(trace, request)\n const result: HarnessRunResult = {\n variant: request.variant,\n scenario: request.scenario,\n trialIndex: request.trialIndex,\n trace,\n score: runScore,\n aggregate: aggregateRunScore(runScore, config.weights),\n }\n await config.onResult?.(result)\n return result\n })\n return { results, selection: selectHarnessVariant(results, config.objectives) }\n}\n\nexport function selectHarnessVariant(\n results: HarnessRunResult[],\n objectives: Array<Objective<HarnessVariantReport>> = DEFAULT_HARNESS_OBJECTIVES,\n): HarnessSelection {\n const reports = summarizeHarnessResults(results)\n if (reports.length === 0) throw new Error('selectHarnessVariant: no results')\n const frontier = paretoFrontier(reports, objectives)\n const candidates = frontier.frontier.length ? frontier.frontier : reports\n const winner = [...candidates].sort((a, b) => b.aggregateMean - a.aggregateMean)[0]\n if (!winner) throw new Error('selectHarnessVariant: no winner')\n return { winner, frontier, reports }\n}\n\nexport function summarizeHarnessResults(results: HarnessRunResult[]): HarnessVariantReport[] {\n const byVariant = new Map<string, HarnessRunResult[]>()\n for (const result of results) {\n byVariant.set(result.variant.id, [...(byVariant.get(result.variant.id) ?? []), result])\n }\n return [...byVariant.values()]\n .map((runs) => {\n const variant = runs[0]?.variant\n if (!variant) throw new Error('summarizeHarnessResults: empty variant bucket')\n return {\n variant,\n runs,\n aggregateMean: mean(runs.map((r) => r.aggregate)),\n passRate: mean(runs.map((r) => r.score.success)),\n costUsdMean: mean(runs.map((r) => r.score.costUsd)),\n wallSecondsMean: mean(runs.map((r) => r.score.wallSeconds)),\n scoreMean: meanRunScore(runs.map((r) => r.score)),\n }\n })\n .sort((a, b) => b.aggregateMean - a.aggregateMean)\n}\n\nfunction buildJobs(config: HarnessExperimentConfig): HarnessRunRequest[] {\n if (config.variants.length === 0)\n throw new Error('runHarnessExperiment: at least one variant required')\n if (config.scenarios.length === 0)\n throw new Error('runHarnessExperiment: at least one scenario required')\n const trials = Math.max(1, Math.floor(config.trialsPerScenario ?? 1))\n const jobs: HarnessRunRequest[] = []\n for (const variant of config.variants) {\n for (const scenario of config.scenarios) {\n for (let trialIndex = 0; trialIndex < trials; trialIndex++) {\n jobs.push({ variant, scenario, trialIndex })\n }\n }\n }\n return jobs\n}\n\nasync function mapLimit<T, R>(\n items: T[],\n limit: number,\n fn: (item: T) => Promise<R>,\n): Promise<R[]> {\n const results: R[] = new Array(items.length)\n let next = 0\n const workerCount = Math.max(1, Math.min(Math.floor(limit), items.length))\n await Promise.all(\n Array.from({ length: workerCount }, async () => {\n while (next < items.length) {\n const index = next++\n const item = items[index]\n if (item === undefined) continue\n results[index] = await fn(item)\n }\n }),\n )\n return results\n}\n\nfunction mean(values: number[]): number {\n return values.length ? values.reduce((sum, value) => sum + value, 0) / values.length : 0\n}\n\nfunction meanRunScore(scores: RunScore[]): RunScore {\n return {\n success: mean(scores.map((s) => s.success)),\n goalProgress: mean(scores.map((s) => s.goalProgress)),\n repoGroundedness: mean(scores.map((s) => s.repoGroundedness)),\n driftPenalty: mean(scores.map((s) => s.driftPenalty)),\n toolUseQuality: mean(scores.map((s) => s.toolUseQuality)),\n patchQuality: mean(scores.map((s) => s.patchQuality)),\n testReality: mean(scores.map((s) => s.testReality)),\n finalGate: mean(scores.map((s) => s.finalGate)),\n reviewerBlockers: mean(scores.map((s) => s.reviewerBlockers)),\n costUsd: mean(scores.map((s) => s.costUsd)),\n wallSeconds: mean(scores.map((s) => s.wallSeconds)),\n notes: scores.flatMap((s) => s.notes ?? []),\n }\n}\n","/**\n * Judge-ensemble reducer — folds N independent judge verdicts on the same\n * artifact into one aggregate score.\n *\n * The pattern every multi-model judge re-implements: run K uncorrelated judges\n * (different model families remove within-family bias), then reduce their\n * per-dimension verdicts to a single composite + an inter-rater disagreement\n * signal. This is the pure reduction — no LLM, no I/O — so a lift it produces\n * is attributable to the scores, not to where they came from.\n *\n * Fail-loud: a judge that errored or returned malformed output is recorded in\n * `failedJudges` with `perDimension: null`, never folded into a zero. If EVERY\n * judge failed the reducer throws — a silent zero here would corrupt the result.\n */\n\nimport type { LlmUsage } from './llm-client'\nimport { clamp01 } from './run-score'\nimport { weightedComposite } from './statistics'\n\n/** One judge's verdict. `perDimension: null` ⇒ that judge call failed (threw or\n * returned malformed output) — recorded, never folded into a zero. */\nexport interface JudgeVerdict<D extends string = string> {\n /** Judge identity (typically the model id) — the `perJudge` / `failedJudges` key. */\n model: string\n /** Per-dimension scores, or `null` when the judge failed. */\n perDimension: Record<D, number> | null\n /** Optional one-line rationale; the first non-empty one becomes the aggregate's. */\n rationale?: string\n /** Optional reported cost, committed by the caller's CostLedger. */\n costUsd?: number\n /** Optional provider usage, committed by the caller's CostLedger. */\n usage?: LlmUsage\n /** Optional per-dimension reasoning/evidence. Carried through to\n * `EnsembleAggregate.verdicts` verbatim — never folded into the math. */\n detail?: Partial<Record<D, { reasoning?: string; evidence?: string }>>\n}\n\n/** The aggregated ensemble result. */\nexport interface EnsembleAggregate<D extends string = string> {\n /** Mean over SURVIVING judges, per dimension (absent-everywhere ⇒ 0). */\n perDimension: Record<D, number>\n /** Weighted mean of `perDimension` (uniform unless `weights` given). */\n composite: number\n /** Each surviving judge's clamped per-dimension scores, for trace drill-down. */\n perJudge: Record<string, Record<D, number>>\n /** Max over dimensions of (max − min) across survivors — the inter-rater signal. */\n maxDisagreement: number\n /** Models whose verdict was null (failed). */\n failedJudges: string[]\n /** First non-empty survivor rationale, or `'llm-judge'`. */\n rationale: string\n /** The input verdicts, verbatim — drill-down to raw scores, `detail`\n * reasoning/evidence, and per-verdict cost without re-running judges. */\n verdicts: JudgeVerdict<D>[]\n}\n\n/**\n * Reduce per-judge verdicts to one aggregate. Generic over the rubric: pass the\n * stable-ordered `dimensionKeys` the judges scored.\n *\n * - Per-dimension score = mean over surviving judges (out-of-range clamped to [0,1]).\n * - `composite` = `weightedComposite` of `perDimension`. No `weights` ⇒ uniform\n * over every dimension. A partial `weights` map selects AND weights exactly the\n * named dimensions (others excluded from the composite) — the substrate's\n * sum-normalized weighting, not re-implemented here.\n * - Throws if `verdicts` or `dimensionKeys` is empty, or if every judge failed.\n */\nexport function aggregateJudgeVerdicts<D extends string>(\n verdicts: readonly JudgeVerdict<D>[],\n dimensionKeys: readonly D[],\n weights?: Partial<Record<D, number>>,\n): EnsembleAggregate<D> {\n if (verdicts.length === 0) {\n throw new Error('aggregateJudgeVerdicts: no verdicts to aggregate')\n }\n if (dimensionKeys.length === 0) {\n throw new Error('aggregateJudgeVerdicts: dimensionKeys is empty')\n }\n\n const perJudge: Record<string, Record<D, number>> = {}\n const failedJudges: string[] = []\n const dimAcc = {} as Record<D, number[]>\n for (const d of dimensionKeys) dimAcc[d] = []\n let rationale = ''\n\n // Same model sampled k times (best-of-N judging) gets keys 'm', 'm#2',\n // 'm#3'… so repeat votes land as distinct perJudge/failedJudges entries\n // instead of overwriting each other.\n const seenCount = new Map<string, number>()\n const keyFor = (model: string): string => {\n const n = (seenCount.get(model) ?? 0) + 1\n seenCount.set(model, n)\n return n === 1 ? model : `${model}#${n}`\n }\n\n for (const v of verdicts) {\n const key = keyFor(v.model)\n if (!v.perDimension) {\n failedJudges.push(key)\n continue\n }\n const dims = {} as Record<D, number>\n for (const d of dimensionKeys) dims[d] = clamp01(Number(v.perDimension[d]))\n perJudge[key] = dims\n for (const d of dimensionKeys) dimAcc[d].push(dims[d])\n if (!rationale && typeof v.rationale === 'string' && v.rationale) rationale = v.rationale\n }\n\n if (failedJudges.length === verdicts.length) {\n throw new Error(`aggregateJudgeVerdicts: all ${verdicts.length} judges failed`)\n }\n\n const perDimension = {} as Record<D, number>\n for (const d of dimensionKeys) {\n const vals = dimAcc[d]\n perDimension[d] = vals.length === 0 ? 0 : vals.reduce((s, x) => s + x, 0) / vals.length\n }\n\n let maxDisagreement = 0\n for (const d of dimensionKeys) {\n const vals = dimAcc[d]\n if (vals.length < 2) continue\n const spread = Math.max(...vals) - Math.min(...vals)\n if (spread > maxDisagreement) maxDisagreement = spread\n }\n\n const w: Record<string, number> = {}\n if (weights) {\n for (const [d, weight] of Object.entries(weights)) {\n if (weight !== undefined) w[d] = weight as number\n }\n } else {\n for (const d of dimensionKeys) w[d] = 1 / dimensionKeys.length\n }\n const composite = weightedComposite({ dims: perDimension, weights: w }).composite\n\n return {\n perDimension,\n composite,\n perJudge,\n maxDisagreement,\n failedJudges,\n rationale: rationale || 'llm-judge',\n verdicts: [...verdicts],\n }\n}\n","/**\n * Wrap a single judge LLM call with retry, optional fallback-model\n * rotation, exponential backoff, and a typed `JudgeRetryOutcome`. Callers\n * MUST inspect `succeeded` before using `value`; on failure the library\n * returns `value: null` rather than substituting a default, so a judge\n * abort cannot silently corrupt a downstream composite.\n *\n * Reporting contract: callers ship `TrialResult.judgeSucceeded = succeeded`\n * and `TrialResult.judgeAttempts = attempts` so `aggregateTrialsByMode`\n * with `mode: 'exclude-failed'` drops the trial.\n */\n\nimport { backoffMs, isTransientLlmError } from './llm-client'\n\n/** Retry policy for judge LLM calls. */\nexport interface JudgeRetryPolicy {\n /** Max attempts per model. Default 3 (one initial + two retries). */\n maxAttempts?: number\n /** Per-attempt timeout in ms. Default 300_000. */\n timeoutMs?: number\n /**\n * Models to try, in order. The first model is the primary; subsequent\n * models are fallbacks invoked only when ALL retries on the previous\n * model have been exhausted. Example: `['claude-code/sonnet', 'kimi-code/k2p6']`\n * runs claude-code up to maxAttempts times, then falls back to kimi.\n * If omitted, the caller's judge function controls model selection and\n * the retries apply to that single model.\n */\n models?: readonly string[]\n /** Exponential backoff function, default `attempt → min(500 * 2^attempt, 16_000)`. */\n backoffMs?: (attempt: number) => number\n /**\n * Predicate deciding whether an error should trigger a retry. Defaults to\n * `isTransientLlmError` — the package-wide classifier shared with\n * `callLlm` — which retries aborts/timeouts, network faults, HTTP/2\n * transport faults, and any `LlmCallError` with status in {429,502,503,504}.\n * JSON-parse and schema-rejection errors are NOT retriable (the model\n * needs prompt adjustment, not another shot).\n */\n isRetryable?: (err: unknown) => boolean\n}\n\n/** Outcome of a wrapped judge invocation. */\nexport interface JudgeRetryOutcome<T> {\n /** The judge's returned value when `succeeded === true`. */\n value: T | null\n /** True iff one of the attempts completed without throwing. */\n succeeded: boolean\n /** Total attempts made across all models. */\n attempts: number\n /** Which model the successful attempt used (when succeeded). */\n modelUsed?: string\n /** Last error captured when `succeeded === false`. */\n error?: Error\n /** Per-attempt error log for forensics. */\n attemptErrors: Array<{ attempt: number; model: string; error: string }>\n}\n\nconst DEFAULT_MAX_ATTEMPTS = 3\nconst DEFAULT_TIMEOUT_MS = 300_000\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms))\n}\n\n/**\n * Wrap a judge call with retry + fallback-model + typed outcome semantics.\n *\n * The `judgeFn` signature is `(model: string, signal: AbortSignal) => Promise<T>`.\n * The signal will be aborted at `timeoutMs`. Callers should pass the signal\n * to their underlying fetch/SDK call so the abort actually fires.\n *\n * Returns a typed outcome — callers MUST inspect `succeeded` before using\n * `value`. The library refuses to default to a silent zero score because a\n * synthetic zero is indistinguishable from a real low score downstream.\n */\nexport async function withJudgeRetry<T>(\n judgeFn: (model: string, signal: AbortSignal) => Promise<T>,\n policy: JudgeRetryPolicy = {},\n): Promise<JudgeRetryOutcome<T>> {\n const maxAttempts = policy.maxAttempts ?? DEFAULT_MAX_ATTEMPTS\n const timeoutMs = policy.timeoutMs ?? DEFAULT_TIMEOUT_MS\n const backoff = policy.backoffMs ?? backoffMs\n const isRetryable = policy.isRetryable ?? isTransientLlmError\n const models =\n policy.models && policy.models.length > 0 ? policy.models : [undefined as unknown as string]\n\n let totalAttempts = 0\n const attemptErrors: JudgeRetryOutcome<T>['attemptErrors'] = []\n let lastError: Error | undefined\n\n for (const model of models) {\n for (let attempt = 0; attempt < maxAttempts; attempt++) {\n totalAttempts += 1\n const controller = new AbortController()\n const timer = setTimeout(() => controller.abort(new Error('TimeoutError')), timeoutMs)\n try {\n const value = await judgeFn(model as string, controller.signal)\n clearTimeout(timer)\n return {\n value,\n succeeded: true,\n attempts: totalAttempts,\n modelUsed: model,\n attemptErrors,\n }\n } catch (err) {\n clearTimeout(timer)\n const errObj = err instanceof Error ? err : new Error(String(err))\n lastError = errObj\n attemptErrors.push({\n attempt: totalAttempts,\n model: model ?? '(default)',\n error: errObj.message,\n })\n if (!isRetryable(errObj)) {\n // Non-retriable (e.g., JSON parse, schema rejection): break out of\n // attempts on this model AND skip the fallback rotation — a\n // permanent error here will be permanent on the fallback too.\n return {\n value: null,\n succeeded: false,\n attempts: totalAttempts,\n error: errObj,\n attemptErrors,\n }\n }\n if (attempt < maxAttempts - 1) {\n await sleep(backoff(attempt))\n }\n }\n }\n // Exhausted attempts on this model — fall through to next model in the\n // rotation (if any). The backoff between MODEL rotations is the same\n // as the last per-attempt backoff (already slept above).\n }\n\n return {\n value: null,\n succeeded: false,\n attempts: totalAttempts,\n error: lastError,\n attemptErrors,\n }\n}\n","/**\n * Multi-model judge panel — `ensembleJudge` builds a campaign `JudgeConfig`\n * that fans one artifact out to K judge models and reduces their verdicts\n * through `aggregateJudgeVerdicts` (src/judge-ensemble.ts).\n *\n * The panel is the fail-loud composition of the substrate's existing judge\n * primitives:\n * - `assertCrossFamily` (construction-time) — a single-family panel is\n * correlated bias, not independent signal.\n * - `withJudgeRetry` (per model, opt-in) — transient-fault retry with a\n * typed outcome; a judge that exhausts retries is recorded as failed,\n * never folded into a zero.\n * - `aggregateJudgeVerdicts` — the pure reducer; throws when EVERY judge\n * failed so a silent zero can't reach the gate.\n *\n * The returned `JudgeScore` is on the campaign [0,1] scale and carries the\n * ensemble extras (`maxDisagreement`, `failedJudges`, `perJudge`) declared\n * on the canonical `JudgeScore` in src/campaign/types.ts.\n */\n\nimport type { JudgeConfig, JudgeScore } from './campaign/types'\nimport {\n CostLedger,\n type CostLedgerHandle,\n type CostReceiptInput,\n type MaximumCharge,\n} from './cost-ledger'\nimport { aggregateJudgeVerdicts, type JudgeVerdict } from './judge-ensemble'\nimport { assertCrossFamily } from './judge-families'\nimport { type JudgeRetryPolicy, withJudgeRetry } from './judge-retry'\nimport { contentHash } from './verdict-cache'\n\nexport interface EnsembleJudgeOptions<D extends string> {\n /** Judge name — becomes the returned `JudgeConfig.name`. */\n name: string\n /** Rubric dimensions every model scores. Keys of the verdict's `perDimension`. */\n dimensions: D[]\n /** Judge model ids — one `scoreWith` call per entry. List a model twice to\n * sample it twice (votes are suffix-keyed `model#2` so none overwrite). */\n models: string[]\n /** Explicit scoring revision for closure state not visible in the static panel config. */\n judgeVersion?: string\n /**\n * Score the artifact with one model. Throw (or reject) on failure — the\n * panel records that model as a failed judge; it is never folded into a\n * zero. Verdict scores are clamped to [0,1] by the reducer.\n */\n scoreWith: (\n model: string,\n input: { artifact: unknown; scenario?: unknown; signal: AbortSignal },\n ) => Promise<JudgeVerdict<D>>\n /** Recover usage from a failed provider response when its error retains one. */\n receiptFromError?: (error: Error, model: string) => CostReceiptInput | undefined\n /** Used by direct score calls; campaigns supply their run ledger in score(). */\n costLedger?: CostLedgerHandle\n /** Required per model when the shared ledger has a dollar cap. */\n maximumCharge?: MaximumCharge | ((model: string) => MaximumCharge)\n /**\n * Per-model retry policy, applied via `withJudgeRetry`. The panel's\n * `models` list drives the fan-out, so `retry.models` (the fallback\n * rotation) is overridden to each panel model in turn.\n */\n retry?: JudgeRetryPolicy\n /** Enforce `assertCrossFamily` over `models` at construction. Default true.\n * Opt out only for deliberate single-family panels (e.g. self-consistency\n * sampling of one model).\n *\n * Construction-time only, over the REQUESTED ids: it cannot see a gateway\n * that answers several ids from one provider. `scoreWith` owns the served\n * side — check the id the provider echoed with `assertServedModel`\n * (./integrity/served-model) inside your judge call. */\n crossFamily?: boolean\n /** Composite weights forwarded to `aggregateJudgeVerdicts`: a partial map\n * selects AND weights exactly the named dimensions. Omit for uniform. */\n weights?: Partial<Record<D, number>>\n}\n\n/**\n * Build a campaign-shaped `JudgeConfig` whose `score()` runs every panel\n * model in parallel and reduces the surviving verdicts to one canonical\n * `JudgeScore` in [0,1].\n *\n * Failure semantics: a model whose `scoreWith` throws (or exhausts `retry`)\n * lands in `failedJudges` and is excluded from the means. When EVERY model\n * fails, `aggregateJudgeVerdicts` throws — the campaign engine records a\n * failed cell instead of averaging a fabricated zero.\n */\nexport function ensembleJudge<D extends string>(\n opts: EnsembleJudgeOptions<D>,\n): JudgeConfig<unknown> {\n if (opts.models.length === 0) {\n throw new Error(`ensembleJudge '${opts.name}': models is empty — nothing to score with`)\n }\n if (opts.dimensions.length === 0) {\n throw new Error(`ensembleJudge '${opts.name}': dimensions is empty — nothing to score`)\n }\n if (opts.crossFamily !== false) {\n assertCrossFamily(opts.models)\n }\n const declaredJudgeVersion = opts.judgeVersion?.trim()\n if (opts.judgeVersion !== undefined && !declaredJudgeVersion) {\n throw new Error(`ensembleJudge '${opts.name}': judgeVersion must be non-empty when provided`)\n }\n const judgeVersion =\n declaredJudgeVersion ??\n contentHash({\n kind: 'ensembleJudge',\n models: opts.models,\n dimensions: opts.dimensions,\n weights: opts.weights ?? null,\n crossFamily: opts.crossFamily ?? true,\n maximumCharge:\n typeof opts.maximumCharge === 'function'\n ? opts.maximumCharge.toString()\n : (opts.maximumCharge ?? null),\n retry: opts.retry\n ? {\n maxAttempts: opts.retry.maxAttempts ?? null,\n timeoutMs: opts.retry.timeoutMs ?? null,\n models: opts.retry.models ?? null,\n backoffMs: opts.retry.backoffMs?.toString() ?? null,\n isRetryable: opts.retry.isRetryable?.toString() ?? null,\n }\n : null,\n scoreWith: opts.scoreWith.toString(),\n })\n const directCostLedger = opts.costLedger ?? new CostLedger()\n\n const scoreOne = async (args: {\n model: string\n artifact: unknown\n scenario?: unknown\n signal: AbortSignal\n costLedger: CostLedgerHandle\n costPhase: string\n costTags?: Record<string, string>\n }): Promise<JudgeVerdict<D>> => {\n const outcome = await withJudgeRetry(\n async (model, retrySignal) => {\n const paid = await args.costLedger.runPaidCall({\n channel: 'judge',\n phase: args.costPhase,\n actor: `${opts.name}.${model}`,\n model,\n maximumCharge:\n typeof opts.maximumCharge === 'function'\n ? opts.maximumCharge(model)\n : opts.maximumCharge,\n tags: args.costTags,\n signal: AbortSignal.any([args.signal, retrySignal]),\n execute: (signal) =>\n opts.scoreWith(model, { artifact: args.artifact, scenario: args.scenario, signal }),\n receipt: (verdict) => {\n const cachedTokens = verdict.usage?.cachedPromptTokens ?? 0\n const usageUnknown = !verdict.usage || verdict.usage.captured === false\n return {\n model: verdict.model,\n inputTokens: Math.max(0, (verdict.usage?.promptTokens ?? 0) - cachedTokens),\n outputTokens: verdict.usage?.completionTokens ?? 0,\n cachedTokens: cachedTokens > 0 ? cachedTokens : undefined,\n usageUnknown,\n ...(verdict.costUsd === undefined ? {} : { actualCostUsd: verdict.costUsd }),\n }\n },\n receiptFromError: (error) => opts.receiptFromError?.(error, model),\n })\n if (!paid.succeeded) throw paid.error\n return paid.value\n },\n opts.retry\n ? { ...opts.retry, models: [args.model] }\n : { maxAttempts: 1, models: [args.model], isRetryable: () => false },\n )\n if (!outcome.succeeded || outcome.value === null) {\n return {\n model: args.model,\n perDimension: null,\n rationale: outcome.error?.message ?? 'judge failed',\n }\n }\n return outcome.value\n }\n\n return {\n name: opts.name,\n dimensions: opts.dimensions.map((d) => ({ key: d, description: d })),\n judgeVersion,\n async score({\n artifact,\n scenario,\n signal,\n costLedger,\n costPhase,\n costTags,\n }): Promise<JudgeScore> {\n const verdicts = await Promise.all(\n opts.models.map((model) =>\n scoreOne({\n model,\n artifact,\n scenario,\n signal,\n costLedger: costLedger ?? directCostLedger,\n costPhase: costPhase ?? 'judge',\n costTags,\n }),\n ),\n )\n // All-failed throws here — propagate so the engine records a failed cell.\n const agg = aggregateJudgeVerdicts(verdicts, opts.dimensions, opts.weights)\n const score: JudgeScore = {\n dimensions: agg.perDimension,\n composite: agg.composite,\n notes: agg.rationale,\n maxDisagreement: agg.maxDisagreement,\n perJudge: agg.perJudge,\n }\n if (agg.failedJudges.length > 0) score.failedJudges = agg.failedJudges\n return score\n },\n }\n}\n","import { cpus } from 'node:os'\nimport {\n type HarnessConfig,\n type SandboxDriver,\n SandboxHarness,\n type SandboxHarnessResult,\n SubprocessSandboxDriver,\n} from './sandbox-harness'\nimport { TraceEmitter } from './trace/emitter'\nimport { InMemoryTraceStore } from './trace/store'\n\nexport type SandboxJudgeKind = 'compiler' | 'test' | 'linter' | 'security'\n\nexport interface SandboxJudgeSpec {\n id: string\n kind: SandboxJudgeKind\n config: HarnessConfig\n}\n\nexport interface SandboxJudgeResult {\n id: string\n kind: SandboxJudgeKind\n passed: boolean\n score: number\n summary: string\n detail: SandboxHarnessResult\n}\n\nexport interface JudgeFleetOptions {\n driver?: SandboxDriver\n parallel?: boolean\n /**\n * Max concurrent judge subprocesses. Each spec spawns its own subprocess\n * via the driver, so unbounded fan-out exhausts file descriptors / PIDs.\n * Defaults to the host CPU count. Ignored when `parallel === false`.\n */\n concurrency?: number\n}\n\nexport class JudgeRunner {\n private readonly driver: SandboxDriver\n\n constructor(driver: SandboxDriver = new SubprocessSandboxDriver()) {\n this.driver = driver\n }\n\n async run(spec: SandboxJudgeSpec): Promise<SandboxJudgeResult> {\n const store = new InMemoryTraceStore()\n const emitter = new TraceEmitter(store, { runId: `judge-${spec.id}` })\n await emitter.startRun({\n scenarioId: spec.id,\n layer: 'meta',\n projectId: 'judge-runner',\n })\n const harness = new SandboxHarness(this.driver)\n const detail = await harness.run(spec.config, emitter)\n await emitter.endRun({ pass: detail.passed, score: detail.score, notes: `${spec.kind} judge` })\n return {\n id: spec.id,\n kind: spec.kind,\n passed: detail.passed,\n score: detail.score,\n summary: renderJudgeSummary(spec.kind, detail),\n detail,\n }\n }\n}\n\nexport async function runJudgeFleet(\n specs: SandboxJudgeSpec[],\n options: JudgeFleetOptions = {},\n): Promise<SandboxJudgeResult[]> {\n const runner = new JudgeRunner(options.driver)\n if (options.parallel === false) {\n const results: SandboxJudgeResult[] = []\n for (const spec of specs) results.push(await runner.run(spec))\n return results\n }\n const concurrency = Math.max(1, options.concurrency ?? cpus().length)\n const results: SandboxJudgeResult[] = new Array(specs.length)\n let cursor = 0\n async function worker(): Promise<void> {\n while (true) {\n const i = cursor++\n if (i >= specs.length) return\n results[i] = await runner.run(specs[i]!)\n }\n }\n await Promise.all(Array.from({ length: Math.min(concurrency, specs.length) }, () => worker()))\n return results\n}\n\n/** Build a `SandboxJudgeSpec` that scores whether the harness compiles without errors. */\nexport function compilerJudge(id: string, config: HarnessConfig): SandboxJudgeSpec {\n return { id, kind: 'compiler', config }\n}\n\n/** Build a `SandboxJudgeSpec` that scores the harness by its test-suite pass rate. */\nexport function testJudge(id: string, config: HarnessConfig): SandboxJudgeSpec {\n return { id, kind: 'test', config }\n}\n\n/** Build a `SandboxJudgeSpec` that scores the harness by linter rule violations. */\nexport function linterJudge(id: string, config: HarnessConfig): SandboxJudgeSpec {\n return { id, kind: 'linter', config }\n}\n\n/** Build a `SandboxJudgeSpec` that scores the harness output for security issues via a security scanner. */\nexport function securityJudge(id: string, config: HarnessConfig): SandboxJudgeSpec {\n return { id, kind: 'security', config }\n}\n\nfunction renderJudgeSummary(kind: SandboxJudgeKind, detail: SandboxHarnessResult): string {\n if (!detail.passed) return `${kind} judge failed`\n if (detail.test?.testsTotal)\n return `${kind} judge passed ${detail.test.testsPassed}/${detail.test.testsTotal} tests`\n return `${kind} judge passed`\n}\n","export interface PlaybookEntry {\n instruction: string\n rationale: string\n category?: string\n evidence?: string\n weight?: number\n sourceRunId?: string\n}\n\nexport interface Playbook {\n entries: PlaybookEntry[]\n}\n\nexport function distillPlaybook(\n entries: PlaybookEntry[],\n options: { maxEntries?: number } = {},\n): Playbook {\n const maxEntries = options.maxEntries ?? 12\n const byInstruction = new Map<string, PlaybookEntry>()\n\n for (const entry of entries) {\n const key = normalizeInstruction(entry.instruction)\n const existing = byInstruction.get(key)\n if (!existing || (entry.weight ?? 0) > (existing.weight ?? 0)) {\n byInstruction.set(key, { ...entry, instruction: canonicalInstruction(entry.instruction) })\n }\n }\n\n const distilled = [...byInstruction.values()]\n .sort((a, b) => (b.weight ?? 0) - (a.weight ?? 0))\n .slice(0, maxEntries)\n\n return { entries: distilled }\n}\n\nexport function renderPlaybookMarkdown(playbook: Playbook): string {\n const lines = ['# Playbook', '']\n for (const entry of playbook.entries) {\n lines.push(`- ${entry.instruction}`)\n lines.push(` Rationale: ${entry.rationale}`)\n if (entry.category) lines.push(` Category: ${entry.category}`)\n if (entry.evidence) lines.push(` Evidence: ${entry.evidence}`)\n if (entry.sourceRunId) lines.push(` Source run: ${entry.sourceRunId}`)\n lines.push('')\n }\n return `${lines.join('\\n').trim()}\\n`\n}\n\nfunction normalizeInstruction(value: string): string {\n return value.trim().toLowerCase().replace(/\\s+/g, ' ')\n}\n\nfunction canonicalInstruction(value: string): string {\n const normalized = value.trim().replace(/\\s+/g, ' ')\n return normalized.length === 0 ? normalized : normalized[0]!.toUpperCase() + normalized.slice(1)\n}\n","/**\n * Versioned prompt registry.\n *\n * Every prompt used in an eval run is registered with an explicit version.\n * Reports include the content hash so A/B compares are rigorous: if the\n * hash changes between two reports, the prompt actually changed; if it\n * matches, the variance is elsewhere.\n *\n * Hash is SHA-256(content), truncated to 12 hex chars for readability.\n * Uses the Web Crypto API (works in Workers, Node 22+, browsers).\n */\n\nexport interface PromptHandle {\n /** Stable human-readable id, e.g. 'browser.system' */\n id: string\n /** Caller-chosen version string, e.g. 'v3' or '2026-04-20' */\n version: string\n /** SHA-256 of content, 12-hex-char prefix */\n hash: string\n /** Full prompt body */\n content: string\n}\n\nexport class PromptRegistry {\n private readonly entries = new Map<string, PromptHandle>() // `${id}@${version}` → handle\n\n /**\n * Register a prompt. Re-registering the same id+version with DIFFERENT\n * content throws — versions are immutable. Re-registering with the SAME\n * content is a no-op (idempotent).\n */\n async register(id: string, version: string, content: string): Promise<PromptHandle> {\n validateId(id)\n validateVersion(version)\n\n const key = makeKey(id, version)\n const hash = await hashContent(content)\n const existing = this.entries.get(key)\n if (existing) {\n if (existing.hash !== hash) {\n throw new Error(\n `Prompt ${key} already registered with a different hash (${existing.hash} vs ${hash}). Bump the version.`,\n )\n }\n return existing\n }\n const handle: PromptHandle = { id, version, hash, content }\n this.entries.set(key, handle)\n return handle\n }\n\n /** Look up a registered prompt. Throws if unknown — no implicit defaults. */\n get(id: string, version: string): PromptHandle {\n const key = makeKey(id, version)\n const handle = this.entries.get(key)\n if (!handle) throw new Error(`Prompt ${key} not registered`)\n return handle\n }\n\n /** Return all versions of an id, newest-first (lex-descending on version). */\n listVersions(id: string): PromptHandle[] {\n return [...this.entries.values()]\n .filter((h) => h.id === id)\n .sort((a, b) => b.version.localeCompare(a.version))\n }\n\n /** Snapshot the whole registry — useful for including in reports. */\n list(): PromptHandle[] {\n return [...this.entries.values()]\n }\n\n /** Verify a hash against registered content. Returns null if not found. */\n verifyHash(id: string, version: string, expectedHash: string): boolean | null {\n const handle = this.entries.get(makeKey(id, version))\n if (!handle) return null\n return handle.hash === expectedHash\n }\n}\n\n/** SHA-256(content) → first 12 hex chars. Stable across runtimes. */\nexport async function hashContent(content: string): Promise<string> {\n const bytes = new TextEncoder().encode(content)\n const digest = await crypto.subtle.digest('SHA-256', bytes)\n const full = Array.from(new Uint8Array(digest))\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('')\n return full.slice(0, 12)\n}\n\nfunction makeKey(id: string, version: string): string {\n return `${id}@${version}`\n}\n\nconst ID_RE = /^[a-z][a-z0-9._-]*$/i\nfunction validateId(id: string): void {\n if (!ID_RE.test(id)) {\n throw new Error(`Invalid prompt id \"${id}\": must match ${ID_RE}`)\n }\n}\n\nfunction validateVersion(version: string): void {\n if (!version || version.length > 64) {\n throw new Error(`Invalid version \"${version}\": must be 1–64 chars`)\n }\n}\n","export interface SteeringRolePrompt {\n system?: string\n append?: string\n}\n\nexport interface SteeringBundle {\n id: string\n coderPrompt?: string\n continuePrompt?: string\n reviewerPrompts?: Record<string, string>\n skills?: string[]\n rolePrompts?: Record<string, SteeringRolePrompt>\n metadata?: Record<string, unknown>\n}\n\nexport interface SteeringDelta {\n coderPrompt?: string\n continuePrompt?: string\n reviewerPrompts?: Record<string, string>\n skills?: string[]\n rolePrompts?: Record<string, SteeringRolePrompt>\n metadata?: Record<string, unknown>\n}\n\nexport function mergeSteeringBundle(base: SteeringBundle, delta: SteeringDelta): SteeringBundle {\n return {\n ...base,\n ...(delta.coderPrompt !== undefined ? { coderPrompt: delta.coderPrompt } : {}),\n ...(delta.continuePrompt !== undefined ? { continuePrompt: delta.continuePrompt } : {}),\n reviewerPrompts: {\n ...(base.reviewerPrompts ?? {}),\n ...(delta.reviewerPrompts ?? {}),\n },\n skills: delta.skills ?? base.skills,\n rolePrompts: {\n ...(base.rolePrompts ?? {}),\n ...(delta.rolePrompts ?? {}),\n },\n metadata: {\n ...(base.metadata ?? {}),\n ...(delta.metadata ?? {}),\n },\n }\n}\n\nexport function renderSteeringText(bundle: SteeringBundle): string {\n const lines: string[] = [`bundle:${bundle.id}`]\n if (bundle.coderPrompt) lines.push(`coder:${bundle.coderPrompt}`)\n if (bundle.continuePrompt) lines.push(`continue:${bundle.continuePrompt}`)\n const reviewers = Object.entries(bundle.reviewerPrompts ?? {}).sort(([a], [b]) =>\n a.localeCompare(b),\n )\n for (const [name, prompt] of reviewers) lines.push(`reviewer:${name}:${prompt}`)\n const roles = Object.entries(bundle.rolePrompts ?? {}).sort(([a], [b]) => a.localeCompare(b))\n for (const [name, role] of roles) {\n lines.push(`role:${name}:system:${role.system ?? ''}:append:${role.append ?? ''}`)\n }\n const skills = [...(bundle.skills ?? [])].sort()\n if (skills.length) lines.push(`skills:${skills.join(',')}`)\n return lines.join('\\n')\n}\n","import { aggregateRunScore, type RunScore, type RunScoreWeights } from './run-score'\nimport type { SteeringBundle } from './steering'\n\nexport type SteeringOptimizerBackend = 'pairwise'\n\nexport interface SteeringOptimizationRow {\n variantId: string\n scenarioId: string\n bundle: SteeringBundle\n score: RunScore\n metadata?: Record<string, unknown>\n}\n\nexport interface SteeringOptimizationSelector {\n backend: SteeringOptimizerBackend\n signature?: string\n labels?: string[]\n rationale?: string\n}\n\nexport interface SteeringOptimizationResult {\n backend: SteeringOptimizerBackend\n recommendedVariantId: string\n rationale: string\n rankings: Array<{ variantId: string; mean: number; runs: number }>\n selector?: SteeringOptimizationSelector\n skipped?: boolean\n}\n\nexport interface SteeringOptimizerConfig {\n weights?: Partial<RunScoreWeights>\n}\n\n/**\n * Rank already-evaluated steering variants.\n *\n * Model-backed candidate generation belongs to the official GEPA campaign\n * integration. This class only performs the deterministic selection it owns.\n */\nexport class PairwiseSteeringOptimizer {\n optimize(\n rows: SteeringOptimizationRow[],\n config: SteeringOptimizerConfig = {},\n ): SteeringOptimizationResult {\n const rankings = rankRows(rows, config.weights)\n if (rankings.length === 0) throw new Error('no steering optimization rows')\n return {\n backend: 'pairwise',\n recommendedVariantId: rankings[0]!.variantId,\n rationale: `Highest observed mean aggregate across ${rows.length} scored run(s).`,\n rankings,\n }\n }\n}\n\nfunction rankRows(\n rows: readonly SteeringOptimizationRow[],\n weights?: Partial<RunScoreWeights>,\n): Array<{ variantId: string; mean: number; runs: number }> {\n const buckets = new Map<string, number[]>()\n for (const row of rows) {\n const values = buckets.get(row.variantId) ?? []\n values.push(aggregateRunScore(row.score, weights))\n buckets.set(row.variantId, values)\n }\n return [...buckets.entries()]\n .map(([variantId, values]) => ({\n variantId,\n mean: values.reduce((sum, value) => sum + value, 0) / values.length,\n runs: values.length,\n }))\n .sort((a, b) => b.mean - a.mean)\n}\n","/**\n * Workspace inspector — score the persisted state of an agent after a run.\n *\n * Many evals don't ask \"did the response say the right thing\" but \"did the\n * agent put the right rows in the DB / files in the vault / entities on the\n * canvas\". This is the primitive for that.\n *\n * Implementations read from D1, KV, filesystem, or any store — the interface\n * is deliberately small so consumers plug in their own backends.\n */\n\nexport interface WorkspaceSnapshot {\n /** Vault files: logical path → content */\n files: Record<string, string>\n /** DB rows: table name → array of rows (post-validation) */\n rows: Record<string, Array<Record<string, unknown>>>\n /** KV entries: key → value (scoped to whatever prefix the inspector chose) */\n kv: Record<string, string>\n /** Free-form blob metadata: for large binaries the inspector stores summary, not bytes */\n blobs?: Record<string, { size: number; hash?: string; mimeType?: string }>\n}\n\nexport interface InspectorContext {\n /** Workspace / agent / thread id — whatever the backend uses to scope the snapshot */\n scopeId: string\n /** Optional scenario id — allows scenario-specific snapshot shaping */\n scenarioId?: string\n}\n\nexport interface WorkspaceInspector {\n name: string\n snapshot(context: InspectorContext): Promise<WorkspaceSnapshot>\n}\n\n// ---------------------------------------------------------------------------\n// In-memory inspector — useful for tests, not for production\n// ---------------------------------------------------------------------------\n\nexport class InMemoryWorkspaceInspector implements WorkspaceInspector {\n readonly name = 'in-memory'\n private readonly snapshots = new Map<string, WorkspaceSnapshot>()\n\n set(scopeId: string, snapshot: WorkspaceSnapshot): void {\n this.snapshots.set(scopeId, snapshot)\n }\n\n async snapshot(context: InspectorContext): Promise<WorkspaceSnapshot> {\n return this.snapshots.get(context.scopeId) ?? { files: {}, rows: {}, kv: {} }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Snapshot-level assertions\n// ---------------------------------------------------------------------------\n\nexport interface WorkspaceAssertion {\n name: string\n description?: string\n check(snapshot: WorkspaceSnapshot): WorkspaceAssertionResult\n}\n\nexport interface WorkspaceAssertionResult {\n pass: boolean\n /** 0..1 — partial credit for assertions that admit it */\n score: number\n detail?: string\n}\n\nexport function fileExists(path: string): WorkspaceAssertion {\n return {\n name: `file_exists:${path}`,\n check(snapshot) {\n const pass = path in snapshot.files\n return {\n pass,\n score: pass ? 1 : 0,\n detail: pass ? undefined : `No file at ${path}`,\n }\n },\n }\n}\n\nexport function fileContains(path: string, needle: string): WorkspaceAssertion {\n return {\n name: `file_contains:${path}:${needle}`,\n check(snapshot) {\n const content = snapshot.files[path]\n if (content === undefined) {\n return { pass: false, score: 0, detail: `File ${path} missing` }\n }\n const pass = content.includes(needle)\n return {\n pass,\n score: pass ? 1 : 0,\n detail: pass ? undefined : `File ${path} missing substring \"${needle}\"`,\n }\n },\n }\n}\n\nexport function rowCount(table: string, min: number, max?: number): WorkspaceAssertion {\n return {\n name: `row_count:${table}:[${min},${max ?? '∞'}]`,\n check(snapshot) {\n const rows = snapshot.rows[table] ?? []\n const count = rows.length\n const upper = max ?? Infinity\n const pass = count >= min && count <= upper\n const score = pass ? 1 : count < min ? Math.max(0, count / min) : Math.max(0, upper / count)\n return {\n pass,\n score,\n detail: pass\n ? undefined\n : `Table ${table} has ${count} rows, expected [${min}, ${max ?? '∞'}]`,\n }\n },\n }\n}\n\nexport function rowWhere<T extends Record<string, unknown>>(\n table: string,\n predicate: (row: T) => boolean,\n options?: { min?: number },\n): WorkspaceAssertion {\n const min = options?.min ?? 1\n return {\n name: `row_where:${table}`,\n check(snapshot) {\n const rows = (snapshot.rows[table] ?? []) as T[]\n const matching = rows.filter(predicate).length\n const pass = matching >= min\n return {\n pass,\n score: pass ? 1 : Math.max(0, matching / min),\n detail: pass\n ? undefined\n : `Table ${table} has ${matching} matching rows, expected ≥ ${min}`,\n }\n },\n }\n}\n\n/** Run many assertions; return aggregate pass + mean score + per-assertion details. */\nexport function runAssertions(\n snapshot: WorkspaceSnapshot,\n assertions: WorkspaceAssertion[],\n): {\n pass: boolean\n score: number\n results: Array<{ assertion: string; result: WorkspaceAssertionResult }>\n} {\n const results = assertions.map((a) => ({ assertion: a.name, result: a.check(snapshot) }))\n const pass = results.every((r) => r.result.pass)\n const score = results.length\n ? results.reduce((acc, r) => acc + r.result.score, 0) / results.length\n : 1\n return { pass, score, results }\n}\n","/**\n * BudgetGuard — enforces token / wall-clock / call / $ caps, records\n * a ledger entry on every decrement, emits `budget_breach` + throws\n * `BudgetBreachError` when a cap is hit.\n *\n * Wraps a TraceEmitter. The emitter persists ledger entries + breach\n * events so the classifier, pipelines, and reports can all read\n * budget state from the trace corpus — no separate accounting.\n */\n\nimport { AgentEvalError } from './errors'\nimport type { TraceEmitter } from './trace/emitter'\nimport type { BudgetSpec } from './trace/schema'\n\nexport class BudgetBreachError extends AgentEvalError {\n constructor(\n public dimension: keyof BudgetSpec,\n public limit: number,\n public attempted: number,\n ) {\n super('verification', `budget breach on ${dimension}: attempted ${attempted} vs limit ${limit}`)\n }\n}\n\nexport class BudgetGuard {\n private consumed: Record<keyof BudgetSpec, number> = { tokens: 0, wallMs: 0, calls: 0, usd: 0 }\n private emitter: TraceEmitter\n private budget: BudgetSpec\n private startedAt: number\n\n constructor(emitter: TraceEmitter, budget: BudgetSpec, now: () => number = () => Date.now()) {\n this.emitter = emitter\n this.budget = budget\n this.startedAt = now()\n }\n\n /** Record consumption. Throws `BudgetBreachError` if any dimension exceeds its cap. */\n async charge(delta: Partial<Record<keyof BudgetSpec, number>>, spanId?: string): Promise<void> {\n for (const [dim, value] of Object.entries(delta) as Array<[keyof BudgetSpec, number]>) {\n if (!Number.isFinite(value) || value < 0) {\n throw new Error(`BudgetGuard.charge: non-finite or negative ${dim}=${value}`)\n }\n this.consumed[dim] += value\n const limit = this.budget[dim]\n const consumed = this.consumed[dim]\n const remaining = limit === undefined ? Infinity : limit - consumed\n const breached = limit !== undefined && consumed > limit\n if (limit !== undefined) {\n await this.emitter.recordBudget({\n dimension: dim,\n limit,\n consumed,\n remaining,\n breached,\n spanId,\n })\n }\n if (breached) {\n throw new BudgetBreachError(dim, limit!, consumed)\n }\n }\n }\n\n /** Convenience: advance wall-clock budget based on elapsed wall time. */\n async tickWall(nowMs: number, spanId?: string): Promise<void> {\n const elapsed = nowMs - this.startedAt\n const already = this.consumed.wallMs\n const delta = Math.max(0, elapsed - already)\n if (delta > 0) await this.charge({ wallMs: delta }, spanId)\n }\n\n get state(): Record<keyof BudgetSpec, number> {\n return { ...this.consumed }\n }\n}\n","/**\n * Hidden-criteria grading firewall — grade an agent on criteria it never saw.\n *\n * A trustworthy benchmark splits every scenario's data by WHERE each field is\n * allowed to flow, then proves the held-out / judge-only fields never reach the\n * agent during the run. The coding bench expresses this with four destinations\n * (prompt / develop-against / held-out suite / rubric); this module lifts the\n * domain-FREE core out of it so research, legal, tax, content — any domain —\n * can declare the same routing and get the same firewall enforcement and the\n * same held-out-weighted composite, plugging in its OWN grader.\n *\n * Two reusable pieces, both domain-agnostic:\n *\n * 1. FIELD ROUTING BY DESTINATION. A scenario declares each field's\n * `FieldDestination`; `assertNoHiddenLeak` is a pure checker that throws if\n * a grading-only or judge-only field's value appears in what reaches the\n * agent. The domain decides which fields exist and where they go — the\n * substrate only enforces \"hidden stays hidden\".\n *\n * 2. HIDDEN-CRITERIA GRADING. The domain supplies its own grader\n * `(artifact, hiddenCriteria) => { passRate, total }` — the coding\n * node-test executor is ONE such grader a consumer plugs in; the substrate\n * bakes in NO node/test/TS/exec/regex. `gradeOnHidden` runs that grader\n * behind the firewall and `blendHeldout` composes its pass rate with a\n * judge score into the final number the leaderboard ranks on.\n *\n * Shape mirrors `treatment-gate`/`authenticity`: pure predicates and pure\n * composition over already-computed values, fail-loud, with the\n * \"which field / which weight / which grader\" decisions left as parameters and\n * no domain literal anywhere in the module.\n *\n * Lives next to `test-graded-scenario` and `partition-held-out` — it is a\n * scorecard/grading concept that makes sense without a running agent loop.\n */\n\nimport type { JudgeScore } from './campaign/types'\nimport { ValidationError } from './errors'\n\n// ── 1. field routing by destination ──────────────────────────────────────────\n\n/**\n * Where one scenario field is allowed to flow. The firewall guarantee is keyed\n * on this tag, not on a field name — a domain can have any number of fields per\n * destination.\n *\n * - `agent-visible` reaches the agent's context during the run (the prompt,\n * the task statement — what the agent reads to act).\n * - `develop-against` seeded into the agent's environment during the run so it\n * can iterate (a visible example/test/reference). The\n * agent MAY read it — that is intentional (real TDD). Not\n * a leak: it is example-grade, not the grading criteria.\n * - `grading-only` the hidden criteria. Used ONLY at grading, after the run\n * — the held-out suite / answer key / hidden requirements.\n * Must NEVER reach the agent context. This is what makes a\n * good score un-memorizable.\n * - `judge-only` grading context for the judge only (rubric anchors,\n * design intent). Lives with the judge, never in the agent\n * context.\n */\nexport type FieldDestination = 'agent-visible' | 'develop-against' | 'grading-only' | 'judge-only'\n\n/** The destinations a value must be kept OUT of the agent context for. */\nconst hiddenDestinations: ReadonlySet<FieldDestination> = new Set<FieldDestination>([\n 'grading-only',\n 'judge-only',\n])\n\n/** True for the destinations whose values must never reach the agent context. */\nexport function isHiddenDestination(destination: FieldDestination): boolean {\n return hiddenDestinations.has(destination)\n}\n\n/**\n * A scenario's fields routed by destination. The domain owns the field set\n * (`TFields` — a record of its named fields to their string-renderable values)\n * and declares one `FieldDestination` per field. `routeFields` builds this from\n * a domain's `(value, destination)` map; the firewall reads it.\n */\nexport interface RoutedField {\n /** The field's name — for diagnostics only. */\n name: string\n /** The field's value as it would be rendered into text. The firewall compares\n * this against the agent context, so a domain that ships structured data\n * passes a stable string projection (e.g. JSON) of the hidden value. */\n value: string\n destination: FieldDestination\n}\n\n/**\n * Route a domain's named fields by destination into the firewall's input shape.\n * The `routing` declares each field's destination; the `values` carry each\n * field's renderable string. A field present in `routing` but missing from\n * `values` is an authoring error (fail loud) — every routed field must have a\n * value the firewall can check.\n */\nexport function routeFields<TName extends string>(\n routing: Readonly<Record<TName, FieldDestination>>,\n values: Readonly<Record<TName, string>>,\n): RoutedField[] {\n const out: RoutedField[] = []\n for (const name of Object.keys(routing) as TName[]) {\n const value = values[name]\n if (value === undefined) {\n throw new ValidationError(\n `routed field \"${name}\" has a destination but no value — every routed field must carry its value`,\n )\n }\n out.push({ name, value, destination: routing[name] })\n }\n return out\n}\n\n/** A single detected leak: a hidden field whose value appears in the agent context. */\nexport interface HiddenLeak {\n field: string\n destination: FieldDestination\n}\n\nexport interface NoLeakOptions {\n /** Minimum hidden-value length to check. A hidden value shorter than this is\n * skipped — a one-word or empty hidden field would substring-match innocuous\n * prose and is not meaningful evidence of a leak. Default 12. */\n minMatchLength?: number\n}\n\n/**\n * The FIREWALL. Throws `ValidationError` if any `grading-only`/`judge-only`\n * field's value is found inside `agentContext` — the exact text that reaches the\n * agent during the run (its prompt, its seeded files concatenated, whatever the\n * caller assembled). `agent-visible` and `develop-against` fields are never\n * checked: they are meant to be there.\n *\n * Substring containment is the check: it is domain-free and catches the failure\n * that matters — a hidden answer key, held-out case, or rubric anchor pasted\n * into the prompt. Returns the routed fields on success so a caller can chain.\n */\nexport function assertNoHiddenLeak(\n fields: readonly RoutedField[],\n agentContext: string,\n opts: NoLeakOptions = {},\n): readonly RoutedField[] {\n const minLen = opts.minMatchLength ?? 12\n const leaks: HiddenLeak[] = []\n for (const field of fields) {\n if (!isHiddenDestination(field.destination)) continue\n const needle = field.value.trim()\n if (needle.length < minLen) continue\n if (agentContext.includes(needle)) {\n leaks.push({ field: field.name, destination: field.destination })\n }\n }\n if (leaks.length > 0) {\n const detail = leaks.map((l) => `\"${l.field}\" (${l.destination})`).join(', ')\n throw new ValidationError(\n `hidden-criteria firewall breached: ${leaks.length} hidden field(s) reached the agent context: ${detail}`,\n )\n }\n return fields\n}\n\n/** Collect the values a domain may safely render into the agent context — the\n * `agent-visible` (and, by intent, `develop-against`) fields — so a caller can\n * ASSEMBLE the context from the routing rather than hand-picking fields and\n * risking a slip. `develop-against` is included because it is seeded into the\n * agent's environment during the run on purpose. */\nexport function agentVisibleFields(fields: readonly RoutedField[]): RoutedField[] {\n return fields.filter((f) => !isHiddenDestination(f.destination))\n}\n\n// ── 2. hidden-criteria grading ────────────────────────────────────────────────\n\n/** What a hidden-criteria grader reports. `passRate = passed / total` over the\n * hidden checks; `total === 0` means the criteria never ran (e.g. the artifact\n * did not even load) — an honest zero, never a spurious pass. */\nexport interface HiddenGradeResult {\n /** Hidden checks that passed. */\n passed: number\n /** Total hidden checks attempted. 0 when the criteria could not run at all. */\n total: number\n /** `passed / total`, or 0 when `total === 0`. The PRIMARY correctness score. */\n passRate: number\n /** Free-form provenance the caller may record (runner output, reason for 0). */\n notes?: string\n}\n\n/**\n * The domain's grader: given the agent's artifact and the HIDDEN criteria,\n * return a pass rate. This is the ONE seam a non-coding domain implements — the\n * coding node-test executor is a single implementation of it; a legal grader\n * checks the brief against hidden required holdings, a research grader checks an\n * answer against held-out facts, a tax grader runs hidden return assertions.\n * The substrate calls it ONLY at grading time, behind the firewall.\n *\n * `THidden` is the domain's hidden-criteria payload (the held-out suite, the\n * answer key, the hidden requirements) — opaque to the substrate.\n */\nexport type HiddenCriteriaGrader<TArtifact, THidden> = (\n artifact: TArtifact,\n hiddenCriteria: THidden,\n signal?: AbortSignal,\n) => Promise<HiddenGradeResult> | HiddenGradeResult\n\n/** Normalize a grader's raw `{passed, total}` into a `HiddenGradeResult` with a\n * consistent, fail-loud `passRate` — the canonical \"honest zero on no-run\"\n * rule, single-sourced so every domain grader gets it. */\nexport function hiddenGrade(passed: number, total: number, notes?: string): HiddenGradeResult {\n const p = Number.isFinite(passed) && passed > 0 ? Math.floor(passed) : 0\n const t = Number.isFinite(total) && total > 0 ? Math.floor(total) : 0\n const passRate = t > 0 ? Math.min(1, p / t) : 0\n return { passed: Math.min(p, t > 0 ? t : p), total: t, passRate, notes }\n}\n\n/**\n * Run a domain's hidden-criteria grader behind the firewall. Before grading, it\n * re-asserts the firewall against the agent context the run actually used —\n * proving (at grading time, on real data) that the hidden criteria never\n * reached the agent — then invokes the grader and returns its pass rate. A\n * domain that wants the firewall and the grader wired together in one call uses\n * this; a domain that already asserted the firewall at dispatch time can call\n * its grader directly and feed the result to `blendHeldout`.\n */\nexport async function gradeOnHidden<TArtifact, THidden>(args: {\n artifact: TArtifact\n hiddenCriteria: THidden\n grader: HiddenCriteriaGrader<TArtifact, THidden>\n /** The routed fields + the exact agent context, re-checked before grading. */\n firewall: { fields: readonly RoutedField[]; agentContext: string; options?: NoLeakOptions }\n signal?: AbortSignal\n}): Promise<HiddenGradeResult> {\n assertNoHiddenLeak(args.firewall.fields, args.firewall.agentContext, args.firewall.options)\n const result = await args.grader(args.artifact, args.hiddenCriteria, args.signal)\n return hiddenGrade(result.passed, result.total, result.notes)\n}\n\n// ── the composite: hidden correctness (PRIMARY) + judge quality (secondary) ────\n\n/** Weights for the held-out / judge blend. Must be finite and non-negative;\n * they are renormalized to sum to 1 so a caller can pass any positive ratio. */\nexport interface BlendWeights {\n /** Weight on the hidden-criteria pass rate (the primary, ungameable score). */\n heldout: number\n /** Weight on the judge's quality composite (the secondary style/quality score). */\n judge: number\n}\n\n/** Default blend: 0.7 hidden correctness, 0.3 judge quality. The coding bench's\n * long-standing split — execution truth dominates, style refines. */\nexport const defaultBlendWeights: BlendWeights = { heldout: 0.7, judge: 0.3 }\n\n/** The input shape a judge's `score` receives — exactly `JudgeConfig.score`'s\n * argument: the artifact, plus any scenario/signal fields the judge carries.\n * `withHeldoutBlend` only reads `artifact`; the rest rides through. */\nexport interface JudgeScoreInput<TArtifact> {\n artifact: TArtifact\n /** Pass-through for the judge's extra input fields (scenario, signal). */\n [key: string]: unknown\n}\n\nfunction normalizeWeights(weights: BlendWeights): { heldout: number; judge: number } {\n const h = Number.isFinite(weights.heldout) && weights.heldout >= 0 ? weights.heldout : 0\n const j = Number.isFinite(weights.judge) && weights.judge >= 0 ? weights.judge : 0\n const sum = h + j\n if (sum <= 0) {\n throw new ValidationError(\n 'blend weights must have a positive sum (got heldout+judge <= 0) — cannot weight a composite by zero',\n )\n }\n return { heldout: h / sum, judge: j / sum }\n}\n\n/**\n * Compose the PRIMARY hidden-criteria pass rate with the SECONDARY judge\n * composite into the single score the leaderboard ranks on. Weights are\n * renormalized, so a solution that fails the hidden criteria is capped low no\n * matter how the judge felt about its style, while a stylistically-mediocre but\n * CORRECT solution still earns the bulk of the points. Both inputs are clamped\n * to [0,1] — a judge on a non-unit scale must be normalized by the caller first.\n */\nexport function blendHeldout(\n heldoutPassRate: number,\n judgeScore: number,\n weights: BlendWeights = defaultBlendWeights,\n): number {\n const w = normalizeWeights(weights)\n const heldout = clampUnit(heldoutPassRate)\n const judge = clampUnit(judgeScore)\n return w.heldout * heldout + w.judge * judge\n}\n\n/**\n * Wrap a judge's `score` so the `composite` it REPORTS is the held-out-weighted\n * blend. The judge still scores its quality dimensions (recorded, secondary),\n * but the composite that downstream selection/scorecard reads becomes\n * `blendHeldout(heldoutPassRate(artifact), judgeComposite, weights)`. The held-\n * out pass rate is read off the artifact via `heldoutPassRate` — already\n * computed before the judge runs — so no second grading pass is needed.\n *\n * Generic over the artifact type, inferred from `heldoutPassRate`, so it\n * composes with both a `campaign` `JudgeConfig.score` and a bare scoring\n * function. The input is the judge's `{ artifact, ... }` — any extra fields\n * (`scenario`, `signal`) ride through untouched via the index signature.\n */\nexport function withHeldoutBlend<TArtifact>(\n score: (input: JudgeScoreInput<TArtifact>) => JudgeScore | Promise<JudgeScore>,\n heldoutPassRate: (artifact: TArtifact) => number,\n weights: BlendWeights = defaultBlendWeights,\n): (input: JudgeScoreInput<TArtifact>) => Promise<JudgeScore> {\n return async (input: JudgeScoreInput<TArtifact>): Promise<JudgeScore> => {\n const base = await score(input)\n if (base.failed) return base\n const rate = clampUnit(heldoutPassRate(input.artifact))\n const composite = blendHeldout(rate, base.composite, weights)\n const w = normalizeWeights(weights)\n return {\n ...base,\n composite,\n notes:\n `composite=${composite.toFixed(3)} ` +\n `(held-out ${(rate * 100).toFixed(0)}% × ${w.heldout.toFixed(2)} + ` +\n `quality ${base.composite.toFixed(3)} × ${w.judge.toFixed(2)})` +\n (base.notes ? ` — ${base.notes}` : ''),\n }\n }\n}\n\nfunction clampUnit(value: number): number {\n if (!Number.isFinite(value)) return 0\n return Math.max(0, Math.min(1, value))\n}\n","import type { RunSplitTag } from './run-record'\n\nexport interface RuntimeTrajectoryHookEvent {\n id: string\n runId: string\n scenarioId?: string\n target: string\n phase: string\n timestamp: number\n stepIndex?: number\n parentId?: string\n payload?: unknown\n metadata?: Record<string, unknown>\n}\n\nexport interface RuntimeTrajectoryRecord {\n id?: string\n scenarioId?: string\n splitTag?: RunSplitTag\n runtimeEvents?: unknown\n [key: string]: unknown\n}\n\nexport interface RuntimeTrajectoryRunRecord {\n runId: string\n scenarioId?: string\n splitTag: RunSplitTag\n}\n\nexport interface RuntimeTrajectoryEvidenceSummary {\n recordCount: number\n recordWithRuntimeEventsCount: number\n runtimeRunCount: number\n lifecycleEventCount: number\n defaultedSplitCount: number\n}\n\nexport interface RuntimeTrajectoryEvidenceProjection {\n runs: RuntimeTrajectoryRunRecord[]\n events: RuntimeTrajectoryHookEvent[]\n summary: RuntimeTrajectoryEvidenceSummary\n diagnostics: string[]\n}\n\nexport interface ProjectRuntimeTrajectoryEvidenceOptions<\n TRecord extends RuntimeTrajectoryRecord = RuntimeTrajectoryRecord,\n> {\n records: TRecord[]\n defaultSplitTag?: RunSplitTag\n recordIdOf?: (record: TRecord, index: number) => string | undefined\n scenarioIdOf?: (record: TRecord, index: number) => string | undefined\n}\n\nconst DEFAULT_SPLIT_TAG: RunSplitTag = 'search'\n\nexport function projectRuntimeTrajectoryEvidence<TRecord extends RuntimeTrajectoryRecord>(\n options: ProjectRuntimeTrajectoryEvidenceOptions<TRecord>,\n): RuntimeTrajectoryEvidenceProjection {\n const diagnostics: string[] = []\n const runsById = new Map<string, RuntimeTrajectoryRunRecord>()\n const events: RuntimeTrajectoryHookEvent[] = []\n let recordWithRuntimeEventsCount = 0\n let defaultedSplitCount = 0\n\n for (let recordIndex = 0; recordIndex < options.records.length; recordIndex += 1) {\n const record = options.records[recordIndex]!\n const key = runtimeTrajectoryRecordKey(record, recordIndex, options.recordIdOf)\n const splitTag = record.splitTag ?? options.defaultSplitTag ?? DEFAULT_SPLIT_TAG\n if (record.splitTag === undefined) defaultedSplitCount += 1\n\n const rawEvents = record.runtimeEvents\n if (!Array.isArray(rawEvents)) {\n diagnostics.push(\n `${key}: runtimeEvents is not an array; no runtime run join can be extracted`,\n )\n continue\n }\n if (rawEvents.length === 0) {\n diagnostics.push(`${key}: no runtimeEvents; no runtime run join can be extracted`)\n continue\n }\n recordWithRuntimeEventsCount += 1\n\n for (let index = 0; index < rawEvents.length; index += 1) {\n const event = parseRuntimeTrajectoryHookEvent(rawEvents[index])\n if (!event) {\n diagnostics.push(`${key}: runtimeEvents[${index}] is not a RuntimeHookEvent`)\n continue\n }\n events.push(event)\n\n const scenarioId =\n event.scenarioId ??\n stringOrUndefined(options.scenarioIdOf?.(record, recordIndex)) ??\n stringOrUndefined(record.scenarioId)\n const prior = runsById.get(event.runId)\n if (!prior) {\n runsById.set(event.runId, { runId: event.runId, scenarioId, splitTag })\n continue\n }\n if (prior.scenarioId !== scenarioId || prior.splitTag !== splitTag) {\n diagnostics.push(`${key}: runId ${event.runId} has conflicting scenario/split metadata`)\n }\n }\n }\n\n const runs = [...runsById.values()]\n return {\n runs,\n events,\n summary: {\n recordCount: options.records.length,\n recordWithRuntimeEventsCount,\n runtimeRunCount: runs.length,\n lifecycleEventCount: events.length,\n defaultedSplitCount,\n },\n diagnostics,\n }\n}\n\nexport function parseRuntimeTrajectoryHookEvent(input: unknown): RuntimeTrajectoryHookEvent | null {\n if (!isRecord(input)) return null\n if (typeof input.id !== 'string' || input.id.length === 0) return null\n if (typeof input.runId !== 'string' || input.runId.length === 0) return null\n if (typeof input.target !== 'string' || input.target.length === 0) return null\n if (typeof input.phase !== 'string' || input.phase.length === 0) return null\n if (typeof input.timestamp !== 'number' || !Number.isFinite(input.timestamp)) return null\n\n return {\n id: input.id,\n runId: input.runId,\n scenarioId: stringOrUndefined(input.scenarioId),\n target: input.target,\n phase: input.phase,\n timestamp: input.timestamp,\n stepIndex: finiteNumberOrUndefined(input.stepIndex),\n parentId: stringOrUndefined(input.parentId),\n payload: input.payload,\n metadata: isRecord(input.metadata) ? { ...input.metadata } : undefined,\n }\n}\n\nfunction runtimeTrajectoryRecordKey<TRecord extends RuntimeTrajectoryRecord>(\n record: TRecord,\n index: number,\n recordIdOf?: (record: TRecord, index: number) => string | undefined,\n): string {\n return (\n stringOrUndefined(recordIdOf?.(record, index)) ??\n stringOrUndefined(record.id) ??\n `record[${index}]`\n )\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\nfunction stringOrUndefined(value: unknown): string | undefined {\n return typeof value === 'string' && value.length > 0 ? value : undefined\n}\n\nfunction finiteNumberOrUndefined(value: unknown): number | undefined {\n return typeof value === 'number' && Number.isFinite(value) ? value : undefined\n}\n","/**\n * Cost tracker — token + USD accounting per scenario and per run.\n *\n * Adapted from generic usage-event accounting. Every\n * optimizer needs to know \"is the quality gain worth the cost delta?\",\n * and every dashboard needs dollars-per-completed-task. MODEL_PRICING\n * from metrics.ts stays authoritative for estimate math; this module\n * adds the aggregation + per-scenario roll-up that was duplicated\n * across 4 verticals.\n */\n\nimport { estimateCost } from './metrics'\n\nexport interface TokenSpec {\n inputTokens: number\n outputTokens: number\n cachedTokens?: number\n reasoningTokens?: number\n}\n\nexport interface CostEntry extends TokenSpec {\n scenarioId: string\n model: string\n /** Override estimate with an observed cost (e.g. from provider response). */\n actualCostUsd?: number\n timestamp: number\n /** Free-form tags (variant id, round #, etc.). */\n tags?: Record<string, string>\n}\n\nexport interface ScenarioCost {\n scenarioId: string\n entries: CostEntry[]\n totalInputTokens: number\n totalOutputTokens: number\n totalCachedTokens: number\n totalCostUsd: number\n /** Pass flag — set by consumer via markOutcome; used for cost-per-completed-task. */\n completed?: boolean\n}\n\nexport class CostTracker {\n private byScenario = new Map<string, ScenarioCost>()\n\n record(entry: Omit<CostEntry, 'timestamp'> & { timestamp?: number }): CostEntry {\n const full: CostEntry = { timestamp: entry.timestamp ?? Date.now(), ...entry }\n assertNonNegative(full.inputTokens, 'inputTokens')\n assertNonNegative(full.outputTokens, 'outputTokens')\n let bucket = this.byScenario.get(full.scenarioId)\n if (!bucket) {\n bucket = {\n scenarioId: full.scenarioId,\n entries: [],\n totalInputTokens: 0,\n totalOutputTokens: 0,\n totalCachedTokens: 0,\n totalCostUsd: 0,\n }\n this.byScenario.set(full.scenarioId, bucket)\n }\n bucket.entries.push(full)\n bucket.totalInputTokens += full.inputTokens\n bucket.totalOutputTokens += full.outputTokens\n bucket.totalCachedTokens += full.cachedTokens ?? 0\n bucket.totalCostUsd += costFor(full)\n return full\n }\n\n markOutcome(scenarioId: string, completed: boolean): void {\n const bucket = this.byScenario.get(scenarioId)\n if (!bucket) throw new Error(`CostTracker.markOutcome: unknown scenario \"${scenarioId}\"`)\n bucket.completed = completed\n }\n\n /**\n * Convenience: record + markOutcome in one call from a\n * `{ usage, verdict }`-shaped response (starter-foundry's\n * `invokeMetaJudge` returns this shape; consumers that wrap any\n * judge/critic can follow the same convention).\n *\n * `usage.model` must be present in `MODEL_PRICING` for cost math to\n * populate; otherwise totalCostUsd stays at 0 for the entry but\n * tokens still aggregate.\n */\n recordVerdict(\n verdict: {\n usage?: {\n inputTokens: number\n outputTokens: number\n model: string\n cachedTokens?: number\n reasoningTokens?: number\n }\n verdict?: 'pass' | 'fail' | 'borderline' | string\n },\n scenarioId: string,\n tags?: Record<string, string>,\n ): CostEntry | null {\n if (!verdict.usage) return null\n const entry = this.record({\n scenarioId,\n model: verdict.usage.model,\n inputTokens: verdict.usage.inputTokens,\n outputTokens: verdict.usage.outputTokens,\n cachedTokens: verdict.usage.cachedTokens,\n reasoningTokens: verdict.usage.reasoningTokens,\n tags,\n })\n this.markOutcome(scenarioId, verdict.verdict === 'pass')\n return entry\n }\n\n get(scenarioId: string): ScenarioCost | undefined {\n return this.byScenario.get(scenarioId)\n }\n\n list(): ScenarioCost[] {\n return [...this.byScenario.values()]\n }\n\n summary(): CostSummary {\n const scenarios = this.list()\n const completed = scenarios.filter((s) => s.completed === true)\n const totalCost = scenarios.reduce((a, s) => a + s.totalCostUsd, 0)\n const totalInput = scenarios.reduce((a, s) => a + s.totalInputTokens, 0)\n const totalOutput = scenarios.reduce((a, s) => a + s.totalOutputTokens, 0)\n const totalCompletedCost = completed.reduce((a, s) => a + s.totalCostUsd, 0)\n return {\n scenarioCount: scenarios.length,\n completedCount: completed.length,\n totalInputTokens: totalInput,\n totalOutputTokens: totalOutput,\n totalCostUsd: totalCost,\n avgCostPerScenarioUsd: scenarios.length ? totalCost / scenarios.length : 0,\n costPerCompletedTaskUsd: completed.length ? totalCompletedCost / completed.length : null,\n }\n }\n}\n\nexport interface CostSummary {\n scenarioCount: number\n completedCount: number\n totalInputTokens: number\n totalOutputTokens: number\n totalCostUsd: number\n avgCostPerScenarioUsd: number\n /** Total USD / completed scenarios — null when nothing completed. */\n costPerCompletedTaskUsd: number | null\n}\n\nfunction costFor(entry: CostEntry): number {\n if (typeof entry.actualCostUsd === 'number' && Number.isFinite(entry.actualCostUsd)) {\n return entry.actualCostUsd\n }\n return estimateCost(entry.inputTokens, entry.outputTokens, entry.model)\n}\n\nfunction assertNonNegative(n: number, name: string): void {\n if (!Number.isFinite(n) || n < 0) {\n throw new Error(`CostTracker: ${name} must be a non-negative finite number, got ${n}`)\n }\n}\n","/**\n * EvalTraceStore — JSONL save / query / compare over the analysis-time\n * `RunRecord` row.\n *\n * `FileSystemTraceStore` (in `./trace/store`) persists the rich TraceSchema-v1\n * span corpus — runs, spans, events, artifacts — the runtime emits live. That\n * is NOT the thing three consumers hand-roll in `tests/eval/lib/trace-store.ts`.\n * What they hand-roll is the *analysis* layer: append each finished run as one\n * JSONL line keyed by scenario/candidate, then query it (\"every run where score\n * < 50\"), pick the best run for a scenario (few-shot seeding), and compare two\n * candidates on matched scenarios.\n *\n * The substrate already has the canonical analysis-time row — `RunRecord` — so\n * this is that query/compare API expressed over `RunRecord[]`, with a\n * JSONL-backed store. It does NOT fork `FileSystemTraceStore`; it sits beside it\n * for the analysis projection.\n */\n\nimport { ValidationError } from './errors'\nimport { isRealnessGated, trainingScore } from './rollout/reward'\nimport { isRunRecord, type RunRecord, type RunSplitTag, validateRunRecord } from './run-record'\n\n/**\n * The score the query/compare layer ranks on: holdout when present, else\n * search, with the anti-Goodhart gate applied — a run flagged as gamed reads 0\n * however high it claims to have scored.\n *\n * The gate is load-bearing here and this function did not previously apply it,\n * despite saying it did. `getBest` is few-shot exemplar selection: whatever it\n * returns is pasted into the next agent's prompt as an example to imitate.\n * Ranking on the raw number handed the highest-scoring gamed trajectory to\n * every subsequent run — propagation through the context window rather than\n * through a gradient, but propagation all the same.\n *\n * Analysis that needs to SEE the inflated number (reward-hack detection,\n * per-run reporting) reads `observedScore` from `rollout/reward.ts` directly.\n *\n * Returns `undefined` for an execution-only record (neither score present):\n * such rows are valid RunRecords, but cannot participate in score-ranked\n * queries. A gated run still reads 0 — the gate's verdict is a number, never\n * a gap.\n */\nexport function runScore(record: RunRecord): number | undefined {\n return trainingScore(record)\n}\n\nexport interface RunRecordFilter {\n experimentId?: string\n candidateId?: string\n scenarioId?: string\n model?: string\n splitTag?: RunSplitTag\n /** Inclusive lower bound on `runScore`. */\n minScore?: number\n /** Inclusive upper bound on `runScore`. */\n maxScore?: number\n /** Match a single tag in `outcome.raw` by exact numeric value. */\n rawEquals?: { key: string; value: number }\n /** Custom predicate, ANDed with the structured filters. */\n where?: (record: RunRecord) => boolean\n}\n\nfunction matches(record: RunRecord, f: RunRecordFilter): boolean {\n if (f.experimentId && record.experimentId !== f.experimentId) return false\n if (f.candidateId && record.candidateId !== f.candidateId) return false\n if (f.scenarioId && record.scenarioId !== f.scenarioId) return false\n if (f.model && record.model !== f.model) return false\n if (f.splitTag && record.splitTag !== f.splitTag) return false\n if (f.minScore !== undefined || f.maxScore !== undefined) {\n const score = runScore(record)\n if (score === undefined) return false\n if (f.minScore !== undefined && score < f.minScore) return false\n if (f.maxScore !== undefined && score > f.maxScore) return false\n }\n if (f.rawEquals && record.outcome.raw[f.rawEquals.key] !== f.rawEquals.value) return false\n if (f.where && !f.where(record)) return false\n return true\n}\n\nexport interface CandidateComparison {\n a: string\n b: string\n /** Scenario ids present for BOTH candidates — the paired comparison set. */\n pairedScenarioIds: string[]\n /** Mean `runScore` for candidate a over the paired scenarios. */\n meanA: number\n /** Mean `runScore` for candidate b over the paired scenarios. */\n meanB: number\n /** meanB − meanA. Positive ⇒ b scored higher on the matched scenarios. */\n meanDelta: number\n /** Scenarios where b beat a (strictly), tied, and a beat b. */\n bWins: number\n ties: number\n aWins: number\n /**\n * Runs of either candidate excluded from the comparison because the\n * authenticity gate flagged them (`outcome.realness.gated`).\n *\n * Excluded rather than scored 0: `runScore` is gated, so leaving them in\n * would have entered a gamed run as a silent zero, which reads as \"this\n * candidate failed the scenario\" when what happened is \"this candidate's\n * result is not evidence\". A non-zero count here is itself the finding — a\n * comparison drawn over a shrunken scenario set has to say so.\n */\n realnessGatedRuns: number\n}\n\n/**\n * Backing persistence for `EvalTraceStore`. The in-memory store is the default;\n * the JSONL file store appends one validated `RunRecord` per line. Both keep an\n * append order so `getBest` / `compareRuns` are reproducible.\n */\nexport interface RunRecordBackend {\n append(record: RunRecord): Promise<void>\n load(): Promise<RunRecord[]>\n}\n\nexport function inMemoryRunRecordBackend(initial: RunRecord[] = []): RunRecordBackend {\n const rows = initial.map((r) => validateRunRecord(r))\n return {\n async append(record) {\n rows.push(record)\n },\n async load() {\n return [...rows]\n },\n }\n}\n\n/**\n * JSONL-backed store at `path`, one `RunRecord` per line. Malformed lines fail\n * loud on load (a corrupt corpus must not silently shrink the analysis set);\n * pass `skipInvalid` only for forensics on a known-bad file.\n */\nexport function jsonlRunRecordBackend(\n path: string,\n opts: { skipInvalid?: boolean } = {},\n): RunRecordBackend {\n return {\n async append(record) {\n const fs = await import('node:fs/promises')\n const pathMod = await import('node:path')\n await fs.mkdir(pathMod.dirname(path), { recursive: true })\n await fs.appendFile(path, `${JSON.stringify(record)}\\n`, 'utf8')\n },\n async load() {\n const fs = await import('node:fs/promises')\n let raw: string\n try {\n raw = await fs.readFile(path, 'utf8')\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') return []\n throw err\n }\n const out: RunRecord[] = []\n let lineNo = 0\n for (const line of raw.split('\\n')) {\n lineNo++\n if (!line.trim()) continue\n let parsed: unknown\n try {\n parsed = JSON.parse(line)\n } catch (err) {\n if (opts.skipInvalid) continue\n throw new ValidationError(`EvalTraceStore: ${path}:${lineNo} is not valid JSON`)\n }\n if (opts.skipInvalid) {\n if (isRunRecord(parsed)) out.push(parsed)\n continue\n }\n try {\n out.push(validateRunRecord(parsed))\n } catch (err) {\n throw new ValidationError(\n `EvalTraceStore: ${path}:${lineNo} is not a valid RunRecord — ${(err as Error).message}`,\n )\n }\n }\n return out\n },\n }\n}\n\n/**\n * Query / compare layer over a `RunRecord` corpus. Append finished runs, query\n * with a structured filter, take the best run for a scenario, and compare two\n * candidates on their matched scenarios. Persistence is injected via\n * `RunRecordBackend` (in-memory by default, JSONL file via\n * `jsonlRunRecordBackend`).\n */\nexport class EvalTraceStore {\n private readonly backend: RunRecordBackend\n\n constructor(backend: RunRecordBackend = inMemoryRunRecordBackend()) {\n this.backend = backend\n }\n\n /** Validate and append one run. Throws on an invalid record — the corpus\n * stays paper-grade. */\n async append(record: RunRecord): Promise<void> {\n await this.backend.append(validateRunRecord(record))\n }\n\n async all(): Promise<RunRecord[]> {\n return this.backend.load()\n }\n\n async query(filter: RunRecordFilter = {}): Promise<RunRecord[]> {\n const rows = await this.backend.load()\n return rows.filter((r) => matches(r, filter))\n }\n\n /**\n * Highest-scoring run for a scenario (optionally restricted to a candidate).\n * Returns null when no run matches. Ties resolve to the earliest-appended run\n * so the result is stable.\n *\n * Runs flagged as gamed are DROPPED, not zeroed. The caller's use for this is\n * few-shot seeding — the returned trajectory becomes an example to copy — so\n * the same rule as SFT applies: a faked success must not be in the candidate\n * set at all. When every run for the scenario is gated the honest answer is\n * `null` (no exemplar), never the least-bad fake.\n */\n async getBest(\n scenarioId: string,\n opts: { candidateId?: string; splitTag?: RunSplitTag } = {},\n ): Promise<RunRecord | null> {\n const rows = (\n await this.query({\n scenarioId,\n candidateId: opts.candidateId,\n splitTag: opts.splitTag,\n })\n ).filter((r) => !isRealnessGated(r))\n const scored = rows.flatMap((record) => {\n const score = runScore(record)\n return score === undefined ? [] : [{ record, score }]\n })\n if (scored.length === 0) return null\n let best = scored[0]!.record\n let bestScore = scored[0]!.score\n for (let i = 1; i < scored.length; i++) {\n const s = scored[i]!.score\n if (s > bestScore) {\n best = scored[i]!.record\n bestScore = s\n }\n }\n return best\n }\n\n /**\n * Compare two candidates on the scenarios they BOTH ran. When a candidate\n * ran a scenario more than once, its best `runScore` for that scenario is\n * used. Throws when there is no paired scenario — an unpaired \"comparison\" is\n * not one.\n *\n * Realness-gated runs are excluded and counted in `realnessGatedRuns`, never\n * folded in as a zero.\n */\n async compareRuns(candidateA: string, candidateB: string): Promise<CandidateComparison> {\n if (candidateA === candidateB) {\n throw new ValidationError(\n `EvalTraceStore.compareRuns: candidates must differ (\"${candidateA}\")`,\n )\n }\n const rows = await this.backend.load()\n let realnessGatedRuns = 0\n const bestByScenario = (candidate: string): Map<string, number> => {\n const m = new Map<string, number>()\n for (const r of rows) {\n if (r.candidateId !== candidate) continue\n const sid = r.scenarioId\n if (!sid) continue\n if (isRealnessGated(r)) {\n realnessGatedRuns++\n continue\n }\n const s = runScore(r)\n if (s === undefined) continue\n const prev = m.get(sid)\n if (prev === undefined || s > prev) m.set(sid, s)\n }\n return m\n }\n const aScores = bestByScenario(candidateA)\n const bScores = bestByScenario(candidateB)\n const paired = [...aScores.keys()].filter((sid) => bScores.has(sid)).sort()\n if (paired.length === 0) {\n // Distinguish \"the corpora never overlapped\" from \"they overlap, but\n // every shared scenario lost a side to the realness gate\" — the second\n // diagnosis points at gamed runs, not at a mislabeled corpus.\n throw new ValidationError(\n realnessGatedRuns > 0\n ? `EvalTraceStore.compareRuns: \"${candidateA}\" and \"${candidateB}\" share no scenario ` +\n `with honest runs on both sides (${realnessGatedRuns} run(s) were realness-gated)`\n : `EvalTraceStore.compareRuns: \"${candidateA}\" and \"${candidateB}\" share no scenario (need scenarioId on records)`,\n )\n }\n let sumA = 0\n let sumB = 0\n let bWins = 0\n let aWins = 0\n let ties = 0\n for (const sid of paired) {\n const sa = aScores.get(sid)!\n const sb = bScores.get(sid)!\n sumA += sa\n sumB += sb\n if (sb > sa) bWins++\n else if (sb < sa) aWins++\n else ties++\n }\n const meanA = sumA / paired.length\n const meanB = sumB / paired.length\n return {\n a: candidateA,\n b: candidateB,\n pairedScenarioIds: paired,\n meanA,\n meanB,\n meanDelta: meanB - meanA,\n bWins,\n ties,\n aWins,\n realnessGatedRuns,\n }\n }\n}\n","/**\n * Cross-profile leaderboard — rank agent profiles (or any grouping) over a corpus\n * of RunRecords on pass-rate with a Wilson CI, joined with the cost / token /\n * latency rollup every benchmark wants next to the score.\n *\n * This is substrate, not benchmark-specific: any consumer of agent-eval gets a\n * cross-harness × model leaderboard without re-implementing grouping, binomial\n * CIs, or the observability join. The benchmark supplies only what \"passed\"\n * means; everything else composes existing primitives (`wilson`, the RunRecord\n * cost/token/wall fields, the AgentProfileCell grouping key).\n */\nimport type { RunRecord } from './run-record'\nimport { wilson } from './statistics'\n\nexport interface LeaderboardRow {\n /** Group key — the agent-profile cellId by default, else a caller dimension. */\n key: string\n /** Display label: `harness · model` when the profile carries them, else the key. */\n label: string\n harness?: string\n model?: string\n rank: number\n /** Measured runs in this group. */\n n: number\n passRate: number\n passRateCi95: [number, number]\n /** Observability rollup — means over the group; null when no run reported it. */\n meanCostUsd: number | null\n meanTokensIn: number | null\n meanTokensOut: number | null\n meanWallMs: number | null\n}\n\nexport interface LeaderboardOptions {\n /** Per-run pass predicate — the benchmark defines what \"passed\" means (real-build\n * hit-rate, test-pass, etc.). The leaderboard owns only the grouping + stats. */\n passed: (record: RunRecord) => boolean\n /** Group key. Default: the agent-profile cellId (harness × model × dimensions),\n * so persona/harness/model sweeps separate without parsing labels. */\n groupBy?: (record: RunRecord) => string\n}\n\nfunction mean(xs: number[]): number | null {\n return xs.length ? xs.reduce((a, b) => a + b, 0) / xs.length : null\n}\n\n/**\n * Group `records`, compute pass-rate + Wilson CI + cost/token/latency means per\n * group, and rank by pass-rate (cost as the tiebreaker — cheaper wins a tie).\n * Pure projection: no I/O, deterministic, safe to call on any RunRecord[].\n */\nexport function leaderboard(records: RunRecord[], opts: LeaderboardOptions): LeaderboardRow[] {\n const keyOf = opts.groupBy ?? ((r: RunRecord) => r.agentProfile?.cellId ?? 'ungrouped')\n const groups = new Map<string, RunRecord[]>()\n for (const r of records) {\n const k = keyOf(r)\n const g = groups.get(k)\n if (g) g.push(r)\n else groups.set(k, [r])\n }\n\n const rows: LeaderboardRow[] = [...groups.entries()].map(([key, rs]) => {\n const passes = rs.filter((r) => opts.passed(r)).length\n const ci = wilson(passes, rs.length)\n const profile = rs[0]!.agentProfile\n const harness = profile?.harness?.id\n const model = profile?.model\n const knownCosts = rs.map((r) => r.costUsd).filter(isFiniteNumber)\n return {\n key,\n label: harness && model ? `${harness} · ${model}` : key,\n ...(harness ? { harness } : {}),\n ...(model ? { model } : {}),\n rank: 0,\n n: rs.length,\n passRate: ci.estimate,\n passRateCi95: [ci.lower, ci.upper],\n meanCostUsd: knownCosts.length === rs.length ? mean(knownCosts) : null,\n meanTokensIn: mean(rs.map((r) => r.tokenUsage.input)),\n meanTokensOut: mean(rs.map((r) => r.tokenUsage.output)),\n meanWallMs: mean(rs.map((r) => r.wallMs)),\n }\n })\n\n rows.sort(\n (a, b) => b.passRate - a.passRate || (a.meanCostUsd ?? Infinity) - (b.meanCostUsd ?? Infinity),\n )\n rows.forEach((row, i) => {\n row.rank = i + 1\n })\n return rows\n}\n\nfunction isFiniteNumber(value: unknown): value is number {\n return typeof value === 'number' && Number.isFinite(value)\n}\n","/**\n * muffled-gate-scanner — test helper that greps consumer source for\n * gate + measurement anti-patterns and fails with file:line locations.\n *\n * Named pattern lives at starter-foundry's `.evolve/patterns/muffled-gate.md`;\n * same shape applies to every consumer (a gate that should fail loud\n * returns silent success; a metric that should emit a real number\n * reports noise/empty).\n *\n * Usage (in a consumer project's test file):\n *\n * import { scanForMuffledGates, DEFAULT_FINDERS } from '@tangle-network/agent-eval'\n *\n * test('no muffled gates in eval surface', () => {\n * const findings = scanForMuffledGates({\n * repoRoot: process.cwd(),\n * scanFiles: ['src/eval/scaffold.ts', 'scripts/promote.mjs'],\n * finders: DEFAULT_FINDERS,\n * })\n * if (findings.length) assert.fail(formatFindings(findings))\n * })\n *\n * Customize by passing your own `finders` — each finder is\n * `(file, text) => Finding[]` and runs per-file.\n *\n * Escape hatch: any line containing `muffle-ok:` is excluded from all\n * finders, letting consumers opt a legitimate fallback out explicitly.\n */\n\nimport { existsSync, readdirSync, readFileSync, statSync } from 'node:fs'\nimport { join } from 'node:path'\n\nexport interface MuffledFinding {\n file: string\n line: number\n lineText: string\n pattern: string\n}\n\nexport type MuffledFinder = (file: string, text: string) => MuffledFinding[]\n\nexport interface ScanOptions {\n /** Absolute path to the repo root. */\n repoRoot: string\n /** Explicit file list (paths relative to repoRoot) for context-specific finders. */\n scanFiles: string[]\n /**\n * Auto-derived scan: walk these dirs for files matching importGlob + the\n * string `importsContain` and run the universal finders on them. Pattern\n * from starter-foundry H4 (research/decisions/001) — catches new files\n * with agent-eval import that would otherwise escape context-specific\n * scan lists.\n */\n autoDerive?: {\n roots: string[] // e.g. ['src', 'scripts']\n extensions: RegExp // e.g. /\\.(ts|mjs|js)$/\n importsContain: string // e.g. '@tangle-network/agent-eval'\n universalFinders: MuffledFinder[]\n }\n /** Per-file finders (context-specific patterns). */\n finders: MuffledFinder[]\n}\n\n/**\n * Strip line comments + block-comment continuation lines from a single line\n * so finders don't match prose about the pattern.\n */\nfunction codeOf(line: string): string {\n return line.replace(/\\/\\/.*$/, '').replace(/^\\s*\\*.*$/, '')\n}\n\n/** Skip if the line carries the `muffle-ok:` escape hatch. */\nfunction isMuffleOk(line: string): boolean {\n return line.includes('muffle-ok:')\n}\n\n/**\n * Default finder: `command || true` in a testCommand/setupCommand/cmd/command\n * string. Swallows exit codes.\n */\nexport const findFallbackToPass: MuffledFinder = (file, text) => {\n const out: MuffledFinding[] = []\n const lines = text.split('\\n')\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i]!\n if (isMuffleOk(line)) continue\n const code = codeOf(line)\n if (!code.trim()) continue\n if (/\\|\\| true/.test(code) && /(testCommand|setupCommand|cmd|command)/.test(code)) {\n out.push({\n file,\n line: i + 1,\n lineText: line.trim(),\n pattern: 'fallback-to-pass (|| true in command string)',\n })\n }\n }\n return out\n}\n\n/**\n * `testCommand: 'true'` literal silent-pass — an unknown-language dispatch\n * arm that returns a no-op instead of throwing.\n */\nexport const findLiteralTruePass: MuffledFinder = (file, text) => {\n const out: MuffledFinding[] = []\n const lines = text.split('\\n')\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i]!\n if (isMuffleOk(line)) continue\n const code = codeOf(line)\n if (!code.trim()) continue\n if (/testCommand\\s*:\\s*['\"]true['\"]/.test(code)) {\n out.push({\n file,\n line: i + 1,\n lineText: line.trim(),\n pattern: 'literal-true-pass (testCommand: \"true\")',\n })\n }\n }\n return out\n}\n\n/**\n * `new SubprocessSandboxDriver({ cwd: ... })` — constructor arg silently\n * dropped in agent-eval <0.7.1. 0.7.1+ honors as fallback, but the form\n * still invites confusion; prefer `new SubprocessSandboxDriver()` with\n * cwd in the per-call HarnessConfig.\n */\nexport const findConstructorCwdDropped: MuffledFinder = (file, text) => {\n const out: MuffledFinding[] = []\n const lines = text.split('\\n')\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i]!\n if (isMuffleOk(line)) continue\n const code = codeOf(line)\n if (!code.trim()) continue\n if (/new\\s+SubprocessSandboxDriver\\s*\\(\\s*\\{[^}]*cwd\\s*:/.test(code)) {\n out.push({\n file,\n line: i + 1,\n lineText: line.trim(),\n pattern:\n 'construct-vs-call cwd dropped (driver.exec reads config.cwd, not constructor.cwd)',\n })\n }\n }\n return out\n}\n\n/**\n * `if (!expected) return true` — matcher auto-passes when ground truth is\n * absent. Inflates accuracy metrics for scenarios without expectations.\n */\nexport const findAutoMatchNoExpectation: MuffledFinder = (file, text) => {\n const out: MuffledFinding[] = []\n const lines = text.split('\\n')\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i]!\n if (isMuffleOk(line)) continue\n const code = codeOf(line)\n if (!code.trim()) continue\n if (/if\\s*\\(\\s*!expected\\s*\\)\\s*return\\s+true/.test(code)) {\n out.push({\n file,\n line: i + 1,\n lineText: line.trim(),\n pattern: 'auto-match-no-expectation (if (!expected) return true)',\n })\n }\n }\n return out\n}\n\n/**\n * `if (p.skipped) return true` — skip-counts-as-pass in quality scorers.\n * Use three-valued `true | false | 'skipped'` return + explicit partial\n * credit instead.\n */\nexport const findSkipCountsAsPass: MuffledFinder = (file, text) => {\n const out: MuffledFinding[] = []\n const lines = text.split('\\n')\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i]!\n if (isMuffleOk(line)) continue\n const code = codeOf(line)\n if (!code.trim()) continue\n if (/if\\s*\\(\\s*\\w+\\.skipped\\s*\\)\\s*return\\s+true/.test(code)) {\n out.push({\n file,\n line: i + 1,\n lineText: line.trim(),\n pattern: 'skip-counts-as-pass (if (.skipped) return true)',\n })\n }\n }\n return out\n}\n\n/**\n * The canonical default bundle. Callers can import these individually,\n * replace them, or append custom finders for project-specific patterns.\n */\nexport const DEFAULT_FINDERS: MuffledFinder[] = [\n findFallbackToPass,\n findLiteralTruePass,\n findAutoMatchNoExpectation,\n findSkipCountsAsPass,\n]\n\n/** Finders that should run on EVERY file with the target import, not just SCAN_FILES. */\nexport const UNIVERSAL_FINDERS: MuffledFinder[] = [findConstructorCwdDropped]\n\n/**\n * Walk `roots` under `repoRoot` and return file paths (relative to repoRoot)\n * whose contents include `importsContain`.\n */\nfunction autoDeriveImporters(\n repoRoot: string,\n roots: string[],\n extensions: RegExp,\n importsContain: string,\n): string[] {\n const matches: string[] = []\n const walk = (rel: string) => {\n const abs = join(repoRoot, rel)\n if (!existsSync(abs)) return\n for (const entry of readdirSync(abs)) {\n const sub = join(rel, entry)\n const subAbs = join(repoRoot, sub)\n let st: ReturnType<typeof statSync>\n try {\n st = statSync(subAbs)\n } catch {\n continue\n }\n if (st.isDirectory()) {\n if (\n entry === 'node_modules' ||\n entry === 'dist' ||\n entry === 'dist-tests' ||\n entry.startsWith('.')\n )\n continue\n walk(sub)\n } else if (st.isFile() && extensions.test(entry)) {\n if (entry.endsWith('.test.ts') || entry.endsWith('.test.mjs') || entry.endsWith('.test.js'))\n continue\n let text: string\n try {\n text = readFileSync(subAbs, 'utf8')\n } catch {\n continue\n }\n if (text.includes(importsContain)) matches.push(sub)\n }\n }\n }\n for (const r of roots) walk(r)\n return matches\n}\n\n/**\n * Run all finders against the configured files. Returns a flat list of\n * findings. Callers format + assert as they prefer.\n */\nexport function scanForMuffledGates(opts: ScanOptions): MuffledFinding[] {\n const findings: MuffledFinding[] = []\n const scanned = new Set<string>()\n\n // Context-specific: run all finders on explicit SCAN_FILES.\n for (const file of opts.scanFiles) {\n const abs = join(opts.repoRoot, file)\n if (!existsSync(abs)) continue\n const text = readFileSync(abs, 'utf8')\n for (const find of opts.finders) findings.push(...find(file, text))\n scanned.add(file)\n }\n\n // Auto-derived: run universal finders on every importer not already scanned.\n if (opts.autoDerive) {\n const importers = autoDeriveImporters(\n opts.repoRoot,\n opts.autoDerive.roots,\n opts.autoDerive.extensions,\n opts.autoDerive.importsContain,\n )\n for (const file of importers) {\n if (scanned.has(file)) continue\n const abs = join(opts.repoRoot, file)\n if (!existsSync(abs)) continue\n const text = readFileSync(abs, 'utf8')\n for (const find of opts.autoDerive.universalFinders) findings.push(...find(file, text))\n }\n }\n\n return findings\n}\n\n/**\n * Format findings into a single assert.fail-ready message. Each finding\n * carries file:line + pattern name + the offending line.\n */\nexport function formatFindings(findings: MuffledFinding[]): string {\n if (findings.length === 0) return ''\n return [\n `Found ${findings.length} muffled-gate pattern(s).`,\n `Fix each or annotate the line with \"// muffle-ok: <reason>\".`,\n '',\n ...findings.map((f) => ` ${f.file}:${f.line} — ${f.pattern}\\n ${f.lineText}`),\n ].join('\\n')\n}\n","/**\n * Declarative oracles — ground-truth assertions without an LLM.\n *\n * Lifted from browser-agent-driver's _oracle.mjs. When you know the\n * expected outcome exactly (a URL, a text fragment, a JSON shape), you\n * don't need an LLM judge — you need a regex. These oracles are\n * composable pass/fail checks over an observation bundle.\n *\n * Each oracle returns { pass, detail, evidence? } and has a short\n * `id` for reporting. `evaluateOracles` runs a batch and aggregates.\n */\n\nexport interface OracleObservation {\n /** Final observable text output from the agent (response, page snapshot, stdout). */\n text?: string\n /** Final URL — for browser-style scenarios. */\n url?: string\n /** Any structured JSON the agent produced. */\n json?: unknown\n /** Free-form context used by custom oracles. */\n context?: Record<string, unknown>\n}\n\nexport interface OracleResult {\n id: string\n pass: boolean\n detail: string\n evidence?: string\n}\n\nexport interface Oracle {\n id: string\n check(obs: OracleObservation): OracleResult\n}\n\nexport function textInSnapshot(needle: string, opts: { caseSensitive?: boolean } = {}): Oracle {\n const id = `text-in-snapshot(${needle})`\n return {\n id,\n check(obs) {\n const hay = obs.text ?? ''\n const found = opts.caseSensitive\n ? hay.includes(needle)\n : hay.toLowerCase().includes(needle.toLowerCase())\n return {\n id,\n pass: found,\n detail: found ? `\"${needle}\" found` : `\"${needle}\" not present in observation`,\n evidence: found ? excerpt(hay, needle, opts.caseSensitive) : undefined,\n }\n },\n }\n}\n\nexport function urlContains(fragment: string): Oracle {\n const id = `url-contains(${fragment})`\n return {\n id,\n check(obs) {\n const url = obs.url ?? ''\n const pass = url.toLowerCase().includes(fragment.toLowerCase())\n return {\n id,\n pass,\n detail: pass ? `url ok (${url})` : `url \"${url}\" missing \"${fragment}\"`,\n evidence: url,\n }\n },\n }\n}\n\nexport function jsonShape(expected: Record<string, unknown>): Oracle {\n const id = `json-shape(${Object.keys(expected).join(',')})`\n return {\n id,\n check(obs) {\n const json = obs.json\n if (!isObject(json)) {\n return { id, pass: false, detail: 'observation.json missing or not an object' }\n }\n for (const [k, v] of Object.entries(expected)) {\n if (!(k in json)) return { id, pass: false, detail: `key \"${k}\" missing` }\n const actual = (json as Record<string, unknown>)[k]\n if (typeof v === 'string' && v.startsWith('re:')) {\n const re = new RegExp(v.slice(3))\n if (typeof actual !== 'string' || !re.test(actual)) {\n return { id, pass: false, detail: `key \"${k}\" failed regex ${v}` }\n }\n } else if (actual !== v) {\n return {\n id,\n pass: false,\n detail: `key \"${k}\" = ${JSON.stringify(actual)}, expected ${JSON.stringify(v)}`,\n }\n }\n }\n return { id, pass: true, detail: 'all keys match' }\n },\n }\n}\n\nexport function regexMatches(pattern: RegExp): Oracle {\n const id = `regex(${pattern.source})`\n return {\n id,\n check(obs) {\n const hay = obs.text ?? ''\n const m = hay.match(pattern)\n return {\n id,\n pass: m !== null,\n detail: m ? `matched \"${m[0]}\"` : `pattern ${pattern.source} not matched`,\n evidence: m?.[0],\n }\n },\n }\n}\n\n/**\n * Anti-bot detector — distinguishes genuine failures from blocked navigation\n * (cloudflare, recaptcha, etc). Returns an Oracle that PASSES when no block\n * marker is present; on block, detail names the blocker so runners can tag\n * results as \"blocked\" rather than \"failed\". Lifted from browser-agent-driver.\n */\nexport function notBlocked(): Oracle {\n const id = 'not-blocked'\n const markers: Array<{ name: string; re: RegExp }> = [\n { name: 'cloudflare', re: /just a moment|verifying you are human|cf-chl-|cloudflare/i },\n { name: 'recaptcha', re: /recaptcha|i'?m not a robot|challenge.?form/i },\n { name: 'hcaptcha', re: /hcaptcha/i },\n { name: 'akamai', re: /akamai|pragma: no-cache/i },\n { name: 'perimeterx', re: /perimeterx|px-captcha/i },\n { name: 'rate-limit', re: /rate.?limit|429 too many requests/i },\n { name: 'access-denied', re: /access denied|403 forbidden/i },\n ]\n return {\n id,\n check(obs) {\n const hay = obs.text ?? ''\n for (const { name, re } of markers) {\n if (re.test(hay)) {\n return {\n id,\n pass: false,\n detail: `blocked by ${name}`,\n evidence: (hay.match(re) ?? [])[0],\n }\n }\n }\n return { id, pass: true, detail: 'no anti-bot block detected' }\n },\n }\n}\n\nexport interface OracleReport {\n results: OracleResult[]\n pass: boolean\n passCount: number\n failCount: number\n /** 0-1 ratio of oracles passed. */\n score: number\n}\n\n/** Run all oracles against one observation and aggregate. */\nexport function evaluateOracles(obs: OracleObservation, oracles: Oracle[]): OracleReport {\n const results = oracles.map((o) => o.check(obs))\n const passCount = results.filter((r) => r.pass).length\n const failCount = results.length - passCount\n return {\n results,\n pass: failCount === 0 && results.length > 0,\n passCount,\n failCount,\n score: results.length ? passCount / results.length : 0,\n }\n}\n\nfunction excerpt(hay: string, needle: string, caseSensitive = false): string {\n const haySearch = caseSensitive ? hay : hay.toLowerCase()\n const needleSearch = caseSensitive ? needle : needle.toLowerCase()\n const idx = haySearch.indexOf(needleSearch)\n if (idx === -1) return ''\n const start = Math.max(0, idx - 20)\n const end = Math.min(hay.length, idx + needle.length + 20)\n return (start > 0 ? '…' : '') + hay.slice(start, end) + (end < hay.length ? '…' : '')\n}\n\nfunction isObject(v: unknown): v is Record<string, unknown> {\n return typeof v === 'object' && v !== null && !Array.isArray(v)\n}\n","/**\n * Deterministic held-out partitioning over stable ids.\n *\n * A promotion gate's paired-delta math needs a fixed partition: the same\n * scenario id lands in the same bucket forever, regardless of when it ran or\n * which loop emitted the record — otherwise the gate has nothing paired to\n * compare against. Picking one global split per run is wrong: every run then\n * stamps either ALL search or ALL holdout, and no id is ever observed on both\n * sides. Per-id deterministic hashing fixes that.\n *\n * Two consumers hand-roll this (agent-builder's `deterministicSplit` and the\n * frontier persona-splitter). The substrate already has a 3-way benchmark\n * `deterministicSplit` in `./benchmarks`; this is the generic, validated batch\n * partitioner: it takes a list of ids, splits them by a stable FNV-1a hash, and\n * fails loud when the inputs can't support a trustworthy held-out comparison\n * (duplicate ids, or a holdout set below the significance floor).\n */\n\nimport { ValidationError } from './errors'\n\n/** 32-bit FNV-1a hash. Stable, allocation-free, deterministic across runtimes —\n * the same id+seed maps to the same bucket on every machine and process. */\nexport function fnv1a32(input: string): number {\n let h = 0x811c9dc5\n for (let i = 0; i < input.length; i++) {\n h ^= input.charCodeAt(i) & 0xff\n h = Math.imul(h, 0x01000193)\n }\n return h >>> 0\n}\n\n/** Map an id+seed to the half-open unit interval [0, 1) deterministically. */\nexport function hashToUnit(id: string, seed: string): number {\n // Newline separator: 'ab' + '\\n' + 'c' can't collide with 'a' + '\\n' + 'bc'.\n return fnv1a32(`${id}\\n${seed}`) / 0x1_0000_0000\n}\n\nexport interface PartitionHeldOutOptions {\n /** Partition seed. Bumping it reshuffles every assignment — do that only when\n * the corpus/policy changes meaningfully so old and new records can't pair.\n * Default 'held-out-v1'. */\n seed?: string\n /** Fraction routed to the held-out bucket, in (0, 1). Default 0.5. */\n holdoutFraction?: number\n /**\n * Minimum held-out ids required for the split to be admissible. Below this,\n * a paired comparison has too few observations to be significant, so the\n * partition throws rather than hand back an underpowered holdout. Default 1\n * (only the empty-holdout degenerate case is rejected). Raise it to enforce\n * real statistical power. */\n minHoldout?: number\n /** Same floor for the search side. Default 1. */\n minSearch?: number\n}\n\nexport interface HeldOutPartition {\n /** Ids the optimizer is allowed to read/optimize against. */\n search: string[]\n /** Ids reserved for gated, held-out evaluation. */\n holdout: string[]\n seed: string\n holdoutFraction: number\n}\n\n/**\n * Assign a single id to `'search'` or `'holdout'` deterministically. Same\n * `(id, seed)` always returns the same tag — the invariant the gate relies on.\n * Use this in a `splitTag:` field literal when stamping records one at a time;\n * use `partitionHeldOut` when you have the whole id list up front and want the\n * validated disjoint split.\n */\nexport function assignHeldOutTag(\n id: string,\n options: { seed?: string; holdoutFraction?: number } = {},\n): 'search' | 'holdout' {\n const seed = options.seed ?? 'held-out-v1'\n const holdoutFraction = options.holdoutFraction ?? 0.5\n assertFraction(holdoutFraction)\n return hashToUnit(id, seed) < holdoutFraction ? 'holdout' : 'search'\n}\n\n/**\n * Partition a list of stable ids into disjoint `search` / `holdout` sets by a\n * deterministic hash. Fail-loud:\n * - empty input throws,\n * - duplicate ids throw (a dup would be observed on both sides, double-counting),\n * - a holdout (or search) set below its floor throws (underpowered comparison).\n *\n * Order within each bucket follows the input order, so the result is stable and\n * reproducible.\n */\nexport function partitionHeldOut(\n ids: string[],\n options: PartitionHeldOutOptions = {},\n): HeldOutPartition {\n const seed = options.seed ?? 'held-out-v1'\n const holdoutFraction = options.holdoutFraction ?? 0.5\n const minHoldout = options.minHoldout ?? 1\n const minSearch = options.minSearch ?? 1\n assertFraction(holdoutFraction)\n if (ids.length === 0) {\n throw new ValidationError('partitionHeldOut: no ids supplied')\n }\n\n const seen = new Set<string>()\n const search: string[] = []\n const holdout: string[] = []\n for (const id of ids) {\n if (typeof id !== 'string' || id.length === 0) {\n throw new ValidationError(\n `partitionHeldOut: ids must be non-empty strings, got ${JSON.stringify(id)}`,\n )\n }\n if (seen.has(id)) {\n throw new ValidationError(\n `partitionHeldOut: duplicate id \"${id}\" — a paired comparison must not double-count`,\n )\n }\n seen.add(id)\n if (hashToUnit(id, seed) < holdoutFraction) holdout.push(id)\n else search.push(id)\n }\n\n if (holdout.length < minHoldout) {\n throw new ValidationError(\n `partitionHeldOut: holdout set has ${holdout.length} id(s), below the floor of ${minHoldout} ` +\n `(n=${ids.length}, holdoutFraction=${holdoutFraction}) — too few for a significant comparison`,\n )\n }\n if (search.length < minSearch) {\n throw new ValidationError(\n `partitionHeldOut: search set has ${search.length} id(s), below the floor of ${minSearch} ` +\n `(n=${ids.length}, holdoutFraction=${holdoutFraction})`,\n )\n }\n\n return { search, holdout, seed, holdoutFraction }\n}\n\nfunction assertFraction(f: number): void {\n if (!Number.isFinite(f) || f <= 0 || f >= 1) {\n throw new ValidationError(`partitionHeldOut: holdoutFraction must be in (0, 1), got ${f}`)\n }\n}\n","/**\n * @stable\n *\n * Eval scorecard — the persistent (persona × profile) score timeline.\n *\n * Every benchmark run folds into per-cell entries; a cell is\n * `(scenarioId, profileHash)` and its timeline carries one entry per commit.\n * The scorecard answers the question a single run cannot: did THIS change\n * regress persona P on profile F, even while the aggregate improved?\n *\n * Storage is an append-only JSONL log — one line per (cell, commit). Appends\n * never read-modify-write, so concurrent campaign runs cannot clobber each\n * other; `loadScorecard` folds the log into the queryable `Scorecard`, and a\n * malformed line never breaks the read. `diffScorecard` compares the latest\n * entry of each cell against its predecessor with Cohen's d + Welch's t-test.\n */\n\nimport { appendFileSync, existsSync, mkdirSync, readFileSync } from 'node:fs'\nimport { dirname } from 'node:path'\nimport type { AgentProfile } from './agent-profile'\nimport { agentProfileHash, agentProfileModelId } from './agent-profile'\nimport { welchsTTest } from './baseline'\nimport { type RunRecord, runTaskScore } from './run-record'\nimport { cohensD } from './statistics'\n\n// ── Types ────────────────────────────────────────────────────────────\n\n/** One commit's measurement of one (scenario, profile) cell. */\nexport interface ScorecardEntry {\n commitSha: string\n /** ISO timestamp the entry was recorded. */\n timestamp: string\n /** Per-seed (or per-rep) scores for this cell at this commit. */\n scores: number[]\n /** Median of `scores` — the cell's headline score for the commit. */\n composite: number\n /** Per-dimension means, when the runs carried a judge breakdown. */\n perDimension?: Record<string, number>\n /** RunRecord ids folded into this entry — provenance. */\n runIds: string[]\n}\n\n/** A (scenario, profile) cell and its commit-ordered score timeline. */\nexport interface ScorecardCell {\n scenarioId: string\n profileHash: string\n /** Model id — denormalised from the profile for readable filtering. */\n model: string\n timeline: ScorecardEntry[]\n}\n\n/** The folded scorecard: every cell, plus the profile definitions by hash. */\nexport interface Scorecard {\n cells: ScorecardCell[]\n /** Profile definitions seen — keeps the scorecard self-describing. */\n profiles: Record<string, AgentProfile>\n}\n\n/** One append-only log line — a single cell's entry for a single commit. */\nexport interface ScorecardLogLine {\n scenarioId: string\n profileHash: string\n model: string\n profile: AgentProfile\n entry: ScorecardEntry\n}\n\n// ── Recording ────────────────────────────────────────────────────────\n\nexport interface RecordRunsOptions {\n /** The profile that produced these runs — keys the cell. */\n profile: AgentProfile\n commitSha: string\n /** Defaults to `new Date().toISOString()`. */\n timestamp?: string\n}\n\nfunction median(xs: number[]): number {\n if (xs.length === 0) return 0\n const sorted = [...xs].sort((a, b) => a - b)\n const mid = Math.floor(sorted.length / 2)\n return sorted.length % 2 === 0 ? (sorted[mid - 1]! + sorted[mid]!) / 2 : sorted[mid]!\n}\n\n// Cells rank on `runTaskScore` — RAW on purpose: a scorecard reports the\n// measurement, and hiding a gamed run's score behind a 0 would make the gaming\n// invisible in the report.\n\n/** Mean of each judge dimension across the runs that reported one. */\nfunction aggregatePerDimension(runs: RunRecord[]): Record<string, number> | undefined {\n const sums = new Map<string, { total: number; count: number }>()\n for (const run of runs) {\n const dims = run.outcome.judgeScores?.perDimMean\n if (!dims) continue\n for (const [dim, value] of Object.entries(dims)) {\n if (!Number.isFinite(value)) continue\n const acc = sums.get(dim) ?? { total: 0, count: 0 }\n acc.total += value\n acc.count += 1\n sums.set(dim, acc)\n }\n }\n if (sums.size === 0) return undefined\n const out: Record<string, number> = {}\n for (const [dim, acc] of sums) out[dim] = acc.total / acc.count\n return out\n}\n\n/**\n * Fold a benchmark's `RunRecord[]` into per-cell scorecard log lines — one\n * line per scenario the runs cover. All runs are attributed to the single\n * `profile` in `opts` (the harness ran them under it); the cell key is\n * `(scenarioId, agentProfileHash(profile))`.\n */\nexport function recordRuns(runs: RunRecord[], opts: RecordRunsOptions): ScorecardLogLine[] {\n const profileHash = agentProfileHash(opts.profile)\n const model = agentProfileModelId(opts.profile)\n const timestamp = opts.timestamp ?? new Date().toISOString()\n\n const byScenario = new Map<string, RunRecord[]>()\n for (const run of runs) {\n const scenarioId = run.scenarioId\n if (!scenarioId) continue // un-keyed run — cannot place it in a cell\n const bucket = byScenario.get(scenarioId)\n if (bucket) bucket.push(run)\n else byScenario.set(scenarioId, [run])\n }\n\n const lines: ScorecardLogLine[] = []\n for (const [scenarioId, scenarioRuns] of byScenario) {\n const scored = scenarioRuns\n .map((run) => ({ run, score: runTaskScore(run) }))\n .filter((s): s is { run: RunRecord; score: number } => s.score !== undefined)\n if (scored.length === 0) continue\n const scores = scored.map((s) => s.score)\n const entry: ScorecardEntry = {\n commitSha: opts.commitSha,\n timestamp,\n scores,\n composite: median(scores),\n runIds: scored.map((s) => s.run.runId),\n }\n const perDimension = aggregatePerDimension(scenarioRuns)\n if (perDimension) entry.perDimension = perDimension\n lines.push({\n scenarioId,\n profileHash,\n model,\n profile: opts.profile,\n entry,\n })\n }\n return lines\n}\n\n// ── Storage ──────────────────────────────────────────────────────────\n\n/** Append cell entries to the JSONL scorecard log. Creates the file/dir. */\nexport function appendScorecard(logPath: string, lines: ScorecardLogLine[]): void {\n if (lines.length === 0) return\n mkdirSync(dirname(logPath), { recursive: true })\n appendFileSync(logPath, `${lines.map((line) => JSON.stringify(line)).join('\\n')}\\n`)\n}\n\n/** Record runs and append them to the log in one call. Returns the lines. */\nexport function recordRunsToScorecard(\n logPath: string,\n runs: RunRecord[],\n opts: RecordRunsOptions,\n): ScorecardLogLine[] {\n const lines = recordRuns(runs, opts)\n appendScorecard(logPath, lines)\n return lines\n}\n\n/**\n * Fold the JSONL log into a queryable `Scorecard`. A missing file yields an\n * empty scorecard; a malformed line is skipped — a corrupt append never\n * breaks the read. Each cell's timeline is sorted chronologically.\n */\nexport function loadScorecard(logPath: string): Scorecard {\n if (!existsSync(logPath)) return { cells: [], profiles: {} }\n const cells = new Map<string, ScorecardCell>()\n const profiles: Record<string, AgentProfile> = {}\n\n for (const raw of readFileSync(logPath, 'utf8').split('\\n')) {\n const line = raw.trim()\n if (!line) continue\n let parsed: ScorecardLogLine\n try {\n parsed = JSON.parse(line) as ScorecardLogLine\n } catch {\n continue // skip a malformed line rather than failing the whole read\n }\n if (!parsed?.scenarioId || !parsed.profileHash || !parsed.entry) continue\n const key = `${parsed.scenarioId}::${parsed.profileHash}`\n let cell = cells.get(key)\n if (!cell) {\n cell = {\n scenarioId: parsed.scenarioId,\n profileHash: parsed.profileHash,\n model: parsed.model,\n timeline: [],\n }\n cells.set(key, cell)\n }\n cell.timeline.push(parsed.entry)\n if (parsed.profile) profiles[parsed.profileHash] = parsed.profile\n }\n\n for (const cell of cells.values()) {\n cell.timeline.sort((a, b) => a.timestamp.localeCompare(b.timestamp))\n }\n return { cells: [...cells.values()], profiles }\n}\n\n// ── Diff ─────────────────────────────────────────────────────────────\n\nexport type CellVerdict = 'improved' | 'regressed' | 'flat' | 'new'\n\nexport interface ScorecardCellDiff {\n scenarioId: string\n profileHash: string\n model: string\n verdict: CellVerdict\n /** Composite of the latest entry. */\n current: number\n /** Composite of the comparison entry — `null` when `verdict === 'new'`. */\n baseline: number | null\n /** `current − baseline` — `null` when new. */\n delta: number | null\n /** Cohen's d of current vs baseline samples — `null` when new or n < 2. */\n cohensD: number | null\n /** Welch's t-test p-value — `null` when new or n < 2. */\n pValue: number | null\n currentCommit: string\n baselineCommit: string | null\n}\n\nexport interface ScorecardDiff {\n cells: ScorecardCellDiff[]\n summary: { improved: number; regressed: number; flat: number; new: number }\n}\n\nexport interface DiffScorecardOptions {\n /** Compare each cell against this commit instead of its immediate predecessor. */\n baselineCommit?: string\n /** |Cohen's d| at/above which a move counts as real. Default 0.5. */\n minEffect?: number\n /** p-value at/below which a move is significant. Default 0.05. */\n maxP?: number\n /**\n * |delta| at/above which a move counts when statistics are unavailable\n * (a cell with fewer than 2 samples on either side). Default 0.05.\n */\n minDelta?: number\n}\n\n/**\n * Compare the latest entry of every cell against its predecessor (or against\n * `baselineCommit`) and classify the move. A move is `improved`/`regressed`\n * only when it clears both the effect-size and significance gates; otherwise\n * `flat`. Cells with no prior entry are `new`.\n */\nexport function diffScorecard(\n scorecard: Scorecard,\n opts: DiffScorecardOptions = {},\n): ScorecardDiff {\n const minEffect = opts.minEffect ?? 0.5\n const maxP = opts.maxP ?? 0.05\n const minDelta = opts.minDelta ?? 0.05\n\n const cells: ScorecardCellDiff[] = []\n for (const cell of scorecard.cells) {\n const timeline = cell.timeline\n if (timeline.length === 0) continue\n const current = timeline[timeline.length - 1]!\n\n const baseline = opts.baselineCommit\n ? [...timeline].reverse().find((e) => e.commitSha === opts.baselineCommit && e !== current)\n : timeline[timeline.length - 2]\n\n const base: Omit<\n ScorecardCellDiff,\n 'verdict' | 'baseline' | 'delta' | 'cohensD' | 'pValue' | 'baselineCommit'\n > = {\n scenarioId: cell.scenarioId,\n profileHash: cell.profileHash,\n model: cell.model,\n current: current.composite,\n currentCommit: current.commitSha,\n }\n\n if (!baseline) {\n cells.push({\n ...base,\n verdict: 'new',\n baseline: null,\n delta: null,\n cohensD: null,\n pValue: null,\n baselineCommit: null,\n })\n continue\n }\n\n const delta = current.composite - baseline.composite\n const canStat = baseline.scores.length >= 2 && current.scores.length >= 2\n let d: number | null = null\n let p: number | null = null\n let verdict: CellVerdict\n\n if (canStat) {\n d = cohensD(baseline.scores, current.scores)\n const t = welchsTTest(baseline.scores, current.scores)\n p = Number.isFinite(t.p) ? t.p : null\n // `canStat` guarantees ≥ 2 samples per side, so a null d means zero\n // pooled spread across a real mean gap — an unbounded standardized\n // effect, which clears any finite threshold.\n const effectClears = d === null || Math.abs(d) >= minEffect\n const significant = effectClears && p !== null && p <= maxP\n verdict = significant ? (delta > 0 ? 'improved' : 'regressed') : 'flat'\n } else {\n // Too few samples for a real test — fall back to a raw-delta threshold.\n verdict = Math.abs(delta) >= minDelta ? (delta > 0 ? 'improved' : 'regressed') : 'flat'\n }\n\n cells.push({\n ...base,\n verdict,\n baseline: baseline.composite,\n delta,\n cohensD: d,\n pValue: p,\n baselineCommit: baseline.commitSha,\n })\n }\n\n const summary = { improved: 0, regressed: 0, flat: 0, new: 0 }\n for (const cell of cells) summary[cell.verdict] += 1\n return { cells, summary }\n}\n\n/**\n * Render a scorecard diff as a human-readable report — the block a feature\n * PR prints. Regressions are listed first; flat cells are summarised, not\n * enumerated.\n */\nexport function formatScorecardDiff(diff: ScorecardDiff): string {\n const lines: string[] = []\n const { summary } = diff\n lines.push(\n `Scorecard: ${summary.regressed} regressed · ${summary.improved} improved · ` +\n `${summary.flat} flat · ${summary.new} new`,\n )\n\n const fmt = (n: number) => n.toFixed(3)\n const noteworthy = diff.cells\n .filter((c) => c.verdict === 'regressed' || c.verdict === 'improved')\n .sort((a, b) => {\n // Regressions first, then by magnitude of delta.\n if (a.verdict !== b.verdict) return a.verdict === 'regressed' ? -1 : 1\n return Math.abs(b.delta ?? 0) - Math.abs(a.delta ?? 0)\n })\n\n for (const cell of noteworthy) {\n const mark = cell.verdict === 'regressed' ? 'REGRESSED' : 'improved'\n const deltaStr =\n cell.delta !== null ? (cell.delta >= 0 ? `+${fmt(cell.delta)}` : fmt(cell.delta)) : '—'\n const stat =\n cell.cohensD !== null\n ? ` (d=${cell.cohensD.toFixed(2)}${cell.pValue !== null ? `, p=${cell.pValue.toFixed(3)}` : ''})`\n : ''\n lines.push(\n ` ${mark} ${cell.scenarioId} · ${cell.model} · ${cell.profileHash.slice(0, 8)} ` +\n `${fmt(cell.baseline ?? 0)} → ${fmt(cell.current)} ${deltaStr}${stat}`,\n )\n }\n\n return lines.join('\\n')\n}\n","/**\n * SLO gates — quantified pass/fail primitives beyond score thresholds.\n *\n * Lifted from ADC's sandbox eval suite. Each SLO defines a metric, a\n * threshold, and a severity (critical | warning). Critical breaches fail\n * the eval; warnings are reported but don't gate CI. Margin is the\n * ratio of actual to threshold for histogramming \"how close are we?\"\n *\n * Consumers assemble their own SLO arrays; DEFAULT_AGENT_SLOS covers\n * the generic agent flow (provision, first token, pass rate, cost).\n */\n\nexport type SloSeverity = 'critical' | 'warning'\nexport type SloComparator = 'lte' | 'gte'\n\nexport interface Slo {\n /** Stable identifier — must be unique within an SLO set. */\n id: string\n /** Human description, shown in reports. */\n description: string\n /** Metric key looked up in the candidate record. */\n metric: string\n /** Whether the metric should stay below (lte) or above (gte) threshold. */\n comparator: SloComparator\n /** Threshold value. */\n threshold: number\n severity: SloSeverity\n}\n\nexport interface SloCheckResult {\n slo: Slo\n actual: number | undefined\n passed: boolean\n /** actual/threshold for lte, threshold/actual for gte. >1 means safe margin; <1 means breach. 0 when actual is missing. */\n margin: number\n detail: string\n}\n\nexport interface SloReport {\n results: SloCheckResult[]\n passedCritical: boolean\n criticalBreaches: SloCheckResult[]\n warnings: SloCheckResult[]\n}\n\n/**\n * Evaluate an SLO set against a candidate metrics object. Missing metrics\n * count as breaches — if you declared it, you must measure it.\n */\nexport function checkSlos(metrics: Record<string, number>, slos: Slo[]): SloReport {\n const results: SloCheckResult[] = slos.map((slo) => check(slo, metrics[slo.metric]))\n const criticalBreaches = results.filter((r) => !r.passed && r.slo.severity === 'critical')\n const warnings = results.filter((r) => !r.passed && r.slo.severity === 'warning')\n return { results, passedCritical: criticalBreaches.length === 0, criticalBreaches, warnings }\n}\n\nfunction check(slo: Slo, actual: number | undefined): SloCheckResult {\n if (actual === undefined || !Number.isFinite(actual)) {\n return {\n slo,\n actual,\n passed: false,\n margin: 0,\n detail: `metric \"${slo.metric}\" missing — declared SLOs must be measured`,\n }\n }\n if (slo.comparator === 'lte') {\n const passed = actual <= slo.threshold\n const margin = slo.threshold === 0 ? (actual === 0 ? Infinity : 0) : slo.threshold / actual\n return {\n slo,\n actual,\n passed,\n margin,\n detail: `${actual} ≤ ${slo.threshold}: ${passed ? 'ok' : 'breach'}`,\n }\n }\n const passed = actual >= slo.threshold\n const margin = actual === 0 ? 0 : actual / slo.threshold\n return {\n slo,\n actual,\n passed,\n margin,\n detail: `${actual} ≥ ${slo.threshold}: ${passed ? 'ok' : 'breach'}`,\n }\n}\n\n/** Reference SLO set for agent-style evals. Tune per-product by cloning + overriding. */\nexport const DEFAULT_AGENT_SLOS: Slo[] = [\n {\n id: 'provision_ms',\n description: 'Sandbox/session provision under 60s',\n metric: 'provisionMs',\n comparator: 'lte',\n threshold: 60_000,\n severity: 'critical',\n },\n {\n id: 'first_token_ms',\n description: 'First token under 15s',\n metric: 'firstTokenMs',\n comparator: 'lte',\n threshold: 15_000,\n severity: 'critical',\n },\n {\n id: 'pass_rate',\n description: 'Scenario pass rate ≥ 90%',\n metric: 'passRate',\n comparator: 'gte',\n threshold: 0.9,\n severity: 'critical',\n },\n {\n id: 'cost_usd',\n description: 'Per-scenario cost under $0.05',\n metric: 'costUsd',\n comparator: 'lte',\n threshold: 0.05,\n severity: 'warning',\n },\n {\n id: 'overall_score',\n description: 'Overall score ≥ 0.7',\n metric: 'overallScore',\n comparator: 'gte',\n threshold: 0.7,\n severity: 'critical',\n },\n]\n","/**\n * State continuity scoring — measures how well a resumed/handed-off agent\n * preserves prior work.\n *\n * When session 2 continues\n * session 1's work, the key question is: did it preserve key artifacts,\n * or start over and lose context? Each `ContinuityCheck` inspects one\n * aspect (file preserved, key count grew, status advanced) and yields\n * 0-1 credit; the aggregate is the simple mean.\n *\n * Generic over any \"snapshot\" shape — pass your own checks.\n */\n\nexport interface ContinuitySnapshotPair<T> {\n before: T\n after: T\n}\n\nexport interface ContinuityCheck<T> {\n /** Stable identifier; shown in the report. */\n id: string\n /** Description of what this check measures. */\n description: string\n /** Returns 0..1 credit for this dimension (1 = fully preserved/improved). */\n score: (pair: ContinuitySnapshotPair<T>) => number\n}\n\nexport interface ContinuityCheckResult {\n id: string\n description: string\n score: number\n pass: boolean\n}\n\nexport interface ContinuityReport {\n results: ContinuityCheckResult[]\n /** Mean of per-check scores, in 0..1. */\n overallScore: number\n /** True iff ALL checks scored ≥ passThreshold. */\n pass: boolean\n}\n\nexport function scoreContinuity<T>(\n pair: ContinuitySnapshotPair<T>,\n checks: ContinuityCheck<T>[],\n options: { passThreshold?: number } = {},\n): ContinuityReport {\n if (checks.length === 0) {\n throw new Error('scoreContinuity: at least 1 check required')\n }\n const passThreshold = options.passThreshold ?? 0.8\n const results: ContinuityCheckResult[] = checks.map((c) => {\n const raw = c.score(pair)\n const clamped = Number.isFinite(raw) ? Math.max(0, Math.min(1, raw)) : 0\n return { id: c.id, description: c.description, score: clamped, pass: clamped >= passThreshold }\n })\n const overallScore = results.reduce((a, r) => a + r.score, 0) / results.length\n return { results, overallScore, pass: results.every((r) => r.pass) }\n}\n\n/** Common check: a required key in a record exists and equals the prior value. */\nexport function keyPreserved<T extends Record<string, unknown>>(\n key: keyof T & string,\n): ContinuityCheck<T> {\n return {\n id: `preserved(${key})`,\n description: `\"${key}\" unchanged from before to after`,\n score: ({ before, after }) => (before[key] !== undefined && before[key] === after[key] ? 1 : 0),\n }\n}\n\n/** Common check: a collection (array) grew or stayed the same size. */\nexport function collectionPreserved<T, K extends keyof T & string>(\n key: K,\n minRatio = 1,\n): ContinuityCheck<T> {\n return {\n id: `collection-preserved(${key})`,\n description: `\"${key}\" length ≥ ${minRatio} × prior length`,\n score: ({ before, after }) => {\n const b = before[key]\n const a = after[key]\n if (!Array.isArray(b) || !Array.isArray(a)) return 0\n if (b.length === 0) return a.length === 0 ? 1 : 1\n return Math.min(1, a.length / (b.length * minRatio))\n },\n }\n}\n\n/** Common check: a status field advanced in an expected order. */\nexport function statusAdvanced<T extends Record<string, unknown>>(\n key: keyof T & string,\n progression: readonly string[],\n): ContinuityCheck<T> {\n return {\n id: `status-advanced(${key})`,\n description: `\"${key}\" progressed along ${progression.join('→')}`,\n score: ({ before, after }) => {\n const bi = progression.indexOf(String(before[key]))\n const ai = progression.indexOf(String(after[key]))\n if (bi === -1 || ai === -1) return 0\n return ai >= bi ? 1 : 0\n },\n }\n}\n","/**\n * Verification-strategy family — the shared vocabulary for \"what certified\n * this result\", covering tasks with an answer key and tasks without one.\n *\n * Charter Wave 5 (docs/charter.md): an unsolved problem has no held-out\n * suite by definition, so the held-out suite must be ONE member of a\n * strategy family, not the family itself. This module carries the taxonomy\n * and the port shape only. A checker is an injected executable boundary\n * that returns a typed outcome, so a consumer binds its own kernel (a Lean\n * toolchain, a metamorphic harness, a replication runner) and this package\n * never chooses one. Instruments, never methods.\n *\n * Full family doc, per-member failure modes in prose, and the BCWW pilot\n * worked example: docs/verification-strategies.md.\n *\n * Leaf module: no imports from this package. `src/verdict.ts` and\n * `src/rl/verifiable-reward.ts` both build on these types.\n */\n\n/**\n * One member of the verification-strategy family.\n *\n * Every member has a documented failure mode — the specific way it can\n * certify a wrong result. A consumer that reads a certification must weigh\n * the member's failure mode, not treat \"certified\" as one bit.\n *\n * - `'compile'` — typecheck / build / lint passed. Deterministic.\n * Failure mode: code that compiles is not code that is correct; the\n * weakest deterministic member.\n * - `'test'` — unit / integration / held-out suite pass-rate. Deterministic.\n * Failure mode: assumes an answer key exists; certifies nothing outside\n * the suite's coverage, and a stubbed integration reports green.\n * - `'schema'` — structured output validates. Deterministic.\n * Failure mode: shape is not meaning; a well-formed wrong answer passes.\n * - `'sandbox'` — sandbox execution exit code. Deterministic.\n * Failure mode: an exit code compresses the whole run to one bit; a\n * faked success exits 0.\n * - `'judge'` — LLM judge score. Probabilistic.\n * Failure mode: drifts across model versions and is Goodhart-gameable by\n * the graded policy.\n * - `'composite'` — weighted blend across members. Determinism inherited\n * from its members.\n * Failure mode: scalar collapse — the blend hides which member carried\n * the score and which failed.\n * - `'proof-kernel'` — a proof assistant's kernel accepted a formal proof.\n * Deterministic.\n * Failure mode: the formalization gap. The kernel certifies the formal\n * statement, never that the formal statement matches the informal claim;\n * a proved theorem about the wrong statement is a wrong result with a\n * valid certificate. Discharge it with the blind statement-equivalence\n * protocol (`src/equivalence-check.ts`).\n * - `'invariant'` — invariant / metamorphic properties held on the result.\n * Deterministic.\n * Failure mode: weak invariants pass everything. An invariant set earns\n * weight only through seeded-bug calibration — a mutation the set\n * provably rejects; an uncalibrated set is a rubber stamp.\n * - `'replication'` — an independent re-execution reproduced the result\n * from pinned inputs. Deterministic given the pins.\n * Failure mode: replication re-runs the method, so it catches\n * nondeterminism and environment drift, never a methodological error the\n * method itself carries.\n * - `'agreement'` — independently-derived results agree. Probabilistic.\n * Failure mode: the shared blind spot. Derivers that share training\n * corpora, priors, or the same misread of the source agree for the same\n * wrong reason; the blindness provenance of each arm is what the\n * certificate rests on.\n */\nexport type VerificationStrategySource =\n | 'compile'\n | 'test'\n | 'schema'\n | 'sandbox'\n | 'judge'\n | 'composite'\n | 'proof-kernel'\n | 'invariant'\n | 'replication'\n | 'agreement'\n\n/**\n * What a strategy member can honestly claim about its outcomes.\n *\n * `determinism: 'inherited'` exists only for `'composite'`: a blend takes\n * the class of its members. The reward axis stays binary\n * (`VerifiableReward.determinism`); this registry describes the family,\n * it never scores a run.\n */\nexport interface VerificationStrategyProfile {\n /** Determinism class a well-formed checker of this member can claim. */\n determinism: 'deterministic' | 'probabilistic' | 'inherited'\n /** The documented way this member certifies a wrong result. */\n failureMode: string\n}\n\n/**\n * The family registry. `Record` over the union keeps it exhaustive: adding\n * a member to `VerificationStrategySource` without a profile here fails to\n * compile. The failure mode travels with the taxonomy so a reader of a\n * certification can surface it without this package's docs at hand.\n */\nexport const VERIFICATION_STRATEGIES: Record<\n VerificationStrategySource,\n VerificationStrategyProfile\n> = {\n compile: {\n determinism: 'deterministic',\n failureMode: 'code that compiles is not code that is correct',\n },\n test: {\n determinism: 'deterministic',\n failureMode:\n 'assumes an answer key; certifies nothing outside suite coverage, and a stubbed integration reports green',\n },\n schema: {\n determinism: 'deterministic',\n failureMode: 'shape is not meaning; a well-formed wrong answer passes',\n },\n sandbox: {\n determinism: 'deterministic',\n failureMode: 'an exit code compresses the run to one bit; a faked success exits 0',\n },\n judge: {\n determinism: 'probabilistic',\n failureMode: 'drifts across model versions and is Goodhart-gameable by the graded policy',\n },\n composite: {\n determinism: 'inherited',\n failureMode: 'scalar collapse: the blend hides which member carried the score',\n },\n 'proof-kernel': {\n determinism: 'deterministic',\n failureMode:\n 'the formalization gap: the kernel certifies the formal statement, never that it matches the informal claim',\n },\n invariant: {\n determinism: 'deterministic',\n failureMode:\n 'weak invariants pass everything; a set uncalibrated by seeded bugs is a rubber stamp',\n },\n replication: {\n determinism: 'deterministic',\n failureMode:\n 're-runs the method, so it catches drift and nondeterminism, never an error the method itself carries',\n },\n agreement: {\n determinism: 'probabilistic',\n failureMode:\n 'the shared blind spot: derivers with common corpora or priors agree for the same wrong reason',\n },\n}\n\n/** Every family member, derived from the registry so it cannot drift. */\nexport const VERIFICATION_STRATEGY_SOURCES = Object.keys(\n VERIFICATION_STRATEGIES,\n) as readonly VerificationStrategySource[]\n\n/**\n * Exact identity of the thing that checked. \"lean4 4.33.0 with Mathlib\n * db584cd6d46c\" and \"lean4, some version\" are different certificates: the\n * first is re-runnable, the second is a story.\n */\nexport interface CheckerIdentity {\n /** Toolchain or model name, e.g. `'lean4'` or a judge model id. */\n name: string\n /** Exact version or snapshot, e.g. `'4.33.0'` or a model snapshot id. */\n version: string\n /**\n * Content pins the version alone does not capture, e.g.\n * `{ mathlib: 'db584cd6d46c' }`. Keyed by dependency name.\n */\n pins?: Record<string, string>\n}\n\n/**\n * Typed outcome of an external checker call. Callers MUST inspect\n * `succeeded` before touching `value`; a failed check keeps its full error\n * text instead of collapsing to null.\n */\nexport type CheckerOutcome<Result> =\n | { succeeded: true; value: Result }\n | { succeeded: false; error: string }\n\n/**\n * The port shape every strategy binds through: an injected executable\n * boundary. This package defines the port and refuses to ship any\n * implementation behind it — the consumer binds its own kernel, invariant\n * harness, replication runner, or judge, and the binding carries its own\n * identity and determinism claim.\n *\n * A checker that ran but could not decide returns\n * `{ succeeded: false, error }` with the reason; `succeeded: true` is\n * reserved for a discharged check.\n */\nexport interface StrategyChecker<Input, Result> {\n /** Which family member this checker discharges obligations for. */\n strategy: VerificationStrategySource\n identity: CheckerIdentity\n /** Determinism class this checker claims for its outcomes. */\n determinism: 'deterministic' | 'probabilistic'\n check(input: Input): Promise<CheckerOutcome<Result>>\n}\n","/**\n * Statement-equivalence protocol — the blind two-arm design as a typed\n * primitive.\n *\n * The problem it closes is the proof-kernel failure mode (the\n * formalization gap): a kernel certifies a formal statement, never that\n * the formal statement matches the informal claim. The protocol makes the\n * gap measurable: two arms derive the formal statement independently and\n * blind to each other, then a checker discharges the obligation that the\n * two statements are equivalent. A statement mismatch is a successful\n * outcome — it is the formalization gap made visible with a separating\n * witness in hand.\n *\n * This module is pure contract + record types + the asymmetry refusals.\n * Execution binds through the same `StrategyChecker` port as every other\n * strategy (src/verification-strategy.ts): the consumer injects its own\n * kernel. The pilot record this shape reproduces was assembled by hand for\n * the BCWW (4.6) inequality; docs/verification-strategies.md carries the\n * worked example with artifact paths.\n *\n * The refusals are the design. An arm that saw the other arm's statement,\n * or the outcome it feeds, did not independently derive anything — the\n * check is invalid, and this module throws rather than record it.\n */\n\nimport type {\n CheckerIdentity,\n StrategyChecker,\n VerificationStrategySource,\n} from './verification-strategy'\nimport { VERIFICATION_STRATEGY_SOURCES } from './verification-strategy'\n\n/**\n * The two-arm blind design. `arms: 2` and `blind: true` are literal types\n * on purpose: a wider design is a different protocol, not a parameter.\n */\nexport interface EquivalenceCheckSpec {\n /**\n * The strategy member whose obligation the check discharges — the pilot\n * used `'proof-kernel'`: the Lean kernel proved the two statements\n * equivalent. The bound checker must declare the same member.\n */\n source: VerificationStrategySource\n /**\n * Stable identity of the claim under verification: a path, digest, or\n * citation. Pilot: arXiv:1507.05650 inequality (4.6) plus the\n * five-atom counterexample record.\n */\n artifact: string\n /** Exactly two independent arms. An N-arm design is not this protocol. */\n arms: 2\n /**\n * Blind derivation is the point: a non-blind run is not a weaker check,\n * it is no check. `false` is unrepresentable here and refused at runtime\n * for untyped callers.\n */\n blind: true\n}\n\n/** A validated, frozen spec. Produced only by `defineEquivalenceCheck`. */\nexport interface EquivalenceCheckDefinition {\n readonly spec: Readonly<EquivalenceCheckSpec>\n}\n\n/** One arm's committed statement plus the provenance the record rests on. */\nexport interface EquivalenceArm {\n armId: string\n /** The committed formal statement text (pilot: the arm's `Statement.lean` source). */\n statement: string\n /**\n * What this arm derived the statement from. Pilot arm A: the paper's\n * LaTeX source; pilot arm B: the campaign's artifacts. The two arms\n * SHOULD derive from different renderings of the claim — that is what\n * makes agreement informative.\n */\n derivedFrom: string\n /**\n * The blindness declaration. Both flags must be `true`; a `false` value\n * is refused loudly, because recording a non-blind arm would launder an\n * invalid check into a valid-looking record.\n */\n blindness: {\n /** This arm never saw any other arm's statement before committing its own. */\n toOtherArms: boolean\n /** This arm never saw the verification outcome before committing. */\n toOutcome: boolean\n }\n}\n\nexport type EquivalenceObligationStatus =\n | 'proved'\n | 'refuted-with-separating-witness'\n | 'unresolved'\n\n/**\n * The discharged (or undischarged) equivalence obligation.\n *\n * Field presence is status-dependent and enforced by\n * `buildEquivalenceRecord`:\n * - `'proved'` requires `evidenceDigest` and forbids `separatingWitness`.\n * - `'refuted-with-separating-witness'` requires both the witness and\n * `evidenceDigest`.\n * - `'unresolved'` requires `unresolvedReason` and forbids the witness —\n * an undischarged obligation keeps its diagnostic instead of faking\n * either verdict.\n */\nexport interface EquivalenceObligation {\n status: EquivalenceObligationStatus\n /** The input on which the two statements provably disagree. */\n separatingWitness?: string\n /** Why the obligation could not be discharged (checker error text, coverage limit). */\n unresolvedReason?: string\n /** The checker that ran (or failed to run) the obligation. */\n checker: CheckerIdentity\n /** Digest of the checker's evidence artifact (pilot: the kernel-checked `Check.lean` run). */\n evidenceDigest?: string\n}\n\n/** The record the protocol produces — the by-hand pilot record, typed. */\nexport interface EquivalenceRecord {\n spec: Readonly<EquivalenceCheckSpec>\n arms: readonly [EquivalenceArm, EquivalenceArm]\n obligation: EquivalenceObligation\n}\n\n/** Input the bound checker receives: the artifact identity and both committed statements. */\nexport interface EquivalenceCheckerInput {\n artifact: string\n statements: readonly [string, string]\n}\n\n/**\n * What a checker that RAN must return. `'unresolved'` is deliberately not\n * a checker result: a checker that could not decide returns\n * `{ succeeded: false, error }` through the port, and the protocol records\n * the unresolved obligation with that reason.\n */\nexport interface EquivalenceCheckerResult {\n status: 'proved' | 'refuted-with-separating-witness'\n /** Required when `status` is refuted. */\n separatingWitness?: string\n evidenceDigest: string\n}\n\n/** An equivalence checker is a `StrategyChecker` — same port as every strategy. */\nexport type EquivalenceChecker = StrategyChecker<EquivalenceCheckerInput, EquivalenceCheckerResult>\n\n/** A refused equivalence check. `code` names the exact refusal for programmatic handling. */\nexport class EquivalenceProtocolError extends Error {\n readonly code:\n | 'arm-count'\n | 'not-blind'\n | 'arm-saw-other'\n | 'arm-saw-outcome'\n | 'duplicate-arm-id'\n | 'empty-field'\n | 'unknown-source'\n | 'witness-missing'\n | 'witness-on-proved'\n | 'witness-on-unresolved'\n | 'reason-missing'\n | 'evidence-missing'\n | 'checker-strategy-mismatch'\n\n constructor(code: EquivalenceProtocolError['code'], message: string) {\n super(message)\n this.name = 'EquivalenceProtocolError'\n this.code = code\n }\n}\n\n/**\n * Validate and freeze a two-arm blind equivalence check spec.\n *\n * The literal types already refuse a wide design at compile time; the\n * runtime checks hold the same line for untyped callers. There is no\n * escape hatch: `arms: 3` or `blind: false` throws, never downgrades.\n */\nexport function defineEquivalenceCheck(spec: EquivalenceCheckSpec): EquivalenceCheckDefinition {\n if (spec.arms !== 2) {\n throw new EquivalenceProtocolError(\n 'arm-count',\n `equivalence check requires exactly 2 arms, received ${String(spec.arms)}`,\n )\n }\n if (spec.blind !== true) {\n throw new EquivalenceProtocolError(\n 'not-blind',\n 'equivalence check requires blind: true — a non-blind run is not a weaker check, it is no check',\n )\n }\n if (typeof spec.artifact !== 'string' || spec.artifact.trim() === '') {\n throw new EquivalenceProtocolError(\n 'empty-field',\n 'spec.artifact must identify the claim under verification',\n )\n }\n if (!VERIFICATION_STRATEGY_SOURCES.includes(spec.source)) {\n throw new EquivalenceProtocolError(\n 'unknown-source',\n `spec.source '${String(spec.source)}' is not a verification-strategy member`,\n )\n }\n return Object.freeze({ spec: Object.freeze({ ...spec }) })\n}\n\n/**\n * Assemble the equivalence record, refusing every asymmetry.\n *\n * Refusals (each throws `EquivalenceProtocolError`):\n * - an arm whose `blindness.toOtherArms` is false — it saw the other\n * statement, so nothing was independently derived;\n * - an arm whose `blindness.toOutcome` is false — it could steer its\n * statement toward (or away from) the known result;\n * - duplicate arm ids, empty statements, empty derivations;\n * - an obligation whose fields contradict its status (see\n * `EquivalenceObligation`).\n */\nexport function buildEquivalenceRecord(\n definition: EquivalenceCheckDefinition,\n arms: readonly [EquivalenceArm, EquivalenceArm],\n obligation: EquivalenceObligation,\n): EquivalenceRecord {\n assertArms(arms)\n assertObligation(obligation)\n return Object.freeze({\n spec: definition.spec,\n arms: Object.freeze([Object.freeze({ ...arms[0] }), Object.freeze({ ...arms[1] })] as const),\n obligation: Object.freeze({ ...obligation }),\n })\n}\n\n/**\n * Discharge the obligation through an injected checker and return the\n * record.\n *\n * Order matters: every arm refusal fires BEFORE the checker runs — an\n * invalid check must not spend. A checker whose `strategy` differs from\n * `spec.source` is refused for the same reason: a judge cannot silently\n * discharge a proof-kernel obligation.\n *\n * A checker failure (`succeeded: false`) is not thrown: it becomes an\n * `'unresolved'` obligation carrying the full error text, which is the\n * honest record of an undischarged check.\n */\nexport async function runEquivalenceCheck(\n definition: EquivalenceCheckDefinition,\n arms: readonly [EquivalenceArm, EquivalenceArm],\n checker: EquivalenceChecker,\n): Promise<EquivalenceRecord> {\n assertArms(arms)\n if (checker.strategy !== definition.spec.source) {\n throw new EquivalenceProtocolError(\n 'checker-strategy-mismatch',\n `spec.source is '${definition.spec.source}' but the bound checker declares '${checker.strategy}'`,\n )\n }\n const outcome = await checker.check({\n artifact: definition.spec.artifact,\n statements: [arms[0].statement, arms[1].statement],\n })\n if (!outcome.succeeded) {\n return buildEquivalenceRecord(definition, arms, {\n status: 'unresolved',\n unresolvedReason: outcome.error,\n checker: checker.identity,\n })\n }\n const { status, separatingWitness, evidenceDigest } = outcome.value\n return buildEquivalenceRecord(definition, arms, {\n status,\n ...(separatingWitness === undefined ? {} : { separatingWitness }),\n checker: checker.identity,\n evidenceDigest,\n })\n}\n\nfunction assertArms(arms: readonly [EquivalenceArm, EquivalenceArm]): void {\n if (arms.length !== 2) {\n throw new EquivalenceProtocolError(\n 'arm-count',\n `equivalence record requires exactly 2 arms, received ${arms.length}`,\n )\n }\n if (arms[0].armId === arms[1].armId) {\n throw new EquivalenceProtocolError(\n 'duplicate-arm-id',\n `both arms declare armId '${arms[0].armId}' — two labels for one derivation is one arm`,\n )\n }\n for (const arm of arms) {\n if (arm.statement.trim() === '') {\n throw new EquivalenceProtocolError(\n 'empty-field',\n `arm '${arm.armId}' committed an empty statement`,\n )\n }\n if (arm.derivedFrom.trim() === '') {\n throw new EquivalenceProtocolError(\n 'empty-field',\n `arm '${arm.armId}' declares no derivation provenance`,\n )\n }\n if (arm.blindness.toOtherArms !== true) {\n throw new EquivalenceProtocolError(\n 'arm-saw-other',\n `arm '${arm.armId}' saw another arm's statement — the derivation is not independent and the check is invalid`,\n )\n }\n if (arm.blindness.toOutcome !== true) {\n throw new EquivalenceProtocolError(\n 'arm-saw-outcome',\n `arm '${arm.armId}' saw the outcome before committing — the check is invalid`,\n )\n }\n }\n}\n\nfunction assertObligation(obligation: EquivalenceObligation): void {\n const { status, separatingWitness, unresolvedReason, evidenceDigest } = obligation\n if (status === 'refuted-with-separating-witness') {\n if (typeof separatingWitness !== 'string' || separatingWitness.trim() === '') {\n throw new EquivalenceProtocolError(\n 'witness-missing',\n 'a refuted equivalence must carry the separating witness — a refutation without one is an assertion',\n )\n }\n if (typeof evidenceDigest !== 'string' || evidenceDigest.trim() === '') {\n throw new EquivalenceProtocolError(\n 'evidence-missing',\n 'a refuted equivalence must carry its evidence digest',\n )\n }\n return\n }\n if (status === 'proved') {\n if (separatingWitness !== undefined) {\n throw new EquivalenceProtocolError(\n 'witness-on-proved',\n 'a proved equivalence cannot carry a separating witness — the two claims contradict',\n )\n }\n if (typeof evidenceDigest !== 'string' || evidenceDigest.trim() === '') {\n throw new EquivalenceProtocolError(\n 'evidence-missing',\n 'a proved equivalence must carry its evidence digest',\n )\n }\n return\n }\n // status === 'unresolved'\n if (separatingWitness !== undefined) {\n throw new EquivalenceProtocolError(\n 'witness-on-unresolved',\n 'an unresolved obligation cannot carry a separating witness — a witness in hand is a refutation',\n )\n }\n if (typeof unresolvedReason !== 'string' || unresolvedReason.trim() === '') {\n throw new EquivalenceProtocolError(\n 'reason-missing',\n \"an unresolved obligation must say why — 'unresolved' with no reason erases the diagnostic\",\n )\n }\n}\n","/**\n * UI audit finding — substrate primitive for \"what is wrong with the UI?\"\n *\n * Used by:\n * - `@tangle-network/agent-runtime` (ui-auditor profile + delegate) —\n * produced as the canonical output of an audit iteration, persisted to\n * disk as GitHub-issue Markdown, surfaced over MCP.\n * - Downstream ship gates / dashboards / analyst consumers — load and\n * transform findings without depending on the runtime.\n *\n * Repo layering: agent-eval is the substrate (no upward deps). Consumers\n * read this type from here; the reverse is forbidden. See CLAUDE.md\n * \"Repo layering\" for the rule. A UI finding makes sense WITHOUT a running\n * agent loop (you can load a saved finding, ship-gate against a set of\n * them, render them in a dashboard), which puts it firmly in substrate.\n *\n * The shape is intentionally minimal — runtime-shaped state (capture\n * timestamps, OTel trace IDs, sandbox placement) lives on auxiliary\n * runtime types in `agent-runtime`, not on the finding itself.\n */\n\n/**\n * Canonical audit lenses. Each lens scopes a finding to a single class of\n * problem so a single audit pass can iterate them without pile-on findings\n * under a generic label.\n *\n * Naming is fixed for cross-package wire compatibility. Treat additions as\n * a substrate-level decision — analysts, gates, and writers all branch on\n * the lens.\n */\nexport type UiLens =\n | 'consistency'\n | 'hierarchy'\n | 'layout'\n | 'ux-flow'\n | 'duplication'\n | 'accessibility'\n | 'responsive'\n | 'states'\n | 'content'\n | 'interaction'\n | 'performance-perceived'\n | 'other'\n\n/** Frozen tuple of lenses for validation + iteration. */\nexport const UI_LENSES: readonly UiLens[] = [\n 'consistency',\n 'hierarchy',\n 'layout',\n 'ux-flow',\n 'duplication',\n 'accessibility',\n 'responsive',\n 'states',\n 'content',\n 'interaction',\n 'performance-perceived',\n 'other',\n] as const\n\n/**\n * Severity scale — intentionally narrow.\n *\n * - `critical` — blocks a core task or is an accessibility blocker.\n * - `high` — confusing, broken-looking, or noticeable friction.\n * - `med` — visible polish issue, would be caught in code review.\n * - `low` — nitpick worth fixing eventually.\n */\nexport type UiFindingSeverity = 'low' | 'med' | 'high' | 'critical'\n\n/** Frozen severity tuple, ordered worst → least bad for sort/report. */\nexport const UI_FINDING_SEVERITIES: readonly UiFindingSeverity[] = [\n 'critical',\n 'high',\n 'med',\n 'low',\n] as const\n\n/**\n * Pointer to a screenshot referenced by the finding. The path is\n * intentionally a relative string (relative to the audit workspace root)\n * so findings remain portable across machines and into GitHub issues.\n */\nexport interface UiFindingScreenshot {\n /** Workspace-relative path to the screenshot file (e.g. `screenshots/home--1280x800--...png`). */\n path: string\n /** Optional viewport the screenshot was taken at, e.g. `1280x800`. */\n viewport?: string\n /** Optional short label that disambiguates multiple captures of the same surface (e.g. `t0`, `step-1`). */\n label?: string\n}\n\n/**\n * A single UI audit finding — the unit of work a contributor can act on.\n *\n * Every field except the documented optionals is required. The shape is\n * deliberately constraining: a finding without a screenshot, a lens, a\n * concrete title, and a suggested fix is not actionable, and the auditor\n * validator hard-fails on those gaps.\n */\nexport interface UiFinding {\n /**\n * Stable identifier within a single audit workspace. Monotonically\n * increasing integer (1, 2, …) assigned by the writer when persisting.\n * Optional in transit (before persistence) — undefined on freshly minted\n * findings emitted from a loop iteration.\n */\n id?: number\n /** Concrete title — names the offending element AND what's wrong. */\n title: string\n /** Lens this finding belongs to. */\n lens: UiLens\n /** Severity. */\n severity: UiFindingSeverity\n /** Logical route the finding was observed on (e.g. `home`, `checkout-step-2`). */\n route: string\n /** Fully qualified URL the finding was observed at. */\n url?: string\n /** Viewport string the offending capture was taken at (e.g. `1280x800`). */\n viewport?: string\n /** CSS selector pinning the offending element, when one can be identified. */\n selector?: string\n /** 1–3 sentences describing what the screenshot shows that is wrong. */\n observation: string\n /** Who is affected and how. Concrete user impact. */\n impact: string\n /** A specific change a contributor could apply without asking back. */\n suggestedFix: string\n /** Optional explicit reproduction steps. Writer synthesizes from route/url/selector when omitted. */\n reproSteps?: string\n /** Free-form tags. */\n tags?: readonly string[]\n /** Screenshot references — required to be non-empty for actionable findings. */\n screenshots: readonly UiFindingScreenshot[]\n /** Cross-references to similar findings already on file, by id. */\n similarTo?: readonly number[]\n /** ISO-8601 creation timestamp set by the writer when persisted. */\n createdAt?: string\n}\n","/**\n * Trace contracts — finite-trace temporal assertions over span sequences.\n *\n * Five LTLf operators over one ordered span sequence — `always(p)`,\n * `never(p)`, `eventually(p)`, `precedes(a, b)`, `neverUnless(p, prior)` —\n * deterministic and judge-free. No nesting: each rule is one operator over\n * flat `SpanPredicate`s; compose richer checks with multiple rules.\n *\n * A built `TraceContract` is a serializable plain object (RegExp matchers\n * are normalized to `SerializedRegex`), so ONE contract definition is\n * dual-use:\n *\n * - recorded eval traces — `evaluateTraceContract(contract, await\n * store.spans({ runId }))`, or via the behavior DSL:\n * `expectAgent(store, runId).toSatisfyContract(contract)`.\n * - the production OTLP stream — `ExportableSpan`s flattened by\n * `trace/otel-bridge` satisfy `ContractSpan` structurally. A production\n * monitor implements `OtelExporter`, buffers `exportSpan` payloads per\n * trace, and runs `checkTraceContracts(buffer, contracts)` on flush:\n *\n * const buffer: ContractSpan[] = []\n * const monitor: OtelExporter = {\n * exportSpan: (s) => { buffer.push(s) },\n * flush: async () => {\n * const { allValid, verdicts } = checkTraceContracts(buffer, contracts)\n * if (!allValid) alert(verdicts)\n * },\n * shutdown: async () => {},\n * }\n * const store = createOtelTracingStore(inner, monitor, runId)\n *\n * `custom` predicate functions are the one non-serializable escape hatch:\n * the builder stamps `requiresCustom: true` (which DOES survive JSON) so a\n * deserialized contract that lost its function fails loud at evaluation\n * instead of silently weakening.\n *\n * Naming: the root barrel exports ci-gate's threshold-contract\n * `evaluateContract`, so the evaluators here are `evaluateTraceContract` /\n * `checkTraceContracts`.\n */\n\nimport type { JudgeConfig, JudgeDimension, Scenario } from './campaign/types'\nimport { ValidationError } from './errors'\nimport type { DefaultVerdict } from './verdict'\n\n// ── Span surface ──────────────────────────────────────────────────────\n\n/**\n * Minimal structural span the checker reads. Both the eval-side `Span`\n * (trace/schema) and the OTLP-flattened `ExportableSpan` (trace/otel-export)\n * satisfy it; any other producer only needs these fields.\n */\nexport interface ContractSpan {\n spanId?: string\n name?: string\n kind?: string\n startedAt?: number\n status?: string\n error?: string\n /** Typed field on eval-side ToolSpans; OTLP flattenings drop it (see\n * `tool` matching order in {@link matchSpan}). */\n toolName?: string\n attributes?: Record<string, unknown>\n}\n\n/** JSON-safe RegExp form — what the builder normalizes RegExp matchers to. */\nexport interface SerializedRegex {\n $regex: string\n flags: string\n}\n\nexport type TextMatcher = string | RegExp | SerializedRegex\n\n/**\n * Proposition over one span. All specified fields must match (AND).\n * At least one field is required — an empty predicate would match every\n * span and is rejected.\n *\n * `tool` resolution order covers both span shapes: `span.toolName` (typed\n * ToolSpan) → `attributes['tool.name']` / `attributes['toolName']`\n * (OTLP-flat attribute conventions) → `span.name` when `kind === 'tool'`\n * (otel-bridge's `ExportableSpan`, which drops `toolName`).\n *\n * `attr` values match by strict equality, or regex-test when the value is a\n * RegExp/SerializedRegex and the attribute is a string. Structured attribute\n * values need `custom`.\n */\nexport interface SpanPredicate {\n name?: TextMatcher\n tool?: TextMatcher\n attr?: Record<string, unknown>\n custom?: (span: ContractSpan) => boolean\n /** Stamped by the builder when `custom` is present. Survives JSON while\n * the function does not, so evaluation of a deserialized contract throws\n * instead of silently dropping the check. */\n requiresCustom?: true\n}\n\n// ── Contract shape ────────────────────────────────────────────────────\n\nexport type ContractRuleKind = 'always' | 'never' | 'eventually' | 'precedes' | 'neverUnless'\n\nexport interface ContractRule {\n kind: ContractRuleKind\n /** Unique within the contract — keys the per-rule score. */\n label: string\n /** Subject predicate for always / never / eventually / neverUnless. */\n p?: SpanPredicate\n /** precedes: the required precondition. */\n a?: SpanPredicate\n /** precedes: the guarded match — every b-match needs an earlier a-match. */\n b?: SpanPredicate\n /** neverUnless: the authorizing earlier match. */\n prior?: SpanPredicate\n}\n\n/** Serializable plain object — `traceContract(name)....build()` output. */\nexport interface TraceContract {\n name: string\n rules: ContractRule[]\n}\n\nexport interface ContractViolation {\n rule: string\n spanId?: string\n detail: string\n}\n\nexport interface ContractVerdict extends DefaultVerdict {\n /** Contract name — keys this verdict in multi-contract reports. */\n contract: string\n valid: boolean\n /** Fraction of rules passing, in [0, 1]. */\n score: number\n /** Per-rule 0|1 keyed by rule label. */\n scores: Record<string, number>\n violations: ContractViolation[]\n}\n\nexport interface ContractCheckResult {\n verdicts: ContractVerdict[]\n allValid: boolean\n}\n\n// ── Predicate matching ────────────────────────────────────────────────\n\nfunction isSerializedRegex(v: unknown): v is SerializedRegex {\n return (\n typeof v === 'object' &&\n v !== null &&\n typeof (v as SerializedRegex).$regex === 'string' &&\n typeof (v as SerializedRegex).flags === 'string'\n )\n}\n\nfunction matchText(actual: string | undefined, matcher: TextMatcher): boolean {\n if (typeof actual !== 'string') return false\n if (typeof matcher === 'string') return actual === matcher\n if (matcher instanceof RegExp) return matcher.test(actual)\n return new RegExp(matcher.$regex, matcher.flags).test(actual)\n}\n\nfunction resolveToolName(span: ContractSpan): string | undefined {\n if (typeof span.toolName === 'string') return span.toolName\n const fromAttr = span.attributes?.['tool.name'] ?? span.attributes?.toolName\n if (typeof fromAttr === 'string') return fromAttr\n if (span.kind === 'tool' && typeof span.name === 'string') return span.name\n return undefined\n}\n\nfunction assertPredicate(value: unknown, where: string): asserts value is SpanPredicate {\n if (value === null || typeof value !== 'object') {\n throw new ValidationError(`${where}: predicate must be an object, got ${typeof value}`)\n }\n const p = value as SpanPredicate\n for (const field of ['name', 'tool'] as const) {\n const m = p[field]\n if (\n m !== undefined &&\n typeof m !== 'string' &&\n !(m instanceof RegExp) &&\n !isSerializedRegex(m)\n ) {\n throw new ValidationError(`${where}: \"${field}\" must be string | RegExp | SerializedRegex`)\n }\n }\n if (\n p.attr !== undefined &&\n (p.attr === null || typeof p.attr !== 'object' || Array.isArray(p.attr))\n ) {\n throw new ValidationError(`${where}: \"attr\" must be a plain object`)\n }\n if (p.requiresCustom && typeof p.custom !== 'function') {\n throw new ValidationError(\n `${where}: rule was built with a custom predicate function, which does not survive JSON ` +\n 'serialization — re-attach `custom` after deserializing or drop the rule',\n )\n }\n const hasAttr = p.attr !== undefined && Object.keys(p.attr).length > 0\n if (p.name === undefined && p.tool === undefined && !hasAttr && typeof p.custom !== 'function') {\n throw new ValidationError(\n `${where}: empty predicate would match every span — specify name, tool, attr, or custom`,\n )\n }\n}\n\n/** Test one span against one predicate. All specified fields must match. */\nexport function matchSpan(span: ContractSpan, predicate: SpanPredicate): boolean {\n assertPredicate(predicate, 'matchSpan')\n if (predicate.name !== undefined && !matchText(span.name, predicate.name)) return false\n if (predicate.tool !== undefined && !matchText(resolveToolName(span), predicate.tool))\n return false\n if (predicate.attr !== undefined) {\n for (const [key, expected] of Object.entries(predicate.attr)) {\n const actual = span.attributes?.[key]\n if (expected instanceof RegExp || isSerializedRegex(expected)) {\n if (!matchText(typeof actual === 'string' ? actual : undefined, expected as TextMatcher)) {\n return false\n }\n } else if (actual !== expected) {\n return false\n }\n }\n }\n if (predicate.custom !== undefined && !predicate.custom(span)) return false\n return true\n}\n\n// ── Builder ───────────────────────────────────────────────────────────\n\nfunction describeMatcher(m: TextMatcher): string {\n if (typeof m === 'string') return m\n if (m instanceof RegExp) return `/${m.source}/${m.flags}`\n return `/${m.$regex}/${m.flags}`\n}\n\nfunction describePredicate(p: SpanPredicate): string {\n const parts: string[] = []\n if (p.name !== undefined) parts.push(`name=${describeMatcher(p.name)}`)\n if (p.tool !== undefined) parts.push(`tool=${describeMatcher(p.tool)}`)\n if (p.attr !== undefined) {\n for (const [k, v] of Object.entries(p.attr)) {\n parts.push(\n `attr.${k}=${v instanceof RegExp || isSerializedRegex(v) ? describeMatcher(v as TextMatcher) : JSON.stringify(v)}`,\n )\n }\n }\n if (typeof p.custom === 'function') parts.push(`custom=${p.custom.name || 'fn'}`)\n return parts.join(',')\n}\n\nfunction normalizeMatcher(m: TextMatcher): string | SerializedRegex {\n return m instanceof RegExp ? { $regex: m.source, flags: m.flags } : m\n}\n\nfunction normalizePredicate(p: SpanPredicate, where: string): SpanPredicate {\n assertPredicate(p, where)\n const out: SpanPredicate = {}\n if (p.name !== undefined) out.name = normalizeMatcher(p.name)\n if (p.tool !== undefined) out.tool = normalizeMatcher(p.tool)\n if (p.attr !== undefined) {\n out.attr = Object.fromEntries(\n Object.entries(p.attr).map(([k, v]) => [k, v instanceof RegExp ? normalizeMatcher(v) : v]),\n )\n }\n if (typeof p.custom === 'function') {\n out.custom = p.custom\n out.requiresCustom = true\n }\n return out\n}\n\nexport class TraceContractBuilder {\n private readonly rules: ContractRule[] = []\n\n constructor(private readonly name: string) {}\n\n /** Every span in the trace must satisfy `p`. */\n always(p: SpanPredicate, label?: string): this {\n const np = normalizePredicate(p, `traceContract(\"${this.name}\").always`)\n return this.add({ kind: 'always', label: label ?? `always(${describePredicate(np)})`, p: np })\n }\n\n /** No span in the trace may satisfy `p`. */\n never(p: SpanPredicate, label?: string): this {\n const np = normalizePredicate(p, `traceContract(\"${this.name}\").never`)\n return this.add({ kind: 'never', label: label ?? `never(${describePredicate(np)})`, p: np })\n }\n\n /** At least one span in the trace must satisfy `p`. */\n eventually(p: SpanPredicate, label?: string): this {\n const np = normalizePredicate(p, `traceContract(\"${this.name}\").eventually`)\n return this.add({\n kind: 'eventually',\n label: label ?? `eventually(${describePredicate(np)})`,\n p: np,\n })\n }\n\n /** Every `b`-match must have a strictly earlier `a`-match. */\n precedes(a: SpanPredicate, b: SpanPredicate, label?: string): this {\n const na = normalizePredicate(a, `traceContract(\"${this.name}\").precedes (a)`)\n const nb = normalizePredicate(b, `traceContract(\"${this.name}\").precedes (b)`)\n return this.add({\n kind: 'precedes',\n label: label ?? `precedes(${describePredicate(na)} -> ${describePredicate(nb)})`,\n a: na,\n b: nb,\n })\n }\n\n /** Every `p`-match is a violation unless a strictly earlier `prior`-match exists. */\n neverUnless(p: SpanPredicate, prior: SpanPredicate, label?: string): this {\n const np = normalizePredicate(p, `traceContract(\"${this.name}\").neverUnless (p)`)\n const nprior = normalizePredicate(prior, `traceContract(\"${this.name}\").neverUnless (prior)`)\n return this.add({\n kind: 'neverUnless',\n label: label ?? `neverUnless(${describePredicate(np)} unless ${describePredicate(nprior)})`,\n p: np,\n prior: nprior,\n })\n }\n\n build(): TraceContract {\n if (this.rules.length === 0) {\n throw new ValidationError(\n `traceContract(\"${this.name}\").build(): no rules — an empty contract would vacuously pass`,\n )\n }\n return { name: this.name, rules: [...this.rules] }\n }\n\n private add(rule: ContractRule): this {\n // Labels key per-rule scores — auto-suffix duplicates so two identical\n // operator+predicate rules never collapse into one score entry.\n let label = rule.label\n let n = 2\n while (this.rules.some((r) => r.label === label)) {\n label = `${rule.label} #${n}`\n n += 1\n }\n this.rules.push({ ...rule, label })\n return this\n }\n}\n\nexport function traceContract(name: string): TraceContractBuilder {\n if (typeof name !== 'string' || name.length === 0) {\n throw new ValidationError('traceContract: name must be a non-empty string')\n }\n return new TraceContractBuilder(name)\n}\n\n// ── Evaluation ────────────────────────────────────────────────────────\n\nfunction assertContract(contract: TraceContract): void {\n if (typeof contract?.name !== 'string' || contract.name.length === 0) {\n throw new ValidationError('evaluateTraceContract: contract.name must be a non-empty string')\n }\n if (!Array.isArray(contract.rules) || contract.rules.length === 0) {\n throw new ValidationError(\n `evaluateTraceContract: contract \"${contract.name}\" has no rules — an empty contract would vacuously pass`,\n )\n }\n const seen = new Set<string>()\n for (const rule of contract.rules) {\n const where = `contract \"${contract.name}\" rule \"${rule?.label ?? '<unlabeled>'}\"`\n if (typeof rule?.label !== 'string' || rule.label.length === 0) {\n throw new ValidationError(`${where}: label must be a non-empty string`)\n }\n if (seen.has(rule.label)) {\n throw new ValidationError(`${where}: duplicate label would collapse per-rule scores`)\n }\n seen.add(rule.label)\n switch (rule.kind) {\n case 'always':\n case 'never':\n case 'eventually':\n assertPredicate(rule.p, `${where} (p)`)\n break\n case 'precedes':\n assertPredicate(rule.a, `${where} (a)`)\n assertPredicate(rule.b, `${where} (b)`)\n break\n case 'neverUnless':\n assertPredicate(rule.p, `${where} (p)`)\n assertPredicate(rule.prior, `${where} (prior)`)\n break\n default:\n throw new ValidationError(\n `${where}: unknown rule kind \"${String((rule as ContractRule).kind)}\"`,\n )\n }\n }\n}\n\n/**\n * Order spans for temporal evaluation: by `startedAt` when EVERY span carries\n * one (stable — ties keep array order), by array order when NONE does. Mixed\n * timestamps throw: neither time order nor array order is a trustworthy total\n * order over a partially-stamped sequence, and guessing would corrupt\n * `precedes` / `neverUnless` verdicts.\n */\nfunction orderSpans(spans: readonly ContractSpan[]): ContractSpan[] {\n const timed = spans.filter(\n (s) => typeof s.startedAt === 'number' && Number.isFinite(s.startedAt),\n ).length\n if (timed === spans.length) {\n return spans\n .map((span, i) => ({ span, i }))\n .sort((x, y) => x.span.startedAt! - y.span.startedAt! || x.i - y.i)\n .map((x) => x.span)\n }\n if (timed === 0) return [...spans]\n throw new ValidationError(\n `evaluateTraceContract: ${timed}/${spans.length} spans carry a finite startedAt — ` +\n 'mixed timestamps make ordering ambiguous; stamp every span or none',\n )\n}\n\nfunction spanRef(span: ContractSpan, index: number): string {\n return span.spanId ?? `#${index}`\n}\n\n// precedes(a, b) and neverUnless(p, prior) share one semantics: every\n// guarded-match must have a STRICTLY earlier guard-match. The guard flag\n// updates after the guarded check, so a span matching both cannot witness\n// itself.\nfunction checkGuarded(args: {\n label: string\n ordered: readonly ContractSpan[]\n guard: SpanPredicate\n guarded: SpanPredicate\n detail: (ref: string) => string\n}): ContractViolation[] {\n const out: ContractViolation[] = []\n let guardSeen = false\n for (let i = 0; i < args.ordered.length; i++) {\n const span = args.ordered[i]!\n if (!guardSeen && matchSpan(span, args.guarded)) {\n out.push({ rule: args.label, spanId: span.spanId, detail: args.detail(spanRef(span, i)) })\n }\n if (matchSpan(span, args.guard)) guardSeen = true\n }\n return out\n}\n\nfunction checkRule(rule: ContractRule, ordered: readonly ContractSpan[]): ContractViolation[] {\n switch (rule.kind) {\n case 'always': {\n const out: ContractViolation[] = []\n for (let i = 0; i < ordered.length; i++) {\n const span = ordered[i]!\n if (!matchSpan(span, rule.p!)) {\n out.push({\n rule: rule.label,\n spanId: span.spanId,\n detail: `span ${spanRef(span, i)} (\"${span.name ?? ''}\") fails always(${describePredicate(rule.p!)})`,\n })\n }\n }\n return out\n }\n case 'never': {\n const out: ContractViolation[] = []\n for (let i = 0; i < ordered.length; i++) {\n const span = ordered[i]!\n if (matchSpan(span, rule.p!)) {\n out.push({\n rule: rule.label,\n spanId: span.spanId,\n detail: `span ${spanRef(span, i)} (\"${span.name ?? ''}\") matches never(${describePredicate(rule.p!)})`,\n })\n }\n }\n return out\n }\n case 'eventually': {\n const hit = ordered.some((span) => matchSpan(span, rule.p!))\n return hit\n ? []\n : [\n {\n rule: rule.label,\n detail: `no span matches eventually(${describePredicate(rule.p!)}) over ${ordered.length} span(s)`,\n },\n ]\n }\n case 'precedes':\n return checkGuarded({\n label: rule.label,\n ordered,\n guard: rule.a!,\n guarded: rule.b!,\n detail: (ref) =>\n `span ${ref} matches ${describePredicate(rule.b!)} with no earlier ${describePredicate(rule.a!)} match`,\n })\n case 'neverUnless':\n return checkGuarded({\n label: rule.label,\n ordered,\n guard: rule.prior!,\n guarded: rule.p!,\n detail: (ref) =>\n `span ${ref} matches ${describePredicate(rule.p!)} with no earlier ${describePredicate(rule.prior!)} match`,\n })\n }\n}\n\n/**\n * Evaluate one contract over a span sequence. Pure and synchronous — works\n * on `Span[]` from a TraceStore, `ExportableSpan[]` from the otel-bridge\n * flattening, or any array satisfying `ContractSpan`.\n */\nexport function evaluateTraceContract(\n contract: TraceContract,\n spans: readonly ContractSpan[],\n): ContractVerdict {\n assertContract(contract)\n const ordered = orderSpans(spans)\n const scores: Record<string, number> = {}\n const violations: ContractViolation[] = []\n for (const rule of contract.rules) {\n const ruleViolations = checkRule(rule, ordered)\n scores[rule.label] = ruleViolations.length === 0 ? 1 : 0\n violations.push(...ruleViolations)\n }\n const ruleCount = contract.rules.length\n const passCount = Object.values(scores).filter((s) => s === 1).length\n return {\n contract: contract.name,\n valid: passCount === ruleCount,\n score: passCount / ruleCount,\n scores,\n violations,\n notes: `${passCount}/${ruleCount} rules passed`,\n }\n}\n\n/**\n * Evaluate many contracts over one span sequence. Throws on an empty\n * contract list — `allValid: true` over zero contracts is a silent pass.\n */\nexport function checkTraceContracts(\n spans: readonly ContractSpan[],\n contracts: readonly TraceContract[],\n): ContractCheckResult {\n if (contracts.length === 0) {\n throw new ValidationError(\n 'checkTraceContracts: empty contract list would vacuously pass — supply at least one contract',\n )\n }\n const verdicts = contracts.map((c) => evaluateTraceContract(c, spans))\n return { verdicts, allValid: verdicts.every((v) => v.valid) }\n}\n\n// ── Campaign judge adapter ────────────────────────────────────────────\n\nexport interface ContractJudgeOptions<TArtifact, TScenario extends Scenario = Scenario> {\n /**\n * Project the span sequence out of a cell's artifact. `JudgeConfig.score`\n * receives only `{ artifact, scenario, signal }` (src/campaign/types.ts) —\n * spans are NOT reachable generically — so the consumer supplies this\n * explicit extraction (e.g. dispatch writes spans into the artifact, or\n * closes over a per-cell TraceStore read).\n */\n spans: (input: { artifact: TArtifact; scenario: TScenario }) => readonly ContractSpan[]\n /** Judge name in campaign reports. Default 'trace-contracts'. */\n name?: string\n}\n\n/**\n * Adapt trace contracts to a campaign `JudgeConfig`. One judge dimension per\n * contract (key = contract name, value = its rule-pass fraction); composite\n * is the mean across contracts. Deterministic — no LLM call.\n */\nexport function contractJudge<TArtifact, TScenario extends Scenario = Scenario>(\n contracts: readonly TraceContract[],\n opts: ContractJudgeOptions<TArtifact, TScenario>,\n): JudgeConfig<TArtifact, TScenario> {\n if (contracts.length === 0) {\n throw new ValidationError('contractJudge: at least one contract required')\n }\n for (const c of contracts) assertContract(c)\n const names = new Set<string>()\n for (const c of contracts) {\n if (names.has(c.name)) {\n throw new ValidationError(\n `contractJudge: duplicate contract name \"${c.name}\" would collapse judge dimensions`,\n )\n }\n names.add(c.name)\n }\n if (typeof opts?.spans !== 'function') {\n throw new ValidationError('contractJudge: opts.spans extraction function is required')\n }\n const dimensions: JudgeDimension[] = contracts.map((c) => ({\n key: c.name,\n description: c.rules.map((r) => r.label).join('; '),\n }))\n return {\n name: opts.name ?? 'trace-contracts',\n dimensions,\n score({ artifact, scenario }) {\n const spans = opts.spans({ artifact, scenario })\n if (!Array.isArray(spans)) {\n throw new ValidationError(\n `contractJudge: spans() must return a span array, got ${typeof spans}`,\n )\n }\n const { verdicts } = checkTraceContracts(spans, contracts)\n const dims: Record<string, number> = {}\n const violations: ContractViolation[] = []\n for (const v of verdicts) {\n dims[v.contract] = v.score\n violations.push(...v.violations)\n }\n const composite = verdicts.reduce((acc, v) => acc + v.score, 0) / verdicts.length\n return {\n dimensions: dims,\n composite,\n notes:\n violations.length === 0\n ? 'all trace contracts satisfied'\n : violations\n .slice(0, 8)\n .map((x) => `${x.rule}: ${x.detail}`)\n .join('\\n'),\n }\n },\n }\n}\n","/**\n * Behavior DSL — pytest-style assertions over a run's trajectory.\n *\n * Shape:\n * expect(store, runId).toCall('search').withArgs({ q: /.+/ })\n * expect(store, runId).toRefuse()\n * expect(store, runId).toOutputMatch(/confirmed/i)\n * expect(store, runId).toRespectBudget('tokens')\n * expect(store, runId).toCompleteWithin({ wallMs: 30_000 })\n *\n * Each matcher returns an `Expectation` with `.check() → MatcherResult`\n * so the DSL is composable with suite runners — you can collect all\n * expectations into a report instead of throwing on first failure.\n */\n\nimport { llmSpans, toolSpans } from './trace/query'\nimport type { BudgetLedgerEntry, Span, ToolSpan } from './trace/schema'\nimport type { TraceStore } from './trace/store'\nimport { evaluateTraceContract, type TraceContract } from './trace-contracts'\n\nexport interface MatcherResult {\n ok: boolean\n detail: string\n evidence?: string\n}\n\nexport interface Expectation {\n /** Human-facing label; used in reports. */\n label: string\n check(): Promise<MatcherResult>\n}\n\nexport class BehaviorAssertion {\n constructor(\n private store: TraceStore,\n private runId: string,\n ) {}\n\n toCall(toolName: string): CallExpectation {\n return new CallExpectation(this.store, this.runId, toolName)\n }\n\n toRefuse(markers: RegExp[] = DEFAULT_REFUSAL_MARKERS): Expectation {\n return {\n label: `agent(${this.runId}).toRefuse()`,\n check: async () => {\n const spans = await llmSpans(this.store, this.runId)\n const output = spans.map((s) => s.output ?? '').join('\\n')\n const hit = markers.some((re) => re.test(output))\n return hit\n ? { ok: true, detail: 'refusal marker detected' }\n : {\n ok: false,\n detail: 'no refusal marker in agent output',\n evidence: output.slice(0, 200),\n }\n },\n }\n }\n\n toOutputMatch(pattern: RegExp): Expectation {\n return {\n label: `agent(${this.runId}).toOutputMatch(${pattern.source})`,\n check: async () => {\n const spans = await llmSpans(this.store, this.runId)\n const output = spans.map((s) => s.output ?? '').join('\\n')\n const m = output.match(pattern)\n return m\n ? { ok: true, detail: `matched \"${m[0]}\"`, evidence: m[0] }\n : { ok: false, detail: 'pattern not matched', evidence: output.slice(0, 200) }\n },\n }\n }\n\n toRespectBudget(\n dimension: keyof BudgetLedgerEntry['dimension'] | 'tokens' | 'wallMs' | 'calls' | 'usd',\n ): Expectation {\n return {\n label: `agent(${this.runId}).toRespectBudget(${String(dimension)})`,\n check: async () => {\n const entries = await this.store.budget(this.runId)\n const breached = entries.some((e) => e.dimension === dimension && e.breached)\n return breached\n ? { ok: false, detail: `budget \"${String(dimension)}\" breached` }\n : { ok: true, detail: `no breach on \"${String(dimension)}\"` }\n },\n }\n }\n\n toCompleteWithin(limits: {\n wallMs?: number\n toolCalls?: number\n llmTurns?: number\n }): Expectation {\n return {\n label: `agent(${this.runId}).toCompleteWithin(${JSON.stringify(limits)})`,\n check: async () => {\n const run = await this.store.getRun(this.runId)\n if (!run?.endedAt) return { ok: false, detail: 'run has not completed' }\n const wallMs = run.endedAt - run.startedAt\n const tool = (await toolSpans(this.store, this.runId)).length\n const llm = (await llmSpans(this.store, this.runId)).length\n const violations: string[] = []\n if (limits.wallMs !== undefined && wallMs > limits.wallMs)\n violations.push(`wallMs ${wallMs} > ${limits.wallMs}`)\n if (limits.toolCalls !== undefined && tool > limits.toolCalls)\n violations.push(`toolCalls ${tool} > ${limits.toolCalls}`)\n if (limits.llmTurns !== undefined && llm > limits.llmTurns)\n violations.push(`llmTurns ${llm} > ${limits.llmTurns}`)\n return violations.length === 0\n ? { ok: true, detail: `within limits (${wallMs}ms, ${tool} tools, ${llm} turns)` }\n : { ok: false, detail: violations.join('; ') }\n },\n }\n }\n\n /** Evaluate a finite-trace temporal contract (`traceContract(...)`) over\n * this run's span sequence. See `trace-contracts.ts` for the operators. */\n toSatisfyContract(contract: TraceContract): Expectation {\n return {\n label: `agent(${this.runId}).toSatisfyContract(${contract.name})`,\n check: async () => {\n const spans = await this.store.spans({ runId: this.runId })\n const verdict = evaluateTraceContract(contract, spans)\n if (verdict.valid) {\n return { ok: true, detail: `contract \"${contract.name}\": ${verdict.notes}` }\n }\n return {\n ok: false,\n detail: verdict.violations.map((v) => `${v.rule}: ${v.detail}`).join('; '),\n evidence: verdict.violations.find((v) => v.spanId)?.spanId,\n }\n },\n }\n }\n\n toNeverCall(toolName: string): Expectation {\n return {\n label: `agent(${this.runId}).toNeverCall(${toolName})`,\n check: async () => {\n const calls = await toolSpans(this.store, this.runId, toolName)\n return calls.length === 0\n ? { ok: true, detail: `tool \"${toolName}\" not invoked` }\n : {\n ok: false,\n detail: `tool \"${toolName}\" called ${calls.length}x`,\n evidence: calls[0]!.spanId,\n }\n },\n }\n }\n}\n\nexport class CallExpectation implements Expectation {\n private argMatchers: Array<(args: unknown) => boolean> = []\n private minCount = 1\n private maxCount = Infinity\n\n constructor(\n private store: TraceStore,\n private runId: string,\n private toolName: string,\n ) {}\n\n get label(): string {\n return `agent(${this.runId}).toCall(${this.toolName})`\n }\n\n withArgs(shape: Record<string, unknown | RegExp>): this {\n this.argMatchers.push((args) => matchArgs(args, shape))\n return this\n }\n\n times(n: number): this {\n this.minCount = n\n this.maxCount = n\n return this\n }\n\n atLeast(n: number): this {\n this.minCount = n\n return this\n }\n\n atMost(n: number): this {\n this.maxCount = n\n return this\n }\n\n async check(): Promise<MatcherResult> {\n const calls = await toolSpans(this.store, this.runId, this.toolName)\n const matching = calls.filter((c) => this.argMatchers.every((fn) => fn(c.args)))\n const count = matching.length\n if (count < this.minCount)\n return {\n ok: false,\n detail: `expected ≥ ${this.minCount} matching \"${this.toolName}\" calls, got ${count}`,\n }\n if (count > this.maxCount)\n return {\n ok: false,\n detail: `expected ≤ ${this.maxCount} matching \"${this.toolName}\" calls, got ${count}`,\n }\n return { ok: true, detail: `${count} matching \"${this.toolName}\" call(s)` }\n }\n}\n\nexport function expectAgent(store: TraceStore, runId: string): BehaviorAssertion {\n return new BehaviorAssertion(store, runId)\n}\n\n/** Runs every expectation, collects results. Never throws. */\nexport async function runExpectations(expectations: Expectation[]): Promise<{\n results: Array<{ label: string; result: MatcherResult }>\n pass: boolean\n passCount: number\n failCount: number\n}> {\n const results = await Promise.all(\n expectations.map(async (e) => ({ label: e.label, result: await e.check() })),\n )\n const passCount = results.filter((r) => r.result.ok).length\n return {\n results,\n pass: passCount === results.length,\n passCount,\n failCount: results.length - passCount,\n }\n}\n\nconst DEFAULT_REFUSAL_MARKERS = [\n /\\b(?:i\\s+(?:can(?:not|'t)|won't|will\\s+not|am\\s+unable|refuse))\\b/i,\n /\\b(?:sorry,?\\s+(?:but\\s+)?i\\s+(?:can't|cannot))/i,\n /\\bthat\\s+(?:would\\s+)?(?:violate|be\\s+against)\\b/i,\n /\\bunable\\s+to\\s+(?:help|assist|comply)\\b/i,\n]\n\nfunction matchArgs(args: unknown, shape: Record<string, unknown | RegExp>): boolean {\n if (args === null || typeof args !== 'object') return false\n const record = args as Record<string, unknown>\n for (const [k, expected] of Object.entries(shape)) {\n const actual = record[k]\n if (expected instanceof RegExp) {\n if (typeof actual !== 'string' || !expected.test(actual)) return false\n } else if (actual !== expected) {\n return false\n }\n }\n return true\n}\n\n// Guard against accidental Span import elision during build-time DTS generation.\nexport type { Span, ToolSpan }\n","/**\n * CI gate — evaluate a corpus against threshold contracts and generate\n * a human-readable PR/build comment.\n *\n * Three layers:\n * 1. `ThresholdContract` declarations (YAML-equivalent TS objects)\n * 2. `evaluateContract` runs the contracts against a TraceStore and\n * returns a structured report + overall pass/fail.\n * 3. `renderMarkdownReport` formats the report for GitHub PR comments.\n *\n * Consumers wrap this in their own `gh pr comment` / CI integration —\n * we don't ship the GitHub Action binary, just the library call that\n * the action invokes.\n */\n\nimport type { BaselineReport } from './baseline'\nimport { compareToBaseline, type MetricSamples } from './baseline'\nimport { checkSlos, type Slo, type SloReport } from './slo'\nimport { aggregateLlm, llmSpans, runFailureClass } from './trace/query'\nimport type { Run } from './trace/schema'\nimport type { RunFilter, TraceStore } from './trace/store'\n\nexport interface ContractMetric {\n /** Metric id matching either a predefined key or a custom extractor. */\n metric: string\n higherIsBetter: boolean\n /** Max tolerated regression (e.g. 0.02 = 2pp worse than baseline). */\n maxRegression?: number\n /** Optional extractor if the metric isn't in the default set. */\n extract?: (run: Run, store: TraceStore) => Promise<number | null>\n}\n\nexport interface ThresholdContract {\n name: string\n baseline: RunFilter\n candidate: RunFilter\n metrics: ContractMetric[]\n slos?: Slo[]\n}\n\nexport interface ContractReport {\n name: string\n baselineReport: BaselineReport\n sloReport?: SloReport\n breaches: string[]\n pass: boolean\n}\n\nexport async function evaluateContract(\n store: TraceStore,\n contract: ThresholdContract,\n): Promise<ContractReport> {\n const baselineRuns = await store.listRuns(contract.baseline)\n const candidateRuns = await store.listRuns(contract.candidate)\n if (candidateRuns.length === 0) {\n return {\n name: contract.name,\n baselineReport: { metrics: [], hasRegression: false, hasUnstable: true },\n breaches: ['no candidate runs matched'],\n pass: false,\n }\n }\n\n const samples: MetricSamples[] = []\n const measurementBreaches: string[] = []\n for (const m of contract.metrics) {\n const extract = m.extract ?? defaultExtract(m.metric)\n const baseline = await extractAll(baselineRuns, extract, store)\n const candidate = await extractAll(candidateRuns, extract, store)\n if (baseline.length !== baselineRuns.length || candidate.length !== candidateRuns.length) {\n measurementBreaches.push(\n `metric \"${m.metric}\" measured ${candidate.length}/${candidateRuns.length} candidate ` +\n `and ${baseline.length}/${baselineRuns.length} baseline run(s); every supplied run must report the metric`,\n )\n continue\n }\n if (baseline.length < 2 || candidate.length < 2) {\n measurementBreaches.push(\n `metric \"${m.metric}\" has too few comparable samples: baseline ${baseline.length}, ` +\n `candidate ${candidate.length}; need at least 2 per arm`,\n )\n continue\n }\n samples.push({ metric: m.metric, higherIsBetter: m.higherIsBetter, baseline, candidate })\n }\n\n const baselineReport =\n samples.length >= 1\n ? compareToBaseline(samples)\n : { metrics: [], hasRegression: false, hasUnstable: samples.length === 0 }\n\n // SLO evaluation against candidate-side aggregate metrics\n let sloReport: SloReport | undefined\n if (contract.slos && contract.slos.length > 0) {\n const agg = await aggregateRunMetrics(candidateRuns, store)\n sloReport = checkSlos(agg, contract.slos)\n }\n\n const breaches: string[] = [...measurementBreaches]\n for (const metric of baselineReport.metrics) {\n const decl = contract.metrics.find((m) => m.metric === metric.metric)\n if (!decl) continue\n if (metric.verdict === 'regressed') {\n const magnitude = Math.abs(metric.delta)\n if (decl.maxRegression === undefined || magnitude > decl.maxRegression) {\n breaches.push(\n `metric \"${metric.metric}\" regressed by ${metric.delta.toFixed(4)} (d=${formatEffectSize(metric.cohensD)}, p=${metric.welchP.toExponential(2)})`,\n )\n }\n }\n }\n if (sloReport) {\n for (const r of sloReport.criticalBreaches) {\n breaches.push(`SLO \"${r.slo.id}\" breached: ${r.detail}`)\n }\n }\n\n return { name: contract.name, baselineReport, sloReport, breaches, pass: breaches.length === 0 }\n}\n\nexport function renderMarkdownReport(reports: ContractReport[]): string {\n const lines: string[] = []\n const overall = reports.every((r) => r.pass)\n lines.push(overall ? '## ✅ agent-eval gate: pass' : '## ❌ agent-eval gate: fail')\n lines.push('')\n for (const r of reports) {\n lines.push(`### ${r.name} ${r.pass ? '✅' : '❌'}`)\n if (r.breaches.length > 0) {\n lines.push('')\n lines.push('**Breaches:**')\n for (const b of r.breaches) lines.push(`- ${b}`)\n }\n if (r.baselineReport.metrics.length > 0) {\n lines.push('')\n lines.push('| metric | baseline | candidate | Δ | Cohen d | p | verdict |')\n lines.push('|---|---|---|---|---|---|---|')\n for (const m of r.baselineReport.metrics) {\n lines.push(\n `| ${m.metric} | ${m.baselineMean.toFixed(4)} | ${m.candidateMean.toFixed(4)} | ${m.delta.toFixed(4)} | ${formatEffectSize(m.cohensD)} | ${m.welchP.toExponential(2)} | ${m.verdict} |`,\n )\n }\n }\n if (r.sloReport && r.sloReport.results.length > 0) {\n lines.push('')\n lines.push('**SLO results:**')\n for (const s of r.sloReport.results) {\n lines.push(`- ${s.slo.id} (${s.slo.severity}): ${s.passed ? 'ok' : 'breach'} — ${s.detail}`)\n }\n }\n lines.push('')\n }\n return lines.join('\\n')\n}\n\n/** Aggregate per-run metrics into the single record expected by `checkSlos`. */\nasync function aggregateRunMetrics(\n runs: Run[],\n store: TraceStore,\n): Promise<Record<string, number>> {\n if (runs.length === 0) return {}\n const durations: number[] = []\n const scores: number[] = []\n const passes: number[] = []\n const costs: number[] = []\n for (const r of runs) {\n if (r.endedAt) durations.push(r.endedAt - r.startedAt)\n if (r.outcome?.score !== undefined) scores.push(r.outcome.score)\n passes.push(r.outcome?.pass === true ? 1 : 0)\n const llm = await llmSpans(store, r.runId)\n costs.push(aggregateLlm(llm).costUsd)\n }\n return {\n provisionMs: average(durations),\n firstTokenMs: average(durations),\n wallMs: average(durations),\n overallScore: average(scores),\n passRate: average(passes),\n costUsd: average(costs),\n }\n}\n\nfunction average(xs: number[]): number {\n if (xs.length === 0) return 0\n return xs.reduce((a, b) => a + b, 0) / xs.length\n}\n\n/** Cohen's d is null when both samples are constant with unequal means — an\n * unbounded effect, which must not be rendered as a number. */\nfunction formatEffectSize(d: number | null): string {\n return d === null ? 'unbounded (zero pooled spread)' : d.toFixed(2)\n}\n\nasync function extractAll(\n runs: Run[],\n extract: (r: Run, s: TraceStore) => Promise<number | null>,\n store: TraceStore,\n): Promise<number[]> {\n const out: number[] = []\n for (const r of runs) {\n const v = await extract(r, store)\n if (v !== null && Number.isFinite(v)) out.push(v)\n }\n return out\n}\n\nfunction defaultExtract(metric: string): (run: Run, store: TraceStore) => Promise<number | null> {\n return async (run, store) => {\n switch (metric) {\n case 'score':\n case 'overallScore':\n return run.outcome?.score ?? null\n case 'pass':\n return run.outcome?.pass === true ? 1 : 0\n case 'durationMs':\n return run.endedAt && run.startedAt ? run.endedAt - run.startedAt : null\n case 'costUsd': {\n const llm = await llmSpans(store, run.runId)\n return aggregateLlm(llm).costUsd\n }\n case 'successClass':\n return runFailureClass(run) === 'success' ? 1 : 0\n default:\n return null\n }\n }\n}\n","/**\n * Observability adapters — bidirectional parity with production backends.\n *\n * `LangfuseAdapter` maps a Run's spans into Langfuse generation/score\n * records (schema-compatible; we don't depend on the SDK — consumers\n * POST the returned JSON to their Langfuse collector).\n *\n * `PrometheusEmitter` converts a TraceStore into a Prometheus text-\n * exposition-format string (counters + gauges for runs, tool calls,\n * errors, cost). Drop into a `/metrics` handler; no SDK needed.\n *\n * `replayTraceThroughJudge` is the canonical \"re-score with a new\n * judge\" path — takes an existing run, runs a judge function over\n * each LLM span, emits JudgeVerdict spans back into the store.\n */\n\nimport { NotFoundError } from './errors'\nimport { TraceEmitter } from './trace/emitter'\nimport { aggregateLlm, llmSpans } from './trace/query'\nimport type { LlmSpan, Span } from './trace/schema'\nimport type { TraceStore } from './trace/store'\n\n// ── Langfuse adapter ─────────────────────────────────────────────────\n\nexport interface LangfuseGeneration {\n id: string\n traceId: string\n name: string\n model: string\n input: unknown\n output: unknown\n startTime: string\n endTime: string\n usage: { input: number; output: number; total: number; totalCost: number }\n metadata: Record<string, unknown>\n}\n\nexport interface LangfuseScore {\n id: string\n traceId: string\n observationId: string\n name: string\n value: number\n comment?: string\n}\n\nexport interface LangfuseEnvelope {\n traceId: string\n generations: LangfuseGeneration[]\n scores: LangfuseScore[]\n}\n\nexport async function toLangfuseEnvelope(\n store: TraceStore,\n runId: string,\n): Promise<LangfuseEnvelope> {\n const run = await store.getRun(runId)\n if (!run) throw new NotFoundError(`run ${runId} not found`)\n const llm = await llmSpans(store, runId)\n const allSpans = await store.spans({ runId })\n const judges = allSpans.filter((s): s is Extract<Span, { kind: 'judge' }> => s.kind === 'judge')\n\n const generations: LangfuseGeneration[] = llm.map((s) => ({\n id: s.spanId,\n traceId: run.runId,\n name: s.name,\n model: s.model,\n input: s.messages,\n output: s.output,\n startTime: new Date(s.startedAt).toISOString(),\n endTime: new Date(s.endedAt ?? s.startedAt).toISOString(),\n usage: {\n input: s.inputTokens ?? 0,\n output: s.outputTokens ?? 0,\n total: (s.inputTokens ?? 0) + (s.outputTokens ?? 0),\n totalCost: s.costUsd ?? 0,\n },\n metadata: { finishReason: s.finishReason, cachedTokens: s.cachedTokens },\n }))\n\n const scores: LangfuseScore[] = judges.map((j) => ({\n id: j.spanId,\n traceId: run.runId,\n observationId: j.targetSpanId,\n name: `${j.judgeId}/${j.dimension}`,\n value: j.score,\n comment: j.rationale,\n }))\n\n return { traceId: run.runId, generations, scores }\n}\n\n// ── Prometheus emitter ───────────────────────────────────────────────\n\nexport async function toPrometheusText(store: TraceStore): Promise<string> {\n const runs = await store.listRuns()\n const toolCalls: Record<string, number> = {}\n const toolErrors: Record<string, number> = {}\n let totalLlmInputTokens = 0\n let totalLlmOutputTokens = 0\n let totalCostUsd = 0\n let passedRuns = 0\n let failedRuns = 0\n for (const r of runs) {\n if (r.outcome?.pass === true) passedRuns++\n else if (r.outcome?.pass === false) failedRuns++\n const llm = await llmSpans(store, r.runId)\n const agg = aggregateLlm(llm)\n totalLlmInputTokens += agg.inputTokens\n totalLlmOutputTokens += agg.outputTokens\n totalCostUsd += agg.costUsd\n const tools = await store.spans({ runId: r.runId, kind: 'tool' })\n for (const t of tools) {\n if (t.kind !== 'tool') continue\n toolCalls[t.toolName] = (toolCalls[t.toolName] ?? 0) + 1\n if (t.status === 'error') toolErrors[t.toolName] = (toolErrors[t.toolName] ?? 0) + 1\n }\n }\n\n const lines: string[] = []\n lines.push('# HELP agent_eval_runs_total Total runs in the trace corpus')\n lines.push('# TYPE agent_eval_runs_total counter')\n lines.push(`agent_eval_runs_total ${runs.length}`)\n lines.push('# HELP agent_eval_runs_passed_total Runs that completed with pass=true')\n lines.push('# TYPE agent_eval_runs_passed_total counter')\n lines.push(`agent_eval_runs_passed_total ${passedRuns}`)\n lines.push('# HELP agent_eval_runs_failed_total Runs that completed with pass=false')\n lines.push('# TYPE agent_eval_runs_failed_total counter')\n lines.push(`agent_eval_runs_failed_total ${failedRuns}`)\n lines.push('# HELP agent_eval_llm_input_tokens_total Aggregate LLM input tokens')\n lines.push('# TYPE agent_eval_llm_input_tokens_total counter')\n lines.push(`agent_eval_llm_input_tokens_total ${totalLlmInputTokens}`)\n lines.push('# HELP agent_eval_llm_output_tokens_total Aggregate LLM output tokens')\n lines.push('# TYPE agent_eval_llm_output_tokens_total counter')\n lines.push(`agent_eval_llm_output_tokens_total ${totalLlmOutputTokens}`)\n lines.push('# HELP agent_eval_cost_usd_total Aggregate LLM cost in USD')\n lines.push('# TYPE agent_eval_cost_usd_total counter')\n lines.push(`agent_eval_cost_usd_total ${totalCostUsd}`)\n lines.push('# HELP agent_eval_tool_calls_total Tool calls by tool name')\n lines.push('# TYPE agent_eval_tool_calls_total counter')\n for (const [name, n] of Object.entries(toolCalls)) {\n lines.push(`agent_eval_tool_calls_total{tool=\"${escapeLabel(name)}\"} ${n}`)\n }\n lines.push('# HELP agent_eval_tool_errors_total Tool errors by tool name')\n lines.push('# TYPE agent_eval_tool_errors_total counter')\n for (const [name, n] of Object.entries(toolErrors)) {\n lines.push(`agent_eval_tool_errors_total{tool=\"${escapeLabel(name)}\"} ${n}`)\n }\n return `${lines.join('\\n')}\\n`\n}\n\nfunction escapeLabel(v: string): string {\n return v.replace(/\\\\/g, '\\\\\\\\').replace(/\"/g, '\\\\\"').replace(/\\n/g, '\\\\n')\n}\n\n// ── Retroactive re-scoring via judge replay ──────────────────────────\n\nexport interface JudgeReplayResult {\n spanId: string\n targetSpanId: string\n dimension: string\n score: number\n rationale?: string\n}\n\n/**\n * Apply a judge function to every LLM span in a run and record the\n * results as JudgeVerdict spans. This is the canonical \"no re-execution\"\n * re-scoring path — you supply a pure judge `(llmSpan) → verdict`.\n */\nexport async function replayTraceThroughJudge(\n store: TraceStore,\n runId: string,\n judge: {\n id: string\n dimension: string\n score: (span: LlmSpan) => Promise<{ score: number; rationale?: string; evidence?: string }>\n },\n): Promise<JudgeReplayResult[]> {\n const run = await store.getRun(runId)\n if (!run) throw new NotFoundError(`run ${runId} not found`)\n const llms = await llmSpans(store, runId)\n const emitter = new TraceEmitter(store, { runId })\n const results: JudgeReplayResult[] = []\n for (const span of llms) {\n const { score, rationale, evidence } = await judge.score(span)\n const verdict = await emitter.recordJudge({\n judgeId: judge.id,\n targetSpanId: span.spanId,\n dimension: judge.dimension,\n score,\n rationale,\n evidence,\n name: `${judge.id}/${judge.dimension}`,\n })\n results.push({\n spanId: verdict.spanId,\n targetSpanId: span.spanId,\n dimension: judge.dimension,\n score,\n rationale,\n })\n }\n return results\n}\n","/**\n * Paraphrase robustness — mutates a scenario prompt in structure-\n * preserving ways, re-scores, and reports score variance.\n *\n * Mutators are pure functions `(prompt: string) => string`. Ship a\n * default set; consumers add domain-specific ones.\n *\n * Robustness score: 1 - stdDev(scores) / (mean if positive else 1).\n * A perfect agent returns the same answer regardless of typo / case /\n * reordering — any variance signals a brittle prompt.\n */\n\nexport type Mutator = (prompt: string, seed: number) => string\n\nexport interface RobustnessResult {\n originalScore: number\n variantScores: Array<{ mutator: string; score: number; mutated: string }>\n meanScore: number\n stdDev: number\n robustness: number\n}\n\nexport async function paraphraseRobustness(\n prompt: string,\n mutators: Array<{ id: string; fn: Mutator }>,\n scoreFn: (prompt: string) => Promise<number>,\n options: { seed?: number } = {},\n): Promise<RobustnessResult> {\n const seed = options.seed ?? 1\n const originalScore = await scoreFn(prompt)\n const variantScores: RobustnessResult['variantScores'] = []\n const all: number[] = [originalScore]\n for (const { id, fn } of mutators) {\n const mutated = fn(prompt, seed)\n const score = await scoreFn(mutated)\n variantScores.push({ mutator: id, score, mutated })\n all.push(score)\n }\n const mean = all.reduce((a, b) => a + b, 0) / all.length\n const variance = all.reduce((a, v) => a + (v - mean) ** 2, 0) / all.length\n const stdDev = Math.sqrt(variance)\n const ref = Math.abs(mean) > 1e-9 ? Math.abs(mean) : 1\n const robustness = Math.max(0, 1 - stdDev / ref)\n return { originalScore, variantScores, meanScore: mean, stdDev, robustness }\n}\n\n// ── Built-in mutators ────────────────────────────────────────────────\n\n/** Lowercase the whole prompt. Robust models ignore case. */\nexport const lowercaseMutator: Mutator = (p) => p.toLowerCase()\n\n/** Reorder sentences. Robust models don't depend on sentence order. */\nexport const sentenceReorderMutator: Mutator = (p, seed) => {\n const sentences = p.split(/(?<=[.!?])\\s+/).filter(Boolean)\n if (sentences.length <= 1) return p\n const shuffled = [...sentences]\n let s = seed >>> 0\n for (let i = shuffled.length - 1; i > 0; i--) {\n s = (s * 1103515245 + 12345) >>> 0\n const j = s % (i + 1)\n ;[shuffled[i], shuffled[j]] = [shuffled[j]!, shuffled[i]!]\n }\n return shuffled.join(' ')\n}\n\n/** Swap adjacent letter pairs (1 per 40 chars, min 1). Robust models tolerate typos. */\nexport const typoMutator: Mutator = (p, seed) => {\n if (p.length < 5) return p\n const chars = p.split('')\n let s = seed >>> 0\n const count = Math.max(1, Math.floor(chars.length / 40))\n for (let n = 0; n < count; n++) {\n for (let attempt = 0; attempt < 20; attempt++) {\n s = (s * 1103515245 + 12345) >>> 0\n const idx = s % (chars.length - 1)\n const a = chars[idx]!\n const b = chars[idx + 1]!\n if (a !== b && /[A-Za-z]/.test(a) && /[A-Za-z]/.test(b)) {\n chars[idx] = b\n chars[idx + 1] = a\n break\n }\n }\n }\n return chars.join('')\n}\n\n/** Add a benign politeness prefix. Robust models ignore flattery. */\nexport const politenessPrefixMutator: Mutator = (p) => `Please, if you would be so kind: ${p}`\n\n/** Compact whitespace, strip newlines. Robust models don't depend on formatting. */\nexport const whitespaceCollapseMutator: Mutator = (p) => p.replace(/\\s+/g, ' ').trim()\n\nexport const DEFAULT_MUTATORS: Array<{ id: string; fn: Mutator }> = [\n { id: 'lowercase', fn: lowercaseMutator },\n { id: 'sentence-reorder', fn: sentenceReorderMutator },\n { id: 'typo', fn: typoMutator },\n { id: 'politeness-prefix', fn: politenessPrefixMutator },\n { id: 'whitespace-collapse', fn: whitespaceCollapseMutator },\n]\n\n// ── Multi-turn scenario convenience wrapper ──────────────────────────\n\nexport interface ParaphraseRobustnessScenarioInput {\n scenarios: Array<{ id: string; userTurns: string[] }>\n /**\n * Mutators applied to every user turn in every scenario. Each\n * scenario is paraphrased once per mutator (so `reps` × `scenarios`\n * × `mutators` total paraphrased runs).\n */\n mutators: Array<{ name: string; mutator: (text: string) => string }>\n /**\n * Run a (possibly mutated) scenario and return its score in [0,1].\n * Called once for the original turns of each scenario, and once per\n * (scenario × mutator × rep) for the paraphrased variants.\n */\n runScenario: (args: { id: string; userTurns: string[] }) => Promise<{ score: number }>\n /** Times to repeat each (scenario × mutator) pair. Default 1. */\n reps?: number\n}\n\nexport interface ParaphraseRobustnessScenarioResult {\n /**\n * Aggregate robustness: `mean(paraphrased) / mean(original)`,\n * clipped to `[0, 1]`. `1` = paraphrasing didn't degrade the agent;\n * `0` = paraphrasing destroyed it (or original was 0).\n */\n score: number\n perScenario: Array<{\n id: string\n originalScore: number\n paraphrasedMean: number\n /** Per-mutator delta (paraphrased − original); negative = mutator hurt. */\n deltas: Record<string, number>\n }>\n mutators: string[]\n}\n\n/**\n * Multi-turn convenience wrapper around {@link paraphraseRobustness}.\n *\n * Consumers with a list of multi-turn scenarios were hand-wrapping the\n * single-prompt runner per scenario; this iterates for them. Mutators\n * are applied to every user turn (mutator runs once per turn with a\n * stable seed derived from the rep index).\n *\n * Contract:\n * - Calls `runScenario` once with the original `userTurns` to\n * establish the baseline `originalScore`.\n * - For each `(scenario, mutator, rep)` combination, builds a\n * mutated copy of `userTurns` (every turn passed through\n * `mutator.mutator`) and calls `runScenario` again.\n * - Aggregates per-scenario means, then computes the overall\n * `mean(paraphrasedMean) / mean(originalScore)`, clipped to\n * `[0, 1]`. If every original score is 0 the aggregate is 0.\n */\nexport async function paraphraseRobustnessScenarios(\n args: ParaphraseRobustnessScenarioInput,\n): Promise<ParaphraseRobustnessScenarioResult> {\n const reps = Math.max(1, args.reps ?? 1)\n const mutatorNames = args.mutators.map((m) => m.name)\n\n const perScenario: ParaphraseRobustnessScenarioResult['perScenario'] = []\n\n for (const scenario of args.scenarios) {\n const baseline = await args.runScenario({\n id: scenario.id,\n userTurns: scenario.userTurns,\n })\n const originalScore = baseline.score\n\n const deltas: Record<string, number> = {}\n const paraphrasedAll: number[] = []\n\n for (const m of args.mutators) {\n const scores: number[] = []\n for (let r = 0; r < reps; r++) {\n const mutatedTurns = scenario.userTurns.map((t) => m.mutator(t))\n const out = await args.runScenario({\n id: scenario.id,\n userTurns: mutatedTurns,\n })\n scores.push(out.score)\n }\n const mean = scores.reduce((a, b) => a + b, 0) / scores.length\n deltas[m.name] = mean - originalScore\n paraphrasedAll.push(...scores)\n }\n\n const paraphrasedMean =\n paraphrasedAll.length === 0\n ? originalScore\n : paraphrasedAll.reduce((a, b) => a + b, 0) / paraphrasedAll.length\n\n perScenario.push({ id: scenario.id, originalScore, paraphrasedMean, deltas })\n }\n\n const meanOriginal =\n perScenario.length === 0\n ? 0\n : perScenario.reduce((a, p) => a + p.originalScore, 0) / perScenario.length\n const meanParaphrased =\n perScenario.length === 0\n ? 0\n : perScenario.reduce((a, p) => a + p.paraphrasedMean, 0) / perScenario.length\n\n const ratio = meanOriginal <= 0 ? 0 : meanParaphrased / meanOriginal\n const score = Math.max(0, Math.min(1, ratio))\n\n return { score, perScenario, mutators: mutatorNames }\n}\n","/**\n * Visual diff — pixel-delta scoring for UI / visual outputs.\n *\n * Minimal dependency-free implementation: accepts two PNGs as byte\n * arrays + width/height and returns a Δ ratio + per-channel histogram.\n * Consumers supply the decoded pixel arrays (we don't pull a PNG\n * decoder into the core — use `sharp`, `@napi-rs/canvas`, or Playwright\n * in the driving test and pass the result here).\n */\n\nimport { ValidationError } from './errors'\n\nexport interface ImageData {\n width: number\n height: number\n /** Pixel data in RGBA order, 4 bytes per pixel. */\n data: Uint8Array | Uint8ClampedArray\n}\n\nexport interface VisualDiffResult {\n /** Ratio of pixels differing beyond `tolerance` (0..1). */\n diffRatio: number\n differingPixels: number\n totalPixels: number\n maxChannelDelta: number\n /** Status for dashboards: unchanged (< 0.1%), changed, or severely-changed (> 5%). */\n status: 'unchanged' | 'changed' | 'severely-changed'\n}\n\nexport interface VisualDiffOptions {\n /** Pixels whose max-channel delta is ≤ this are considered unchanged. Default 8/255. */\n tolerance?: number\n}\n\nexport function visualDiff(\n a: ImageData,\n b: ImageData,\n options: VisualDiffOptions = {},\n): VisualDiffResult {\n if (a.width !== b.width || a.height !== b.height) {\n throw new ValidationError(\n `visualDiff: image dims differ (${a.width}x${a.height} vs ${b.width}x${b.height})`,\n )\n }\n if (a.data.length !== b.data.length) {\n throw new ValidationError('visualDiff: image data length mismatch')\n }\n const tolerance = options.tolerance ?? 8\n const totalPixels = a.width * a.height\n let differing = 0\n let maxDelta = 0\n for (let i = 0; i < a.data.length; i += 4) {\n const dr = Math.abs(a.data[i]! - b.data[i]!)\n const dg = Math.abs(a.data[i + 1]! - b.data[i + 1]!)\n const db = Math.abs(a.data[i + 2]! - b.data[i + 2]!)\n const da = Math.abs(a.data[i + 3]! - b.data[i + 3]!)\n const worst = Math.max(dr, dg, db, da)\n if (worst > maxDelta) maxDelta = worst\n if (worst > tolerance) differing++\n }\n const diffRatio = totalPixels > 0 ? differing / totalPixels : 0\n const status = diffRatio < 0.001 ? 'unchanged' : diffRatio > 0.05 ? 'severely-changed' : 'changed'\n return { diffRatio, differingPixels: differing, totalPixels, maxChannelDelta: maxDelta, status }\n}\n\n/** Convenience: diffs two byte-identical-dim RGBA arrays, returns just the ratio. */\nexport function pixelDeltaRatio(\n a: Uint8Array,\n b: Uint8Array,\n width: number,\n height: number,\n tolerance = 8,\n): number {\n return visualDiff({ width, height, data: a }, { width, height, data: b }, { tolerance }).diffRatio\n}\n","/**\n * Bisector — auto-locate the change that introduced an eval regression.\n *\n * Two shapes:\n * - `commitBisect` — walk an ordered SHA list, binary-search for the\n * first commit that fails.\n * - `promptBisect` — given a good and bad prompt, progressively port\n * paragraphs from good→bad to localize the breaking change.\n *\n * Generic `bisect<T>` lets callers drive any ordered state space\n * (dataset versions, config files, CLI flag combinations).\n */\n\nexport interface BisectOptions<T> {\n /** State known to pass. */\n good: T\n /** State known to fail. */\n bad: T\n /** Equality test on state values — default Object.is. */\n equals?: (a: T, b: T) => boolean\n /** Pick the halfway state between good + bad. Return null when no further\n * split is possible (e.g. adjacent commits). */\n halfway: (good: T, bad: T) => T | null\n /** Produce a verdict for a state. */\n runEval: (state: T) => Promise<{ score: number; pass: boolean }>\n /** Hard cap on iterations (default 40 — covers ~1T ordered states). */\n maxIterations?: number\n}\n\nexport interface BisectStep<T> {\n state: T\n score: number\n pass: boolean\n}\n\nexport interface BisectResult<T> {\n /** The first bad state — typically `bad` in the final (good, bad) adjacent pair. */\n culprit: T\n /** Ordered trace of all states evaluated. */\n path: BisectStep<T>[]\n /** True when we narrowed to an adjacent (good, bad) pair. */\n converged: boolean\n /** True when `good` itself failed or `bad` itself passed — the caller's\n * premise was broken. */\n inputInconsistent: boolean\n}\n\nexport async function bisect<T>(options: BisectOptions<T>): Promise<BisectResult<T>> {\n const equals = options.equals ?? ((a, b) => Object.is(a, b))\n const maxIter = options.maxIterations ?? 40\n const path: BisectStep<T>[] = []\n\n const goodVerdict = await options.runEval(options.good)\n path.push({ state: options.good, ...goodVerdict })\n const badVerdict = await options.runEval(options.bad)\n path.push({ state: options.bad, ...badVerdict })\n\n if (!goodVerdict.pass) {\n return { culprit: options.good, path, converged: false, inputInconsistent: true }\n }\n if (badVerdict.pass) {\n return { culprit: options.bad, path, converged: false, inputInconsistent: true }\n }\n\n let good = options.good\n let bad = options.bad\n for (let i = 0; i < maxIter; i++) {\n const mid = options.halfway(good, bad)\n if (mid === null || equals(mid, good) || equals(mid, bad)) {\n return { culprit: bad, path, converged: true, inputInconsistent: false }\n }\n const v = await options.runEval(mid)\n path.push({ state: mid, ...v })\n if (v.pass) good = mid\n else bad = mid\n }\n return { culprit: bad, path, converged: false, inputInconsistent: false }\n}\n\n/**\n * Commit bisect — `commits` is an ordered SHA list, oldest to newest.\n * `good` and `bad` must both be present in the list.\n */\nexport async function commitBisect(options: {\n commits: string[]\n good: string\n bad: string\n runEval: (sha: string) => Promise<{ score: number; pass: boolean }>\n maxIterations?: number\n}): Promise<BisectResult<string>> {\n const { commits } = options\n const goodIdx = commits.indexOf(options.good)\n const badIdx = commits.indexOf(options.bad)\n if (goodIdx < 0 || badIdx < 0) {\n throw new Error(\n `commitBisect: good or bad SHA not in commit list (good=${options.good}, bad=${options.bad})`,\n )\n }\n if (goodIdx >= badIdx) {\n throw new Error('commitBisect: good must precede bad in the commit list')\n }\n return bisect<string>({\n good: options.good,\n bad: options.bad,\n runEval: options.runEval,\n maxIterations: options.maxIterations,\n halfway: (g, b) => {\n const gi = commits.indexOf(g)\n const bi = commits.indexOf(b)\n if (bi - gi <= 1) return null\n return commits[Math.floor((gi + bi) / 2)] ?? null\n },\n })\n}\n\n/**\n * Prompt bisect — splits the good and bad prompts into paragraphs, then\n * progressively replaces paragraphs in `good` with their counterparts\n * from `bad` to localize the offending change. Only works when the two\n * prompts have the same paragraph count (a common editorial workflow\n * constraint — one paragraph = one change unit).\n */\nexport async function promptBisect(options: {\n good: string\n bad: string\n runEval: (prompt: string) => Promise<{ score: number; pass: boolean }>\n maxIterations?: number\n paragraphSplitter?: (prompt: string) => string[]\n}): Promise<BisectResult<string> & { offendingParagraphIndex?: number }> {\n const split = options.paragraphSplitter ?? ((p: string) => p.split(/\\n\\s*\\n/))\n const join = (paragraphs: string[]) => paragraphs.join('\\n\\n')\n const goodParas = split(options.good)\n const badParas = split(options.bad)\n if (goodParas.length !== badParas.length) {\n throw new Error(\n `promptBisect: paragraph count mismatch (${goodParas.length} vs ${badParas.length})`,\n )\n }\n if (goodParas.length < 2) {\n throw new Error('promptBisect: need at least 2 paragraphs to bisect')\n }\n // Represent state as a bit-mask of which paragraphs come from `bad`.\n // good = all-zero, bad = all-one; halfway = flip the midpoint half.\n const n = goodParas.length\n const goodMask = '0'.repeat(n)\n const badMask = '1'.repeat(n)\n\n function paragraphsFor(mask: string): string[] {\n return mask.split('').map((c, i) => (c === '1' ? badParas[i]! : goodParas[i]!))\n }\n\n const result = await bisect<string>({\n good: goodMask,\n bad: badMask,\n runEval: (mask) => options.runEval(join(paragraphsFor(mask))),\n maxIterations: options.maxIterations ?? n + 5,\n halfway: (g, b) => {\n // Pick the first differing position and flip it.\n for (let i = 0; i < g.length; i++) {\n if (g[i] !== b[i]) {\n // Flip the midpoint between the remaining diff positions.\n const differing: number[] = []\n for (let j = i; j < g.length; j++) if (g[j] !== b[j]) differing.push(j)\n if (differing.length === 0) return null\n if (differing.length === 1) return null // adjacent — can't narrow further\n // Flip the first half of differing positions from good → bad.\n const flip = differing.slice(0, Math.ceil(differing.length / 2))\n const chars = g.split('')\n for (const f of flip) chars[f] = b[f]!\n return chars.join('')\n }\n }\n return null\n },\n equals: (a, b) => a === b,\n })\n\n // Identify the offending paragraph as the index that changed between the\n // last good and final bad in the path.\n let offendingParagraphIndex: number | undefined\n const lastGood = result.path.filter((s) => s.pass).pop()\n const culprit = result.culprit\n if (lastGood) {\n for (let i = 0; i < n; i++) {\n if (lastGood.state[i] !== culprit[i]) {\n offendingParagraphIndex = i\n break\n }\n }\n }\n\n // Materialize path states back into full prompts for caller consumption.\n const materializedPath: BisectStep<string>[] = result.path.map((s) => ({\n state: join(paragraphsFor(s.state)),\n score: s.score,\n pass: s.pass,\n }))\n\n return {\n culprit: join(paragraphsFor(culprit)),\n path: materializedPath,\n converged: result.converged,\n inputInconsistent: result.inputInconsistent,\n offendingParagraphIndex,\n }\n}\n","/**\n * Full cross-trace diff — align two trajectories step-by-step, report\n * per-step score deltas, attribute a variant's total outcome lead to\n * specific turns.\n *\n * 0.5 shipped `firstDivergenceView` (finds the first differing step).\n * This does the heavier work: full alignment via LCS, per-step\n * contribution to score delta using PRM verdicts when available,\n * fallback to structural heuristics (latency, token count, tool\n * outcome) otherwise.\n */\n\nimport type { JudgeSpan, Span } from './trace/schema'\nimport { isJudgeSpan } from './trace/schema'\nimport type { TraceStore } from './trace/store'\nimport { buildTrajectory, type TrajectoryStep } from './trajectory'\n\nexport type AlignmentOp =\n | { op: 'match'; a: TrajectoryStep; b: TrajectoryStep }\n | { op: 'insert'; b: TrajectoryStep }\n | { op: 'delete'; a: TrajectoryStep }\n | { op: 'replace'; a: TrajectoryStep; b: TrajectoryStep }\n\nexport interface StepAttribution {\n op: AlignmentOp\n /** Difference in PRM score (or null when not scored by a matching judge). */\n prmDelta: number | null\n /** Difference in latency (endedAt - startedAt). */\n latencyDeltaMs: number | null\n /** Difference in token count (LLM spans). */\n tokenDelta: number | null\n /** Reason this step is / isn't considered a contributor to the outcome delta. */\n note: string\n}\n\nexport interface CrossTraceDiff {\n runA: string\n runB: string\n alignment: AlignmentOp[]\n attributions: StepAttribution[]\n /** Total score delta (B - A). */\n totalScoreDelta: number | null\n /** Sum of PRM deltas across matched/replaced steps. Close to\n * `totalScoreDelta` when PRM covers the trajectory; gap indicates\n * unmodeled variance. */\n prmDeltaSum: number\n}\n\nexport interface CrossTraceDiffOptions {\n stepEquals?: (a: TrajectoryStep, b: TrajectoryStep) => boolean\n}\n\nexport async function crossTraceDiff(\n store: TraceStore,\n runA: string,\n runB: string,\n options: CrossTraceDiffOptions = {},\n): Promise<CrossTraceDiff> {\n const [a, b] = await Promise.all([buildTrajectory(store, runA), buildTrajectory(store, runB)])\n const eq = options.stepEquals ?? defaultStepEquals\n const alignment = align(a.steps, b.steps, eq)\n\n const [judgesA, judgesB] = await Promise.all([\n store.spans({ runId: runA, kind: 'judge' }).then((s) => s.filter(isJudgeSpan)),\n store.spans({ runId: runB, kind: 'judge' }).then((s) => s.filter(isJudgeSpan)),\n ])\n const prmByTargetA = indexPrmByTarget(judgesA)\n const prmByTargetB = indexPrmByTarget(judgesB)\n\n const attributions: StepAttribution[] = alignment.map((ao) =>\n attributeStep(ao, prmByTargetA, prmByTargetB),\n )\n const prmDeltaSum = attributions.reduce((acc, at) => acc + (at.prmDelta ?? 0), 0)\n\n const [runRecA, runRecB] = await Promise.all([store.getRun(runA), store.getRun(runB)])\n const totalScoreDelta =\n runRecA?.outcome?.score !== undefined && runRecB?.outcome?.score !== undefined\n ? runRecB.outcome.score - runRecA.outcome.score\n : null\n\n return { runA, runB, alignment, attributions, totalScoreDelta, prmDeltaSum }\n}\n\n// ── Alignment (LCS-based) ────────────────────────────────────────────\n\nfunction align(\n a: TrajectoryStep[],\n b: TrajectoryStep[],\n eq: (x: TrajectoryStep, y: TrajectoryStep) => boolean,\n): AlignmentOp[] {\n const dp: number[][] = Array.from({ length: a.length + 1 }, () => new Array(b.length + 1).fill(0))\n for (let i = 1; i <= a.length; i++) {\n for (let j = 1; j <= b.length; j++) {\n if (eq(a[i - 1]!, b[j - 1]!)) dp[i]![j] = dp[i - 1]![j - 1]! + 1\n else dp[i]![j] = Math.max(dp[i - 1]![j]!, dp[i]![j - 1]!)\n }\n }\n // Walk back to recover ops.\n const ops: AlignmentOp[] = []\n let i = a.length\n let j = b.length\n while (i > 0 || j > 0) {\n if (i > 0 && j > 0 && eq(a[i - 1]!, b[j - 1]!)) {\n ops.push({ op: 'match', a: a[i - 1]!, b: b[j - 1]! })\n i--\n j--\n } else if (i > 0 && j > 0 && dp[i - 1]![j]! === dp[i]![j - 1]!) {\n // Tie → call it a replace when same kind, else delete+insert.\n if (a[i - 1]!.span.kind === b[j - 1]!.span.kind) {\n ops.push({ op: 'replace', a: a[i - 1]!, b: b[j - 1]! })\n i--\n j--\n } else if (dp[i - 1]![j]! >= dp[i]![j - 1]!) {\n ops.push({ op: 'delete', a: a[i - 1]! })\n i--\n } else {\n ops.push({ op: 'insert', b: b[j - 1]! })\n j--\n }\n } else if (i > 0 && (j === 0 || dp[i - 1]![j]! >= dp[i]![j - 1]!)) {\n ops.push({ op: 'delete', a: a[i - 1]! })\n i--\n } else {\n ops.push({ op: 'insert', b: b[j - 1]! })\n j--\n }\n }\n return ops.reverse()\n}\n\nfunction defaultStepEquals(a: TrajectoryStep, b: TrajectoryStep): boolean {\n if (a.span.kind !== b.span.kind) return false\n if (a.span.kind === 'tool' && b.span.kind === 'tool') return a.span.toolName === b.span.toolName\n if (a.span.kind === 'llm' && b.span.kind === 'llm') return a.span.model === b.span.model\n return a.span.name === b.span.name\n}\n\n// ── PRM indexing + attribution ───────────────────────────────────────\n\nfunction indexPrmByTarget(judges: JudgeSpan[]): Map<string, number> {\n const out = new Map<string, number>()\n for (const j of judges) {\n const prior = out.get(j.targetSpanId) ?? 0\n out.set(j.targetSpanId, prior + j.score)\n }\n return out\n}\n\nfunction spanLatency(s: Span): number | null {\n return s.endedAt && s.startedAt ? s.endedAt - s.startedAt : null\n}\n\nfunction spanTokens(s: Span): number | null {\n if (s.kind !== 'llm') return null\n return (s.inputTokens ?? 0) + (s.outputTokens ?? 0)\n}\n\nfunction attributeStep(\n op: AlignmentOp,\n prmA: Map<string, number>,\n prmB: Map<string, number>,\n): StepAttribution {\n if (op.op === 'match') {\n const pa = prmA.get(op.a.span.spanId)\n const pb = prmB.get(op.b.span.spanId)\n const prmDelta = pa !== undefined && pb !== undefined ? pb - pa : null\n const la = spanLatency(op.a.span)\n const lb = spanLatency(op.b.span)\n const ta = spanTokens(op.a.span)\n const tb = spanTokens(op.b.span)\n return {\n op,\n prmDelta,\n latencyDeltaMs: la !== null && lb !== null ? lb - la : null,\n tokenDelta: ta !== null && tb !== null ? tb - ta : null,\n note:\n prmDelta === null ? 'matched step, no PRM coverage' : 'matched step, PRM delta recorded',\n }\n }\n if (op.op === 'replace') {\n const pa = prmA.get(op.a.span.spanId) ?? 0\n const pb = prmB.get(op.b.span.spanId) ?? 0\n return {\n op,\n prmDelta: pb - pa,\n latencyDeltaMs: null,\n tokenDelta: null,\n note: `replaced ${op.a.span.kind}/${op.a.span.name} → ${op.b.span.kind}/${op.b.span.name}`,\n }\n }\n if (op.op === 'insert') {\n const pb = prmB.get(op.b.span.spanId) ?? 0\n return {\n op,\n prmDelta: pb,\n latencyDeltaMs: null,\n tokenDelta: null,\n note: `inserted step in B (${op.b.span.kind}/${op.b.span.name})`,\n }\n }\n // delete\n const pa = prmA.get(op.a.span.spanId) ?? 0\n return {\n op,\n prmDelta: -pa,\n latencyDeltaMs: null,\n tokenDelta: null,\n note: `deleted step from A (${op.a.span.kind}/${op.a.span.name})`,\n }\n}\n","/**\n * Active learning — agent-as-scenario-author.\n *\n * Analyzes an existing Dataset + trace corpus for coverage gaps and\n * weak spots, returns a prioritized list of *synthesis targets*:\n * (gap description, existing-neighbor examples, suggested direction).\n *\n * Does NOT call an LLM itself — the proposer agent is caller-supplied.\n * This module's job is to identify WHERE new scenarios would compound\n * the most information, not to author them.\n *\n * Gaps we detect:\n * - dimensions with high score variance (unstable, need more data)\n * - dimensions with low coverage count (undersampled)\n * - failure classes with clusters (systematic weakness)\n * - difficulty bins with no coverage\n */\n\nimport type { Dataset, DatasetScenario } from './dataset'\nimport { classifyFailure } from './failure-taxonomy'\nimport type { Run } from './trace/schema'\nimport type { TraceStore } from './trace/store'\n\nexport type SynthesisReason =\n | 'high-variance'\n | 'undersampled'\n | 'failure-cluster'\n | 'difficulty-gap'\n\nexport interface SynthesisTarget {\n reason: SynthesisReason\n description: string\n /** Existing scenarios that are closest to the gap; caller feeds these to\n * their LLM proposer as few-shot examples. */\n neighbors: DatasetScenario[]\n /** Suggested direction — e.g. \"harder variants\", \"edge cases of X\", \"failure class Y\". */\n direction: string\n /** Priority score — higher = more information-dense gap. 0..1. */\n priority: number\n}\n\nexport interface ActiveLearningOptions {\n /** Minimum scenarios per difficulty band to count as \"covered\". */\n minPerBand?: number\n /** Variance threshold above which a scenario's dimension is \"unstable\". */\n varianceThreshold?: number\n /** Max synthesis targets returned. */\n topK?: number\n}\n\nexport async function proposeSynthesisTargets(\n dataset: Dataset,\n traceStore: TraceStore,\n options: ActiveLearningOptions = {},\n): Promise<SynthesisTarget[]> {\n const minPerBand = options.minPerBand ?? 5\n const varianceThreshold = options.varianceThreshold ?? 0.05\n const topK = options.topK ?? 10\n const scenarios = dataset.all()\n\n const targets: SynthesisTarget[] = []\n\n // 1. Difficulty coverage gaps\n const BANDS: Array<DatasetScenario['difficulty']> = ['easy', 'medium', 'hard', 'extreme']\n for (const band of BANDS) {\n const count = scenarios.filter((s) => s.difficulty === band).length\n if (count < minPerBand) {\n const neighbors = scenarios.filter((s) => s.difficulty === band).slice(0, 3)\n targets.push({\n reason: 'difficulty-gap',\n description: `difficulty=\"${band}\" has ${count} scenario(s) — below minimum ${minPerBand}`,\n neighbors: [...neighbors],\n direction: `create more \"${band}\" scenarios; reuse domain but shift complexity`,\n priority: Math.max(0, 1 - count / minPerBand),\n })\n }\n }\n\n // 2. Undersampled scenarios (few runs per scenario)\n const runs = await traceStore.listRuns()\n const runCountByScenario = new Map<string, number>()\n for (const r of runs) {\n runCountByScenario.set(r.scenarioId, (runCountByScenario.get(r.scenarioId) ?? 0) + 1)\n }\n const runCounts = [...runCountByScenario.values()]\n const p25 = runCounts.length > 0 ? quantile(runCounts, 0.25) : 0\n for (const s of scenarios) {\n const count = runCountByScenario.get(s.id) ?? 0\n if (count <= p25 && count < 3) {\n targets.push({\n reason: 'undersampled',\n description: `scenario \"${s.id}\" has only ${count} run(s)`,\n neighbors: [s],\n direction: `create near-duplicates of \"${s.id}\" to stabilize its mean`,\n priority: Math.max(0, 1 - count / 3) * 0.7,\n })\n }\n }\n\n // 3. High-variance scenarios (same scenario scored inconsistently)\n for (const s of scenarios) {\n const sRuns = runs.filter((r) => r.scenarioId === s.id)\n const scores = sRuns\n .map((r) => r.outcome?.score)\n .filter((x): x is number => typeof x === 'number')\n if (scores.length < 3) continue\n const mean = scores.reduce((a, b) => a + b, 0) / scores.length\n const variance = scores.reduce((a, b) => a + (b - mean) ** 2, 0) / scores.length\n if (variance > varianceThreshold) {\n targets.push({\n reason: 'high-variance',\n description: `scenario \"${s.id}\" has unstable scoring (variance ${variance.toFixed(3)})`,\n neighbors: [s],\n direction: `disambiguate the scenario description — current wording admits too many valid interpretations`,\n priority: Math.min(1, variance * 5),\n })\n }\n }\n\n // 4. Failure-class clusters — run classifier across the corpus\n const failureByClass = new Map<string, Run[]>()\n for (const run of runs) {\n if (run.outcome?.pass === true) continue\n const spans = await traceStore.spans({ runId: run.runId })\n const events = await traceStore.events({ runId: run.runId })\n const { failureClass } = classifyFailure({ run, spans, events })\n if (failureClass === 'success' || failureClass === 'unknown') continue\n const arr = failureByClass.get(failureClass) ?? []\n arr.push(run)\n failureByClass.set(failureClass, arr)\n }\n for (const [cls, runs] of failureByClass) {\n if (runs.length < 3) continue\n const affectedScenarios = [...new Set(runs.map((r) => r.scenarioId))]\n const neighbors = scenarios.filter((s) => affectedScenarios.includes(s.id)).slice(0, 3)\n targets.push({\n reason: 'failure-cluster',\n description: `failure class \"${cls}\" observed ${runs.length}× across ${affectedScenarios.length} scenario(s)`,\n neighbors,\n direction: `create scenarios that exercise \"${cls}\" recovery — currently a systematic weakness`,\n priority: Math.min(1, runs.length / 10),\n })\n }\n\n return targets.sort((a, b) => b.priority - a.priority).slice(0, topK)\n}\n\nfunction quantile(xs: number[], p: number): number {\n const sorted = [...xs].sort((a, b) => a - b)\n const idx = p * (sorted.length - 1)\n const lo = Math.floor(idx)\n const hi = Math.ceil(idx)\n return sorted[lo]! + (sorted[hi]! - sorted[lo]!) * (idx - lo)\n}\n","/**\n * Causal attribution via factorial experiments.\n *\n * Run every combination of {model × prompt × scenario × seed}, then\n * decompose observed score variance into main effects + interactions.\n * Moves from correlational \"variant B is better\" to causal \"the model\n * swap accounts for 42% of the lead; the prompt change accounts for 28%;\n * interaction is 30%.\"\n *\n * Minimal implementation: 2-way factorial (two factors at a time) with\n * main-effect + interaction decomposition via variance of cell means.\n * Consumers run the factorial design themselves (we don't schedule\n * runs); this module consumes the (factorLevels, observedScores)\n * table and does the attribution math.\n */\n\nexport interface FactorialCell {\n /** Map factor name → level id. e.g. { model: 'claude', prompt: 'v2' } */\n levels: Record<string, string>\n /** Observed score for this cell (mean over replications if n > 1). */\n score: number\n /** Number of replications averaged to produce `score`. */\n n: number\n}\n\nexport interface FactorContribution {\n factor: string\n /** Variance attributed to this factor's main effect, as a fraction of total. */\n shareOfVariance: number\n /** Range of cell means across levels of this factor. */\n range: number\n}\n\nexport interface InteractionContribution {\n factors: [string, string]\n shareOfVariance: number\n}\n\nexport interface CausalAttributionReport {\n totalVariance: number\n mainEffects: FactorContribution[]\n interactions: InteractionContribution[]\n /** Residual = variance unexplained by main effects + modeled interactions. */\n residualShare: number\n /** Sanity: shares sum to 1 (within fp). */\n sharesSum: number\n}\n\nexport function causalAttribution(cells: FactorialCell[]): CausalAttributionReport {\n if (cells.length < 4) throw new Error('causalAttribution: need ≥ 4 cells to estimate effects')\n const factors = Object.keys(cells[0]!.levels)\n if (factors.length < 2) throw new Error('causalAttribution: need ≥ 2 factors')\n\n const allScores = cells.map((c) => c.score)\n const grandMean = allScores.reduce((a, b) => a + b, 0) / allScores.length\n const totalVariance =\n allScores.reduce((acc, s) => acc + (s - grandMean) ** 2, 0) / allScores.length\n if (totalVariance === 0) {\n return {\n totalVariance: 0,\n mainEffects: factors.map((f) => ({ factor: f, shareOfVariance: 0, range: 0 })),\n interactions: [],\n residualShare: 1,\n sharesSum: 1,\n }\n }\n\n // Main effects: variance of cell-mean-by-level, averaged across other factors.\n const mainEffects: FactorContribution[] = factors.map((f) => {\n const byLevel = groupBy(cells, (c) => c.levels[f] ?? '')\n const means: number[] = []\n for (const arr of byLevel.values()) {\n means.push(arr.reduce((a, c) => a + c.score, 0) / arr.length)\n }\n const mainVariance = means.reduce((acc, m) => acc + (m - grandMean) ** 2, 0) / means.length\n return {\n factor: f,\n shareOfVariance: mainVariance / totalVariance,\n range: Math.max(...means) - Math.min(...means),\n }\n })\n\n // Pairwise interactions: cell mean by (factor_i, factor_j) vs main effects\n const interactions: InteractionContribution[] = []\n for (let i = 0; i < factors.length; i++) {\n for (let j = i + 1; j < factors.length; j++) {\n const fi = factors[i]!\n const fj = factors[j]!\n const byPair = groupBy(cells, (c) => `${c.levels[fi]}|${c.levels[fj]}`)\n const pairMeans: number[] = []\n for (const arr of byPair.values()) {\n pairMeans.push(arr.reduce((a, c) => a + c.score, 0) / arr.length)\n }\n const pairVariance =\n pairMeans.reduce((acc, m) => acc + (m - grandMean) ** 2, 0) / pairMeans.length\n const mainI = mainEffects[i]!.shareOfVariance * totalVariance\n const mainJ = mainEffects[j]!.shareOfVariance * totalVariance\n const interactionVariance = Math.max(0, pairVariance - mainI - mainJ)\n interactions.push({\n factors: [fi, fj],\n shareOfVariance: interactionVariance / totalVariance,\n })\n }\n }\n\n const mainSum = mainEffects.reduce((a, m) => a + m.shareOfVariance, 0)\n const interactionSum = interactions.reduce((a, m) => a + m.shareOfVariance, 0)\n const residualShare = Math.max(0, 1 - mainSum - interactionSum)\n const sharesSum = mainSum + interactionSum + residualShare\n return { totalVariance, mainEffects, interactions, residualShare, sharesSum }\n}\n\nfunction groupBy<T>(items: T[], key: (t: T) => string): Map<string, T[]> {\n const m = new Map<string, T[]>()\n for (const item of items) {\n const k = key(item)\n const arr = m.get(k) ?? []\n arr.push(item)\n m.set(k, arr)\n }\n return m\n}\n","/**\n * Export PRM-graded traces as training data for downstream reward-model\n * fine-tuning. Canonical format is NDJSON of\n * `{ trajectory_text, step_index, rubric, score }` so a small model can\n * learn to predict step rewards from step context.\n *\n * The framework doesn't train the model — we emit the data; callers\n * plug it into their preferred trainer (TRL, Unsloth, custom).\n */\n\nimport type { LlmSpan, Span } from '../trace/schema'\nimport { isLlmSpan, isToolSpan } from '../trace/schema'\nimport type { TraceStore } from '../trace/store'\nimport { buildTrajectory } from '../trajectory'\nimport type { PrmGradedTrace } from './rubric'\n\nexport interface PrmTrainingSample {\n runId: string\n spanId: string\n rubricId: string\n score: number\n /** Serialized step context — step + surrounding conversation. */\n context: {\n priorTurns: Array<{ role: string; content: string }>\n step: { kind: Span['kind']; text: string }\n }\n /** Optional evidence + rationale for auditability. */\n rationale?: string\n evidence?: string\n}\n\nexport async function exportTrainingData(\n store: TraceStore,\n graded: PrmGradedTrace[],\n options: { contextWindow?: number } = {},\n): Promise<PrmTrainingSample[]> {\n const window = options.contextWindow ?? 5\n const out: PrmTrainingSample[] = []\n for (const g of graded) {\n const trajectory = await buildTrajectory(store, g.runId)\n const spanById = new Map(trajectory.steps.map((s) => [s.span.spanId, s]))\n for (const gs of g.steps) {\n const node = spanById.get(gs.spanId)\n if (!node) continue\n const idx = trajectory.steps.indexOf(node)\n const priorSpans = trajectory.steps.slice(Math.max(0, idx - window), idx).map((s) => s.span)\n out.push({\n runId: g.runId,\n spanId: gs.spanId,\n rubricId: gs.rubricId,\n score: gs.score,\n context: {\n priorTurns: priorSpans\n .map(spanToTurn)\n .filter((t): t is { role: string; content: string } => t !== null),\n step: { kind: node.span.kind, text: spanToText(node.span) },\n },\n rationale: gs.rationale,\n evidence: gs.evidence,\n })\n }\n }\n return out\n}\n\n/** NDJSON serialization — write to file or stream directly to a trainer. */\nexport function toNdjson(samples: PrmTrainingSample[]): string {\n return `${samples.map((s) => JSON.stringify(s)).join('\\n')}\\n`\n}\n\nfunction spanToTurn(span: Span): { role: string; content: string } | null {\n if (isLlmSpan(span)) {\n const text = span.output ?? span.messages.map((m) => `${m.role}: ${m.content}`).join('\\n')\n return { role: 'assistant', content: text }\n }\n if (isToolSpan(span)) {\n return {\n role: 'tool',\n content: `${span.toolName}(${safeStringify(span.args)}) → ${safeStringify(span.result)}`,\n }\n }\n return null\n}\n\nfunction spanToText(span: Span): string {\n if (isLlmSpan(span)) return (span as LlmSpan).output ?? ''\n if (isToolSpan(span))\n return `${span.toolName}(${safeStringify(span.args)}) → ${safeStringify(span.result)}`\n return span.name\n}\n\nfunction safeStringify(v: unknown): string {\n if (v === null || v === undefined) return ''\n if (typeof v === 'string') return v\n try {\n return JSON.stringify(v)\n } catch {\n return String(v)\n }\n}\n","/**\n * Reward-model export — the productizable wrapper around PRM training\n * data. Takes a TraceStore + PrmGrader, produces an embeddable\n * inference scorer that customers plug into their own agent stack.\n *\n * Two export forms:\n * - `exportRewardModel(store, graders)` — serializes the (step-context,\n * score) corpus to a framework-agnostic payload. Customer fine-tunes\n * their own model; we ship the scaffolding.\n * - `loadScorerFromTraces(store, grader)` — a zero-deps \"reward model\"\n * that literally replays the trained rubric at inference time. Works\n * as a reference baseline + deterministic fallback.\n */\n\nimport type { PrmGradedTrace, PrmGrader } from './prm/rubric'\nimport { exportTrainingData, type PrmTrainingSample, toNdjson } from './prm/training-export'\nimport type { TraceStore } from './trace/store'\nimport type { Trajectory } from './trajectory'\nimport { buildTrajectory } from './trajectory'\n\nexport interface ExportedRewardModel {\n /** Version of the export format. Bump when payload shape changes. */\n version: '1.0'\n /** Metadata about the training corpus. */\n metadata: {\n nTraces: number\n nSamples: number\n rubrics: string[]\n exportedAt: string\n /** Mean reward across training corpus — use as sanity check at load. */\n meanReward: number\n }\n /** NDJSON training payload suitable for most fine-tuning frameworks. */\n trainingNdjson: string\n}\n\nexport async function exportRewardModel(\n store: TraceStore,\n grader: PrmGrader,\n runIds: string[],\n): Promise<ExportedRewardModel> {\n const graded = await Promise.all(runIds.map((id) => grader.grade(store, id)))\n const samples = await exportTrainingData(store, graded)\n const rubrics = [...new Set(samples.map((s) => s.rubricId))]\n const meanReward =\n samples.length > 0 ? samples.reduce((a, s) => a + s.score, 0) / samples.length : 0\n return {\n version: '1.0',\n metadata: {\n nTraces: graded.length,\n nSamples: samples.length,\n rubrics,\n exportedAt: new Date().toISOString(),\n meanReward,\n },\n trainingNdjson: toNdjson(samples),\n }\n}\n\n/**\n * Zero-deps inference scorer — apply a grader to a trajectory and return\n * its aggregate score. This is the \"reward model\" customers embed when\n * they don't want (or can't) fine-tune one. Deterministic + portable.\n */\nexport interface InferenceScorer {\n /** Score a completed trajectory. Higher is better. */\n score(trajectory: Trajectory, store: TraceStore): Promise<number>\n metadata: { rubrics: string[]; deterministic: true }\n}\n\nexport function loadScorerFromGrader(grader: PrmGrader): InferenceScorer {\n return {\n async score(trajectory, store) {\n const graded = await grader.grade(store, trajectory.runId)\n return graded.aggregateScore\n },\n metadata: {\n rubrics: ['grader-backed'],\n deterministic: true,\n },\n }\n}\n\n/**\n * Replay a trace corpus through a scorer — produces the canonical\n * \"what would this reward model have said about every run?\" table.\n * Callers use this to validate a trained model against the training\n * corpus (expect high agreement; drift indicates overfitting).\n */\nexport async function replayScorerOverCorpus(\n store: TraceStore,\n scorer: InferenceScorer,\n runIds: string[],\n): Promise<Array<{ runId: string; score: number; outcomeScore: number | null }>> {\n return Promise.all(\n runIds.map(async (runId) => {\n const [trajectory, run] = await Promise.all([\n buildTrajectory(store, runId),\n store.getRun(runId),\n ])\n return {\n runId,\n score: await scorer.score(trajectory, store),\n outcomeScore: run?.outcome?.score ?? null,\n }\n }),\n )\n}\n\n// Re-export for ergonomics\nexport type { PrmGradedTrace, PrmTrainingSample }\n","/**\n * Self-play scenario evolution — agents generate adversarial scenarios\n * against each other; survivors become part of the eval corpus.\n *\n * Framework-agnostic about how scenarios are generated. Caller supplies:\n * - `propose`: asks a \"proposer\" agent for candidate scenarios\n * - `scoreAgainst`: runs a target agent against a scenario and returns\n * its score\n *\n * A scenario *survives* if it reveals a meaningful score difference\n * between two target agents (or between a target agent and itself on\n * different runs). Survivors are promoted to a Dataset; the caller\n * decides what to do with them (hold-out, training, regression set).\n *\n * Guard rails: minimum absolute score delta to consider a scenario\n * informative; floor on absolute target score so degenerate break-all\n * scenarios (noise, gibberish) don't flood the corpus.\n */\n\nimport { Dataset, type DatasetScenario } from './dataset'\n\nexport interface CandidateScenario {\n id: string\n payload: unknown\n /** Free-form tags (domain, generation, parent). */\n tags?: Record<string, string>\n}\n\nexport interface ScoredTarget {\n targetId: string\n score: number\n}\n\nexport interface EvolutionRound {\n round: number\n proposed: CandidateScenario[]\n survived: CandidateScenario[]\n rejected: Array<{ candidate: CandidateScenario; reason: string }>\n scoredBreakdown: Array<{ candidate: CandidateScenario; scores: ScoredTarget[]; spread: number }>\n}\n\nexport interface SelfPlayOptions {\n /** Minimum score spread across targets for a scenario to survive. Default 0.1. */\n minSpread?: number\n /** Minimum floor score across targets — keeps degenerate break-all scenarios\n * out. Default 0.1 (if every target scores below this, discard). */\n minAbsoluteFloor?: number\n /** Hard cap on survivors per round. Default 50. */\n maxSurvivors?: number\n /** Rounds to run. Default 1. Each round's survivors can be fed back into\n * `propose` to compound. */\n rounds?: number\n /** Seed for scenario id generation if proposer doesn't provide one. */\n seed?: number\n}\n\nexport interface SelfPlayProposer {\n propose(round: number, priorSurvivors: CandidateScenario[]): Promise<CandidateScenario[]>\n}\n\nexport interface SelfPlayScorer {\n /** Score one candidate against every target; returns parallel array. */\n scoreCandidate(candidate: CandidateScenario, targets: string[]): Promise<ScoredTarget[]>\n}\n\nexport async function runSelfPlay(\n proposer: SelfPlayProposer,\n scorer: SelfPlayScorer,\n targets: string[],\n options: SelfPlayOptions = {},\n): Promise<{ rounds: EvolutionRound[]; dataset: Dataset }> {\n if (targets.length < 2)\n throw new Error('runSelfPlay: at least 2 targets required (need a difference to measure)')\n const minSpread = options.minSpread ?? 0.1\n const floor = options.minAbsoluteFloor ?? 0.1\n const maxSurvivors = options.maxSurvivors ?? 50\n const totalRounds = options.rounds ?? 1\n\n const allRounds: EvolutionRound[] = []\n let priorSurvivors: CandidateScenario[] = []\n const datasetScenarios: DatasetScenario[] = []\n\n for (let r = 0; r < totalRounds; r++) {\n const proposed = await proposer.propose(r, priorSurvivors)\n const scored: EvolutionRound['scoredBreakdown'] = []\n const rejected: EvolutionRound['rejected'] = []\n const surviving: CandidateScenario[] = []\n for (const candidate of proposed) {\n const scores = await scorer.scoreCandidate(candidate, targets)\n if (scores.length < 2) {\n rejected.push({ candidate, reason: 'scorer returned <2 results' })\n continue\n }\n const values = scores.map((s) => s.score)\n const spread = Math.max(...values) - Math.min(...values)\n const maxScore = Math.max(...values)\n scored.push({ candidate, scores, spread })\n if (maxScore < floor) {\n rejected.push({\n candidate,\n reason: `every target below floor (max=${maxScore.toFixed(3)} < ${floor})`,\n })\n continue\n }\n if (spread < minSpread) {\n rejected.push({\n candidate,\n reason: `spread below threshold (${spread.toFixed(3)} < ${minSpread})`,\n })\n continue\n }\n surviving.push(candidate)\n }\n\n // Rank by spread descending, cap at maxSurvivors\n surviving.sort((a, b) => {\n const sa = scored.find((s) => s.candidate.id === a.id)?.spread ?? 0\n const sb = scored.find((s) => s.candidate.id === b.id)?.spread ?? 0\n return sb - sa\n })\n const capped = surviving.slice(0, maxSurvivors)\n\n for (const s of capped) {\n datasetScenarios.push({\n id: s.id,\n payload: s.payload,\n split: 'test',\n tags: { ...s.tags, evolutionRound: String(r), origin: 'self-play' },\n })\n }\n\n allRounds.push({ round: r, proposed, survived: capped, rejected, scoredBreakdown: scored })\n priorSurvivors = capped\n }\n\n const dataset = new Dataset({\n name: 'self-play-survivors',\n provenance: {\n version: '1.0.0',\n createdAt: new Date().toISOString(),\n contributor: 'self-play',\n description: `Evolved across ${totalRounds} round(s), ${allRounds.reduce((a, r) => a + r.survived.length, 0)} survivors`,\n },\n scenarios: datasetScenarios,\n })\n return { rounds: allRounds, dataset }\n}\n","/**\n * CommandRunner — abstract subprocess execution surface.\n *\n * Layers in a {@link MultiLayerVerifier} that need to invoke external\n * tools (compilers, test runners, package managers) call out via this\n * interface rather than directly using `child_process`. Two reasons:\n *\n * 1. **Sandbox interchangeability.** A run that targets a sandbox box\n * (via SDK-specific Box.exec) and a run that targets the host both\n * satisfy this same contract. The harness doesn't care which.\n * 2. **Testability.** Tests inject a fake runner and assert on calls\n * without spawning real subprocesses.\n *\n * agent-eval ships only the local implementation (host-process). Sandbox\n * implementations live with their consumer because they depend on\n * SDK-specific Box / Sandbox types that don't belong in this package.\n */\n\nimport { spawnSync } from 'node:child_process'\nimport {\n accessSync,\n existsSync,\n constants as fsConstants,\n readdirSync,\n readFileSync,\n statSync,\n} from 'node:fs'\nimport { delimiter, join } from 'node:path'\n\n// ─── Types ──────────────────────────────────────────────────────────────\n\nexport interface RunCommandInput {\n /** Executable name, looked up via PATH unless absolute. */\n cmd: string\n /** Argument vector, NOT shell-interpolated. Each element passed to argv. */\n argv: string[]\n /** Working directory. Defaults to runner's notion of cwd if omitted. */\n cwd?: string\n /**\n * Wall-clock cap in ms. The runner SHOULD return `timedOut: true` when\n * exceeded; callers MAY treat status null + timedOut as \"killed.\"\n */\n capMs?: number\n /** Env overrides merged on top of the runner's base environment. */\n env?: Record<string, string>\n /** Optional stdin payload. */\n stdin?: string\n}\n\nexport interface RunCommandResult {\n /** Exit code, or null when the process couldn't start / was killed. */\n status: number | null\n stdout: string\n stderr: string\n durationMs: number\n timedOut: boolean\n /** Non-fatal runner-side error (binary missing, signal, etc.). */\n runnerError?: string\n}\n\nexport interface DirEntry {\n name: string\n isDirectory: boolean\n isFile: boolean\n /** File size in bytes. `null` for directories (not stat'd). */\n sizeBytes: number | null\n}\n\nexport interface CommandRunner {\n /** Identifier for telemetry + logs. Open-ended literal-union for new runners. */\n readonly name: string\n /** Execute a command in the runner's environment. */\n run(input: RunCommandInput): Promise<RunCommandResult>\n /** True iff `<name>` resolves on the runner's PATH. */\n hasBin(name: string): Promise<boolean>\n /** True iff the given path exists in the runner's filesystem. */\n fileExists(path: string): Promise<boolean>\n /** Read a file. Returns `null` if missing or unreadable. */\n readFile(path: string): Promise<string | null>\n /** List a directory. Returns `[]` if unreadable / missing. */\n readDir(path: string): Promise<DirEntry[]>\n}\n\n// ─── Local runner ───────────────────────────────────────────────────────\n\n/**\n * Host-process runner. Uses node:child_process spawnSync (synchronous\n * under the hood — wrapped in a Promise to satisfy the interface). For\n * very long-running commands consider an async-spawn variant; this\n * shape matches VB's existing behavior and is fine for build/test/lint\n * subprocesses that finish in seconds-to-minutes.\n */\nexport const localCommandRunner: CommandRunner = {\n name: 'local',\n async run(input: RunCommandInput): Promise<RunCommandResult> {\n const start = Date.now()\n const res = spawnSync(input.cmd, input.argv, {\n cwd: input.cwd,\n encoding: 'utf8',\n timeout: input.capMs,\n env: { ...process.env, CI: '1', ...(input.env ?? {}) },\n input: input.stdin,\n })\n const durationMs = Date.now() - start\n const timedOut = !!(\n res.error &&\n 'code' in res.error &&\n (res.error as NodeJS.ErrnoException).code === 'ETIMEDOUT'\n )\n return {\n status: res.status ?? null,\n stdout: (res.stdout ?? '').toString(),\n stderr: (res.stderr ?? '').toString(),\n durationMs,\n timedOut,\n runnerError: res.error && !timedOut ? String(res.error.message ?? res.error) : undefined,\n }\n },\n async hasBin(name: string): Promise<boolean> {\n return resolveBinOnPath(name) !== null\n },\n async fileExists(path: string): Promise<boolean> {\n return existsSync(path)\n },\n async readFile(path: string): Promise<string | null> {\n try {\n return readFileSync(path, 'utf8')\n } catch (err) {\n // ENOENT is the only \"legitimately absent\" signal → null. Any other\n // errno (EACCES, EISDIR, EIO, …) is a real failure that must NOT\n // masquerade as \"file not present\" — surface it so callers don't\n // treat a permission/IO error as a missing artifact.\n if (isErrnoCode(err, 'ENOENT')) return null\n throw err\n }\n },\n async readDir(path: string): Promise<DirEntry[]> {\n let entries: string[]\n try {\n entries = readdirSync(path)\n } catch (err) {\n // Same ENOENT-vs-real-error split as readFile: a missing directory\n // is legitimately empty (→ []); EACCES/ENOTDIR/EIO must surface so\n // an unreadable directory isn't silently reported as having no files.\n if (isErrnoCode(err, 'ENOENT')) return []\n throw err\n }\n const out: DirEntry[] = []\n for (const name of entries) {\n try {\n const st = statSync(join(path, name))\n out.push({\n name,\n isDirectory: st.isDirectory(),\n isFile: st.isFile(),\n sizeBytes: st.isFile() ? st.size : null,\n })\n } catch (err) {\n // An entry that vanished between readdir and stat (TOCTOU) is a\n // benign race → skip. Any other errno surfaces.\n if (isErrnoCode(err, 'ENOENT')) continue\n throw err\n }\n }\n return out\n },\n}\n\nfunction isErrnoCode(err: unknown, code: NodeJS.ErrnoException['code']): boolean {\n return typeof err === 'object' && err !== null && (err as NodeJS.ErrnoException).code === code\n}\n\n/**\n * Resolve `name` to an executable absolute path using the runner's PATH,\n * or `null` if not found. Cross-platform: does not depend on `which`\n * (absent on Windows) or a `command -v` shell (absent on minimal\n * containers). On Windows, candidate extensions come from PATHEXT.\n *\n * Throws only on a non-ENOENT/EACCES filesystem error while probing a\n * candidate — those indicate a real IO fault, not \"binary absent.\"\n */\nfunction resolveBinOnPath(name: string): string | null {\n // An explicit path component means PATH lookup doesn't apply: probe directly.\n if (name.includes('/') || name.includes('\\\\')) {\n return isExecutable(name) ? name : null\n }\n const pathEnv = process.env.PATH ?? ''\n const dirs = pathEnv.split(delimiter).filter((d) => d.length > 0)\n const exts =\n process.platform === 'win32'\n ? (process.env.PATHEXT ?? '.COM;.EXE;.BAT;.CMD').split(';').filter((e) => e.length > 0)\n : ['']\n for (const dir of dirs) {\n for (const ext of exts) {\n const candidate = join(dir, name + ext)\n if (isExecutable(candidate)) return candidate\n }\n }\n return null\n}\n\nfunction isExecutable(path: string): boolean {\n try {\n // On win32 X_OK is a no-op; presence of the file (with a PATHEXT\n // extension) is the executability signal there.\n accessSync(path, process.platform === 'win32' ? fsConstants.F_OK : fsConstants.X_OK)\n return true\n } catch (err) {\n // Not found / not executable / not permitted → \"not a usable binary\n // here,\" keep scanning. A different errno (EIO, ELOOP, …) is a real\n // fault and must surface rather than silently yield a false negative.\n if (isErrnoCode(err, 'ENOENT') || isErrnoCode(err, 'EACCES') || isErrnoCode(err, 'ENOTDIR')) {\n return false\n }\n throw err\n }\n}\n","/**\n * Deploy gate layer — would the agent's build actually publish?\n *\n * The product Blueprint Agent fronts promises \"go from idea to live URL.\"\n * Pre-Gen-48 the eval stopped at install/typecheck/build/serve — every\n * one of which can pass while `vite build` (or `next build`, etc) fails\n * on a production-only constraint (env-var requirement, dynamic import\n * not statically resolvable, missing public asset).\n *\n * Deploy gate runs the production build via the supplied {@link DeployRunner}\n * and asserts:\n * - command exited 0\n * - artifact dir contains an entry point (index.html for static SPAs,\n * equivalent per framework family)\n *\n * Ships with a canonical `vite` runner. Additional runners\n * (wrangler-deploy --dry-run, next-build, etc.) plug in as factories.\n */\n\nimport type { Layer, LayerResult } from './multi-layer-verifier'\n\n// ─── Types ──────────────────────────────────────────────────────────────\n\nexport type DeployFamily = 'frontend-static' | 'nextjs' | 'remix' | 'fullstack-ts'\n\nexport interface DeployRunResult {\n ok: boolean\n /** Stdout/stderr tail surfaced as evidence. Bounded in caller. */\n output?: string\n /** Wall-clock duration of the build command. */\n durationMs?: number\n /** Path to artifact directory the runner expects (dist/, .next/, build/, etc). */\n artifactDir?: string\n /** True iff artifactDir contains the family's expected entry point. */\n artifactValid?: boolean\n}\n\nexport interface DeployRunner {\n /** Run the production build. The runner owns command + cwd. */\n run(): Promise<DeployRunResult>\n}\n\nexport interface DeployGateLayerInput {\n /** Build the runner per call. */\n runner: () => DeployRunner | Promise<DeployRunner>\n /** Family hint — for logging, surfaced in diagnostics. */\n family?: DeployFamily\n /** Layer name. Default `deploy`. */\n name?: string\n /** Layer dependencies — default `['build']`. */\n dependsOn?: string[]\n /** Weight in blendedScore. Default 1. */\n weight?: number\n /** Cap (ms). Default 120s — prod builds are slower than dev. */\n capMs?: number\n /** When true, treat artifactValid=false as a fail (default true). */\n requireArtifact?: boolean\n}\n\n// ─── Layer factory ──────────────────────────────────────────────────────\n\n/**\n * Build a deploy gate layer that runs the production build and verifies\n * the artifact. Pass: ok && artifactValid. Score: 1.0 (pass) or 0 (fail).\n *\n * For families where artifact-validation isn't applicable (e.g. a\n * server-rendered build that prints a manifest), set `requireArtifact:\n * false` and rely on the runner's own ok signal.\n */\nexport function deployGateLayer<Env = unknown>(input: DeployGateLayerInput): Layer<Env> {\n const requireArtifact = input.requireArtifact ?? true\n return {\n name: input.name ?? 'deploy',\n dependsOn: input.dependsOn ?? ['build'],\n weight: input.weight ?? 1,\n capMs: input.capMs ?? 120_000,\n run: async (ctx) => {\n const start = Date.now()\n let runner: DeployRunner\n try {\n runner = await input.runner()\n } catch (err) {\n return {\n layer: input.name ?? 'deploy',\n status: 'error',\n durationMs: Date.now() - start,\n findings: [\n {\n severity: 'major',\n message: `deploy runner failed to start: ${err instanceof Error ? err.message : String(err)}`,\n },\n ],\n reason: 'runner-init-failed',\n }\n }\n let result: DeployRunResult\n try {\n result = await runner.run()\n } catch (err) {\n return {\n layer: input.name ?? 'deploy',\n status: 'error',\n durationMs: Date.now() - start,\n findings: [\n {\n severity: 'major',\n message: `deploy command threw: ${err instanceof Error ? err.message : String(err)}`,\n },\n ],\n reason: 'runner-throw',\n }\n }\n if (ctx.signal.aborted) {\n return {\n layer: input.name ?? 'deploy',\n status: 'timeout',\n durationMs: Date.now() - start,\n findings: [],\n reason: 'aborted by overall cap',\n }\n }\n\n const artifactOk = !requireArtifact || result.artifactValid === true\n const pass = result.ok && artifactOk\n const findings: LayerResult['findings'] = []\n if (!result.ok) {\n findings.push({\n severity: 'critical',\n message: 'deploy build exited non-zero',\n evidence: (result.output ?? '').slice(-1200),\n })\n }\n if (result.ok && requireArtifact && !result.artifactValid) {\n findings.push({\n severity: 'major',\n message: `deploy build succeeded but artifact ${result.artifactDir ?? '(unknown)'} is invalid or empty`,\n })\n }\n return {\n layer: input.name ?? 'deploy',\n status: pass ? 'pass' : 'fail',\n score: pass ? 1 : 0,\n durationMs: Date.now() - start,\n findings,\n reason: pass\n ? `deploy build OK${input.family ? ` (${input.family})` : ''}${result.artifactDir ? ` → ${result.artifactDir}` : ''}`\n : !result.ok\n ? 'build command failed'\n : 'artifact missing or invalid',\n diagnostics: {\n deployBuildOk: result.ok ? 1 : 0,\n deployArtifactOk: result.artifactValid === true ? 1 : 0,\n deployBuildMs: result.durationMs ?? null,\n },\n }\n },\n }\n}\n\n// ─── Canonical vite runner ──────────────────────────────────────────────\n\nexport interface ViteDeployRunnerInput {\n /** Workdir to build. The runner cd's here. */\n workdir: string\n /**\n * Function to run a shell command in `workdir`. Same shape as\n * agent-eval's CommandRunner.run for compositional reuse.\n */\n exec: (\n cmd: string,\n opts?: { cwd?: string; timeoutMs?: number },\n ) => Promise<{ stdout: string; stderr: string; exitCode: number }>\n /**\n * Function to test whether a path exists in the workdir. Inject\n * `(p) => existsSync(join(workdir, p))` for host runs.\n */\n exists: (relativePath: string) => boolean | Promise<boolean>\n /** Build command. Default `npm run build`. */\n buildCommand?: string\n /** Artifact directory to validate. Default `dist`. */\n artifactDir?: string\n /** Entry-point file under artifactDir. Default `index.html`. */\n artifactEntry?: string\n /** Per-build cap (ms). Default 90s. */\n timeoutMs?: number\n}\n\n/**\n * Canonical runner for `frontend-static` family — runs the build script,\n * validates `<artifactDir>/<artifactEntry>` exists. Use as the `runner:`\n * factory for {@link deployGateLayer}.\n */\nexport function viteDeployRunner(input: ViteDeployRunnerInput): DeployRunner {\n return {\n run: async () => {\n const start = Date.now()\n const cmd = input.buildCommand ?? 'npm run build'\n const artifactDir = input.artifactDir ?? 'dist'\n const artifactEntry = input.artifactEntry ?? 'index.html'\n const timeoutMs = input.timeoutMs ?? 90_000\n const result = await input.exec(cmd, { cwd: input.workdir, timeoutMs })\n const ok = result.exitCode === 0\n let artifactValid = false\n try {\n const entryExists = await input.exists(`${artifactDir}/${artifactEntry}`)\n artifactValid = ok && Boolean(entryExists)\n } catch {\n artifactValid = false\n }\n const tail = ((result.stderr || result.stdout) ?? '').slice(-1500)\n return {\n ok,\n output: tail,\n durationMs: Date.now() - start,\n artifactDir,\n artifactValid,\n }\n },\n }\n}\n\n// ─── Canonical wrangler runner ──────────────────────────────────────────\n\nexport interface WranglerDeployRunnerInput {\n workdir: string\n exec: (\n cmd: string,\n opts?: { cwd?: string; timeoutMs?: number },\n ) => Promise<{ stdout: string; stderr: string; exitCode: number }>\n exists: (relativePath: string) => boolean | Promise<boolean>\n /** Build command. Default `npm run build`. */\n buildCommand?: string\n /** Wrangler dry-run command. Default `npx wrangler deploy --dry-run --outdir dist`. */\n dryRunCommand?: string\n /** Per-step cap (ms). Default 120s. */\n timeoutMs?: number\n}\n\n/**\n * Canonical runner for the `fullstack-ts` family on Cloudflare Workers\n * (Remix / React Router v7 / Hono on Workers). Detects wrangler.toml or\n * wrangler.jsonc in the workdir, builds, then `wrangler deploy --dry-run`\n * to catch missing bindings, syntax errors in wrangler config, and\n * import-time crashes that don't surface in `tsc`.\n *\n * No wrangler config = skip with \"no wrangler\" evidence (not a failure\n * — the gate caller decides whether to require deploy validation).\n */\nexport function wranglerDeployRunner(input: WranglerDeployRunnerInput): DeployRunner {\n return {\n run: async () => {\n const start = Date.now()\n const buildCmd = input.buildCommand ?? 'npm run build'\n const dryCmd = input.dryRunCommand ?? 'npx wrangler deploy --dry-run --outdir dist'\n const timeoutMs = input.timeoutMs ?? 120_000\n\n const hasToml = await input.exists('wrangler.toml')\n const hasJsonc = hasToml ? false : await input.exists('wrangler.jsonc')\n if (!hasToml && !hasJsonc) {\n return {\n ok: false,\n output: 'no wrangler config found (wrangler.toml / wrangler.jsonc absent)',\n durationMs: Date.now() - start,\n artifactDir: 'dist',\n artifactValid: false,\n }\n }\n\n const build = await input.exec(buildCmd, { cwd: input.workdir, timeoutMs })\n if (build.exitCode !== 0) {\n const tail = ((build.stderr || build.stdout) ?? '').slice(-1500)\n return {\n ok: false,\n output: `build failed: ${tail}`,\n durationMs: Date.now() - start,\n artifactDir: 'dist',\n artifactValid: false,\n }\n }\n\n const dry = await input.exec(dryCmd, { cwd: input.workdir, timeoutMs })\n if (dry.exitCode !== 0) {\n const tail = ((dry.stderr || dry.stdout) ?? '').slice(-1500)\n return {\n ok: false,\n output: `wrangler dry-run failed: ${tail}`,\n durationMs: Date.now() - start,\n artifactDir: 'dist',\n artifactValid: false,\n }\n }\n\n const tail = ((dry.stdout || dry.stderr) ?? '').slice(-1500)\n return {\n ok: true,\n output: tail,\n durationMs: Date.now() - start,\n artifactDir: 'dist',\n artifactValid: true,\n }\n },\n }\n}\n","/**\n * Toolchain error-count extractor.\n *\n * Given stderr/stdout from a compiler or test runner, count the number\n * of reported errors/failures. Patterns are deliberately narrow —\n * unknown stderr returns `null` rather than zero so callers can\n * distinguish \"no errors\" from \"different toolchain, couldn't parse\".\n *\n * All patterns are anchored to the start of a line and use bounded\n * character classes to avoid catastrophic backtracking on pathological\n * inputs.\n *\n * Add new toolchains by appending to {@link ERROR_COUNT_PATTERNS};\n * order matters only in the sense that the first matching pattern wins.\n */\n\nexport interface ErrorCountPattern {\n /** Stable identifier for logging + tests. */\n name: string\n /** Must be global (`g` flag) — the extractor counts matches. */\n regex: RegExp\n /** Optional post-processing to extract a count from a single captured match. */\n transform?: (match: RegExpMatchArray) => number\n}\n\nexport const ERROR_COUNT_PATTERNS: ErrorCountPattern[] = [\n {\n // tsc / ts-node: `src/foo.ts(12,3): error TS1234: ...`\n name: 'typescript-tsc',\n regex: /[\\w./-]+\\(\\d+,\\d+\\): error TS\\d+:/g,\n },\n {\n // pytest: `FAILED tests/test_foo.py::test_bar`\n name: 'pytest-failed',\n regex: /^FAILED\\s+\\S+/gm,\n },\n {\n // rustc: `error[E0308]: ...` or `error: ...`\n name: 'rustc',\n regex: /^error(?:\\[[A-Z]\\d+\\])?:/gm,\n },\n {\n // go build: `./foo.go:12:3: ...` — any file:line:col: is an error line\n name: 'golang',\n regex: /^\\.\\/[\\w./-]+\\.go:\\d+:\\d+:/gm,\n },\n {\n // eslint default formatter per-line: ` 12:34 error message rule-id`\n name: 'eslint',\n regex: /^\\s+\\d+:\\d+\\s+error\\s+/gm,\n },\n {\n // eslint summary line: `✖ 17 problems (12 errors, 5 warnings)`\n // Use this only when the per-line formatter isn't present; transform\n // reads the errors count directly.\n name: 'eslint-summary',\n regex: /✖\\s+\\d+\\s+problems?\\s+\\((\\d+)\\s+errors?/gm,\n transform: (m) => Number(m[1] ?? 0),\n },\n]\n\nexport interface ExtractOptions {\n /** Restrict to named patterns — default: all patterns. */\n only?: string[]\n /** Additional patterns to consider BEFORE the built-in list. */\n extra?: ErrorCountPattern[]\n}\n\nexport interface ExtractResult {\n /** Total count of matched errors, or null when no pattern matched. */\n count: number | null\n /** Name of the pattern that matched, or null. */\n matched: string | null\n /** Original matches for callers that want to surface specifics. */\n samples: string[]\n}\n\n/**\n * Try each pattern in order; return the first with matches.\n *\n * Returning `null` (instead of zero) on no-match is deliberate — a\n * callsite that greps for \"typescript errors\" on cargo output should\n * NOT treat that as \"zero TS errors\" because the toolchain is wrong.\n */\nexport function extractErrorCount(text: string, opts: ExtractOptions = {}): ExtractResult {\n if (!text) return { count: null, matched: null, samples: [] }\n\n const patterns = [...(opts.extra ?? []), ...ERROR_COUNT_PATTERNS].filter(\n (p) => !opts.only || opts.only.includes(p.name),\n )\n\n for (const p of patterns) {\n const matches = Array.from(text.matchAll(p.regex))\n if (matches.length === 0) continue\n\n const count = p.transform\n ? matches.reduce((sum, m) => sum + p.transform!(m), 0)\n : matches.length\n\n return {\n count,\n matched: p.name,\n samples: matches.slice(0, 5).map((m) => m[0]),\n }\n }\n\n return { count: null, matched: null, samples: [] }\n}\n","/**\n * Flow layer — drive a previewed app through a scripted user walk.\n *\n * The MultiLayerVerifier already had a `flow` slot wired in\n * VerticalBench's verification-harness, but the layer module was\n * always-skipped (\"flow layer module not yet wired\"). This adds the\n * module: a Layer<Env> that takes a {@link FlowSpec} (URL + steps),\n * boots a preview server via the supplied {@link FlowRunner}, executes\n * each step, and returns a LayerResult whose `findings` enumerate\n * which step failed.\n *\n * The runner is injected so this module can swap between:\n * - production: agent-browser CLI (a11y-tree based steps)\n * - test: in-memory mock that returns canned step outcomes\n * - future: Playwright, Puppeteer, custom scrapers\n *\n * Paired with {@link runIntentMatchJudge}: intent-match catches \"wrong\n * app entirely\"; flow-layer catches \"right app but the buttons don't work.\"\n */\n\nimport type { Layer, LayerResult, Severity } from './multi-layer-verifier'\n\n// ─── Types ──────────────────────────────────────────────────────────────\n\nexport type FlowAction =\n | 'navigate'\n | 'click'\n | 'fill'\n | 'expect-text'\n | 'expect-element'\n | 'expect-url'\n | 'wait'\n\nexport interface FlowStep {\n /** What this step does. */\n action: FlowAction\n /** Human-readable description for findings. */\n describe?: string\n /**\n * For navigate/expect-url: full URL. For click/fill/expect-element:\n * accessible-name selector or CSS selector.\n * For expect-text: substring expected on the page.\n * For wait: ignored (use `value` for ms).\n */\n target?: string\n /** For fill: text to enter. For wait: ms. */\n value?: string\n /** Severity of a failure. Default `major`. */\n severity?: Severity\n}\n\nexport interface FlowSpec {\n /** Initial URL the runner should open. */\n url: string\n /** Ordered steps. Stops at the first failure unless `continueOnFail: true`. */\n steps: FlowStep[]\n /** When true, execute every step even after a failure (collect all findings). */\n continueOnFail?: boolean\n /** Per-step wall cap (ms). Default 15s. */\n stepTimeoutMs?: number\n}\n\nexport interface FlowRunnerStepResult {\n ok: boolean\n /** Concrete observation: matched text snippet, captured URL, error message. */\n evidence?: string\n /** Wall-clock duration of the step. */\n durationMs?: number\n}\n\nexport interface FlowRunner {\n /** Open the target URL. Returns when the page is interactable. */\n open(url: string): Promise<FlowRunnerStepResult>\n /** Execute one step. The runner owns interpretation of `target`. */\n step(step: FlowStep): Promise<FlowRunnerStepResult>\n /** Tear down browser, free resources. Always called once per layer.run. */\n close(): Promise<void>\n}\n\nexport interface FlowLayerEnv {\n /** Optional override per-call. Defaults supplied by the layer factory. */\n flowSpec?: FlowSpec\n}\n\nexport interface FlowLayerFactoryInput {\n /** Static spec (used when env doesn't supply one). */\n flowSpec?: FlowSpec\n /** Build the runner per call (lets the layer create + tear down per leaf). */\n runner: () => FlowRunner | Promise<FlowRunner>\n /** Layer name. Default `flow`. */\n name?: string\n /** Layer dependencies — default `['serve']` so a non-booting preview skips us. */\n dependsOn?: string[]\n /** Layer weight for blendedScore (0..1+). Default 1. */\n weight?: number\n /** Cap for the entire flow run (ms). Default 60s. */\n capMs?: number\n}\n\n// ─── Layer factory ──────────────────────────────────────────────────────\n\n/**\n * Build a flow layer that scripts a user walk via the supplied runner.\n *\n * Score: 1.0 when every step passed; otherwise 1 - (failedSteps / totalSteps).\n * Status: `pass` iff every step passed; `fail` if any step failed; `error`\n * on runner setup error; `skipped` when no flowSpec is available.\n */\nexport function flowLayer<Env extends FlowLayerEnv = FlowLayerEnv>(\n input: FlowLayerFactoryInput,\n): Layer<Env> {\n return {\n name: input.name ?? 'flow',\n dependsOn: input.dependsOn ?? ['serve'],\n weight: input.weight ?? 1,\n capMs: input.capMs ?? 60_000,\n run: async (ctx) => {\n const start = Date.now()\n const spec = ctx.env?.flowSpec ?? input.flowSpec\n if (!spec) {\n return {\n layer: input.name ?? 'flow',\n status: 'skipped',\n durationMs: 0,\n findings: [],\n reason: 'no flowSpec supplied',\n }\n }\n\n let runner: FlowRunner\n try {\n runner = await input.runner()\n } catch (err) {\n return {\n layer: input.name ?? 'flow',\n status: 'error',\n durationMs: Date.now() - start,\n findings: [\n {\n severity: 'major',\n message: `flow runner failed to start: ${err instanceof Error ? err.message : String(err)}`,\n },\n ],\n reason: 'runner-init-failed',\n }\n }\n\n const findings: LayerResult['findings'] = []\n const stepResults: Array<{ step: FlowStep; result: FlowRunnerStepResult; index: number }> = []\n let openOk = false\n try {\n const opened = await runner.open(spec.url)\n openOk = opened.ok\n if (!opened.ok) {\n findings.push({\n severity: 'major',\n message: `flow.open(${spec.url}) failed${opened.evidence ? `: ${opened.evidence}` : ''}`,\n })\n }\n if (openOk || spec.continueOnFail) {\n for (let i = 0; i < spec.steps.length; i++) {\n const step = spec.steps[i]!\n if (ctx.signal.aborted) break\n const stepStart = Date.now()\n let result: FlowRunnerStepResult\n try {\n result = await runner.step(step)\n } catch (err) {\n result = {\n ok: false,\n evidence: err instanceof Error ? err.message : String(err),\n durationMs: Date.now() - stepStart,\n }\n }\n stepResults.push({ step, result, index: i })\n if (!result.ok) {\n findings.push({\n severity: step.severity ?? 'major',\n message: `step[${i}] ${step.action}${step.target ? `(${step.target})` : ''} failed${result.evidence ? `: ${result.evidence}` : ''}`,\n })\n if (!spec.continueOnFail) break\n }\n }\n }\n } finally {\n try {\n await runner.close()\n } catch {\n /* best effort */\n }\n }\n\n const totalSteps = spec.steps.length\n const ranSteps = stepResults.length\n const passedSteps = stepResults.filter((s) => s.result.ok).length\n const status: LayerResult['status'] = !openOk\n ? 'fail'\n : passedSteps === totalSteps\n ? 'pass'\n : 'fail'\n // Score: open + each passing step contribute equally. A flow with\n // 4 steps where 3 pass scores 4/5 = 0.8 (0.2 from the open + 3*0.2\n // from the steps when totalSteps=4). We weight open and steps\n // equally to avoid any single step dominating short specs.\n const denominator = 1 + totalSteps\n const numerator = (openOk ? 1 : 0) + passedSteps\n const score = denominator > 0 ? Number((numerator / denominator).toFixed(3)) : 0\n\n return {\n layer: input.name ?? 'flow',\n status,\n score,\n durationMs: Date.now() - start,\n findings,\n reason:\n status === 'pass'\n ? `${totalSteps}/${totalSteps} steps passed`\n : `${passedSteps}/${totalSteps} steps passed${ranSteps < totalSteps ? ` (stopped at step ${ranSteps})` : ''}`,\n diagnostics: {\n flowOpenOk: openOk ? 1 : 0,\n flowStepsTotal: totalSteps,\n flowStepsPassed: passedSteps,\n flowStepsRan: ranSteps,\n },\n }\n },\n }\n}\n","/**\n * Intent-match judge — \"did the agent build the right APP, ignoring\n * whether every feature is wired up?\"\n *\n * Distinct from {@link runSemanticConceptJudge} which scores per-concept\n * presence. The semantic judge can return 0/4 concepts present even\n * when the agent built a thoughtful, polished, on-brief app that just\n * lacks one or two features. The semantic judge can also return 4/4\n * present even when the agent shipped the wrong project (keyword-rich\n * stub).\n *\n * Intent-match asks ONE question:\n * \"Looking at the agent's work as a whole — independent of feature\n * coverage — is this an honest attempt at the user's request?\"\n *\n * Returns a 0–1 score and a 1-sentence evidence string. Use as a sanity\n * check on `completenessScore`-style metrics: if intent-match is high\n * and concept count is low, the agent built the right thing but is\n * missing features (ship and iterate). If intent-match is low, the\n * agent built the wrong thing (reject regardless of concept count).\n *\n * Soft-fails on LLM/JSON error (`available: false`) so callers can\n * treat failure as \"judge skipped.\"\n */\n\nimport { CostLedger, type CostLedgerHandle, type CostReceipt } from './cost-ledger'\nimport {\n callLlmJson,\n costReceiptFromLlm,\n costReceiptFromLlmError,\n type LlmCallRequest,\n type LlmClientOptions,\n maximumChargeForLlmRequest,\n} from './llm-client'\n\nexport const INTENT_MATCH_JUDGE_VERSION = 'intent-match-judge-v1-2026-04-24'\n\nexport interface IntentMatchInput {\n /** The full natural-language prompt the agent was handed. */\n userRequest: string\n /** Top-level source files from the agent's workdir. */\n sourceFiles: Array<{ path: string; content: string }>\n /** Rendered HTML the preview returned, when available. */\n servedHtml?: string\n /** Optional metadata to inject (id, vertical, difficulty). */\n artifactLabel?: string\n artifactDescription?: string\n}\n\nexport interface IntentMatchResult {\n kind: 'intent-match'\n version: string\n /** 0..1 — 1 = unmistakably the right app, 0 = unrelated to the brief. */\n score: number\n /** One-sentence rationale citing concrete evidence (file or HTML). */\n evidence: string\n durationMs: number\n costUsd: number | null\n available: boolean\n error?: string\n}\n\nexport interface IntentMatchOptions {\n model?: string\n timeoutMs?: number\n maxTokens?: number\n maxSourceChars?: number\n maxPerFileChars?: number\n maxHtmlChars?: number\n llm?: LlmClientOptions\n costLedger?: CostLedgerHandle\n costPhase?: string\n costTags?: Record<string, string>\n signal?: AbortSignal\n}\n\nconst DEFAULT_MODEL = 'claude-sonnet-4-6'\nconst DEFAULT_TIMEOUT = 300_000\nconst DEFAULT_MAX_TOKENS = 800\nconst DEFAULT_MAX_SOURCE = 25_000\nconst DEFAULT_MAX_PER_FILE = 12_000\nconst DEFAULT_MAX_HTML = 20_000\n\nconst INTENT_SCHEMA = {\n type: 'object',\n additionalProperties: false,\n required: ['score', 'evidence'],\n properties: {\n score: { type: 'number', minimum: 0, maximum: 1 },\n evidence: { type: 'string', minLength: 10, maxLength: 400 },\n },\n}\n\nfunction truncate(body: string, cap: number, label: string): string {\n if (body.length <= cap) return body\n return `${body.slice(0, cap)}\\n… [truncated ${body.length - cap} chars of ${label}]`\n}\n\nfunction buildPrompt(input: IntentMatchInput, opts: Required<IntentMatchOptions>): string {\n const sourceBlob = input.sourceFiles\n .filter((f) => f.content.length <= opts.maxPerFileChars)\n .map((f) => `--- FILE: ${f.path} ---\\n${f.content}`)\n .join('\\n\\n')\n const html = input.servedHtml ?? ''\n\n return `You are evaluating whether an agent built THE RIGHT APP for a user request.\n\nYou are NOT scoring feature coverage. You are NOT scoring code quality.\nYou are answering ONE question: when a person looks at this work, do they\nsee an honest attempt at the user's request — or do they see the wrong\nproject entirely?\n\nUSER REQUEST:\n${input.userRequest}\n\n${input.artifactLabel ? `ARTIFACT METADATA:\\n name: ${input.artifactLabel}\\n description: ${input.artifactDescription ?? ''}\\n\\n` : ''}${html ? `SERVED HTML (what the preview returns):\\n${truncate(html, opts.maxHtmlChars, 'HTML')}\\n\\n` : ''}SOURCE FILES (the agent's workdir):\n${truncate(sourceBlob, opts.maxSourceChars, 'source')}\n\nScore 0–1:\n 1.0 — unmistakably the right app. Even with bugs, gaps, or missing\n features, a reviewer would say \"yes, this is what was asked for.\"\n 0.7 — recognizable. Domain matches; some required surface areas exist.\n A reviewer would say \"right direction, lots of work needed.\"\n 0.4 — partially related. Wrong framing or wrong product entirely but\n with some shared keywords or a tangential overlap.\n 0.0 — wrong project. The agent shipped something unrelated to the\n request (e.g. asked for an NFT mint page, shipped a generic\n landing page with zero NFT-related code).\n\nEvidence: one sentence citing the strongest concrete signal — a file\nname, a route, a rendered headline, a missing core surface. Don't\nrestate the request.\n\nExamples:\n - \"src/App.tsx renders <MintWidget /> with mint-1/mint-5 buttons and\n wagmi imports — clearly the requested NFT mint page.\" → 0.95\n - \"src/App.tsx is the default Vite React template; no\n mint/wallet/contract code in any file under src/.\" → 0.05\n\nReturn STRICT JSON. No prose outside.`\n}\n\n/**\n * Run the intent-match judge. Soft-fails to available=false on error.\n */\nexport async function runIntentMatchJudge(\n input: IntentMatchInput,\n options: IntentMatchOptions = {},\n): Promise<IntentMatchResult> {\n const start = Date.now()\n const opts: Required<IntentMatchOptions> = {\n model: options.model ?? DEFAULT_MODEL,\n timeoutMs: options.timeoutMs ?? DEFAULT_TIMEOUT,\n maxTokens: options.maxTokens ?? DEFAULT_MAX_TOKENS,\n maxSourceChars: options.maxSourceChars ?? DEFAULT_MAX_SOURCE,\n maxPerFileChars: options.maxPerFileChars ?? DEFAULT_MAX_PER_FILE,\n maxHtmlChars: options.maxHtmlChars ?? DEFAULT_MAX_HTML,\n llm: options.llm ?? {},\n costLedger: options.costLedger ?? new CostLedger(),\n costPhase: options.costPhase ?? 'judge.intent-match',\n costTags: options.costTags ?? {},\n signal: options.signal ?? new AbortController().signal,\n }\n\n if (input.sourceFiles.length === 0 && !input.servedHtml) {\n return {\n kind: 'intent-match',\n version: INTENT_MATCH_JUDGE_VERSION,\n score: 0,\n evidence: 'no source files and no served HTML — nothing to evaluate',\n durationMs: 0,\n costUsd: null,\n available: false,\n error: 'no input artifact',\n }\n }\n\n let receipt: CostReceipt | undefined\n try {\n const request = {\n model: opts.model,\n messages: [\n {\n role: 'system' as const,\n content:\n 'You are a holistic code reviewer answering one question: did the agent build the right app for the user. Return strict JSON. No prose outside.',\n },\n { role: 'user' as const, content: buildPrompt(input, opts) },\n ],\n jsonSchema: { name: 'intent_match_judge', schema: INTENT_SCHEMA },\n temperature: 0,\n maxTokens: opts.maxTokens,\n timeoutMs: opts.timeoutMs,\n } satisfies LlmCallRequest\n const paid = await opts.costLedger.runPaidCall({\n channel: 'judge',\n phase: opts.costPhase,\n actor: 'intent-match',\n model: opts.model,\n ...(Object.keys(opts.costTags).length > 0 ? { tags: opts.costTags } : {}),\n maximumCharge: maximumChargeForLlmRequest(request, opts.llm),\n signal: opts.signal,\n execute: (signal, callId) =>\n callLlmJson<{ score: number; evidence: string }>(request, {\n ...opts.llm,\n signal,\n idempotencyKey: callId,\n }),\n receipt: ({ result }) => costReceiptFromLlm(result),\n receiptFromError: costReceiptFromLlmError,\n })\n receipt = paid.receipt\n if (!paid.succeeded) throw paid.error\n const { value } = paid.value\n\n const score = Math.max(0, Math.min(1, Number(value?.score ?? 0)))\n return {\n kind: 'intent-match',\n version: INTENT_MATCH_JUDGE_VERSION,\n score: Number(score.toFixed(3)),\n evidence: String(value?.evidence ?? '').slice(0, 400),\n durationMs: Date.now() - start,\n costUsd: paid.receipt.costUnknown ? null : paid.receipt.costUsd,\n available: true,\n }\n } catch (err) {\n return {\n kind: 'intent-match',\n version: INTENT_MATCH_JUDGE_VERSION,\n score: 0,\n evidence: '',\n durationMs: Date.now() - start,\n costUsd: receipt && !receipt.costUnknown ? receipt.costUsd : null,\n available: false,\n error: err instanceof Error ? err.message : String(err),\n }\n }\n}\n\n/**\n * Factory: pin LLM options once, return a closure.\n */\nexport function createIntentMatchJudge(\n options: IntentMatchOptions = {},\n): (input: IntentMatchInput) => Promise<IntentMatchResult> {\n return (input) => runIntentMatchJudge(input, options)\n}\n","/**\n * Keyword-coverage judge — baseline complement to the semantic concept\n * judge.\n *\n * Where {@link runSemanticConceptJudge} uses an LLM to read source code\n * and decide whether a concept is REALLY implemented (not just\n * keyword-mentioned), this judge does the cheap, deterministic version:\n * fetch the served preview, concatenate every linked CSS/JS asset, and\n * substring-match each expected concept's keywords against the\n * concatenated haystack. Optional `requiredElement` selector adds a\n * structural gate so \"supply counter\" can require an actual `<input>` or\n * `<table>`, not just a comment containing the word.\n *\n * Use both judges. Keyword coverage is a fast 0-cost gate — a stub page\n * with the right keywords passes here, fails the semantic judge. Score\n * divergence between the two is itself a signal: high keyword coverage\n * + low semantic = \"the agent slapped the right words on the right\n * scaffold but didn't wire any of it up.\"\n *\n * Pure functions, soft-fail on fetch error, no LLM dependency.\n */\n\n// ─── Types ──────────────────────────────────────────────────────────────\n\nexport interface KeywordConceptSpec {\n name: string\n keywords: string[]\n /**\n * Optional CSS selector that must match in the HTML for the concept\n * to count as present. Tiny subset:\n * - `tag` (e.g. `form`)\n * - `tag[attr=\"value\"]` (e.g. `input[type=\"number\"]`)\n * - `tag[attr]` (presence only)\n * Anything more complex is rejected with `null` (treated as\n * \"unenforced\", not \"failed\").\n */\n requiredElement?: string\n}\n\nexport interface KeywordCoverageFinding {\n concept: string\n found: boolean\n matchedKeywords: string[]\n /** True iff the optional requiredElement selector matched; null when no selector. */\n requiredElementPresent: boolean | null\n}\n\nexport interface KeywordCoverageResult {\n /** 0..1 share of concepts satisfied. */\n score: number\n presentCount: number\n totalCount: number\n findings: KeywordCoverageFinding[]\n durationMs: number\n /** Total bytes assembled across html + linked assets. */\n totalAssembledBytes: number\n /** Soft-failure reason if the audit couldn't run. */\n error?: string\n}\n\nexport interface KeywordCoverageOptions {\n /** Override fetch implementation — for tests. */\n fetch?: typeof fetch\n /** Per-asset fetch timeout (default 3s). */\n assetTimeoutMs?: number\n /** Initial-HTML fetch timeout (default 5s). */\n htmlTimeoutMs?: number\n}\n\n// ─── Selector matcher ──────────────────────────────────────────────────\n\n/**\n * Element-presence check using a tiny CSS-selector subset. Returns\n * null when the selector isn't supported — caller treats that as\n * \"unenforced\" rather than \"failed.\"\n */\nexport function htmlContainsElement(html: string, selector: string): boolean | null {\n const tagOnly = /^([a-zA-Z][\\w-]*)$/.exec(selector)\n if (tagOnly) {\n const re = new RegExp(`<${tagOnly[1]}\\\\b`, 'i')\n return re.test(html)\n }\n const tagAttrEq = /^([a-zA-Z][\\w-]*)\\[([\\w-]+)\\s*=\\s*[\"']?([^\"'\\]]+)[\"']?\\]$/.exec(selector)\n if (tagAttrEq) {\n const [, tag, attr, value] = tagAttrEq\n const re = new RegExp(\n `<${tag}\\\\b[^>]*\\\\b${attr}\\\\s*=\\\\s*[\"']${value!.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')}[\"']`,\n 'i',\n )\n return re.test(html)\n }\n const tagAttrPresence = /^([a-zA-Z][\\w-]*)\\[([\\w-]+)\\]$/.exec(selector)\n if (tagAttrPresence) {\n const [, tag, attr] = tagAttrPresence\n const re = new RegExp(`<${tag}\\\\b[^>]*\\\\b${attr}\\\\b`, 'i')\n return re.test(html)\n }\n return null\n}\n\n// ─── Asset extraction ─────────────────────────────────────────────────\n\n/**\n * Pull every `<link rel=stylesheet href>` and `<script src>` from a\n * raw HTML body. Returns absolute URLs resolved against `baseUrl`.\n * Permissive regex — agent-authored markup doesn't always quote\n * attributes the same way.\n */\nexport function extractAssetUrls(html: string, baseUrl: string): string[] {\n const urls = new Set<string>()\n const linkRe = /<link\\b[^>]*\\bhref\\s*=\\s*[\"']([^\"']+)[\"'][^>]*>/gi\n const scriptRe = /<script\\b[^>]*\\bsrc\\s*=\\s*[\"']([^\"']+)[\"'][^>]*>/gi\n for (const re of [linkRe, scriptRe]) {\n let match: RegExpExecArray | null = re.exec(html)\n while (match !== null) {\n const raw = match[1]!\n try {\n urls.add(new URL(raw, baseUrl).toString())\n } catch {\n // unresolvable refs (e.g. data: URLs) — skip\n }\n match = re.exec(html)\n }\n }\n return Array.from(urls)\n}\n\n// ─── Coverage scorer ──────────────────────────────────────────────────\n\n/**\n * Score expected concepts against an already-fetched HTML payload + any\n * pre-fetched CSS/JS assets. Use when the runner has the bytes in hand\n * and doesn't want a fresh HTTP round-trip — e.g. sandbox runtime where\n * the preview content was fetched via curl from inside the container.\n */\nexport function runKeywordCoverageJudge(\n html: string,\n expectedConcepts: ReadonlyArray<KeywordConceptSpec>,\n assets: ReadonlyArray<string> = [],\n): KeywordCoverageResult {\n const start = Date.now()\n if (expectedConcepts.length === 0) {\n return {\n score: 0,\n presentCount: 0,\n totalCount: 0,\n findings: [],\n durationMs: 0,\n totalAssembledBytes: 0,\n }\n }\n const haystack = `${html}\\n${assets.join('\\n')}`.toLowerCase()\n const findings: KeywordCoverageFinding[] = expectedConcepts.map((concept) => {\n const matchedKeywords: string[] = []\n for (const kw of concept.keywords) {\n if (haystack.includes(kw.toLowerCase())) matchedKeywords.push(kw)\n }\n const requiredElementPresent = concept.requiredElement\n ? htmlContainsElement(html, concept.requiredElement)\n : null\n const passesElementGate = requiredElementPresent === null || requiredElementPresent === true\n const found = matchedKeywords.length > 0 && passesElementGate\n return { concept: concept.name, found, matchedKeywords, requiredElementPresent }\n })\n const presentCount = findings.filter((f) => f.found).length\n return {\n score: presentCount / expectedConcepts.length,\n presentCount,\n totalCount: expectedConcepts.length,\n findings,\n durationMs: Date.now() - start,\n totalAssembledBytes: haystack.length,\n }\n}\n\n/**\n * URL-fetch flavor — GET the preview, parallel-fetch every linked\n * stylesheet + script (with bounded timeouts, soft-fail individually),\n * then score via {@link runKeywordCoverageJudge}.\n */\nexport async function runKeywordCoverageJudgeUrl(\n previewUrl: string,\n expectedConcepts: ReadonlyArray<KeywordConceptSpec>,\n options: KeywordCoverageOptions = {},\n): Promise<KeywordCoverageResult> {\n const start = Date.now()\n const fetchFn = options.fetch ?? globalThis.fetch\n const htmlTimeout = options.htmlTimeoutMs ?? 5_000\n const assetTimeout = options.assetTimeoutMs ?? 3_000\n\n if (expectedConcepts.length === 0) {\n return {\n score: 0,\n presentCount: 0,\n totalCount: 0,\n findings: [],\n durationMs: 0,\n totalAssembledBytes: 0,\n }\n }\n\n let html = ''\n try {\n const resp = await fetchFn(previewUrl, {\n redirect: 'follow',\n signal: AbortSignal.timeout(htmlTimeout),\n })\n if (!resp.ok) {\n return softFail(expectedConcepts, start, `preview HTTP ${resp.status}`)\n }\n html = await resp.text()\n } catch (err) {\n return softFail(expectedConcepts, start, err instanceof Error ? err.message : String(err))\n }\n\n const assetUrls = extractAssetUrls(html, previewUrl)\n const assetBodies = await Promise.all(\n assetUrls.map(async (u) => {\n try {\n const r = await fetchFn(u, {\n redirect: 'follow',\n signal: AbortSignal.timeout(assetTimeout),\n })\n if (!r.ok) return ''\n return await r.text()\n } catch {\n return ''\n }\n }),\n )\n\n return runKeywordCoverageJudge(html, expectedConcepts, assetBodies)\n}\n\nfunction softFail(\n expectedConcepts: ReadonlyArray<KeywordConceptSpec>,\n start: number,\n error: string,\n): KeywordCoverageResult {\n return {\n score: 0,\n presentCount: 0,\n totalCount: expectedConcepts.length,\n findings: expectedConcepts.map((c) => ({\n concept: c.name,\n found: false,\n matchedKeywords: [],\n requiredElementPresent: null,\n })),\n durationMs: Date.now() - start,\n totalAssembledBytes: 0,\n error,\n }\n}\n","/**\n * Multi-layer verifier — ordered pipeline of verification layers.\n *\n * Different contract from {@link JudgeRunner} (which runs parallel\n * specs against a sandbox). MultiLayerVerifier is a DAG of layers\n * (install → typecheck → build → lint → serve → semantic → …) with\n * dependency-based skip, per-layer findings, soft-fail semantics, and\n * an aggregated `blendedScore` across all passed layers.\n *\n * Use when you want:\n * - ordered stages where a failing upstream stage skips downstream ones\n * - each stage produces rich `findings` (severity + message + evidence)\n * - a single composite score across stages with per-stage weights\n * - soft-fail stages whose failure doesn't abort the pipeline\n *\n * Use {@link JudgeRunner} when you want:\n * - N independent judges running in parallel against the same artifact\n * - no inter-judge dependencies\n * - boolean `passed` per judge + overall\n *\n * Both primitives compose — JudgeRunner can be invoked as a single\n * layer inside a MultiLayerVerifier if that suits the caller.\n */\n\nimport type { DefaultVerdict } from './verdict'\n\n// ─── Types ──────────────────────────────────────────────────────────────\n\nexport type LayerStatus = 'pass' | 'fail' | 'skipped' | 'error' | 'timeout'\n\nexport type Severity = 'critical' | 'major' | 'minor' | 'info'\n\nexport interface Finding {\n severity: Severity\n message: string\n evidence?: string\n /** Optional layer name the finding belongs to (set by the verifier if omitted). */\n layer?: string\n /**\n * Free-form structured payload — used by `multiToolchainLayer` to attach\n * `{ adapter: 'pnpm' }`, by judges to attach evidence pointers, etc.\n * Renderers MAY interrogate; agent-eval primitives never assume shape.\n */\n detail?: Record<string, unknown>\n}\n\nexport interface LayerResult {\n layer: string\n status: LayerStatus\n /** Origin of an `error` or `timeout`. Defaults to `execution`. */\n errorSource?: 'execution' | 'judge'\n /** 0..1 score, optional — layers that don't produce a numeric score omit. */\n score?: number\n durationMs: number\n findings: Finding[]\n /** Short human-readable summary (one line). */\n reason?: string\n /**\n * Numeric layer-level diagnostics: error counts, warning counts,\n * cyclomatic complexity, total adapter wall-time, etc. Keyed by\n * diagnostic name; null = \"diagnostic not applicable / not measured.\"\n * Renderers that know the keys can display them; ones that don't,\n * ignore. Free-form on purpose — consumers type the value shape in\n * their own namespace.\n */\n diagnostics?: Record<string, number | null>\n /** Any rich per-layer detail — rendered as-is by consumers that know the layer. */\n detail?: Record<string, unknown>\n}\n\nexport interface VerifyContext<Env = unknown> {\n /** Per-run opaque context the caller provides. Layers destructure what they need. */\n env: Env\n /** Previously-computed results from layers that already ran. */\n prior: Record<string, LayerResult>\n /** Signal — if aborted, layers MUST bail within reasonable wall. */\n signal: AbortSignal\n}\n\nexport interface Layer<Env = unknown> {\n name: string\n /** Origin assigned when this layer errors or times out. Defaults to `execution`. */\n errorSource?: 'execution' | 'judge'\n /** Stages that must have `status: 'pass'` before this layer runs. */\n dependsOn?: string[]\n /**\n * Weight in the composite `blendedScore`. Default 1.0. Layers with weight 0\n * contribute findings but not score.\n */\n weight?: number\n /**\n * If true, a `fail` status contributes to `blendedScore` (as 0) instead of\n * being dropped — use for layers whose failure is a real signal. Default:\n * fail drops from numerator + denominator, matching VB's existing semantics.\n */\n failContributesToScore?: boolean\n /** Optional per-layer wall-cap in ms. Honored by the verifier (AbortSignal). */\n capMs?: number\n run: (ctx: VerifyContext<Env>) => Promise<LayerResult> | LayerResult\n}\n\nexport interface VerifyOptions<Env = unknown> {\n env: Env\n /**\n * Overall wall cap. Default: sum of layer capMs, or Infinity if any layer\n * omits a cap. The verifier short-circuits remaining layers on overall cap.\n */\n overallCapMs?: number\n /** Called with each layer result as it completes. */\n onLayer?: (result: LayerResult) => void\n}\n\n/** Extends the substrate verdict spine: `valid` = `allPass`; `score` is the\n * complete task score or 0 when the configured scoring panel was incomplete. */\nexport interface VerificationReport extends DefaultVerdict {\n layers: LayerResult[]\n passCount: number\n failCount: number\n skippedCount: number\n errorCount: number\n /** True iff the configured scoring panel completed and every layer passed. */\n allPass: boolean\n /**\n * Diagnostic weighted mean across contributing layers. This may represent a\n * partial panel. It is 0 when no layer contributed.\n */\n blendedScore: number\n /**\n * Complete task-quality measurement.\n * Present when at least one layer produced a valid score, every other layer\n * completed successfully or contributed an explicit scored failure, and no\n * result is missing because of a failure, skip, error, or timeout.\n * Use this field, not `blendedScore`, when creating task labels.\n */\n taskScore?: number\n durationMs: number\n startedAt: string\n finishedAt: string\n}\n\n// ─── Helpers ────────────────────────────────────────────────────────────\n\n/**\n * Grade a semantic-concept-style judge result into a single layer status.\n *\n * Pass when overall score >= threshold AND no critical-severity concept gap.\n * Fail otherwise. Use inside a `Layer.run` when wrapping a concept judge.\n *\n * Generalized from VerticalBench H3 fix: `failingConcepts.length === 0` was\n * too strict — a single concept at 6/10 failed the entire layer despite\n * overall score being >= 0.7. Now we trust the judge's own `severity` field:\n * `critical` findings veto; `major`/`minor` reduce the score but don't veto.\n */\nexport function gradeSemanticStatus(input: {\n score: number\n findings: Array<{ severity: Severity; present?: boolean; score?: number }>\n available: boolean\n threshold?: number\n}): LayerStatus {\n if (!input.available) return 'error'\n const threshold = input.threshold ?? 0.7\n const criticalGaps = input.findings.filter(\n (f) => f.severity === 'critical' && (f.present === false || (f.score ?? 0) < 7),\n )\n return input.score >= threshold && criticalGaps.length === 0 ? 'pass' : 'fail'\n}\n\n// ─── Verifier ───────────────────────────────────────────────────────────\n\n/**\n * Ordered DAG of verification layers with dependency-based skipping, per-layer findings, soft-fail semantics, and a blended composite score across all passed layers.\n */\nexport class MultiLayerVerifier<Env = unknown> {\n constructor(private readonly layers: Layer<Env>[]) {\n const seen = new Set<string>()\n for (const l of layers) {\n if (seen.has(l.name)) throw new Error(`MultiLayerVerifier: duplicate layer name \"${l.name}\"`)\n seen.add(l.name)\n }\n for (const l of layers) {\n for (const dep of l.dependsOn ?? []) {\n if (!seen.has(dep)) {\n throw new Error(\n `MultiLayerVerifier: layer \"${l.name}\" depends on \"${dep}\" which is not registered`,\n )\n }\n }\n }\n }\n\n async run(opts: VerifyOptions<Env>): Promise<VerificationReport> {\n const startedAtMs = Date.now()\n const startedAt = new Date(startedAtMs).toISOString()\n const controller = new AbortController()\n const overallCap = opts.overallCapMs\n const overallTimer =\n overallCap != null\n ? setTimeout(() => controller.abort(new Error('overall cap exceeded')), overallCap)\n : null\n\n const results: LayerResult[] = []\n const byName: Record<string, LayerResult> = {}\n\n try {\n for (const layer of this.layers) {\n // Skip if any dependency didn't pass.\n const unmet = (layer.dependsOn ?? []).filter((d) => byName[d]?.status !== 'pass')\n if (unmet.length > 0) {\n const skipped: LayerResult = {\n layer: layer.name,\n status: 'skipped',\n durationMs: 0,\n findings: [],\n reason: `skipped — upstream not passing: ${unmet.join(', ')}`,\n }\n results.push(skipped)\n byName[layer.name] = skipped\n opts.onLayer?.(skipped)\n continue\n }\n\n // Per-layer cap — compose with overall signal.\n const perLayerController = new AbortController()\n const mergedSignal = mergeSignals(controller.signal, perLayerController.signal)\n const layerTimer =\n layer.capMs != null\n ? setTimeout(\n () => perLayerController.abort(new Error(`layer ${layer.name} cap`)),\n layer.capMs,\n )\n : null\n\n const layerStart = Date.now()\n let result: LayerResult\n let rejectOnAbort: (() => void) | undefined\n const abortPromise = new Promise<never>((_resolve, reject) => {\n const rejectWithReason = (): void => {\n const reason = mergedSignal.reason\n reject(reason instanceof Error ? reason : new Error(String(reason ?? 'aborted')))\n }\n if (mergedSignal.aborted) {\n rejectWithReason()\n return\n }\n mergedSignal.addEventListener('abort', rejectWithReason, { once: true })\n rejectOnAbort = () => mergedSignal.removeEventListener('abort', rejectWithReason)\n })\n try {\n result = await Promise.race([\n Promise.resolve(\n layer.run({ env: opts.env, prior: { ...byName }, signal: mergedSignal }),\n ),\n abortPromise,\n ])\n } catch (err) {\n const aborted = mergedSignal.aborted\n result = {\n layer: layer.name,\n status: aborted ? 'timeout' : 'error',\n errorSource: layer.errorSource ?? 'execution',\n durationMs: Date.now() - layerStart,\n findings: [\n {\n severity: 'major',\n message: err instanceof Error ? err.message : String(err),\n layer: layer.name,\n },\n ],\n reason: err instanceof Error ? err.message : String(err),\n }\n } finally {\n rejectOnAbort?.()\n if (layerTimer) clearTimeout(layerTimer)\n }\n\n if (result.status === 'error' || result.status === 'timeout') {\n result.errorSource ??= layer.errorSource ?? 'execution'\n }\n\n // Normalize findings to attach layer name if omitted.\n result.findings = result.findings.map((f) => ({ ...f, layer: f.layer ?? layer.name }))\n results.push(result)\n byName[layer.name] = result\n opts.onLayer?.(result)\n\n if (controller.signal.aborted) break\n }\n\n const report = aggregate(this.layers, results, startedAt, startedAtMs)\n return report\n } finally {\n if (overallTimer) clearTimeout(overallTimer)\n }\n }\n}\n\nfunction aggregate<Env>(\n layers: Layer<Env>[],\n results: LayerResult[],\n startedAt: string,\n startedAtMs: number,\n): VerificationReport {\n const weightByName = new Map<string, number>()\n const failContribByName = new Map<string, boolean>()\n for (const l of layers) {\n weightByName.set(l.name, l.weight ?? 1)\n failContribByName.set(l.name, l.failContributesToScore ?? false)\n }\n\n let passCount = 0\n let failCount = 0\n let skippedCount = 0\n let errorCount = 0\n let scoredWeightSum = 0\n let scoredWeightedTotal = 0\n\n for (const r of results) {\n const weight = weightByName.get(r.layer) ?? 1\n const failContrib = failContribByName.get(r.layer) ?? false\n if (r.status === 'pass') passCount++\n else if (r.status === 'fail') failCount++\n else if (r.status === 'skipped') skippedCount++\n else errorCount++\n\n if (isValidTaskMeasurement(r) && weight > 0) {\n if (r.status === 'pass') {\n scoredWeightSum += weight\n scoredWeightedTotal += weight * r.score\n } else if (r.status === 'fail') {\n if (failContrib) {\n scoredWeightSum += weight\n scoredWeightedTotal += weight * r.score\n }\n }\n // skipped / error / timeout layers don't contribute\n }\n }\n\n const finishedAtMs = Date.now()\n const blendedScore = scoredWeightSum > 0 ? scoredWeightedTotal / scoredWeightSum : 0\n const resultByName = new Map(results.map((result) => [result.layer, result]))\n const completeTaskMeasurement =\n scoredWeightSum > 0 &&\n results.length === layers.length &&\n layers.every((layer) => {\n const result = resultByName.get(layer.name)\n if (!result) return false\n if ((layer.weight ?? 1) <= 0) return true\n if (result.status === 'pass') {\n return result.score === undefined || isValidTaskMeasurement(result)\n }\n return (\n result.status === 'fail' &&\n layer.failContributesToScore === true &&\n isValidTaskMeasurement(result)\n )\n })\n const taskScore =\n completeTaskMeasurement && scoredWeightSum > 0 && Number.isFinite(blendedScore)\n ? blendedScore\n : undefined\n const allPass =\n taskScore !== undefined &&\n results.length === layers.length &&\n failCount === 0 &&\n skippedCount === 0 &&\n errorCount === 0\n return {\n layers: results,\n passCount,\n failCount,\n skippedCount,\n errorCount,\n allPass,\n blendedScore,\n ...(taskScore === undefined ? {} : { taskScore }),\n valid: allPass,\n score: taskScore ?? 0,\n durationMs: finishedAtMs - startedAtMs,\n startedAt,\n finishedAt: new Date(finishedAtMs).toISOString(),\n }\n}\n\nfunction isValidTaskMeasurement(\n result: LayerResult,\n): result is LayerResult & { status: 'pass' | 'fail'; score: number } {\n return (\n (result.status === 'pass' || result.status === 'fail') &&\n typeof result.score === 'number' &&\n Number.isFinite(result.score) &&\n result.score >= 0 &&\n result.score <= 1\n )\n}\n\nfunction mergeSignals(a: AbortSignal, b: AbortSignal): AbortSignal {\n if (a.aborted) return a\n if (b.aborted) return b\n const c = new AbortController()\n const onAbort = (signal: AbortSignal) => () => c.abort(signal.reason)\n a.addEventListener('abort', onAbort(a), { once: true })\n b.addEventListener('abort', onAbort(b), { once: true })\n return c.signal\n}\n","/**\n * Multi-toolchain layer factory + merge helper.\n *\n * Some verification stages (install, typecheck, build, lint) run the\n * SAME logical layer across multiple parallel adapters — pnpm AND npm\n * AND cargo AND forge for a polyglot scaffold. The verifier presents\n * one row per stage; the toolchain breakdown lives in `findings.detail`.\n *\n * This module provides the merge: take N independent `LayerResult`s\n * (one per adapter) and reduce them to a single `LayerResult` whose\n * status is the worst of the parts and whose findings cite the adapter\n * that produced each one. Plus a {@link multiToolchainLayer} factory\n * that runs the adapter calls in parallel + applies the reducer.\n *\n * Pure utility — composes with {@link MultiLayerVerifier}.{run}.\n */\n\nimport type {\n Layer,\n LayerResult,\n LayerStatus,\n Severity,\n VerifyContext,\n} from './multi-layer-verifier'\n\n// ─── Status reduction ──────────────────────────────────────────────────\n\nconst STATUS_RANK: Record<LayerStatus, number> = {\n pass: 0,\n skipped: 1,\n fail: 2,\n timeout: 3,\n error: 4,\n}\n\nfunction worst(a: LayerStatus, b: LayerStatus): LayerStatus {\n return (STATUS_RANK[a] ?? 0) >= (STATUS_RANK[b] ?? 0) ? a : b\n}\n\nconst SEVERITY_RANK: Record<Severity, number> = {\n info: 0,\n minor: 1,\n major: 2,\n critical: 3,\n}\n\nfunction maxSeverity(findings: ReadonlyArray<{ severity: Severity }>): Severity {\n let best: Severity = 'info'\n for (const f of findings) {\n if (SEVERITY_RANK[f.severity] > SEVERITY_RANK[best]) best = f.severity\n }\n return best\n}\n\n// ─── Merge ──────────────────────────────────────────────────────────────\n\nexport interface AdapterRun {\n /** Identifier for the adapter (e.g. 'pnpm', 'npm', 'cargo', 'forge'). */\n adapter: string\n result: LayerResult\n}\n\nexport interface MergeOptions {\n /**\n * How to combine per-adapter `durationMs`. Default `'max'` (parallel\n * wall-clock). Set `'sum'` when reporting total work done across\n * adapters rather than wall time.\n */\n mergeDuration?: 'max' | 'sum'\n /**\n * Prefix finding messages with a per-adapter tag (e.g. `[pnpm] typecheck failed`).\n * Default: no prefix (renderers read `detail.adapter` instead).\n */\n messagePrefixer?: (adapter: string) => string\n /**\n * How to reduce per-adapter `LayerResult.diagnostics` into the merged\n * result's diagnostics. `'max'` (default) — for each key, merged =\n * max across adapters where value is non-null (matches \"if ANY adapter\n * saw N errors, merged saw N\"). `'sum'` — sum non-null values.\n */\n mergeDiagnostics?: 'max' | 'sum'\n}\n\n/**\n * Reduce N adapter runs to a single `LayerResult` for a logical layer.\n *\n * - status: worst of the parts (pass < skipped < fail < timeout < error)\n * - score: weighted mean of numeric scores (skip = no contribution)\n * - findings: union, each tagged with `detail.adapter`\n * - durationMs: `mergeDuration` option (default 'max' for parallel wall-clock)\n * - diagnostics: `mergeDiagnostics` option (default 'max' per key)\n * - reason: \" · \"-joined `name: status` per adapter\n */\nexport function mergeLayerResults(\n name: string,\n perAdapter: AdapterRun[],\n options: MergeOptions = {},\n): LayerResult {\n const mergeDuration = options.mergeDuration ?? 'max'\n const mergeDiagnostics = options.mergeDiagnostics ?? 'max'\n const prefix = options.messagePrefixer\n\n if (perAdapter.length === 0) {\n return {\n layer: name,\n status: 'skipped',\n durationMs: 0,\n findings: [],\n reason: 'no adapters',\n }\n }\n if (perAdapter.length === 1) {\n const only = perAdapter[0]!\n return {\n ...only.result,\n layer: name,\n findings: only.result.findings.map((f) => ({\n ...f,\n layer: name,\n message: prefix ? `${prefix(only.adapter)} ${f.message}` : f.message,\n detail: { ...(f.detail ?? {}), adapter: only.adapter },\n })),\n reason: only.result.reason ?? `${only.adapter}: ${only.result.status}`,\n }\n }\n\n let status: LayerStatus = 'pass'\n let weightedScoreSum = 0\n let weightCount = 0\n const findings: LayerResult['findings'] = []\n let durationMs = 0\n const reasonParts: string[] = []\n const diagnostics: Record<string, number | null> = {}\n\n for (const { adapter, result } of perAdapter) {\n status = worst(status, result.status)\n if (typeof result.score === 'number') {\n weightedScoreSum += result.score\n weightCount += 1\n }\n durationMs =\n mergeDuration === 'sum'\n ? durationMs + result.durationMs\n : Math.max(durationMs, result.durationMs)\n reasonParts.push(`${adapter}: ${result.status}`)\n for (const f of result.findings) {\n findings.push({\n ...f,\n layer: name,\n message: prefix ? `${prefix(adapter)} ${f.message}` : f.message,\n detail: { ...(f.detail ?? {}), adapter },\n })\n }\n for (const [k, v] of Object.entries(result.diagnostics ?? {})) {\n if (typeof v !== 'number' || !Number.isFinite(v)) continue\n const prev = diagnostics[k]\n if (prev == null) diagnostics[k] = v\n else diagnostics[k] = mergeDiagnostics === 'sum' ? prev + v : Math.max(prev, v)\n }\n }\n\n return {\n layer: name,\n status,\n score: weightCount > 0 ? weightedScoreSum / weightCount : undefined,\n durationMs,\n findings,\n reason: reasonParts.join(' · '),\n diagnostics: Object.keys(diagnostics).length > 0 ? diagnostics : undefined,\n detail: {\n adapters: perAdapter.map(({ adapter, result }) => ({\n adapter,\n status: result.status,\n score: result.score ?? null,\n })),\n worstSeverity: maxSeverity(findings),\n },\n }\n}\n\n// ─── Layer factory ──────────────────────────────────────────────────────\n\nexport interface MultiToolchainLayerConfig<Env, Adapter> {\n name: string\n adapters: ReadonlyArray<Adapter>\n /** Adapter identifier — used in findings + reason. */\n adapterName: (a: Adapter) => string\n /** Run a single adapter against the verify context. */\n run: (a: Adapter, ctx: VerifyContext<Env>) => Promise<LayerResult> | LayerResult\n dependsOn?: string[]\n weight?: number\n failContributesToScore?: boolean\n capMs?: number\n /**\n * Per-adapter parallel cap. Defaults to 8 — defense in depth against a\n * caller passing 50 adapters and fanning out 50 simultaneous subprocesses.\n * Adapters that need higher concurrency raise this explicitly.\n */\n maxParallel?: number\n}\n\n/**\n * Build a {@link Layer} that fans the same logical stage across N adapters\n * in parallel and merges via {@link mergeLayerResults}.\n *\n * Per-adapter throws are caught + converted to `status: 'error'` results\n * so one bad adapter doesn't poison the whole layer.\n */\nexport function multiToolchainLayer<Env, Adapter>(\n config: MultiToolchainLayerConfig<Env, Adapter>,\n): Layer<Env> {\n const maxParallel = Math.max(1, config.maxParallel ?? 8)\n return {\n name: config.name,\n dependsOn: config.dependsOn,\n weight: config.weight,\n failContributesToScore: config.failContributesToScore,\n capMs: config.capMs,\n async run(ctx) {\n if (config.adapters.length === 0) {\n return {\n layer: config.name,\n status: 'skipped',\n durationMs: 0,\n findings: [],\n reason: 'no adapters detected',\n }\n }\n\n const runOne = async (adapter: Adapter): Promise<AdapterRun> => {\n const adapterName = config.adapterName(adapter)\n try {\n const r = await config.run(adapter, ctx)\n return { adapter: adapterName, result: r }\n } catch (err) {\n return {\n adapter: adapterName,\n result: {\n layer: config.name,\n status: 'error',\n durationMs: 0,\n findings: [\n {\n severity: 'major',\n layer: config.name,\n message: err instanceof Error ? err.message : String(err),\n detail: { adapter: adapterName },\n },\n ],\n reason: err instanceof Error ? err.message : String(err),\n },\n }\n }\n }\n\n // Bounded parallelism — chunked into groups of size maxParallel.\n const results: AdapterRun[] = []\n for (let i = 0; i < config.adapters.length; i += maxParallel) {\n const chunk = config.adapters.slice(i, i + maxParallel)\n const chunkResults = await Promise.all(chunk.map(runOne))\n results.push(...chunkResults)\n }\n return mergeLayerResults(config.name, results)\n },\n }\n}\n","/**\n * Reference replay — score an agent against withheld historical outcomes.\n *\n * This is the generic version of the public-audit replay pattern:\n * run a candidate system on an old task, keep the reference answers hidden\n * until after execution, then score recall/precision and gate promotion\n * across train/dev/test/holdout splits.\n */\n\nimport { appendFileSync, existsSync, mkdirSync, readFileSync } from 'node:fs'\nimport { dirname } from 'node:path'\nimport { Mutex } from './concurrency'\n\nexport type ReferenceReplaySplit = 'train' | 'dev' | 'test' | 'holdout'\nexport type ReferenceReplayMatchStrategy = 'reference-order' | 'global-greedy'\n\nexport interface ReferenceReplayItem {\n id: string\n title: string\n description?: string\n severity?: string\n tags?: string[]\n weight?: number\n}\n\nexport interface ReferenceReplayCandidate {\n id: string\n title: string\n description?: string\n severity?: string\n tags?: string[]\n metadata?: Record<string, unknown>\n}\n\nexport interface ReferenceReplayScenario {\n id: string\n split?: ReferenceReplaySplit\n references: ReferenceReplayItem[]\n candidates: ReferenceReplayCandidate[]\n metadata?: Record<string, unknown>\n}\n\nexport interface ReferenceReplayCase<Input = unknown> {\n id: string\n split?: ReferenceReplaySplit\n input: Input\n references: ReferenceReplayItem[]\n metadata?: Record<string, unknown>\n}\n\nexport interface ReferenceReplayExecutionScenario<Input = unknown> {\n id: string\n split: ReferenceReplaySplit\n input: Input\n metadata?: Record<string, unknown>\n}\n\nexport interface ReferenceReplayRunContext {\n runId: string\n caseIndex: number\n abortSignal?: AbortSignal\n}\n\nexport interface ReferenceReplayAdapter<Input = unknown> {\n run(\n scenario: ReferenceReplayExecutionScenario<Input>,\n context: ReferenceReplayRunContext,\n ): Promise<ReferenceReplayCandidate[]>\n}\n\nexport type ReferenceReplayAdapterFn<Input = unknown> = (\n scenario: ReferenceReplayExecutionScenario<Input>,\n context: ReferenceReplayRunContext,\n) => Promise<ReferenceReplayCandidate[]>\n\nexport type ReferenceReplayAdapterLike<Input = unknown> =\n | ReferenceReplayAdapter<Input>\n | ReferenceReplayAdapterFn<Input>\n\nexport interface ReferenceReplayMatch {\n scenarioId: string\n referenceId: string\n candidateId: string | null\n score: number\n matched: boolean\n weight: number\n reason: string\n}\n\nexport interface ReferenceReplayScenarioScore {\n scenarioId: string\n split: ReferenceReplaySplit\n matched: number\n total: number\n falsePositives: number\n matchedWeight: number\n totalWeight: number\n precision: number\n recall: number\n f1: number\n matches: ReferenceReplayMatch[]\n}\n\nexport interface ReferenceReplayAggregate {\n matched: number\n total: number\n falsePositives: number\n matchedWeight: number\n totalWeight: number\n precision: number\n recall: number\n f1: number\n weightedRecall: number\n}\n\nexport interface ReferenceReplayScore {\n scenarios: ReferenceReplayScenarioScore[]\n aggregate: ReferenceReplayAggregate\n bySplit: Partial<Record<ReferenceReplaySplit, ReferenceReplayAggregate>>\n}\n\nexport interface ReferenceMatchResult {\n score: number\n reason?: string\n}\n\nexport type ReferenceReplayMatcher = (\n reference: ReferenceReplayItem,\n candidate: ReferenceReplayCandidate,\n scenario: ReferenceReplayScenario,\n) => ReferenceMatchResult\n\nexport interface ReferenceReplayScoreOptions {\n matcher?: ReferenceReplayMatcher\n matchThreshold?: number\n matchStrategy?: ReferenceReplayMatchStrategy\n includeHoldout?: boolean\n splits?: ReferenceReplaySplit[]\n}\n\nexport interface ReferenceReplayPromotionPolicy {\n /** Splits that must improve or stay flat. Default: ['dev', 'test']. */\n requiredSplits?: ReferenceReplaySplit[]\n /** Minimum aggregate F1 lift required on required splits. Default 0. */\n minF1Delta?: number\n /** Maximum F1 drop allowed on any compared split. Default 0. */\n maxRegression?: number\n /** If true, holdout must be present and must not regress. Default true. */\n requireHoldoutNonRegression?: boolean\n}\n\nexport interface ReferenceReplaySplitComparison {\n split: ReferenceReplaySplit\n baselineF1: number\n candidateF1: number\n f1Delta: number\n baselineRecall: number\n candidateRecall: number\n recallDelta: number\n}\n\nexport interface ReferenceReplayPromotionDecision {\n promote: boolean\n reason: string\n aggregateDelta: number\n comparisons: ReferenceReplaySplitComparison[]\n regressions: ReferenceReplaySplitComparison[]\n}\n\nexport interface ReferenceReplayCaseRun<Input = unknown> {\n caseId: string\n split: ReferenceReplaySplit\n input: Input\n metadata?: Record<string, unknown>\n references: ReferenceReplayItem[]\n candidates: ReferenceReplayCandidate[]\n score: ReferenceReplayScenarioScore\n durationMs: number\n error?: string\n}\n\nexport interface ReferenceReplayRun<Input = unknown> {\n id: string\n variantId?: string\n startedAt: number\n completedAt: number\n durationMs: number\n cases: ReferenceReplayCaseRun<Input>[]\n score: ReferenceReplayScore\n metadata?: Record<string, unknown>\n}\n\nexport interface ReferenceReplayRunOptions<Input = unknown> extends ReferenceReplayScoreOptions {\n adapter: ReferenceReplayAdapterLike<Input>\n runId?: string\n variantId?: string\n metadata?: Record<string, unknown>\n store?: ReferenceReplayRunStore<Input>\n abortSignal?: AbortSignal\n continueOnError?: boolean\n now?: () => number\n}\n\nexport interface ReferenceReplayRunStore<Input = unknown> {\n save(run: ReferenceReplayRun<Input>): Promise<void>\n list(): Promise<ReferenceReplayRun<Input>[]>\n}\n\nconst DEFAULT_MATCH_THRESHOLD = 0.55\nconst ALL_SPLITS: ReferenceReplaySplit[] = ['train', 'dev', 'test', 'holdout']\n\nexport async function runReferenceReplay<Input = unknown>(\n cases: ReferenceReplayCase<Input>[],\n options: ReferenceReplayRunOptions<Input>,\n): Promise<ReferenceReplayRun<Input>> {\n const now = options.now ?? Date.now\n const startedAt = now()\n const runId = options.runId ?? `${options.variantId ?? 'reference-replay'}-${startedAt}`\n const allowedSplits = new Set(options.splits ?? ALL_SPLITS)\n const caseRuns: ReferenceReplayCaseRun<Input>[] = []\n\n for (const [caseIndex, replayCase] of cases.entries()) {\n const split = replayCase.split ?? 'train'\n if (split === 'holdout' && !options.includeHoldout) continue\n if (!allowedSplits.has(split)) continue\n\n const caseStart = now()\n const executionScenario: ReferenceReplayExecutionScenario<Input> = {\n id: replayCase.id,\n split,\n input: replayCase.input,\n ...(replayCase.metadata !== undefined ? { metadata: replayCase.metadata } : {}),\n }\n\n let candidates: ReferenceReplayCandidate[] = []\n let error: string | undefined\n try {\n throwIfAborted(options.abortSignal)\n candidates = await runAdapter(options.adapter, executionScenario, {\n runId,\n caseIndex,\n abortSignal: options.abortSignal,\n })\n throwIfAborted(options.abortSignal)\n } catch (cause) {\n if (options.abortSignal?.aborted) throw cause\n if (!options.continueOnError) throw cause\n error = cause instanceof Error ? cause.message : String(cause)\n }\n\n const scenario: ReferenceReplayScenario = {\n id: replayCase.id,\n split,\n references: replayCase.references,\n candidates,\n ...(replayCase.metadata !== undefined ? { metadata: replayCase.metadata } : {}),\n }\n const scoreOptions: ReferenceReplayScoreOptions = {\n matcher: options.matcher,\n matchThreshold: options.matchThreshold,\n matchStrategy: options.matchStrategy,\n includeHoldout: true,\n }\n const scenarioScore = scoreReferenceReplay([scenario], scoreOptions).scenarios[0]!\n caseRuns.push({\n caseId: replayCase.id,\n split,\n input: replayCase.input,\n references: replayCase.references,\n candidates,\n score: scenarioScore,\n durationMs: Math.max(0, now() - caseStart),\n ...(replayCase.metadata !== undefined ? { metadata: replayCase.metadata } : {}),\n ...(error !== undefined ? { error } : {}),\n })\n }\n\n const completedAt = now()\n const scoreOptions: ReferenceReplayScoreOptions = {\n matcher: options.matcher,\n matchThreshold: options.matchThreshold,\n matchStrategy: options.matchStrategy,\n includeHoldout: true,\n }\n const run: ReferenceReplayRun<Input> = {\n id: runId,\n startedAt,\n completedAt,\n durationMs: Math.max(0, completedAt - startedAt),\n cases: caseRuns,\n score: scoreReferenceReplay(\n caseRuns.map((caseRun) => ({\n id: caseRun.caseId,\n split: caseRun.split,\n references: caseRun.references,\n candidates: caseRun.candidates,\n ...(caseRun.metadata !== undefined ? { metadata: caseRun.metadata } : {}),\n })),\n scoreOptions,\n ),\n ...(options.variantId !== undefined ? { variantId: options.variantId } : {}),\n ...(options.metadata !== undefined ? { metadata: options.metadata } : {}),\n }\n\n await options.store?.save(run)\n return run\n}\n\nexport function decideReferenceReplayRunPromotion(\n baseline: ReferenceReplayRun,\n candidate: ReferenceReplayRun,\n policy: ReferenceReplayPromotionPolicy = {},\n): ReferenceReplayPromotionDecision {\n return decideReferenceReplayPromotion(baseline.score, candidate.score, policy)\n}\n\nexport function inMemoryReferenceReplayStore<Input = unknown>(\n initial: ReferenceReplayRun<Input>[] = [],\n): ReferenceReplayRunStore<Input> {\n const runs = [...initial]\n return {\n async save(run) {\n runs.push(run)\n },\n async list() {\n return [...runs]\n },\n }\n}\n\n// Per-path Mutex registry. `appendFileSync` on POSIX is only atomic up to\n// PIPE_BUF (~4KB) — and a `ReferenceReplayRun` line routinely exceeds that.\n// Concurrent in-process writers without a lock produce torn lines that\n// break `list()` on parse. Cross-process safety still requires file\n// locking (fcntl/flock); we don't take that on here because every current\n// agent-eval flow is single-process.\nconst jsonlStoreLocks = new Map<string, Mutex>()\nfunction getJsonlStoreLock(path: string): Mutex {\n let m = jsonlStoreLocks.get(path)\n if (!m) {\n m = new Mutex()\n jsonlStoreLocks.set(path, m)\n }\n return m\n}\n\nexport function jsonlReferenceReplayStore<Input = unknown>(\n path: string,\n): ReferenceReplayRunStore<Input> {\n const lock = getJsonlStoreLock(path)\n return {\n async save(run) {\n await lock.runExclusive(() => {\n mkdirSync(dirname(path), { recursive: true })\n appendFileSync(path, `${JSON.stringify(run)}\\n`)\n })\n },\n async list() {\n return lock.runExclusive(() => {\n if (!existsSync(path)) return []\n return readJsonl(path)\n })\n },\n }\n}\n\nexport function scoreReferenceReplay(\n scenarios: ReferenceReplayScenario[],\n options: ReferenceReplayScoreOptions = {},\n): ReferenceReplayScore {\n const matcher = options.matcher ?? defaultReferenceReplayMatcher\n const threshold = options.matchThreshold ?? DEFAULT_MATCH_THRESHOLD\n const matchStrategy = options.matchStrategy ?? 'reference-order'\n const allowedSplits = new Set(options.splits ?? ALL_SPLITS)\n const scores = scenarios\n .filter((scenario) => {\n const split = scenario.split ?? 'train'\n if (split === 'holdout' && !options.includeHoldout) return false\n return allowedSplits.has(split)\n })\n .map((scenario) => scoreScenario(scenario, matcher, threshold, matchStrategy))\n\n return {\n scenarios: scores,\n aggregate: aggregateScenarioScores(scores),\n bySplit: aggregateBySplit(scores),\n }\n}\n\nexport function compareReferenceReplay(\n baseline: ReferenceReplayScore,\n candidate: ReferenceReplayScore,\n): ReferenceReplaySplitComparison[] {\n const splits = new Set<ReferenceReplaySplit>([\n ...(Object.keys(baseline.bySplit) as ReferenceReplaySplit[]),\n ...(Object.keys(candidate.bySplit) as ReferenceReplaySplit[]),\n ])\n return [...splits].sort(bySplitOrder).map((split) => {\n const before = baseline.bySplit[split] ?? emptyAggregate()\n const after = candidate.bySplit[split] ?? emptyAggregate()\n return {\n split,\n baselineF1: before.f1,\n candidateF1: after.f1,\n f1Delta: after.f1 - before.f1,\n baselineRecall: before.recall,\n candidateRecall: after.recall,\n recallDelta: after.recall - before.recall,\n }\n })\n}\n\nexport function decideReferenceReplayPromotion(\n baseline: ReferenceReplayScore,\n candidate: ReferenceReplayScore,\n policy: ReferenceReplayPromotionPolicy = {},\n): ReferenceReplayPromotionDecision {\n const requiredSplits = policy.requiredSplits ?? ['dev', 'test']\n const minF1Delta = policy.minF1Delta ?? 0\n const maxRegression = policy.maxRegression ?? 0\n const requireHoldout = policy.requireHoldoutNonRegression ?? true\n const comparisons = compareReferenceReplay(baseline, candidate)\n const missingRequiredSplits = requiredSplits.filter(\n (split) => !hasSplit(baseline, split) || !hasSplit(candidate, split),\n )\n const compared = comparisons.filter((item) => requiredSplits.includes(item.split))\n const regressions = comparisons.filter((item) => item.f1Delta < -maxRegression)\n const aggregateDelta = candidate.aggregate.f1 - baseline.aggregate.f1\n const coverageMismatch = compareScenarioCoverage(baseline, candidate)\n\n if (missingRequiredSplits.length > 0) {\n return {\n promote: false,\n reason: `Required split missing from baseline or candidate: ${missingRequiredSplits.join(', ')}`,\n aggregateDelta,\n comparisons,\n regressions,\n }\n }\n\n if (compared.length === 0) {\n return {\n promote: false,\n reason: `No required split scores found: ${requiredSplits.join(', ')}`,\n aggregateDelta,\n comparisons,\n regressions,\n }\n }\n\n if (regressions.length > 0) {\n return {\n promote: false,\n reason: `Regression in ${regressions.map((r) => r.split).join(', ')}`,\n aggregateDelta,\n comparisons,\n regressions,\n }\n }\n\n if (requireHoldout && (!hasSplit(baseline, 'holdout') || !hasSplit(candidate, 'holdout'))) {\n return {\n promote: false,\n reason: 'Holdout split is required for promotion',\n aggregateDelta,\n comparisons,\n regressions,\n }\n }\n\n if (coverageMismatch.candidateMissing.length > 0 || coverageMismatch.baselineMissing.length > 0) {\n const gaps = [\n coverageMismatch.candidateMissing.length > 0\n ? `candidate missing ${formatScenarioIds(coverageMismatch.candidateMissing)}`\n : null,\n coverageMismatch.baselineMissing.length > 0\n ? `baseline missing ${formatScenarioIds(coverageMismatch.baselineMissing)}`\n : null,\n ].filter((part): part is string => part !== null)\n return {\n promote: false,\n reason:\n `Scenario coverage differs: baseline ${baseline.scenarios.length}, ` +\n `candidate ${candidate.scenarios.length}; ${gaps.join('; ')}`,\n aggregateDelta,\n comparisons,\n regressions,\n }\n }\n\n const requiredMeanDelta = mean(compared.map((item) => item.f1Delta))\n if (requiredMeanDelta < minF1Delta) {\n return {\n promote: false,\n reason: `Required split F1 delta ${formatPct(requiredMeanDelta)} below ${formatPct(minF1Delta)}`,\n aggregateDelta,\n comparisons,\n regressions,\n }\n }\n\n return {\n promote: true,\n reason: `Required splits improved by ${formatPct(requiredMeanDelta)} with no regressions`,\n aggregateDelta,\n comparisons,\n regressions,\n }\n}\n\ninterface ScenarioCoverageMismatch {\n candidateMissing: string[]\n baselineMissing: string[]\n}\n\nfunction compareScenarioCoverage(\n baseline: ReferenceReplayScore,\n candidate: ReferenceReplayScore,\n): ScenarioCoverageMismatch {\n const baselineCounts = scenarioIdentityCounts(baseline)\n const candidateCounts = scenarioIdentityCounts(candidate)\n return {\n candidateMissing: countDifference(baselineCounts, candidateCounts),\n baselineMissing: countDifference(candidateCounts, baselineCounts),\n }\n}\n\nfunction scenarioIdentityCounts(score: ReferenceReplayScore): Map<string, number> {\n const counts = new Map<string, number>()\n for (const scenario of score.scenarios) {\n const identity = `${scenario.split}:${scenario.scenarioId}`\n counts.set(identity, (counts.get(identity) ?? 0) + 1)\n }\n return counts\n}\n\nfunction countDifference(expected: Map<string, number>, actual: Map<string, number>): string[] {\n const missing: string[] = []\n for (const [identity, count] of expected) {\n const difference = count - (actual.get(identity) ?? 0)\n for (let index = 0; index < difference; index++) missing.push(identity)\n }\n return missing.sort()\n}\n\nfunction formatScenarioIds(ids: string[]): string {\n const shown = ids.slice(0, 5)\n const remaining = ids.length - shown.length\n return remaining > 0 ? `${shown.join(', ')}, +${remaining} more` : shown.join(', ')\n}\n\nexport function defaultReferenceReplayMatcher(\n reference: ReferenceReplayItem,\n candidate: ReferenceReplayCandidate,\n): ReferenceMatchResult {\n const referenceText = `${reference.title} ${reference.description ?? ''}`\n const candidateText = `${candidate.title} ${candidate.description ?? ''}`\n const textScore = tokenJaccard(referenceText, candidateText)\n const severityScore =\n reference.severity && candidate.severity\n ? normalize(reference.severity) === normalize(candidate.severity)\n ? 0.1\n : -0.05\n : 0\n const tagScore = tagOverlap(reference.tags, candidate.tags) * 0.15\n const score = clamp01(textScore * 0.85 + tagScore + severityScore)\n return {\n score,\n reason: `token=${textScore.toFixed(2)} tags=${tagScore.toFixed(2)} severity=${severityScore.toFixed(2)}`,\n }\n}\n\nfunction scoreScenario(\n scenario: ReferenceReplayScenario,\n matcher: ReferenceReplayMatcher,\n threshold: number,\n matchStrategy: ReferenceReplayMatchStrategy,\n): ReferenceReplayScenarioScore {\n return matchStrategy === 'global-greedy'\n ? scoreScenarioGlobalGreedy(scenario, matcher, threshold)\n : scoreScenarioReferenceOrder(scenario, matcher, threshold)\n}\n\nfunction scoreScenarioReferenceOrder(\n scenario: ReferenceReplayScenario,\n matcher: ReferenceReplayMatcher,\n threshold: number,\n): ReferenceReplayScenarioScore {\n const candidatesLeft = scenario.candidates.map((candidate, index) => ({ candidate, index }))\n const matches: ReferenceReplayMatch[] = []\n\n for (const reference of scenario.references) {\n let best: {\n candidate: ReferenceReplayCandidate\n index: number\n score: number\n reason: string\n } | null = null\n for (const item of candidatesLeft) {\n const result = scorePair(scenario, matcher, reference, item.candidate)\n if (!best || result.score > best.score) {\n best = { ...item, ...result }\n }\n }\n\n const weight = reference.weight ?? 1\n if (best && best.score >= threshold) {\n const matchIndex = candidatesLeft.findIndex((item) => item.index === best.index)\n if (matchIndex >= 0) candidatesLeft.splice(matchIndex, 1)\n matches.push({\n scenarioId: scenario.id,\n referenceId: reference.id,\n candidateId: best.candidate.id,\n score: best.score,\n matched: true,\n weight,\n reason: best.reason,\n })\n } else {\n matches.push({\n scenarioId: scenario.id,\n referenceId: reference.id,\n candidateId: best?.candidate.id ?? null,\n score: best?.score ?? 0,\n matched: false,\n weight,\n reason: best?.reason ?? 'no candidates',\n })\n }\n }\n\n return buildScenarioScore(scenario, matches, candidatesLeft.length)\n}\n\ninterface ReferenceCandidatePair {\n referenceIndex: number\n candidateIndex: number\n reference: ReferenceReplayItem\n candidate: ReferenceReplayCandidate\n score: number\n reason: string\n}\n\nfunction scoreScenarioGlobalGreedy(\n scenario: ReferenceReplayScenario,\n matcher: ReferenceReplayMatcher,\n threshold: number,\n): ReferenceReplayScenarioScore {\n const pairs: ReferenceCandidatePair[] = []\n for (const [referenceIndex, reference] of scenario.references.entries()) {\n for (const [candidateIndex, candidate] of scenario.candidates.entries()) {\n pairs.push({\n referenceIndex,\n candidateIndex,\n reference,\n candidate,\n ...scorePair(scenario, matcher, reference, candidate),\n })\n }\n }\n\n pairs.sort(\n (a, b) =>\n b.score - a.score ||\n a.referenceIndex - b.referenceIndex ||\n a.candidateIndex - b.candidateIndex,\n )\n\n const selectedByReference = new Map<number, ReferenceCandidatePair>()\n const selectedCandidates = new Set<number>()\n for (const pair of pairs) {\n if (pair.score < threshold) break\n if (selectedByReference.has(pair.referenceIndex) || selectedCandidates.has(pair.candidateIndex))\n continue\n selectedByReference.set(pair.referenceIndex, pair)\n selectedCandidates.add(pair.candidateIndex)\n }\n\n const matches = scenario.references.map((reference, referenceIndex) => {\n const weight = reference.weight ?? 1\n const selected = selectedByReference.get(referenceIndex)\n if (selected) {\n return {\n scenarioId: scenario.id,\n referenceId: reference.id,\n candidateId: selected.candidate.id,\n score: selected.score,\n matched: true,\n weight,\n reason: selected.reason,\n }\n }\n\n const bestRejected = pairs.find((pair) => pair.referenceIndex === referenceIndex)\n return {\n scenarioId: scenario.id,\n referenceId: reference.id,\n candidateId: bestRejected?.candidate.id ?? null,\n score: bestRejected?.score ?? 0,\n matched: false,\n weight,\n reason: bestRejected?.reason ?? 'no candidates',\n }\n })\n\n return buildScenarioScore(scenario, matches, scenario.candidates.length - selectedCandidates.size)\n}\n\nfunction scorePair(\n scenario: ReferenceReplayScenario,\n matcher: ReferenceReplayMatcher,\n reference: ReferenceReplayItem,\n candidate: ReferenceReplayCandidate,\n): { score: number; reason: string } {\n const result = matcher(reference, candidate, scenario)\n if (!Number.isFinite(result.score)) {\n throw new Error(\n `reference replay matcher returned non-finite score for ${scenario.id}:${reference.id}:${candidate.id}`,\n )\n }\n return { score: clamp01(result.score), reason: result.reason ?? '' }\n}\n\nfunction buildScenarioScore(\n scenario: ReferenceReplayScenario,\n matches: ReferenceReplayMatch[],\n falsePositives: number,\n): ReferenceReplayScenarioScore {\n const matched = matches.filter((match) => match.matched).length\n const total = scenario.references.length\n const matchedWeight = matches\n .filter((match) => match.matched)\n .reduce((sum, match) => sum + match.weight, 0)\n const totalWeight = matches.reduce((sum, match) => sum + match.weight, 0)\n const precision = ratio(matched, matched + falsePositives)\n const recall = ratio(matched, total)\n return {\n scenarioId: scenario.id,\n split: scenario.split ?? 'train',\n matched,\n total,\n falsePositives,\n matchedWeight,\n totalWeight,\n precision,\n recall,\n f1: f1(precision, recall),\n matches,\n }\n}\n\nfunction aggregateBySplit(\n scores: ReferenceReplayScenarioScore[],\n): Partial<Record<ReferenceReplaySplit, ReferenceReplayAggregate>> {\n const out: Partial<Record<ReferenceReplaySplit, ReferenceReplayAggregate>> = {}\n for (const split of ALL_SPLITS) {\n const scoped = scores.filter((score) => score.split === split)\n if (scoped.length > 0) out[split] = aggregateScenarioScores(scoped)\n }\n return out\n}\n\nfunction aggregateScenarioScores(scores: ReferenceReplayScenarioScore[]): ReferenceReplayAggregate {\n const matched = sum(scores.map((score) => score.matched))\n const total = sum(scores.map((score) => score.total))\n const falsePositives = sum(scores.map((score) => score.falsePositives))\n const matchedWeight = sum(scores.map((score) => score.matchedWeight))\n const totalWeight = sum(scores.map((score) => score.totalWeight))\n const precision = ratio(matched, matched + falsePositives)\n const recall = ratio(matched, total)\n return {\n matched,\n total,\n falsePositives,\n matchedWeight,\n totalWeight,\n precision,\n recall,\n f1: f1(precision, recall),\n weightedRecall: ratio(matchedWeight, totalWeight),\n }\n}\n\nfunction emptyAggregate(): ReferenceReplayAggregate {\n return {\n matched: 0,\n total: 0,\n falsePositives: 0,\n matchedWeight: 0,\n totalWeight: 0,\n precision: 0,\n recall: 0,\n f1: 0,\n weightedRecall: 0,\n }\n}\n\nfunction hasSplit(score: ReferenceReplayScore, split: ReferenceReplaySplit): boolean {\n return score.bySplit[split] !== undefined\n}\n\nfunction f1(precision: number, recall: number): number {\n return precision + recall === 0 ? 0 : (2 * precision * recall) / (precision + recall)\n}\n\nfunction ratio(numerator: number, denominator: number): number {\n return denominator > 0 ? numerator / denominator : 0\n}\n\nfunction tokenJaccard(a: string, b: string): number {\n const left = new Set(tokens(a))\n const right = new Set(tokens(b))\n if (left.size === 0 || right.size === 0) return 0\n let intersection = 0\n for (const token of left) {\n if (right.has(token)) intersection++\n }\n return intersection / (left.size + right.size - intersection)\n}\n\nfunction tagOverlap(a: string[] | undefined, b: string[] | undefined): number {\n if (!a?.length || !b?.length) return 0\n const left = new Set(a.map(normalize))\n const right = new Set(b.map(normalize))\n let intersection = 0\n for (const tag of left) {\n if (right.has(tag)) intersection++\n }\n return intersection / Math.max(left.size, right.size)\n}\n\nfunction tokens(text: string): string[] {\n return normalize(text)\n .split(/\\s+/)\n .filter((token) => token.length >= 3 && !STOP_WORDS.has(token))\n}\n\nfunction normalize(text: string): string {\n return text\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, ' ')\n .trim()\n}\n\nfunction clamp01(value: number): number {\n if (!Number.isFinite(value)) return 0\n return Math.max(0, Math.min(1, value))\n}\n\nfunction sum(values: number[]): number {\n return values.reduce((acc, value) => acc + value, 0)\n}\n\nfunction mean(values: number[]): number {\n return values.length ? sum(values) / values.length : 0\n}\n\nfunction formatPct(value: number): string {\n return `${(value * 100).toFixed(1)}%`\n}\n\nfunction bySplitOrder(a: ReferenceReplaySplit, b: ReferenceReplaySplit): number {\n return ALL_SPLITS.indexOf(a) - ALL_SPLITS.indexOf(b)\n}\n\nfunction runAdapter<Input>(\n adapter: ReferenceReplayAdapterLike<Input>,\n scenario: ReferenceReplayExecutionScenario<Input>,\n context: ReferenceReplayRunContext,\n): Promise<ReferenceReplayCandidate[]> {\n return typeof adapter === 'function' ? adapter(scenario, context) : adapter.run(scenario, context)\n}\n\nfunction throwIfAborted(signal: AbortSignal | undefined): void {\n if (!signal?.aborted) return\n if (signal.reason instanceof Error) throw signal.reason\n throw new Error(signal.reason ? String(signal.reason) : 'reference replay aborted')\n}\n\nfunction readJsonl<Input>(path: string): ReferenceReplayRun<Input>[] {\n const raw = readFileSync(path, 'utf8')\n const out: ReferenceReplayRun<Input>[] = []\n for (const line of raw.split('\\n')) {\n const trimmed = line.trim()\n if (!trimmed) continue\n out.push(JSON.parse(trimmed) as ReferenceReplayRun<Input>)\n }\n return out\n}\n\nconst STOP_WORDS = new Set([\n 'the',\n 'and',\n 'for',\n 'with',\n 'that',\n 'this',\n 'from',\n 'into',\n 'onto',\n 'are',\n 'can',\n 'will',\n 'should',\n 'could',\n 'would',\n 'when',\n 'where',\n 'which',\n])\n","/**\n * Reviewer primitives — prompt builder + default ReviewFn factory.\n *\n * `buildReviewerPrompt` is the pure, LLM-agnostic piece: takes\n * `ReviewerPromptInput` (user request, trace summary, verification\n * summary, memory, optional extra context) and emits the system +\n * user message pair. No LLM dependency — callers that want to drive\n * their own transport get full control.\n *\n * `createDefaultReviewer` is the convenience factory: wires the prompt\n * builder to `callLlmJson` with a default schema + soft-fail policy.\n * Returns a function that maps `ReviewerPromptInput` to `ReviewerOutput`.\n *\n * Same pattern as `runSemanticConceptJudge` / `createSemanticConceptJudge`:\n * low-level pure builder + high-level factory built on top.\n */\n\nimport { CostLedger, type CostLedgerHandle, type CostReceipt } from './cost-ledger'\nimport {\n callLlmJson,\n costReceiptFromLlm,\n costReceiptFromLlmError,\n type LlmCallRequest,\n type LlmClientOptions,\n maximumChargeForLlmRequest,\n} from './llm-client'\n\n// ─── Types ──────────────────────────────────────────────────────────────\n\nexport interface ReviewerMemoryEntry {\n shot: number\n ts?: string\n observations?: string\n diagnosis?: string\n nextShotInstruction?: string\n shouldContinue?: boolean\n confidence?: number\n}\n\nexport interface ReviewerVerificationSummary {\n blendedScore: number\n allPass: boolean\n failCount: number\n failingLayers?: string[]\n}\n\nexport interface ReviewerPromptInput {\n shot: number\n userRequest: string\n /**\n * Compact trace summary — tool-call counts, errors, recent activity\n * lines. Built by the caller from whatever trace format they have;\n * agent-eval does not prescribe.\n */\n traceSummary: string\n verification: ReviewerVerificationSummary\n memory: ReviewerMemoryEntry[]\n /**\n * Optional extra context injected into the prompt between the trace\n * and the verification blocks. Use for workdir file-tree snapshots,\n * scaffold descriptions, or any environmental fact the reviewer\n * needs to direct the next shot accurately.\n */\n extraContext?: string\n /**\n * Optional extra section appended at the end of the prompt (e.g.\n * leaf metadata, scenario id). Free-form — no agent-eval-shaped\n * schema.\n */\n trailingContext?: string\n}\n\nexport interface ReviewerOutput {\n shot: number\n observations: string\n diagnosis: string\n nextShotInstruction: string\n shouldContinue: boolean\n /** 0..1 self-assessed confidence in the directive. */\n confidence: number\n /** LLM cost in USD if the transport reports it, else null. */\n costUsd: number | null\n durationMs: number\n /** False when the LLM errored or returned malformed JSON; caller soft-fails to defaults. */\n available: boolean\n error?: string\n}\n\nexport interface ReviewerSoftFailDefaults {\n observations?: string\n diagnosis?: string\n nextShotInstruction?: string\n shouldContinue?: boolean\n confidence?: number\n}\n\nexport interface CreateDefaultReviewerOptions {\n /** Model id to call. */\n model: string\n /** Per-call timeout. Default 300s. */\n timeoutMs?: number\n /** Provider-enforced output limit. Default 4000. */\n maxTokens?: number\n /** LlmClient transport config (baseUrl, apiKey, authHeader, etc.). */\n llm?: LlmClientOptions\n /** Shared run spend account. */\n costLedger?: CostLedgerHandle\n costPhase?: string\n signal?: AbortSignal\n /**\n * Override the prompt builder. Default: `buildReviewerPrompt`.\n * Consumers with different reviewer voices pass their own.\n */\n promptBuilder?: (input: ReviewerPromptInput) => { system: string; user: string }\n /**\n * Soft-fail values when the LLM throws or returns unparseable JSON.\n * Matches VerticalBench's shipped policy: continue with generic\n * instruction at confidence 0.3 so the worker keeps trying.\n */\n softFailDefaults?: ReviewerSoftFailDefaults\n}\n\n// ─── JSON schema ───────────────────────────────────────────────────────\n\nconst REVIEWER_SCHEMA = {\n type: 'object',\n additionalProperties: false,\n required: ['observations', 'diagnosis', 'nextShotInstruction', 'shouldContinue', 'confidence'],\n properties: {\n observations: { type: 'string', minLength: 20, maxLength: 2000 },\n diagnosis: { type: 'string', minLength: 20, maxLength: 1500 },\n nextShotInstruction: { type: 'string', minLength: 40, maxLength: 3000 },\n shouldContinue: { type: 'boolean' },\n confidence: { type: 'number', minimum: 0, maximum: 1 },\n },\n} as const\n\n// ─── Prompt builder ────────────────────────────────────────────────────\n\nfunction summarizeMemory(memory: ReviewerMemoryEntry[]): string {\n if (memory.length === 0) return '(no prior shots)'\n return memory\n .map((m) => {\n const header = `shot ${m.shot} — confidence=${(m.confidence ?? 0).toFixed(2)} shouldContinue=${m.shouldContinue ?? '?'}`\n const obs = m.observations ? ` observations: ${m.observations.slice(0, 400)}` : ''\n const diag = m.diagnosis ? ` diagnosis: ${m.diagnosis.slice(0, 400)}` : ''\n const instr = m.nextShotInstruction\n ? ` instruction given: ${m.nextShotInstruction.slice(0, 400)}`\n : ''\n return [header, obs, diag, instr].filter(Boolean).join('\\n')\n })\n .join('\\n\\n')\n}\n\n/**\n * Build the reviewer's system + user messages. Pure function, no LLM\n * call. Callers that want their own transport or a different structured\n * output can use this and skip `createDefaultReviewer` entirely.\n */\nexport function buildReviewerPrompt(input: ReviewerPromptInput): { system: string; user: string } {\n const system =\n 'You are a senior-engineer-grade reviewer directing an agent through a multi-shot build. ' +\n \"Your job is NOT to grade; your job IS to direct the worker's next shot using the trace, \" +\n 'verification result, prior memory, and user request. Return STRICT JSON. No prose outside the JSON.'\n\n const failingLayersBlock =\n input.verification.failingLayers && input.verification.failingLayers.length > 0\n ? `failing layers: ${input.verification.failingLayers.join(', ')}`\n : 'no layers failing'\n\n const user = `=== SHOT NUMBER ===\nshot ${input.shot} of the review loop\n\n=== USER REQUEST ===\n${input.userRequest}\n\n=== WORKER TRACE (shot ${input.shot}) ===\n${input.traceSummary}\n${input.extraContext ? `\\n=== EXTRA CONTEXT ===\\n${input.extraContext}\\n` : ''}\n=== VERIFICATION (shot ${input.shot}) ===\nblendedScore: ${input.verification.blendedScore.toFixed(2)}\nallPass: ${input.verification.allPass}\nfailCount: ${input.verification.failCount}\n${failingLayersBlock}\n\n=== REVIEWER MEMORY ===\n${summarizeMemory(input.memory)}\n${input.trailingContext ? `\\n=== TRAILING CONTEXT ===\\n${input.trailingContext}\\n` : ''}\n=== YOUR TASK ===\nReturn STRICT JSON:\n\n1. observations (20-2000 chars): first-person worker behavior from the trace (tool call counts, errors, loops).\n2. diagnosis (20-1500 chars): root cause of current failures, not a restatement of verification.\n3. nextShotInstruction (40-3000 chars): concrete \"FIX THESE:\" directive for the worker's next shot. Reference memory when instructions repeat.\n4. shouldContinue (boolean): FALSE if verification.allPass=true, if worker is thrashing, if confidence < 0.3, or if the request looks unachievable. TRUE otherwise.\n5. confidence (0-1): self-assessment.\n\nRULES:\n- If verification.allPass is true, shouldContinue MUST be false.\n- If memory shows the same failing layer for 2 shots, reduce confidence — strategy isn't working.\n- If the trace shows zero tool calls, the worker didn't run — surface that.\n- Do NOT re-grade. Direct.`\n\n return { system, user }\n}\n\n// ─── Default reviewer factory ───────────────────────────────────────────\n\nconst DEFAULT_SOFT_FAIL: Required<ReviewerSoftFailDefaults> = {\n observations: 'reviewer soft-failed — no observations captured',\n diagnosis: 'reviewer soft-failed — inspect verification findings and retry',\n nextShotInstruction:\n 'Inspect the verification findings above and address the highest-severity failing layer first. ' +\n 'If install failed, start there; otherwise work from the first failing gate and address compilation/build errors before layout/semantic issues.',\n shouldContinue: true,\n confidence: 0.3,\n}\n\n/**\n * Factory: returns a function that invokes the default reviewer against\n * an LLM and parses the structured output. Soft-fails to the provided\n * defaults on LLM throw or JSON-parse error so the shot loop keeps\n * moving rather than crashing.\n */\nexport function createDefaultReviewer(\n options: CreateDefaultReviewerOptions,\n): (input: ReviewerPromptInput) => Promise<ReviewerOutput> {\n const softFail: Required<ReviewerSoftFailDefaults> = {\n ...DEFAULT_SOFT_FAIL,\n ...(options.softFailDefaults ?? {}),\n }\n const promptBuilder = options.promptBuilder ?? buildReviewerPrompt\n const timeoutMs = options.timeoutMs ?? 300_000\n const maxTokens = options.maxTokens ?? 4_000\n const costLedger = options.costLedger ?? new CostLedger()\n\n return async (input) => {\n const start = Date.now()\n const { system, user } = promptBuilder(input)\n let receipt: CostReceipt | undefined\n try {\n const request = {\n model: options.model,\n messages: [\n { role: 'system' as const, content: system },\n { role: 'user' as const, content: user },\n ],\n jsonSchema: { name: 'reviewer_output', schema: REVIEWER_SCHEMA },\n temperature: 0,\n maxTokens,\n timeoutMs,\n } satisfies LlmCallRequest\n const paid = await costLedger.runPaidCall({\n channel: 'analyst',\n phase: options.costPhase ?? 'review',\n actor: 'default-reviewer',\n model: options.model,\n maximumCharge: maximumChargeForLlmRequest(request, options.llm),\n signal: options.signal,\n execute: (signal, callId) =>\n callLlmJson<{\n observations: string\n diagnosis: string\n nextShotInstruction: string\n shouldContinue: boolean\n confidence: number\n }>(request, {\n ...options.llm,\n signal,\n idempotencyKey: callId,\n }),\n receipt: ({ result }) => costReceiptFromLlm(result),\n receiptFromError: costReceiptFromLlmError,\n })\n receipt = paid.receipt\n if (!paid.succeeded) throw paid.error\n const { value } = paid.value\n\n return {\n shot: input.shot,\n observations: String(value.observations ?? softFail.observations),\n diagnosis: String(value.diagnosis ?? softFail.diagnosis),\n nextShotInstruction: String(value.nextShotInstruction ?? softFail.nextShotInstruction),\n shouldContinue: Boolean(value.shouldContinue),\n confidence: Math.max(0, Math.min(1, Number(value.confidence ?? softFail.confidence))),\n costUsd: paid.receipt.costUnknown ? null : paid.receipt.costUsd,\n durationMs: Date.now() - start,\n available: true,\n }\n } catch (err) {\n return {\n shot: input.shot,\n observations: softFail.observations,\n diagnosis: softFail.diagnosis,\n nextShotInstruction: softFail.nextShotInstruction,\n shouldContinue: softFail.shouldContinue,\n confidence: softFail.confidence,\n costUsd: receipt && !receipt.costUnknown ? receipt.costUsd : null,\n durationMs: Date.now() - start,\n available: false,\n error: err instanceof Error ? err.message : String(err),\n }\n }\n }\n}\n","import { gzipSync } from 'node:zlib'\nimport { ValidationError } from './errors'\nimport { type RunRecord, runTaskScore } from './run-record'\n\n/**\n * DescriptionLengthGate — a Minimum-Description-Length promotion gate, the\n * Builder/Breaker acceptance rule from Wang & Buehler, \"Self-Revising Discovery\n * Systems for Science\" (arXiv:2606.01444, MIT LAMM), eq. 5:\n *\n * L(M, D) = L_model(M) + L_data(D | M)\n * accept M' over M iff L(M', D∪E) < L(M, D∪E)\n *\n * Both candidate and baseline are scored on the SAME enlarged evidence set\n * (every accumulated task — NOT just the held-out split), and the candidate is\n * accepted only if it lowers the TOTAL bit cost. This is the gate's whole\n * point and what distinguishes it from a monotone held-out delta:\n *\n * - L_model(M) — the candidate's own description length: the compressed size\n * of its model text (a prompt, skill, profile, or symbolic model). A bigger\n * model pays more bits.\n * - L_data(D|M) — the residual: bits of \"surprise\" that the model did not\n * simply succeed, −Σ_i log2(s_i) over the model's per-task score s_i.\n * Perfect scores cost 0 bits; failure costs a lot (capped, not infinite).\n *\n * A candidate that merely memorizes new counterexamples grows L_model faster\n * than it shrinks L_data and LOSES — a principled, complexity-penalized\n * alternative to HeldOutGate's held-out paired delta. Use this gate\n * when the model text whose size you want to penalize is available; use\n * HeldOutGate when promotion should turn on held-out generalization with an\n * overfit-gap check instead.\n *\n * Scale / calibration: a gzip'd prose model is hundreds–thousands of bits;\n * a single task contributes at most −log2(scoreFloor) data bits (≈10). So with\n * little evidence the model term dominates and the gate is conservative about\n * model GROWTH — it promotes a larger model only once accumulated evidence\n * genuinely pays for the added bits (exactly the paper's regime, where D∪E\n * grows). `lambda` is the lever: λ<1 discounts model bits (more permissive),\n * λ>1 is stricter. A shrinking-or-equal model that does no worse always wins.\n *\n * Stateless: construct once with the description-length budget, call\n * `evaluate` per (candidate, baseline) pair.\n */\n\nexport type DescriptionLengthRejectionCode =\n | 'few_tasks'\n | 'missing_task_scores'\n | 'no_total_gain'\n | 'model_bloat'\n\nexport interface DescriptionLengthConfig {\n /** Stable label of the baseline. Required — paper-grade evaluation never\n * compares two unlabelled candidates. */\n baselineKey: string\n /** Weight on model bits relative to data bits (the description-length\n * budget λ). 1 = bits are bits. >1 = more complexity-averse. Default 1. */\n lambda?: number\n /** The candidate must beat the baseline by at least this many bits to\n * promote — a robustness margin against measurement noise. Default 0\n * (strict `<`, as the paper). */\n marginBits?: number\n /** Per-task score floor for the residual code: −log2(max(s, floor)). Caps a\n * total-failure task's surprise instead of letting it diverge. Default\n * 2^-10 (a failed task costs 10 bits, not ∞). */\n scoreFloor?: number\n /** Minimum number of shared (candidate, baseline) tasks before the gate will\n * consider promoting. Default 3. */\n minTasks?: number\n}\n\nexport interface DescriptionLengthEvidence {\n /** Shared tasks scored on both sides (the enlarged evidence D∪E). */\n tasks: number\n /** Compressed-model bits — L_model. */\n modelBits: { candidate: number; baseline: number }\n /** Residual surprise bits — L_data(D|M). */\n dataBits: { candidate: number; baseline: number }\n /** λ·L_model + L_data — the quantity the gate minimizes. */\n totalBits: { candidate: number; baseline: number }\n /** candidate − baseline total. Negative = candidate compresses better. */\n deltaBits: number\n /** Per-component deltas, for audit: did the win come from a smaller model,\n * better outcomes, or both? */\n modelBitsDelta: number\n dataBitsDelta: number\n}\n\nexport interface DescriptionLengthDecision {\n promote: boolean\n candidateId: string\n baselineId: string\n evidence: DescriptionLengthEvidence\n reason: string\n rejectionCode: DescriptionLengthRejectionCode | null\n}\n\nexport interface DescriptionLengthCandidate {\n /** The model text whose size is L_model (a prompt, skill, profile, or\n * symbolic model; concatenated if several files). */\n content: string\n /** Runs whose per-task scores form L_data. */\n runs: RunRecord[]\n}\n\n/** Return the canonical task-quality score, if the run carries one. */\nfunction runScore(run: RunRecord): number | undefined {\n // Ungated. KNOWN HOLE: the residual is -log2(s), so a gated run claiming\n // s=1.0 contributes zero surprise bits — the largest possible improvement to\n // L_data. Excluding gated runs from this gate is a promotion-policy change,\n // tracked separately from this correctness fix.\n return runTaskScore(run)\n}\n\n/** Pairing key — the same scenario/experiment identity HeldOutGate pairs on. */\nfunction taskKey(run: RunRecord): string {\n return run.scenarioId\n}\n\ninterface ArmTaskScores {\n dealt: Set<string>\n answered: Map<string, number>\n}\n\n/** Tasks one arm was dealt and the mean score for each task it answered. */\nfunction perTaskMeanScore(runs: RunRecord[]): ArmTaskScores {\n const dealt = new Set<string>()\n const acc = new Map<string, { sum: number; n: number }>()\n for (const run of runs) {\n const key = taskKey(run)\n dealt.add(key)\n const s = runScore(run)\n if (s === undefined) continue\n const cur = acc.get(key) ?? { sum: 0, n: 0 }\n cur.sum += s\n cur.n += 1\n acc.set(key, cur)\n }\n return {\n dealt,\n answered: new Map([...acc].map(([key, value]) => [key, value.sum / value.n])),\n }\n}\n\n/** Compressed-model bits — the model's description length L_model. gzip is a\n * deterministic, dependency-free stand-in for Kolmogorov complexity; it\n * rewards genuine compactness and penalizes boilerplate padding. */\nexport function modelDescriptionBits(content: string): number {\n return gzipSync(Buffer.from(content, 'utf8')).byteLength * 8\n}\n\n/** Residual surprise L_data(D|M) = −Σ_i log2(max(s_i, floor)) over the given\n * per-task scores. Lower = the model more reliably succeeds. */\nexport function dataDescriptionBits(\n scoreByTask: Map<string, number>,\n keys: Iterable<string>,\n scoreFloor: number,\n): number {\n let bits = 0\n for (const key of keys) {\n const s = scoreByTask.get(key)\n if (s === undefined) {\n throw new ValidationError(`dataDescriptionBits: no score for task '${key}'`)\n }\n bits += -Math.log2(Math.max(s, scoreFloor))\n }\n return bits\n}\n\nexport class DescriptionLengthGate {\n private readonly baselineKey: string\n private readonly lambda: number\n private readonly marginBits: number\n private readonly scoreFloor: number\n private readonly minTasks: number\n\n constructor(config: DescriptionLengthConfig) {\n if (!config.baselineKey) throw new Error('DescriptionLengthGate: baselineKey is required')\n this.baselineKey = config.baselineKey\n this.lambda = config.lambda ?? 1\n this.marginBits = config.marginBits ?? 0\n this.scoreFloor = config.scoreFloor ?? 2 ** -10\n this.minTasks = config.minTasks ?? 3\n if (!(this.lambda >= 0)) throw new Error('DescriptionLengthGate: lambda must be ≥ 0')\n if (!(this.scoreFloor > 0 && this.scoreFloor < 1))\n throw new Error('DescriptionLengthGate: scoreFloor must be in (0,1)')\n }\n\n /** Decide whether `candidate` should replace `baseline`. Both are scored on\n * the shared task set (the enlarged evidence); the candidate promotes only\n * if λ·L_model + L_data is strictly lower by at least `marginBits`. */\n evaluate(\n candidate: DescriptionLengthCandidate,\n baseline: DescriptionLengthCandidate,\n ): DescriptionLengthDecision {\n const candidateId = inferCandidateId(candidate.runs, this.baselineKey)\n const candidateTasks = perTaskMeanScore(candidate.runs)\n const baselineTasks = perTaskMeanScore(baseline.runs)\n const candScores = candidateTasks.answered\n const baseScores = baselineTasks.answered\n const dealt = [...new Set([...candidateTasks.dealt, ...baselineTasks.dealt])].sort()\n const shared = dealt.filter((key) => candScores.has(key) && baseScores.has(key))\n const candidateMissing = dealt.filter((key) => !candScores.has(key))\n const baselineMissing = dealt.filter((key) => !baseScores.has(key))\n\n const modelBits = {\n candidate: this.lambda * modelDescriptionBits(candidate.content),\n baseline: this.lambda * modelDescriptionBits(baseline.content),\n }\n const dataBits = {\n candidate: dataDescriptionBits(candScores, shared, this.scoreFloor),\n baseline: dataDescriptionBits(baseScores, shared, this.scoreFloor),\n }\n const totalBits = {\n candidate: modelBits.candidate + dataBits.candidate,\n baseline: modelBits.baseline + dataBits.baseline,\n }\n const evidence: DescriptionLengthEvidence = {\n tasks: shared.length,\n modelBits,\n dataBits,\n totalBits,\n deltaBits: totalBits.candidate - totalBits.baseline,\n modelBitsDelta: modelBits.candidate - modelBits.baseline,\n dataBitsDelta: dataBits.candidate - dataBits.baseline,\n }\n const base = { candidateId, baselineId: this.baselineKey, evidence }\n const fmt = (n: number) => n.toFixed(1)\n\n if (shared.length < this.minTasks) {\n return {\n ...base,\n promote: false,\n reason: `few_tasks: ${shared.length} shared task(s) < min ${this.minTasks}`,\n rejectionCode: 'few_tasks',\n }\n }\n if (candidateMissing.length > 0 || baselineMissing.length > 0) {\n const missing = [\n candidateMissing.length > 0\n ? `candidate answered ${candScores.size}/${dealt.length}, ${candidateMissing.length} missing: ${formatTaskIds(candidateMissing)}`\n : null,\n baselineMissing.length > 0\n ? `baseline answered ${baseScores.size}/${dealt.length}, ${baselineMissing.length} missing: ${formatTaskIds(baselineMissing)}`\n : null,\n ].filter((part): part is string => part !== null)\n return {\n ...base,\n promote: false,\n reason:\n `missing_task_scores: ${missing.join('; ')}. ` +\n `The decision cannot use only the ${shared.length} task(s) both arms answered`,\n rejectionCode: 'missing_task_scores',\n }\n }\n if (!(evidence.deltaBits < -this.marginBits)) {\n // No net compression. Name the cause: did the model bloat eat a real\n // data gain, or was there no data gain at all?\n const code: DescriptionLengthRejectionCode =\n evidence.dataBitsDelta < 0 ? 'model_bloat' : 'no_total_gain'\n const why =\n code === 'model_bloat'\n ? `model grew ${fmt(evidence.modelBitsDelta)} bits, outpacing a ${fmt(-evidence.dataBitsDelta)}-bit data gain`\n : `outcomes did not improve (data Δ=${fmt(evidence.dataBitsDelta)} bits)`\n return {\n ...base,\n promote: false,\n reason: `${code}: total Δ=${fmt(evidence.deltaBits)} bits does not clear the ${fmt(this.marginBits)}-bit margin — ${why}`,\n rejectionCode: code,\n }\n }\n return {\n ...base,\n promote: true,\n reason: `promote: total Δ=${fmt(evidence.deltaBits)} bits (model Δ=${fmt(evidence.modelBitsDelta)}, data Δ=${fmt(evidence.dataBitsDelta)}) over ${shared.length} tasks`,\n rejectionCode: null,\n }\n }\n}\n\nfunction formatTaskIds(ids: string[]): string {\n const shown = ids.slice(0, 5)\n const remaining = ids.length - shown.length\n return remaining > 0 ? `${shown.join(', ')}, +${remaining} more` : shown.join(', ')\n}\n\nfunction inferCandidateId(runs: RunRecord[], baselineKey: string): string {\n for (const run of runs)\n if (run.candidateId && run.candidateId !== baselineKey) return run.candidateId\n return runs[0]?.candidateId ?? '(unknown candidate)'\n}\n","/**\n * Walk a personas directory and return every file matching the convention\n * `NN-slug.{yaml,yml,json,md}`. Sorted by filename so the numeric prefix\n * gives stable persona ordering for reproducibility. Consumers filter\n * through `include` / `exclude`.\n */\n\nimport { promises as fs } from 'node:fs'\nimport { basename, extname, join } from 'node:path'\n\nexport interface DiscoverPersonasOptions {\n /**\n * Regex applied to filenames. Files that don't match are skipped.\n * Default: `^[0-9]{2}-.+\\.(yaml|yml|json|md)$`.\n */\n pattern?: RegExp\n /**\n * Filenames (or basenames) to skip. Use this to exclude WIP / archived\n * personas without removing the file.\n */\n exclude?: readonly string[]\n /**\n * If set, return only personas whose basename contains one of these\n * substrings (post-pattern filter).\n */\n include?: readonly string[]\n /** Recurse into subdirectories. Default false. */\n recursive?: boolean\n}\n\nexport interface DiscoveredPersona {\n /** Absolute file path. */\n path: string\n /** Filename without directory. */\n filename: string\n /** Filename without extension — the conventional persona id. */\n id: string\n}\n\nconst DEFAULT_PATTERN = /^\\d{2}-.+\\.(yaml|yml|json|md)$/\n\nexport async function discoverPersonas(\n dir: string,\n opts: DiscoverPersonasOptions = {},\n): Promise<DiscoveredPersona[]> {\n const pattern = opts.pattern ?? DEFAULT_PATTERN\n const exclude = new Set(opts.exclude ?? [])\n const include = opts.include\n\n async function walk(d: string): Promise<DiscoveredPersona[]> {\n let entries: Array<{ name: string; isDir: boolean }>\n try {\n const raw = await fs.readdir(d, { withFileTypes: true })\n entries = raw.map((e) => ({ name: e.name, isDir: e.isDirectory() }))\n } catch (err) {\n const code = (err as NodeJS.ErrnoException).code\n if (code === 'ENOENT') return []\n throw err\n }\n const out: DiscoveredPersona[] = []\n for (const entry of entries) {\n const full = join(d, entry.name)\n if (entry.isDir) {\n if (opts.recursive) out.push(...(await walk(full)))\n continue\n }\n if (!pattern.test(entry.name)) continue\n if (exclude.has(entry.name) || exclude.has(basename(entry.name, extname(entry.name))))\n continue\n if (include && include.length > 0) {\n const id = basename(entry.name, extname(entry.name))\n const matched = include.some((needle) => entry.name.includes(needle) || id.includes(needle))\n if (!matched) continue\n }\n out.push({\n path: full,\n filename: entry.name,\n id: basename(entry.name, extname(entry.name)),\n })\n }\n return out\n }\n\n const results = await walk(dir)\n results.sort((a, b) => a.filename.localeCompare(b.filename))\n return results\n}\n","/**\n * GoldenMatcher — fuzzy matcher for \"did the agent produce the expected things?\".\n *\n * Universal primitive across agent-eval consumers. Use it for:\n * - Test suites: did the run hit the expected assertions?\n * - Tool agents: did the agent emit the expected tool call sequence?\n * - Judges: did the verdict include the expected concepts?\n * - Design audits: did the auditor surface the planted defects?\n *\n * Match rule (per golden):\n * - Any phrase in `golden.any` (case-insensitive substring) appears in the\n * candidate's text fields, OR\n * - Any pattern in `golden.anyRegex` (case-insensitive) matches.\n *\n * Recall is severity-weighted by default: critical=3, major=2, minor=1.\n * Missing one critical hurts more than missing three minors.\n */\n\nexport type GoldenSeverity = 'critical' | 'major' | 'minor'\n\nexport interface GoldenSpec {\n /** Stable identifier — survives across runs so consumers can grep by id. */\n id: string\n /** Severity drives recall weighting. */\n severity: GoldenSeverity\n /**\n * Substring phrases (case-insensitive). A hit on ANY phrase counts as a\n * match. Keep these SHORT (3-6 words) and SPECIFIC.\n */\n any: string[]\n /** Optional regex patterns. ORed with `any`. */\n anyRegex?: string[]\n /** Free-form note — surfaces in reports for humans. */\n hint?: string\n /** Optional category for grouping/filtering. */\n category?: string\n}\n\nexport interface MatchResult {\n /** Same length as goldens; `true` when matched. */\n matches: boolean[]\n /** Convenience: count of hits. */\n hits: number\n /** Convenience: total goldens. */\n total: number\n}\n\n/**\n * Match each golden against `candidates`, where each candidate exposes one or\n * more text fields the matcher should search. Defaults to searching all\n * string-typed fields concatenated.\n */\nexport function matchGoldens<T>(\n goldens: GoldenSpec[],\n candidates: T[],\n options: {\n /**\n * Extract the searchable text for a candidate. Default: concatenate every\n * top-level string field with a space.\n */\n text?: (candidate: T) => string\n } = {},\n): MatchResult {\n const extract = options.text ?? defaultExtract\n const haystacks = candidates.map((c) => extract(c).toLowerCase())\n const matches = goldens.map((golden) => goldenMatched(golden, haystacks))\n return {\n matches,\n hits: matches.filter(Boolean).length,\n total: goldens.length,\n }\n}\n\nfunction defaultExtract(candidate: unknown): string {\n if (typeof candidate === 'string') return candidate\n if (candidate && typeof candidate === 'object') {\n const parts: string[] = []\n for (const v of Object.values(candidate as Record<string, unknown>)) {\n if (typeof v === 'string') parts.push(v)\n }\n return parts.join(' ')\n }\n return String(candidate ?? '')\n}\n\nfunction goldenMatched(golden: GoldenSpec, haystacks: string[]): boolean {\n for (const phrase of golden.any) {\n const needle = phrase.toLowerCase().trim()\n if (!needle) continue\n if (haystacks.some((h) => h.includes(needle))) return true\n }\n for (const pattern of golden.anyRegex ?? []) {\n let re: RegExp\n try {\n re = new RegExp(pattern, 'i')\n } catch {\n continue\n }\n if (haystacks.some((h) => re.test(h))) return true\n }\n return false\n}\n\n/** Severity weights — exposed so consumers can override (rare). */\nexport const DEFAULT_SEVERITY_WEIGHTS: Record<GoldenSeverity, number> = {\n critical: 3,\n major: 2,\n minor: 1,\n}\n\n/** Severity-weighted recall over a MatchResult + the goldens that produced it. */\nexport function weightedRecall(\n goldens: GoldenSpec[],\n result: MatchResult,\n weights: Record<GoldenSeverity, number> = DEFAULT_SEVERITY_WEIGHTS,\n): number {\n if (goldens.length === 0) return 1\n const total = goldens.reduce((s, g) => s + (weights[g.severity] ?? 1), 0)\n if (total === 0) return 1\n const hit = goldens.reduce(\n (s, g, i) => s + (result.matches[i] ? (weights[g.severity] ?? 1) : 0),\n 0,\n )\n return hit / total\n}\n\n/**\n * Precision proxy: fraction of emitted candidates that match SOME golden.\n *\n * No human-labelled negatives means unmatched candidates are SOFT false\n * positives — punishes verbose agents that pad with filler. Doesn't punish\n * unknown-but-real findings; the way to tighten this is to grow the golden\n * set, not to invent a stricter score.\n */\nexport function precision<T>(\n goldens: GoldenSpec[],\n candidates: T[],\n options: { text?: (candidate: T) => string } = {},\n): number {\n if (candidates.length === 0) return 1\n const extract = options.text ?? defaultExtract\n let matched = 0\n for (const cand of candidates) {\n const haystack = extract(cand).toLowerCase()\n const matchedAny = goldens.some(\n (g) =>\n g.any.some((phrase) => phrase.length > 0 && haystack.includes(phrase.toLowerCase())) ||\n (g.anyRegex ?? []).some((pat) => {\n try {\n return new RegExp(pat, 'i').test(haystack)\n } catch {\n return false\n }\n }),\n )\n if (matchedAny) matched++\n }\n return matched / candidates.length\n}\n","/**\n * HeldOutGate — first-class held-out paired-delta promotion gate.\n *\n * Encodes the \"honesty override\" pattern that lived inline in\n * `~/webb/redteam/scripts/agent-eval-autoresearch.ts:138–171`.\n * The optimizer's best-guess is one thing; what we should actually\n * ship is another. The gate is the line between them.\n *\n * A candidate is promoted iff ALL FOUR pass:\n *\n * 0. **Coverage**: on BOTH splits, the fraction of DEALT work items that\n * carry a real score on BOTH arms is at least `minCoverage`\n * (default 1 — all of them). See \"Missing scores are missing data\".\n * 1. **Productive runs**: the candidate has at least\n * `minProductiveRuns` paired observations on items where BOTH\n * candidate and baseline produced a real (non-silent) score.\n * 2. **Paired delta**: the lower bound of the CI on the per-item\n * holdout delta (candidate − baseline) is strictly greater than\n * `pairedDeltaThreshold`. WHICH paired statistic carries that CI\n * depends on the outcome's shape — see \"Choosing the statistic\".\n * 3. **Overfit gap**: the candidate's gap between search-split\n * score and holdout-split score is no worse (more positive)\n * than the baseline's gap by more than `overfitGapThreshold`.\n * \"Better on search, worse on holdout\" is the canonical\n * overfit pattern; this catches it.\n *\n * ## Missing scores are missing data\n *\n * Gates 1-3 all read numbers off the items where BOTH arms produced a finite\n * score. Without gate 0 that set is a SILENT FILTER: an item the candidate\n * crashed on, timed out on, or never wrote a row for simply left the\n * comparison, and the verdict was computed over whatever survived. Measured on\n * the pre-0.134 gate: 26 held-out items, a candidate that produced no score at\n * all on 20 of them, promoted at every threshold from −0.05 to +0.30 on the 6\n * it answered (`unpairedBaselineRuns: 20` sat in the evidence, read by\n * nothing); the control — the same 20 failures scored as the 0 they earned —\n * was correctly refused at a mean paired delta of −0.3808. An agent that fails\n * 77% of its tasks was promoted, and every guarantee gates 1-3 provide sat\n * behind that filter.\n *\n * The gate does NOT impute a value for those items. It cannot: it does not know\n * the failure value of the caller's metric (0 on [0,1]? 0 on 0-100? a\n * lower-is-better latency?), and guessing one is exactly the silent assumption\n * this gate exists to remove. A caller who DOES know it writes it onto the\n * record before calling — that is the caller's decision to make and to be\n * accountable for, and it then travels in the run corpus where an auditor can\n * see it. What the gate does instead is REFUSE, and report the full coverage\n * accounting (`GateEvidence.holdoutCoverage` / `searchCoverage`) so the caller\n * can see exactly which items went dark and on which arm.\n *\n * The denominator is MEASURED, never assumed: it is the set of work items the\n * comparison was DEALT, which is what `pairRunRecords` reports when it is given\n * every row of a split rather than only the scored ones. There is no list of\n * \"expected\" scenarios to keep in sync and nothing to trust — an item counts as\n * dealt because a row for it exists on at least one arm.\n *\n * ## Choosing the statistic\n *\n * The median paired delta is the robust default, but it goes BLIND wherever\n * ties dominate: with more than half the pairs tied its sample value is exactly\n * 0 whatever the shift on the rest, and the whole bootstrap CI collapses to\n * [0, 0]. `low > threshold` is then \"no\" forever at a non-negative threshold\n * and \"yes\" forever at a negative one — the gate refuses real gains AND\n * promotes real regressions. Measured: 76 held-out items with 15 candidate\n * wins, 5 candidate losses and 56 ties is a real +13.2pp lift whose median\n * paired delta is 0; the median-CI gate refused it at every non-negative\n * threshold while PROMOTING the mirror-image −13.2pp regression at any\n * negative one.\n *\n * So the statistic is picked by the shape of the data, in three cases:\n *\n * 1. **Two-point (pass/fail) outcomes on ANY encoding** — every value on both\n * arms is either 0 or one common positive level, so {0,1} and {0,100} and\n * {0,5} all qualify (see `pairedBinaryScale`). The estimand is the change in\n * success rate, rescaled into the caller's native units. Two statistics\n * answer about it and BOTH must agree before anything is promoted:\n * `pairedRiskDifferenceScore` (Tango's score interval) supplies the\n * interval, and McNemar's exact test — carried on\n * `pairedRiskDifferenceExact` — holds a veto at any non-negative threshold.\n * The score interval is the one that decides because it is valid at a\n * NONZERO margin, which is the only thing a noninferiority threshold asks\n * about; the exact test's own Clopper-Pearson interval is conditional on the\n * discordant count and is therefore a valid interval only at margin 0.\n * McNemar's b/c/p ship as evidence.\n * 2. **Everything else** — the bootstrap CI of the MEAN paired delta. The mean\n * is the estimator that answers the gate's own question (\"by how much did\n * the score move\") in the caller's units, and it is well defined on every\n * shape the median loses: tie-dominated vectors, low-cardinality lattices\n * (block scores in {⅔, 1} from averaging pass/fail leaves; integer 0-100\n * judge dimensions), and mixed arms. Measured: 26 blocks of 3 pass/fail\n * leaves carrying a real +12.8pp lift, only 23% of pairs tied, give a\n * median CI of [0, 0.333] — a lower bound of exactly 0 refuses a real lift\n * at threshold 0, which is the original bug one lattice over. There is\n * therefore no tie-fraction cutoff: any cutoff leaves the lattice case open\n * on the far side of it. `heldoutSignificance` has defaulted to the mean\n * since #316 for the same reason.\n *\n * Set `deltaStatistic: 'median'` to force the median on every input — the\n * pre-0.134 behaviour, kept for callers who want outlier robustness and accept\n * the blindness that comes with it.\n *\n * ## Fail closed\n *\n * A ZERO-WIDTH CI carries no information about how far the estimate could be\n * wrong, wherever it sits. At [0, 0] it cannot tell a gain from a regression\n * and it clears every negative threshold. Away from zero it fails the opposite\n * way: n identical positive deltas give [g, g], which clears threshold 0 on no\n * spread at all. Both are an absence of evidence, so the gate refuses with\n * `indeterminate_delta` rather than answering \"promote\".\n *\n * The decision carries a machine-readable `rejectionCode` plus an\n * `evidence` block with every number the gate looked at, so the\n * downstream researcher / paper / dashboard can re-derive the\n * verdict without re-running.\n *\n * See also:\n * - `src/statistics.ts` for `pairedBootstrap` + `wilcoxonSignedRank`, and\n * `pairedRiskDifferenceScore` / `pairedRiskDifferenceExact` (+\n * `pairedBinaryScale`) for the binary path\n * - `src/run-record.ts` for the input row schema\n * - `src/reference-replay.ts` for the older, reference-replay-\n * specific promotion path (still useful for replay-style evals).\n */\n\nimport { pairRunRecords } from './paired-arms'\nimport { minimumPairsForPairedDeltaTest } from './paired-delta-test'\nimport {\n decidePairedPromotion,\n type PairedDecisionShape,\n type PairedDecisionStatistic,\n pairedDecisionShape,\n} from './paired-promotion-decision'\nimport { isRealnessGated, observedSplitScore, type ScorePreference } from './rollout/reward'\nimport type { RunRecord } from './run-record'\nimport { wilcoxonSignedRank } from './statistics'\n\nexport type HeldOutGateRejectionCode =\n | 'few_runs'\n | 'incomplete_coverage'\n | 'missing_split_scores'\n | 'missing_cost'\n | 'negative_delta'\n | 'indeterminate_delta'\n | 'overfit_gap'\n | 'cost_ceiling'\n\n/**\n * How much of one split's DEALT work the comparison actually measured.\n *\n * `answered + unscoredPairs + candidateOnly + baselineOnly === dealt` — a\n * complete, mutually exclusive partition of the item slots the split was dealt,\n * so nothing can leave the comparison without appearing in exactly one bucket.\n */\nexport interface SplitCoverage {\n /** Work items the split was dealt: every item with a row on either arm. */\n dealt: number\n /** Dealt items carrying a finite score on BOTH arms — the only ones any\n * paired statistic can read. */\n answered: number\n /** Dealt items with a row on both arms where at least one row carried no\n * finite score: a run happened and produced nothing (crash, timeout, judge\n * failure). Measured absence, not an absent item. */\n unscoredPairs: number\n /** Dealt items only the candidate produced a row for. */\n candidateOnly: number\n /** Dealt items only the baseline produced a row for. */\n baselineOnly: number\n /** `answered / dealt`, or 0 when nothing was dealt. 1 means every dealt item\n * was scored on both arms. */\n coverage: number\n}\n\nexport interface HeldOutGateConfig {\n /** Minimum number of paired (candidate, baseline) holdout observations\n * required before promotion. The exact small-sample test may require more\n * observations at the selected confidence. */\n minProductiveRuns?: number\n /** The CI lower bound on the paired holdout delta must exceed this to\n * promote. Read in the same units as the holdout scores: with binary\n * (0/1) outcomes that is a change in success RATE (0.05 = +5pp).\n * Default 0. */\n pairedDeltaThreshold?: number\n /**\n * Which paired statistic carries the promotion CI.\n *\n * `'auto'` (default) picks by outcome shape — two-point outcomes on the exact\n * paired risk difference, everything else on the mean bootstrap (see the\n * module header). `'median'` forces the median bootstrap on every input,\n * including shapes where it is structurally blind and will refuse a real lift\n * and accept a real regression. Set it for outlier robustness on genuinely\n * continuous outcomes, or to reproduce a pre-0.134 verdict.\n */\n deltaStatistic?: 'auto' | 'median'\n /** Maximum allowed worsening of (search − holdout) gap relative to\n * baseline. Default 0.15 (i.e. candidate may overfit by up to 15\n * absolute score points more than baseline before rejection). */\n overfitGapThreshold?: number\n /** Stable label of the baseline candidate. Required — paper-grade\n * evaluation never compares two unlabelled candidates. */\n baselineKey: string\n /** Confidence level for the bootstrap CI. Default 0.95. */\n confidence?: number\n /** Bootstrap resamples. Default 2000. */\n bootstrapResamples?: number\n /** Optional deterministic seed for the bootstrap. Default undefined\n * (Math.random). */\n seed?: number\n /**\n * Smallest acceptable `answered / dealt` fraction, required on BOTH splits.\n * Default 1: every work item the comparison was dealt must carry a real score\n * on both arms before the gate will decide anything.\n *\n * The default is 1 because a missing score is missing data, and a promotion\n * computed over \"the items that happened to answer\" is a promotion computed\n * over a set the candidate selected by failing (see the module header). One\n * split below `minCoverage` rejects with `incomplete_coverage`.\n *\n * Lowering it is a real, defensible choice for a caller who accepts a known\n * flake rate — but it must be DECLARED, not inherited: the shrunken\n * denominator then still ships in `GateEvidence.holdoutCoverage` /\n * `searchCoverage`, so the verdict can never be read without it. Must be in\n * [0, 1]; anything else throws rather than clamping.\n */\n minCoverage?: number\n /**\n * Hard ceiling on the candidate's median per-task USD cost. When the\n * candidate clears the quality gates (paired-delta + overfit-gap) but\n * its median cost exceeds this number, the gate rejects with\n * `cost_ceiling`. Default `undefined` = no cost ceiling, behaving\n * exactly like the pre-cost gate.\n *\n * This exists because \"we ship the better prompt\" is only an honest\n * pitch when the better prompt also fits a customer-stated budget.\n * Cost is read from `RunRecord.costUsd`; a null amount rejects a\n * configured cost check because the limit cannot be proven.\n */\n costPerTaskCeiling?: number\n}\n\n/** Which paired statistic a `HeldOutGate` verdict was decided on. One\n * definition, shared with every other gate that decides a paired interval. */\nexport type DeltaStatistic = PairedDecisionStatistic\n\nexport interface GateEvidence {\n /** Number of paired (candidate, baseline) holdout observations used. */\n productiveRuns: number\n /** Candidate holdout rows with no baseline row at the same work identity. */\n unpairedCandidateRuns: number\n /** Baseline holdout rows with no candidate row at the same work identity. */\n unpairedBaselineRuns: number\n /**\n * How much of the dealt HOLDOUT work carried a score on both arms — the\n * denominator behind `productiveRuns`, `medianPairedDelta`, `pairedCI` and\n * `holdoutScore`. A `coverage` below 1 means those numbers describe a\n * SUBSET of the items the comparison was dealt, and which items are in that\n * subset was decided by whichever arm went dark.\n */\n holdoutCoverage: SplitCoverage\n /**\n * The same accounting for the SEARCH split — the denominator behind\n * `searchScore`, and therefore behind both overfit gaps.\n */\n searchCoverage: SplitCoverage\n /** Median of paired holdout deltas, or null when there are no pairs.\n * ALWAYS the literal median — a diagnostic, not necessarily the statistic\n * the verdict keyed on (see `deltaStatistic` / `decidingDelta`). On binary\n * outcomes this is normally 0 by construction. */\n medianPairedDelta: number | null\n /** Which paired statistic the promotion CI was computed on, and therefore\n * what `decidingDelta` / `pairedCI` mean. `'median_bootstrap'` = bootstrap\n * CI on the median paired delta (continuous outcomes).\n * `'mean_bootstrap'` = bootstrap CI on the mean paired delta, used when ties\n * dominate and pin the median at 0. `'paired_risk_difference'` = change in\n * success rate on a two-point (pass/fail) outcome, on an EXACT conditional\n * interval dual to McNemar's exact test, rescaled to the outcome's native\n * units (so a 0-100 dimension reports points, not a rate). */\n deltaStatistic: DeltaStatistic\n /** Point estimate of `deltaStatistic` — the number the `pairedDeltaThreshold`\n * check is about. Null when no CI was computed. */\n decidingDelta: number | null\n /** CI on `deltaStatistic`, if computed. The gate promotes iff\n * `pairedCI.low > pairedDeltaThreshold`. */\n pairedCI: { low: number; high: number } | null\n /** Wilcoxon signed-rank p-value, if computed. Always the Wilcoxon, on both\n * paths, so this field never changes meaning. */\n pairedPValue: number | null\n /** McNemar's exact paired-binary test on the holdout pairs, or null when the\n * outcomes were not two-point (or no CI was computed). `b` = candidate-only\n * wins, `c` = baseline-only wins; only these discordant pairs carry signal.\n * When present it is not merely reported: the promotion interval is dual to\n * this p-value, so a promotion at a non-negative threshold implies\n * `pValue < 1 − confidence`. */\n mcnemar: { b: number; c: number; nDiscordant: number; pValue: number } | null\n /** The common positive level of a two-point outcome — 1 for {0,1}, 100 for a\n * 0-100 pass/fail dimension — or null when the outcome is not two-point.\n * Non-null is exactly the condition for the `paired_risk_difference` path,\n * and it is the factor `decidingDelta` / `pairedCI` were rescaled by. */\n binaryScale: number | null\n /** Fraction of paired holdout deltas that are exact ties, or null when there\n * are no pairs. At or above 0.5 the median paired delta is pinned at 0 by\n * construction; this is the diagnostic for why a median-decided verdict\n * (`deltaStatistic: 'median'`) saw nothing. */\n tieFraction: number | null\n /** Mean candidate score on the search split, or null when absent. */\n searchScore: number | null\n /** Mean candidate score on the holdout split, or null when absent. */\n holdoutScore: number | null\n /** Candidate (search − holdout) gap, or null when either side is absent. */\n overfitGap: number | null\n /** Baseline (search − holdout) gap, or null when either side is absent. */\n baselineOverfitGap: number | null\n /** Median per-task USD cost across the candidate's runs. Recorded\n * even when no `costPerTaskCeiling` is configured so downstream\n * dashboards (intelligence.tangle.tools) can render \\$/task per\n * generation regardless of gating policy. */\n medianCandidateCost: number | null\n /** Median per-task USD cost across the baseline runs, for\n * symmetric reporting. */\n medianBaselineCost: number | null\n /**\n * Runs (candidate + baseline) dropped before pairing because the\n * authenticity gate flagged them as gamed. Surfaced rather than silent: a\n * promotion decision computed over a shrunken pool has to say by how much,\n * and a nonzero count here is itself the finding.\n */\n realnessGatedRuns: number\n}\n\nexport interface GateDecision {\n /** Final promote/no-promote verdict. */\n promote: boolean\n /** The candidate that was evaluated. */\n candidateId: string\n /** The baseline it was compared against. */\n baselineId: string\n /** Every number the gate looked at, for audit + paper export. */\n evidence: GateEvidence\n /** Human-readable reason. */\n reason: string\n /** Machine-readable rejection code, or null on promote. */\n rejectionCode: HeldOutGateRejectionCode | null\n}\n\n/**\n * Held-out paired-delta promotion gate. Construct once with config,\n * call `evaluate(candidateRuns, baselineRuns)` per (candidate,\n * baseline) pair. Stateless across calls.\n */\nexport class HeldOutGate {\n private readonly minProductiveRuns: number\n private readonly pairedDeltaThreshold: number\n private readonly overfitGapThreshold: number\n private readonly baselineKey: string\n private readonly confidence: number\n private readonly resamples: number\n private readonly seed?: number\n private readonly costPerTaskCeiling?: number\n private readonly minCoverage: number\n private readonly deltaStatistic: 'auto' | 'median'\n\n constructor(config: HeldOutGateConfig) {\n if (!config.baselineKey) {\n throw new Error('HeldOutGate: baselineKey is required')\n }\n if (\n config.minCoverage !== undefined &&\n !(Number.isFinite(config.minCoverage) && config.minCoverage >= 0 && config.minCoverage <= 1)\n ) {\n throw new Error(\n `HeldOutGate: minCoverage must be a finite fraction in [0, 1], got ${config.minCoverage}`,\n )\n }\n this.minCoverage = config.minCoverage ?? 1\n this.confidence = config.confidence ?? 0.95\n this.minProductiveRuns = Math.max(\n config.minProductiveRuns ?? 3,\n minimumPairsForPairedDeltaTest(this.confidence),\n )\n this.pairedDeltaThreshold = config.pairedDeltaThreshold ?? 0\n this.overfitGapThreshold = config.overfitGapThreshold ?? 0.15\n this.baselineKey = config.baselineKey\n this.resamples = config.bootstrapResamples ?? 2000\n this.seed = config.seed\n this.deltaStatistic = config.deltaStatistic ?? 'auto'\n if (\n config.costPerTaskCeiling !== undefined &&\n !(Number.isFinite(config.costPerTaskCeiling) && config.costPerTaskCeiling > 0)\n ) {\n throw new Error('HeldOutGate: costPerTaskCeiling must be a positive finite number')\n }\n this.costPerTaskCeiling = config.costPerTaskCeiling\n }\n\n /** Decide whether `candidate` should replace `baseline`.\n * Pairing is by `(experimentId, scenarioId, seed)`.\n * Missing or duplicate identities throw instead of comparing by position. */\n evaluate(candidate: RunRecord[], baseline: RunRecord[]): GateDecision {\n const candidateId = inferCandidateId(candidate, this.baselineKey)\n const baselineId = this.baselineKey\n assertScenarioIdentities([...candidate, ...baseline])\n\n // Runs flagged as gamed are dropped from BOTH sides before anything is\n // paired. This is a promotion decision, and the whole point of the\n // authenticity gate is that a faked success must not buy a promotion; the\n // count ships in the evidence so the shrunken pool is never invisible.\n const realnessGatedRuns = [...candidate, ...baseline].filter(isRealnessGated).length\n const honestCandidate = candidate.filter((run) => !isRealnessGated(run))\n const honestBaseline = baseline.filter((run) => !isRealnessGated(run))\n\n const candidateSearch = scoredRuns(honestCandidate, 'search')\n const baselineSearch = scoredRuns(honestBaseline, 'search')\n const candidateHoldout = scoredRuns(honestCandidate, 'holdout')\n const baselineHoldout = scoredRuns(honestBaseline, 'holdout')\n const searchPairing = pairRunRecords(baselineSearch, candidateSearch)\n const holdoutPairing = pairRunRecords(baselineHoldout, candidateHoldout)\n // The DEALT denominators, measured over every row of each split — scored or\n // not — so an item that produced no number is still counted as work the\n // comparison was given. `splitCoverage` re-pairs the unfiltered rows with\n // the same primitive the decision pairs with, which is the only way the\n // \"dealt\" set can be derived rather than assumed.\n const searchCoverage = splitCoverage(honestBaseline, honestCandidate, 'search')\n const holdoutCoverage = splitCoverage(honestBaseline, honestCandidate, 'holdout')\n // `scoredRuns` admits only rows whose split score is a finite number, so\n // the non-null assertion below cannot fire on data the pairing saw.\n const splitScoreOf = (run: RunRecord, split: ScorePreference): number =>\n observedSplitScore(run, split) as number\n const beforeSearch = searchPairing.pairs.map((pair) => splitScoreOf(pair.baseline, 'search'))\n const afterSearch = searchPairing.pairs.map((pair) => splitScoreOf(pair.treatment, 'search'))\n const beforeHoldout = holdoutPairing.pairs.map((pair) => splitScoreOf(pair.baseline, 'holdout'))\n const afterHoldout = holdoutPairing.pairs.map((pair) => splitScoreOf(pair.treatment, 'holdout'))\n\n const productiveRuns = beforeHoldout.length\n\n const candidateSearchMean = meanOrNull(afterSearch)\n const candidateHoldoutMean = meanOrNull(afterHoldout)\n const baselineSearchMean = meanOrNull(beforeSearch)\n const baselineHoldoutMean = meanOrNull(beforeHoldout)\n\n const overfitGap = diffOrNull(candidateSearchMean, candidateHoldoutMean)\n const baselineOverfitGap = diffOrNull(baselineSearchMean, baselineHoldoutMean)\n\n // Cost summary — surfaced in evidence regardless of gating policy so\n // downstream dashboards always know what the candidate cost.\n //\n // The population is the rows that DECIDED this verdict: the matched pairs\n // on both splits, and nothing else. Taking the median over every row the\n // caller happened to pass is a denominator nobody measured, and it is\n // trivially movable — 48 rows tagged `dev` at $0.0001, which the gate never\n // scores and the coverage check never counts, drag a real $5.00/task\n // candidate to a reported $0.0001 and clear a $1.00 ceiling. Deriving the\n // population from the pairing rather than from a list of split tags means\n // there is no tag to sit outside the rule: a row either decided the verdict\n // or it does not describe its cost.\n const medianCandidateCost = completeCostMedian([\n ...searchPairing.pairs.map((pair) => pair.treatment),\n ...holdoutPairing.pairs.map((pair) => pair.treatment),\n ])\n const medianBaselineCost = completeCostMedian([\n ...searchPairing.pairs.map((pair) => pair.baseline),\n ...holdoutPairing.pairs.map((pair) => pair.baseline),\n ])\n const commonEvidence = {\n productiveRuns,\n unpairedCandidateRuns: holdoutPairing.unpairedTreatment.length,\n unpairedBaselineRuns: holdoutPairing.unpairedBaseline.length,\n searchScore: candidateSearchMean,\n holdoutScore: candidateHoldoutMean,\n overfitGap,\n baselineOverfitGap,\n medianCandidateCost,\n medianBaselineCost,\n realnessGatedRuns,\n searchCoverage,\n holdoutCoverage,\n }\n /** Evidence for the early exits, where no CI was computed at all. The\n * statistic that WOULD have decided is still reported so a caller can see\n * which branch their data lands in without producing a verdict. */\n const earlyShape = this.chooseShape(beforeHoldout, afterHoldout)\n const noCiEvidence = {\n ...commonEvidence,\n medianPairedDelta: productiveRuns > 0 ? medianDelta(beforeHoldout, afterHoldout) : null,\n deltaStatistic: earlyShape.statistic,\n decidingDelta: null,\n pairedCI: null,\n pairedPValue: null,\n mcnemar: null,\n binaryScale: earlyShape.binaryScale,\n tieFraction: earlyShape.tieFraction,\n }\n\n const missingSplitScores = [\n candidateSearch.length === 0 ? 'candidate search' : null,\n candidateHoldout.length === 0 ? 'candidate holdout' : null,\n baselineSearch.length === 0 ? 'baseline search' : null,\n baselineHoldout.length === 0 ? 'baseline holdout' : null,\n ].filter((label): label is string => label !== null)\n if (missingSplitScores.length > 0) {\n return {\n promote: false,\n candidateId,\n baselineId,\n evidence: noCiEvidence,\n reason: `missing_split_scores: ${missingSplitScores.join(', ')} score evidence is absent`,\n rejectionCode: 'missing_split_scores',\n }\n }\n\n // COVERAGE — before every statistic, because every statistic below reads\n // only the items that answered. A candidate that went dark on most of its\n // work does not get judged on the remainder; missing scores are missing\n // data, and the gate refuses rather than shrinking the denominator to the\n // subset that happened to answer. Checked ahead of `few_runs` because \"6 of\n // 26 items produced no score\" is the finding, and \"6 paired observations\"\n // is only its shadow.\n const shortfalls = (\n [\n ['holdout', holdoutCoverage],\n ['search', searchCoverage],\n ] as const\n ).filter(([, cov]) => cov.coverage < this.minCoverage)\n if (shortfalls.length > 0) {\n return {\n promote: false,\n candidateId,\n baselineId,\n evidence: noCiEvidence,\n reason:\n `incomplete_coverage: ${shortfalls.map(([split, cov]) => describeCoverage(split, cov)).join('; ')}` +\n ` — required ${fmt(this.minCoverage)} of every dealt item scored on both arms.` +\n ' A missing score is missing data, not an absent item: the gate will not decide on the subset that answered',\n rejectionCode: 'incomplete_coverage',\n }\n }\n\n if (productiveRuns < this.minProductiveRuns) {\n return {\n promote: false,\n candidateId,\n baselineId,\n evidence: noCiEvidence,\n reason: `few_runs: ${productiveRuns} paired holdout observation(s) < min ${this.minProductiveRuns}`,\n rejectionCode: 'few_runs',\n }\n }\n if (overfitGap === null || baselineOverfitGap === null) {\n throw new Error('HeldOutGate: complete split scores did not produce overfit gaps')\n }\n\n // The paired holdout delta, decided by the one shared rule (see\n // `paired-promotion-decision.ts`): the estimator comes from the outcome's\n // shape, McNemar vetoes at a non-negative threshold, and a zero-width\n // interval is refused. `medianPairedDelta` stays the literal median on\n // EVERY path so the number that made the old gate blind remains visible.\n const decision = decidePairedPromotion(beforeHoldout, afterHoldout, {\n threshold: this.pairedDeltaThreshold,\n confidence: this.confidence,\n resamples: this.resamples,\n seed: this.seed,\n minPairs: this.minProductiveRuns,\n statistic: this.deltaStatistic === 'median' ? 'median' : 'mean',\n })\n const literalMedian = medianDelta(beforeHoldout, afterHoldout)\n const wilcoxon = wilcoxonSignedRank(beforeHoldout, afterHoldout)\n const { delta: decidingDelta, low, high, label: deltaLabel } = decision\n\n const evidence: GateEvidence = {\n ...commonEvidence,\n medianPairedDelta: literalMedian,\n deltaStatistic: decision.statistic,\n decidingDelta,\n pairedCI: { low, high },\n pairedPValue: wilcoxon.p,\n mcnemar: decision.mcnemar,\n binaryScale: decision.binaryScale,\n tieFraction: decision.tieFraction,\n }\n\n // FAIL CLOSED on a ZERO-WIDTH interval, wherever it sits. [0, 0] cannot\n // tell a gain from a regression and clears every negative threshold, which\n // is exactly how a tie-pinned median laundered a −13.2pp regression into a\n // promotion. But the same emptiness away from zero is just as false a\n // certainty and it fails the other way: n identical positive deltas give\n // [g, g], which clears threshold 0 with no spread to support it. Under a\n // bounded asymmetric null whose true mean paired delta is exactly 0 — 2 %\n // of pairs dropping by 1.0, the rest gaining 0.0204 — every sample that\n // misses the drop is exactly that shape, and a `low === 0 && high === 0`\n // test promotes 65.65 % of them at n = 20 against a nominal 5 %.\n if (decision.indeterminate) {\n return {\n promote: false,\n candidateId,\n baselineId,\n evidence,\n reason:\n `indeterminate_delta: ${decision.indeterminateCause}, so the paired holdout CI is ` +\n `[${fmt(low)}, ${fmt(high)}] and carries no direction — ` +\n `it cannot clear threshold ${fmt(this.pairedDeltaThreshold)} on evidence`,\n rejectionCode: 'indeterminate_delta',\n }\n }\n\n // The exact test is a VETO on the two-point path. Redundant by construction\n // — `pairedRiskDifferenceExact`'s interval is dual to this p-value, so\n // `low > 0` already implies `pValue < 1 − confidence` (verified over 8108\n // (b, c, ties, confidence) shapes) — and kept anyway so that swapping the\n // estimator for one without that duality (the Wald interval, which\n // undercovers on a handful of discordant pairs) cannot silently reintroduce\n // \"promotes what the exact test refuses\". Only applies at a non-negative\n // threshold: a negative threshold is a non-inferiority question, which\n // McNemar's test of \"no difference\" is not the right test for.\n const exactTestVetoes = decision.exactTestVetoes\n\n // Negative-delta gate (the paired-delta evidence must clear the threshold).\n if (!decision.clearsThreshold || exactTestVetoes) {\n const detail = exactTestVetoes\n ? ` McNemar exact p=${decision.mcnemar?.pValue.toExponential(2)} does not reject at α=${fmt(1 - this.confidence)}.`\n : decision.methodDetail\n return {\n promote: false,\n candidateId,\n baselineId,\n evidence,\n reason:\n `negative_delta: paired holdout ${deltaLabel} Δ=${fmt(decidingDelta)} ` +\n `CI=[${fmt(low)}, ${fmt(high)}] does not clear threshold ${fmt(this.pairedDeltaThreshold)}.${detail}`,\n rejectionCode: 'negative_delta',\n }\n }\n\n // Overfit-gap gate. We allow some absolute slack —\n // candidate.gap ≤ baseline.gap + overfitGapThreshold.\n if (overfitGap > baselineOverfitGap + this.overfitGapThreshold) {\n return {\n promote: false,\n candidateId,\n baselineId,\n evidence,\n reason:\n `overfit_gap: candidate gap=${fmt(overfitGap)} exceeds baseline gap=${fmt(baselineOverfitGap)} ` +\n `by more than ${fmt(this.overfitGapThreshold)}`,\n rejectionCode: 'overfit_gap',\n }\n }\n\n // Cost-ceiling gate. Runs after quality gates so a cost-driven\n // rejection always carries a \"you cleared quality but blew budget\"\n // story rather than masking a quality failure.\n if (this.costPerTaskCeiling !== undefined && medianCandidateCost === null) {\n return {\n promote: false,\n candidateId,\n baselineId,\n evidence,\n reason: 'missing_cost: candidate cost evidence is incomplete',\n rejectionCode: 'missing_cost',\n }\n }\n if (\n this.costPerTaskCeiling !== undefined &&\n medianCandidateCost !== null &&\n medianCandidateCost > this.costPerTaskCeiling\n ) {\n return {\n promote: false,\n candidateId,\n baselineId,\n evidence,\n reason:\n `cost_ceiling: candidate median cost $${fmt(medianCandidateCost)} ` +\n `exceeds ceiling $${fmt(this.costPerTaskCeiling)} (baseline $${fmt(medianBaselineCost)})`,\n rejectionCode: 'cost_ceiling',\n }\n }\n\n return {\n promote: true,\n candidateId,\n baselineId,\n evidence,\n reason:\n `promote: paired holdout ${deltaLabel} Δ=${fmt(decidingDelta)} ` +\n `CI=[${fmt(low)}, ${fmt(high)}] over ${productiveRuns} pairs; ` +\n `overfit gap candidate=${fmt(overfitGap)} vs baseline=${fmt(baselineOverfitGap)}; ` +\n `median cost candidate=$${fmt(medianCandidateCost)} vs baseline=$${fmt(medianBaselineCost)}`,\n rejectionCode: null,\n }\n }\n\n /**\n * Which paired statistic decides this data, and the shape facts behind it —\n * for the early exits, where no interval is computed. Delegates to\n * {@link pairedDecisionShape} so the reported shape can never disagree with\n * the shape the decision actually routes on.\n */\n private chooseShape(before: number[], after: number[]): PairedDecisionShape {\n return pairedDecisionShape(before, after, this.deltaStatistic === 'median' ? 'median' : 'mean')\n }\n}\n\n// ── Helpers ──────────────────────────────────────────────────────────\n\nfunction inferCandidateId(candidate: RunRecord[], baselineKey: string): string {\n for (const run of candidate) {\n if (run.candidateId && run.candidateId !== baselineKey) return run.candidateId\n }\n // All candidate rows match the baseline key — caller mistake, but\n // surface the symptom rather than throwing inside the gate.\n return candidate[0]?.candidateId ?? '(unknown candidate)'\n}\n\nfunction assertScenarioIdentities(runs: RunRecord[]): void {\n for (const run of runs) {\n if (typeof run.scenarioId !== 'string' || run.scenarioId.trim() === '') {\n throw new Error(`HeldOutGate: run ${run.runId} is missing scenarioId`)\n }\n }\n}\n\n/**\n * Rows carrying a finite score on one split. RAW (`observedSplitScore`) by\n * choice: the gated runs are already removed by the caller, so applying the\n * gate again here would only zero runs that are no longer in the set, and the\n * reported means must describe the runs that actually decided the promotion.\n */\nfunction scoredRuns(runs: RunRecord[], split: ScorePreference): RunRecord[] {\n return runs.filter((run) => {\n if (run.splitTag !== split) return false\n const v = observedSplitScore(run, split)\n return typeof v === 'number' && Number.isFinite(v)\n })\n}\n\n/** Every row tagged to one split, scored or not — the work the split was\n * DEALT, as opposed to the work it managed to measure. */\nfunction dealtRuns(runs: RunRecord[], split: ScorePreference): RunRecord[] {\n return runs.filter((run) => run.splitTag === split)\n}\n\nfunction hasFiniteScore(run: RunRecord, split: ScorePreference): boolean {\n const v = observedSplitScore(run, split)\n return typeof v === 'number' && Number.isFinite(v)\n}\n\n/**\n * Partition one split's dealt work into answered / unscored / one-armed.\n *\n * Pairs the UNFILTERED rows with the same `pairRunRecords` the decision uses,\n * so the denominator comes out of the same identity rules as the numerator and\n * cannot drift from it. Deliberately a SECOND pairing rather than a widening of\n * the decision's own: the decision keeps pairing exactly the rows it always\n * paired, so this check can only ever add a refusal, never move a verdict that\n * was already being made on a complete set.\n */\nfunction splitCoverage(\n baseline: RunRecord[],\n candidate: RunRecord[],\n split: ScorePreference,\n): SplitCoverage {\n const pairing = pairRunRecords(dealtRuns(baseline, split), dealtRuns(candidate, split))\n let answered = 0\n for (const pair of pairing.pairs) {\n if (hasFiniteScore(pair.baseline, split) && hasFiniteScore(pair.treatment, split)) answered += 1\n }\n const unscoredPairs = pairing.pairs.length - answered\n const candidateOnly = pairing.unpairedTreatment.length\n const baselineOnly = pairing.unpairedBaseline.length\n const dealt = pairing.pairs.length + candidateOnly + baselineOnly\n return {\n dealt,\n answered,\n unscoredPairs,\n candidateOnly,\n baselineOnly,\n coverage: dealt === 0 ? 0 : answered / dealt,\n }\n}\n\nfunction describeCoverage(split: string, cov: SplitCoverage): string {\n const dark = [\n cov.unscoredPairs > 0 ? `${cov.unscoredPairs} ran on both arms but produced no score` : null,\n cov.baselineOnly > 0 ? `${cov.baselineOnly} only the baseline produced a row for` : null,\n cov.candidateOnly > 0 ? `${cov.candidateOnly} only the candidate produced a row for` : null,\n ].filter((part): part is string => part !== null)\n return (\n `${split} scored ${cov.answered} of ${cov.dealt} dealt items (coverage ${fmt(cov.coverage)})` +\n (dark.length > 0 ? ` — ${dark.join(', ')}` : '')\n )\n}\n\nfunction meanOrNull(xs: number[]): number | null {\n if (xs.length === 0) return null\n return xs.reduce((s, x) => s + x, 0) / xs.length\n}\n\nfunction diffOrNull(a: number | null, b: number | null): number | null {\n if (a === null || b === null) return null\n return a - b\n}\n\nfunction medianDelta(before: number[], after: number[]): number {\n const ds = before.map((b, i) => after[i]! - b).sort((x, y) => x - y)\n if (ds.length === 0) throw new Error('HeldOutGate: median delta requires at least one pair')\n const mid = Math.floor(ds.length / 2)\n return ds.length % 2 === 0 ? (ds[mid - 1]! + ds[mid]!) / 2 : ds[mid]!\n}\n\nfunction medianFinite(xs: number[]): number | null {\n const ys = xs.filter((x) => Number.isFinite(x)).sort((x, y) => x - y)\n if (ys.length === 0) return null\n const mid = Math.floor(ys.length / 2)\n return ys.length % 2 === 0 ? (ys[mid - 1]! + ys[mid]!) / 2 : ys[mid]!\n}\n\nfunction completeCostMedian(runs: RunRecord[]): number | null {\n if (runs.length === 0) return null\n const costs: number[] = []\n for (const run of runs) {\n const provenance = run.costProvenance\n if (provenance.kind === 'uncaptured') return null\n costs.push(provenance.usd)\n }\n return medianFinite(costs)\n}\n\nfunction fmt(x: number | null): string {\n if (x === null) return 'n/a'\n return x.toFixed(4)\n}\n","/**\n * Inter-critic / inter-pass orthogonality.\n *\n * Detects redundant ensembles. When you run N critics (or N audit passes,\n * or N specialized agents) on the same input, you want them to disagree —\n * each contributing distinct signal. If they all converge on the same set\n * of findings, you're paying N× cost for ~1× signal.\n *\n * The metric is `1 − mean pairwise cosine similarity` over bags of words\n * extracted from each pass's outputs. 1.0 = fully orthogonal,\n * 0.0 = fully redundant.\n *\n * Universal primitive: pass anything that produces text (findings, tool\n * calls rendered as JSON, verdict strings) and the matcher derives its own\n * vocabulary.\n */\n\nexport interface OrthogonalityInput<T> {\n passes: Array<{ findings: T[] }>\n /** Render one element to text. Default: defaultRender (concatenates string fields). */\n text?: (item: T) => string\n /** Minimum token length kept in the bag. Default 4 (drops short fillers). */\n minTokenLength?: number\n}\n\nexport interface OrthogonalityResult {\n /** 1 − mean pairwise cosine similarity across passes. 1=fully orthogonal, 0=fully redundant. */\n orthogonality: number\n /** Number of passes considered. */\n passCount: number\n /** Pairwise cosine similarities, in upper-triangular order (for debugging). */\n similarities: number[]\n}\n\nexport function passOrthogonality<T>(input: OrthogonalityInput<T>): OrthogonalityResult {\n const passes = input.passes\n if (passes.length < 2) {\n return { orthogonality: 1, passCount: passes.length, similarities: [] }\n }\n const render = input.text ?? defaultRender\n const minLen = input.minTokenLength ?? 4\n const vectors = passes.map((p) => bagOfWords(p.findings, render, minLen))\n const sims: number[] = []\n for (let i = 0; i < vectors.length; i++) {\n for (let j = i + 1; j < vectors.length; j++) {\n sims.push(cosineSimilarity(vectors[i]!, vectors[j]!))\n }\n }\n const mean = sims.length === 0 ? 0 : sims.reduce((a, b) => a + b, 0) / sims.length\n return {\n orthogonality: Math.max(0, Math.min(1, 1 - mean)),\n passCount: passes.length,\n similarities: sims,\n }\n}\n\nfunction defaultRender(item: unknown): string {\n if (typeof item === 'string') return item\n if (item && typeof item === 'object') {\n const parts: string[] = []\n for (const v of Object.values(item as Record<string, unknown>)) {\n if (typeof v === 'string') parts.push(v)\n }\n return parts.join(' ')\n }\n return String(item ?? '')\n}\n\nfunction bagOfWords<T>(\n items: T[],\n render: (item: T) => string,\n minLen: number,\n): Map<string, number> {\n const bag = new Map<string, number>()\n for (const item of items) {\n const text = render(item).toLowerCase()\n for (const tok of text.split(/[^a-z0-9]+/).filter((w) => w.length >= minLen)) {\n bag.set(tok, (bag.get(tok) ?? 0) + 1)\n }\n }\n return bag\n}\n\nfunction cosineSimilarity(a: Map<string, number>, b: Map<string, number>): number {\n let dot = 0\n let aMag = 0\n let bMag = 0\n for (const [, v] of a) aMag += v * v\n for (const [, v] of b) bMag += v * v\n for (const [k, v] of a) {\n const bv = b.get(k)\n if (bv) dot += v * bv\n }\n if (aMag === 0 || bMag === 0) return 0\n return dot / (Math.sqrt(aMag) * Math.sqrt(bMag))\n}\n","import type {\n ReferenceReplayCaseRun,\n ReferenceReplayRun,\n ReferenceReplayScenarioScore,\n} from './reference-replay'\nimport type { RunScore } from './run-score'\nimport type { SteeringBundle } from './steering'\nimport type { SteeringOptimizationRow } from './steering-optimizer'\n\nexport interface ReferenceReplaySteeringRowsOptions<Input = unknown> {\n bundleForRun?: (run: ReferenceReplayRun<Input>) => SteeringBundle\n scoreForCase?: (\n caseRun: ReferenceReplayCaseRun<Input>,\n run: ReferenceReplayRun<Input>,\n ) => RunScore\n}\n\nexport function referenceReplayRunsToSteeringRows<Input = unknown>(\n runs: ReferenceReplayRun<Input>[],\n options: ReferenceReplaySteeringRowsOptions<Input> = {},\n): SteeringOptimizationRow[] {\n const rows: SteeringOptimizationRow[] = []\n for (const run of runs) {\n const variantId = run.variantId ?? run.id\n const bundle = options.bundleForRun?.(run) ?? {\n id: variantId,\n metadata: run.metadata,\n }\n\n for (const caseRun of run.cases) {\n rows.push({\n variantId,\n scenarioId: caseRun.caseId,\n bundle,\n score:\n options.scoreForCase?.(caseRun, run) ??\n referenceReplayScenarioToRunScore(caseRun.score, caseRun.durationMs),\n metadata: {\n runId: run.id,\n split: caseRun.split,\n task: caseRun.metadata?.task ?? caseRun.metadata?.repo ?? caseRun.caseId,\n referenceCount: caseRun.references.length,\n candidateCount: caseRun.candidates.length,\n matched: caseRun.score.matched,\n total: caseRun.score.total,\n falsePositives: caseRun.score.falsePositives,\n precision: caseRun.score.precision,\n recall: caseRun.score.recall,\n f1: caseRun.score.f1,\n error: caseRun.error,\n ...(caseRun.metadata ?? {}),\n },\n })\n }\n }\n return rows\n}\n\nexport function referenceReplayScenarioToRunScore(\n scenarioScore: ReferenceReplayScenarioScore,\n durationMs = 0,\n): RunScore {\n const success = scenarioScore.f1\n const recall = scenarioScore.recall\n const precision = scenarioScore.precision\n const failed = scenarioScore.total > 0 && scenarioScore.matched === 0\n\n return {\n success,\n goalProgress: recall,\n repoGroundedness: precision,\n driftPenalty: 1 - precision,\n toolUseQuality: precision,\n patchQuality: 0,\n testReality: scenarioScore.total > 0 ? 1 : 0,\n finalGate: success,\n reviewerBlockers: failed ? 1 : 0,\n costUsd: 0,\n wallSeconds: Math.max(0, durationMs / 1000),\n notes: [\n `reference-replay matched ${scenarioScore.matched}/${scenarioScore.total}`,\n `precision=${precision.toFixed(3)} recall=${recall.toFixed(3)} f1=${success.toFixed(3)}`,\n ],\n }\n}\n","/**\n * Researcher interface — stable hook for an external autonomous-research\n * agent to drive the meta-loop.\n *\n * Implementations live downstream (typically in a private repo that\n * runs the actual LLM). This package ships only the contract + a\n * `NoopResearcher` so consumers can wire the surface without being\n * forced to implement every method up front.\n *\n * The four methods mirror the four stages of the paper \"Two Loops,\n * Three Roles\":\n *\n * inspectFailures — given the observed runs, what failure modes\n * are present? (data → diagnosis)\n * proposeChange — given diagnosed failure modes, what\n * structural changes should we try?\n * (diagnosis → plan delta)\n * applyChange — fold the proposed deltas into a concrete\n * experiment plan against an existing baseline.\n * (plan delta → executable plan)\n * evaluateChange — run the plan, return runs + the gate verdict.\n * (executable plan → verdict)\n *\n * Composition is the discipline: a Researcher implementation MUST\n * keep these four steps separate and inspectable. Conflating\n * \"diagnose + propose + run\" into a single LLM call defeats the\n * point of the framework — you can't audit which step lied.\n *\n * THIS INTERFACE IS STABLE. Breaking changes require a new module\n * (e.g. `Researcher2`) so existing implementations keep working.\n */\n\nimport type { GateDecision } from './held-out-gate'\nimport type { RunRecord, RunSplitTag } from './run-record'\n\n/** A diagnosed failure mode with the run-IDs that exhibit it. */\nexport interface FailureMode {\n /** Short machine-readable code. Must be stable across runs of the\n * same researcher to enable longitudinal tracking. */\n code: string\n /** Human-readable description for the paper / dashboard. */\n description: string\n evidence: {\n /** Run IDs (from `RunRecord.runId`) where this failure mode was\n * observed. */\n runIds: string[]\n /** Number of run samples that informed the diagnosis. */\n samples: number\n }\n}\n\n/** A single steering change the researcher wants to try. */\nexport interface SteeringChange {\n kind: 'reviewer_prompt' | 'skill_add' | 'skill_remove' | 'threshold' | 'budget'\n /** Implementation-specific payload. Researcher implementations\n * define the schema — keep this `unknown` here to avoid coupling\n * the public interface to any one researcher's internal model. */\n payload: unknown\n /** Why the researcher proposed this change. Goes into the audit\n * trail next to the failure-mode evidence. */\n rationale: string\n /** Optional self-reported expected delta on the headline metric. */\n expectedDelta?: number\n}\n\n/** A single experiment plan, mapped onto the search/holdout splits. */\nexport interface ExperimentPlan {\n baselineCandidateId: string\n proposedCandidateId: string\n changes: SteeringChange[]\n /** USD ceiling for the entire experiment. The runner must stop\n * before exceeding this and report a partial result. */\n evaluationBudgetUsd: number\n /** Item IDs (your dataset keys) for the search vs holdout splits. */\n splits: { search: string[]; holdout: string[] }\n}\n\n/** Result of running a plan: every run, plus the gate verdict. */\nexport interface ExperimentResult {\n plan: ExperimentPlan\n runs: RunRecord[]\n gateDecision: GateDecision\n}\n\n/**\n * The researcher loop. Stable, four-step, inspectable.\n *\n * ┌──────────┐ inspectFailures ┌──────────┐ proposeChange ┌──────────┐\n * │ runs │ ─────────────────▶│ failures │ ──────────────▶│ changes │\n * └──────────┘ └──────────┘ └────┬─────┘\n * │\n * ▼\n * ┌────────────────┐ applyChange ┌────────┐\n * │ ExperimentPlan │ ◀────────────│ base │\n * └────────┬───────┘ └────────┘\n * │\n * evaluateChange ▼\n * ┌────────────────┐\n * │ ExperimentResult│\n * └────────────────┘\n */\nexport interface Researcher {\n inspectFailures(runs: RunRecord[]): Promise<FailureMode[]>\n proposeChange(failures: FailureMode[]): Promise<SteeringChange[]>\n applyChange(changes: SteeringChange[], baseline: ExperimentPlan): Promise<ExperimentPlan>\n evaluateChange(plan: ExperimentPlan): Promise<ExperimentResult>\n}\n\nexport interface CallbackResearcherOptions {\n inspectFailures: Researcher['inspectFailures']\n proposeChange: Researcher['proposeChange']\n applyChange: Researcher['applyChange']\n evaluateChange: Researcher['evaluateChange']\n}\n\n/**\n * Minimal concrete researcher for tests, scripts, and small integrations.\n * Larger autonomous researchers can still implement `Researcher` directly.\n */\nexport class CallbackResearcher implements Researcher {\n constructor(private readonly callbacks: CallbackResearcherOptions) {}\n\n inspectFailures(runs: RunRecord[]): Promise<FailureMode[]> {\n return this.callbacks.inspectFailures(runs)\n }\n\n proposeChange(failures: FailureMode[]): Promise<SteeringChange[]> {\n return this.callbacks.proposeChange(failures)\n }\n\n applyChange(changes: SteeringChange[], baseline: ExperimentPlan): Promise<ExperimentPlan> {\n return this.callbacks.applyChange(changes, baseline)\n }\n\n evaluateChange(plan: ExperimentPlan): Promise<ExperimentResult> {\n return this.callbacks.evaluateChange(plan)\n }\n}\n\n/**\n * No-op researcher — fails loud on every method. Use as a placeholder\n * in code paths that wire the interface but don't have an implementation\n * yet. Importantly, this does NOT silently succeed: a no-op researcher\n * that returned empty arrays would muffle the loop's signal that\n * nobody implemented the brain.\n */\nexport class NoopResearcher implements Researcher {\n private readonly hint: string\n\n constructor(hint = 'NoopResearcher: no implementation wired') {\n this.hint = hint\n }\n\n async inspectFailures(_runs: RunRecord[]): Promise<FailureMode[]> {\n throw new Error(`${this.hint} (inspectFailures not implemented)`)\n }\n\n async proposeChange(_failures: FailureMode[]): Promise<SteeringChange[]> {\n throw new Error(`${this.hint} (proposeChange not implemented)`)\n }\n\n async applyChange(\n _changes: SteeringChange[],\n _baseline: ExperimentPlan,\n ): Promise<ExperimentPlan> {\n throw new Error(`${this.hint} (applyChange not implemented)`)\n }\n\n async evaluateChange(_plan: ExperimentPlan): Promise<ExperimentResult> {\n throw new Error(`${this.hint} (evaluateChange not implemented)`)\n }\n}\n\n/** Re-export the run split type with the researcher contracts. */\nexport type { RunSplitTag }\n","/**\n * SandboxPool — bounded checkout/release pool for mutation slots.\n *\n * The composite-mutator's `code` channel needs an isolated workspace per\n * mutation attempt: a git worktree, a sandbox container, a tmpdir clone —\n * whatever the consumer's runtime is. Without a pool, every consumer\n * re-implements the same machinery (mint N slots, check one out per\n * mutation, reset before reuse, drain at the end, track utilisation for\n * the cost ledger). This primitive ships that machinery so consumers\n * supply only a `SlotFactory`.\n *\n * Generic over a slot resource `T` so the same pool serves git worktrees\n * (T = path), Tangle sandboxes (T = SandboxBox), or anything else with\n * the create/reset/destroy lifecycle.\n *\n * Concurrency: FIFO via the shared `Mutex` primitive. Each `checkout()`\n * either takes an idle slot or queues until one is released. Lifecycle\n * is single-process — multi-process pools need external coordination\n * (file locks, etc.) and are deliberately out of scope.\n */\n\nimport { Mutex } from './concurrency'\n\nexport interface PoolSlot<T> {\n /** Stable id assigned at slot creation. Use for telemetry / lineage. */\n readonly id: string\n /** Consumer-defined resource. */\n readonly resource: T\n}\n\nexport interface SlotFactory<T> {\n /** Build a new slot. Called lazily as the pool grows up to `size`. */\n create(slotId: string): Promise<T>\n /**\n * Reset a slot to a clean state before reuse. Called BEFORE every\n * checkout returns it (including the first — so the factory's\n * `create` can leave the slot dirty and let `reset` normalise).\n * Optional; default is a no-op.\n */\n reset?(slot: PoolSlot<T>): Promise<void>\n /** Tear the slot down. Called by `drain()`. */\n destroy(slot: PoolSlot<T>): Promise<void>\n}\n\nexport interface SandboxPool<T> {\n /**\n * Take a slot. If all slots are busy, the promise resolves when one\n * is released. Always pair with the returned `release` (or wrap with\n * `withSlot`).\n */\n checkout(): Promise<{ slot: PoolSlot<T>; release: () => void }>\n /**\n * Run `fn` with a checked-out slot, releasing on completion or throw.\n * The convenience wrapper most callers should use.\n */\n withSlot<R>(fn: (slot: PoolSlot<T>) => Promise<R>): Promise<R>\n /** Destroy every slot. Idempotent. */\n drain(): Promise<void>\n /** How many slots have been minted (≤ `size`). */\n poolSize(): number\n /** How many checkouts are currently outstanding. */\n activeCheckouts(): number\n /** Snapshot of busy/total durations for the cost ledger. */\n utilization(): { busyMs: number; totalMs: number; checkouts: number }\n}\n\nexport interface CreateSandboxPoolOpts<T> {\n /** Maximum concurrent slots. Slots are minted on first need, not eagerly. */\n size: number\n factory: SlotFactory<T>\n}\n\ninterface SlotState<T> {\n slot: PoolSlot<T>\n busy: boolean\n}\n\nexport function createSandboxPool<T>(opts: CreateSandboxPoolOpts<T>): SandboxPool<T> {\n if (opts.size < 1) throw new Error(`sandbox pool size must be >= 1 (got ${opts.size})`)\n\n const slots: SlotState<T>[] = []\n interface Waiter {\n resolve: (s: SlotState<T>) => void\n reject: (err: unknown) => void\n }\n const waiters: Waiter[] = []\n const mutex = new Mutex()\n let nextSlotId = 0\n // In-flight mints: a slot is decided under the mutex but only push()ed into\n // `slots` AFTER the un-locked factory.create(). Counting reservations against\n // capacity in the SAME critical section as the gate stops two concurrent\n // acquires from both minting past `size` (slots.length alone is still 0 for\n // both until the first push lands).\n let reserving = 0\n let totalCheckouts = 0\n let busyMs = 0\n let drained = false\n const startedAt = Date.now()\n\n /**\n * Acquire — atomic across `mutex`. Either find an idle slot, mint a\n * new one (if under capacity), or queue. The mutex bounds at the\n * search/mint boundary; the actual create() runs OUTSIDE the lock so\n * a slow factory doesn't starve other waiters.\n */\n async function acquireSlot(): Promise<SlotState<T>> {\n let mintId: string | undefined\n const ready = await mutex.runExclusive(async () => {\n const idle = slots.find((s) => !s.busy)\n if (idle) {\n idle.busy = true\n return idle\n }\n if (slots.length + reserving < opts.size) {\n // Reserve capacity synchronously (live slots + in-flight mints) so\n // concurrent acquireSlot calls can't all decide to mint past the cap.\n mintId = `slot_${nextSlotId++}`\n reserving++\n return null\n }\n return null\n })\n if (ready) return ready\n if (mintId !== undefined) {\n let resource: T\n try {\n resource = await opts.factory.create(mintId)\n } catch (err) {\n // Release the reservation and hand the freed capacity to a waiter,\n // otherwise a failed create leaks a capacity slot forever.\n await mutex.runExclusive(() => {\n reserving--\n })\n if (!drained) wakeWaiterToMint()\n throw err\n }\n const state: SlotState<T> = {\n slot: { id: mintId, resource },\n busy: true,\n }\n await mutex.runExclusive(() => {\n slots.push(state)\n reserving--\n })\n return state\n }\n // All slots busy + at cap: queue.\n return new Promise<SlotState<T>>((resolve, reject) => {\n waiters.push({ resolve, reject })\n })\n }\n\n /**\n * Hand `state` (clean + idle) to the next queued waiter, or leave it\n * idle if none are waiting. Caller must have already marked the slot\n * not-busy. Runs under no lock; waiters are FIFO.\n */\n function handOffCleanSlot(state: SlotState<T>): void {\n const next = waiters.shift()\n if (next) {\n state.busy = true\n next.resolve(state)\n }\n }\n\n /**\n * Wake a queued waiter when a slot was destroyed (so capacity freed up\n * but no clean slot is on hand). The waiter re-enters acquisition and\n * mints a fresh slot. Any acquisition failure is routed to that waiter\n * — never dropped on the floor.\n */\n function wakeWaiterToMint(): void {\n const next = waiters.shift()\n if (!next) return\n acquireSlot().then(next.resolve, next.reject)\n }\n\n /**\n * Release a checked-out slot. Reset is async; we kick it off and the\n * slot only becomes available to the next waiter once reset lands\n * CLEAN. If reset fails, the slot is dirty — destroy and remove it\n * rather than recycle a corrupted workspace to the next waiter, then\n * free the capacity so a fresh slot can be minted. The whole flow is\n * awaited inside one IIFE whose rejection is caught, so a failed\n * destroy can't surface as an unhandled rejection.\n */\n function releaseSlot(state: SlotState<T>): void {\n void (async () => {\n try {\n if (opts.factory.reset) {\n await opts.factory.reset(state.slot)\n }\n state.busy = false\n if (!drained) handOffCleanSlot(state)\n } catch (resetErr) {\n // Dirty slot: do NOT recycle it. Remove from the pool and tear it\n // down, then wake a waiter to mint a clean replacement.\n await mutex.runExclusive(() => {\n const i = slots.indexOf(state)\n if (i !== -1) slots.splice(i, 1)\n })\n try {\n await opts.factory.destroy(state.slot)\n } catch (destroyErr) {\n console.warn(\n `[sandbox-pool] destroy of dirty slot ${state.slot.id} failed after reset error:`,\n destroyErr,\n )\n }\n console.warn(\n `[sandbox-pool] reset failed for slot ${state.slot.id} — slot destroyed, not recycled:`,\n resetErr,\n )\n if (!drained) wakeWaiterToMint()\n }\n })().catch((err) => {\n // Defense in depth: nothing above should throw out here, but if it\n // does, surface it instead of producing an unhandled rejection.\n console.warn(`[sandbox-pool] release of slot ${state.slot.id} faulted:`, err)\n })\n }\n\n async function checkout(): Promise<{ slot: PoolSlot<T>; release: () => void }> {\n const state = await acquireSlot()\n const checkoutStart = Date.now()\n totalCheckouts++\n return {\n slot: state.slot,\n release: () => {\n busyMs += Date.now() - checkoutStart\n releaseSlot(state)\n },\n }\n }\n\n async function withSlot<R>(fn: (slot: PoolSlot<T>) => Promise<R>): Promise<R> {\n const { slot, release } = await checkout()\n try {\n return await fn(slot)\n } finally {\n release()\n }\n }\n\n async function drain(): Promise<void> {\n drained = true\n // Snapshot under lock; destroy outside lock so a slow teardown\n // doesn't block a concurrent drain caller.\n const { snapshot, pending } = await mutex.runExclusive(() => {\n const taken = slots.splice(0, slots.length)\n const queued = waiters.splice(0, waiters.length)\n return { snapshot: taken, pending: queued }\n })\n // Reject any pending waiters — the pool is going away, so their\n // checkout promise can never be satisfied. Failing loud beats leaving\n // a caller hung on an awaited checkout() forever.\n for (const w of pending) {\n w.reject(new Error('sandbox pool drained while a checkout was pending'))\n }\n await Promise.allSettled(snapshot.map((s) => opts.factory.destroy(s.slot)))\n }\n\n function utilization() {\n return {\n busyMs,\n totalMs: Date.now() - startedAt,\n checkouts: totalCheckouts,\n }\n }\n\n return {\n checkout,\n withSlot,\n drain,\n poolSize: () => slots.length,\n activeCheckouts: () => slots.filter((s) => s.busy).length,\n utilization,\n }\n}\n","/**\n * Pipeline-level OTEL integration — auto-attaches an OTEL exporter when\n * OTEL_EXPORTER_OTLP_ENDPOINT is set. Pipelines call `withOtelPipeline()`\n * to get a configured exporter + shutdown handle without manual wiring.\n */\n\nimport { createOtelExporter, type OtelExportConfig, type OtelExporter } from './trace/otel-export'\n\nexport interface OtelPipelineHandle {\n /** The active exporter, or undefined if no endpoint is configured. */\n exporter: OtelExporter | undefined\n /** Call at pipeline end to flush + shutdown. Safe to call even if exporter is undefined. */\n shutdown(): Promise<void>\n}\n\nexport interface OtelPipelineOptions {\n /** Override OTEL config. */\n otelConfig?: OtelExportConfig\n /** Pipeline-specific resource attributes. */\n pipelineKind?: string\n pipelineId?: string\n}\n\n/**\n * Create an OTEL exporter scoped to a pipeline run. Auto-reads\n * OTEL_EXPORTER_OTLP_ENDPOINT from env when no explicit config is passed.\n *\n * Returns a handle with `exporter` (possibly undefined) and `shutdown()`.\n */\nexport function withOtelPipeline(opts?: OtelPipelineOptions): OtelPipelineHandle {\n const config: OtelExportConfig = {\n ...opts?.otelConfig,\n resourceAttributes: {\n ...(opts?.pipelineKind ? { 'pipeline.kind': opts.pipelineKind } : {}),\n ...(opts?.pipelineId ? { 'pipeline.id': opts.pipelineId } : {}),\n ...opts?.otelConfig?.resourceAttributes,\n },\n }\n\n const exporter = createOtelExporter(config)\n\n return {\n exporter,\n async shutdown() {\n if (exporter) await exporter.shutdown()\n },\n }\n}\n\n/**\n * Check if OTEL export is configured (endpoint is set).\n */\nexport function isOtelConfigured(): boolean {\n return !!(typeof process !== 'undefined' && process.env.OTEL_EXPORTER_OTLP_ENDPOINT)\n}\n","/**\n * Strong, generically-useful baseline ROLES — the top zone of an `AgentProfile`\n * before any domain layer. A product composes one of these with its own\n * environment description (its sandbox) and its domain guidance, which lives in\n * the product repo (not here): a profile is `<baseline role> + <environment> +\n * <domain sections>`. Domain strength is NOT generalized into the substrate —\n * it is lifted here only once ≥2 products genuinely reuse it.\n *\n * Three roles cover the common shapes:\n * - `engineerRole` — builds + verifies real artifacts in a sandbox. Distilled\n * from agent-runtime's `coderProfile` doctrine (minimal\n * correct change, run the checks, fix the root cause,\n * never weaken a test or hide an error).\n * - `researcherRole` — gathers from real sources and grounds every claim\n * (cite or mark inferred; never fabricate).\n * - `generalistRole` — a strong default: helpful, grounded, verify-before-assert.\n *\n * All three are verification-first and domain-agnostic. They describe HOW a\n * capable IC operates, not WHAT domain it works in.\n */\n\n/** Senior-IC engineer operating in a sandbox — produces real artifacts and\n * verifies them before declaring done. The shared operator foundation for any\n * file-producing, tool-using product agent. */\nexport const engineerRole: string = [\n 'You are a senior principal engineer — a 10x individual contributor — operating inside an isolated sandbox workspace with real tools (shell, filesystem, editors, test runners).',\n 'You do not behave like a chatbot that describes work. You DO the work: you produce the actual artifact in the workspace, then you verify it.',\n '',\n 'How you operate:',\n '- Deliver the smallest correct change that fully satisfies the goal. Bias to the real artifact (the file, the patch, the document), never a description of it.',\n '- Before declaring done, run the available checks (tests, typecheck, validators, a re-read of what you produced). If a check fails, fix the ROOT CAUSE — never weaken the check, never hide the error, never fake success.',\n '- External-boundary calls (shell, network, filesystem) can fail. Inspect the outcome before relying on it; surface failures loudly rather than proceeding on a bad value.',\n '- State outcomes faithfully: what you verified, what you skipped, what is still failing. \"Done\" means produced AND verified.',\n].join('\\n')\n\n/** Researcher who grounds every claim in real sources — gathers, cites, and\n * distinguishes verified fact from inference. */\nexport const researcherRole: string = [\n 'You are a principal research analyst operating inside a workspace with tools to read sources, search, and record findings.',\n 'Your output is only as good as its grounding. You gather from the real sources in front of you and you ground every material claim.',\n '',\n 'How you operate:',\n '- Read the actual sources before concluding. Do not answer from memory when a source is available to check.',\n '- Cite the source for every material claim; explicitly mark anything you infer rather than verify. Never fabricate a source, a quote, a number, or a citation.',\n '- Distinguish what the sources establish from what you are extrapolating, and say which is which.',\n '- When the sources are insufficient or contradictory, say so plainly rather than papering over the gap.',\n].join('\\n')\n\n/** Strong general-purpose default — helpful, grounded, verifies before asserting. */\nexport const generalistRole: string = [\n 'You are a capable, senior generalist assistant operating inside a workspace with real tools.',\n 'You are direct and grounded: you verify before you assert, and you produce real output rather than describing it.',\n '',\n 'How you operate:',\n '- Prefer doing over describing — when the workspace lets you produce the artifact, produce it.',\n '- Ground claims in what you can check; when you cannot check something, say so instead of guessing confidently.',\n '- Verify your output before declaring done, and report what you verified vs. what remains uncertain.',\n '- Ask the user only when a choice is genuinely theirs and you cannot resolve it from the task, the workspace, or sensible defaults.',\n].join('\\n')\n\n/** The named baseline roles, for selection by key (e.g. from a product config). */\nexport const BASELINE_ROLES = {\n engineer: engineerRole,\n researcher: researcherRole,\n generalist: generalistRole,\n} as const\n\nexport type BaselineRoleKey = keyof typeof BASELINE_ROLES\n","/**\n * Structured prompt profile — the system prompt as named, addressable sections\n * instead of one opaque blob. The self-improvement loop targets ONE evolvable\n * `domain` section at a time (via `applyDomainPatch`); the role, environment,\n * tool conventions, and skill roster stay fixed so a candidate diff is\n * attributable to a single section rather than a whole-prompt rewrite.\n *\n * `renderProfile` emits the prompt in a fixed five-zone order — role,\n * Environment, Tool conventions, Skills, Domain guidance — mirroring the layout\n * of Harvey LAB's `harness/system_prompt.md` (workspace root, read-only\n * documents, output dir, skills dir). `profileToSurface` is the bridge to the\n * loop's string `MutableSurface`: a profile renders to exactly the text a\n * candidate is scored on.\n *\n * Distinct from the canonical `AgentProfile` exported by\n * `@tangle-network/agent-interface`. This helper builds prompt content that can\n * be rendered into an agent-interface profile's `prompt.systemPrompt`.\n */\n\nimport { surfaceContentHash } from '../campaign/surface-identity'\nimport { BASELINE_ROLES, type BaselineRoleKey } from './baselines'\n\nexport {\n BASELINE_ROLES,\n type BaselineRoleKey,\n engineerRole,\n generalistRole,\n researcherRole,\n} from './baselines'\n\n/** A named, addressable region of the system prompt. `evolvable` marks whether\n * the self-improvement loop is allowed to patch its body; fixed scaffolding\n * (e.g. a compliance preamble) sets `evolvable: false`. */\nexport interface AgentProfileSection {\n id: string\n title: string\n body: string\n evolvable: boolean\n}\n\n/** A skill the agent can invoke. `triggers` are the phrases/conditions that\n * should activate it; `scriptsDir` points at its executable scripts when the\n * skill ships code (mirrors Harvey's `skills/<name>/scripts/`). */\nexport interface ProfileSkill {\n name: string\n description: string\n triggers: string[]\n scriptsDir?: string\n}\n\n/** The structured system prompt. The first four fields are fixed scaffolding;\n * `domain` is the evolvable surface the loop optimizes. */\nexport interface PromptProfile {\n role: string\n environment: string\n toolConventions: string\n skills: ProfileSkill[]\n domain: AgentProfileSection[]\n}\n\nfunction renderSkill(skill: ProfileSkill): string {\n const lines = [`### ${skill.name}`, skill.description]\n if (skill.triggers.length > 0) {\n lines.push(`Triggers: ${skill.triggers.join(', ')}`)\n }\n if (skill.scriptsDir !== undefined) {\n lines.push(`Scripts: ${skill.scriptsDir}`)\n }\n return lines.join('\\n')\n}\n\n/**\n * Emit the sectioned system prompt in fixed order: role text, then\n * `## Environment`, `## Tool conventions`, `## Skills` (each skill as\n * `### <name>` + description + triggers), `## Domain guidance` (each section as\n * `### <title>` + body). The order is load-bearing — the loop diffs rendered\n * text, and reordering would make every candidate look like a full rewrite.\n */\nexport function renderProfile(p: PromptProfile): string {\n const zones: string[] = [\n p.role.trim(),\n `## Environment\\n\\n${p.environment.trim()}`,\n `## Tool conventions\\n\\n${p.toolConventions.trim()}`,\n `## Skills\\n\\n${\n p.skills.length > 0 ? p.skills.map(renderSkill).join('\\n\\n') : '_No skills configured._'\n }`,\n `## Domain guidance\\n\\n${\n p.domain.length > 0\n ? p.domain.map((s) => `### ${s.title}\\n\\n${s.body.trim()}`).join('\\n\\n')\n : '_No domain guidance yet._'\n }`,\n ]\n return zones.join('\\n\\n')\n}\n\n/** The string `MutableSurface` the self-improvement loop scores — a profile\n * renders to exactly the text a candidate is graded on. */\nexport function profileToSurface(p: PromptProfile): string {\n return renderProfile(p)\n}\n\nconst STOCK_SKILLS: ProfileSkill[] = [\n {\n name: 'read-documents',\n description:\n 'Read every source document under the read-only documents directory before drafting.',\n triggers: [\n 'task references a source document',\n 'instructions cite an exhibit, filing, or input file',\n ],\n },\n {\n name: 'write-deliverable',\n description:\n 'Write deliverables to the output directory; use markdown for notes and the file-type skills for binary artifacts.',\n triggers: ['the task asks for a produced artifact', 'a deliverable is named in the brief'],\n },\n]\n\nconst ENVIRONMENT_PREAMBLE =\n 'You are an AI agent executing a task within a single workspace root.\\n\\n' +\n '- Workspace root: bash starts here. Use it for notes, scratch files, and intermediate work.\\n' +\n '- Documents directory: task source documents live here and are read-only — never write to them.\\n' +\n '- Output directory: write every deliverable here; relative write/edit paths route here automatically.\\n' +\n '- Skills directory: skill scripts live at <workspace>/skills/<name>/scripts/.'\n\nconst TOOL_CONVENTIONS_PREAMBLE =\n 'Use read to consume input files. Use write only for plain markdown (typically a response summary). ' +\n 'Use edit for incremental refinement of a file you already created. ' +\n 'External-boundary calls return typed outcomes — inspect success before using a value.'\n\n/**\n * The fixed-scaffolding baseline: a `role`/`environment`/`toolConventions`\n * profile with the stock skill roster and NO domain guidance. The\n * production profile is this plus shipped domain sections.\n */\nexport function baselineProfile(args: {\n role: string\n environment?: string\n toolConventions?: string\n skills?: ProfileSkill[]\n}): PromptProfile {\n return {\n role: args.role,\n environment: args.environment ?? ENVIRONMENT_PREAMBLE,\n toolConventions: args.toolConventions ?? TOOL_CONVENTIONS_PREAMBLE,\n skills: args.skills ?? STOCK_SKILLS,\n domain: [],\n }\n}\n\n/**\n * Baseline from one of the strong generic roles (`'engineer' | 'researcher' |\n * 'generalist'`) — the common case: pick a role foundation, optionally override\n * the environment to describe THIS product's sandbox, then layer domain via\n * `prodProfile`. Domain guidance stays in the product repo; this only supplies\n * the generically-useful role + stock scaffolding.\n */\nexport function baselineProfileFromRole(\n role: BaselineRoleKey,\n args: { environment?: string; toolConventions?: string; skills?: ProfileSkill[] } = {},\n): PromptProfile {\n return baselineProfile({ role: BASELINE_ROLES[role], ...args })\n}\n\n/** The production profile: the baseline scaffolding plus the domain sections\n * shipped after self-improvement. Differs from the baseline ONLY in `domain`\n * (and any skills the caller layered into the baseline) — the role,\n * environment, and tool conventions are carried through unchanged. */\nexport function prodProfile(\n baseline: PromptProfile,\n shipped: AgentProfileSection[],\n): PromptProfile {\n return { ...baseline, domain: [...baseline.domain, ...shipped] }\n}\n\n/**\n * Section-scoped edit — replace the body of ONE domain section by id, leaving\n * every other section byte-identical. This is how the loop targets a single\n * evolvable surface. Throws on an unknown section id (a patch that hits no\n * section is a silent no-op otherwise — fail loud). Throws when the targeted\n * section is `evolvable: false`.\n */\nexport function applyDomainPatch(\n p: PromptProfile,\n sectionId: string,\n newBody: string,\n): PromptProfile {\n const idx = p.domain.findIndex((s) => s.id === sectionId)\n if (idx === -1) {\n throw new Error(\n `applyDomainPatch: no domain section \"${sectionId}\" (have: ${\n p.domain.map((s) => s.id).join(', ') || '<none>'\n })`,\n )\n }\n const target = p.domain[idx]\n if (target === undefined) {\n throw new Error(`applyDomainPatch: domain section \"${sectionId}\" resolved to undefined`)\n }\n if (!target.evolvable) {\n throw new Error(`applyDomainPatch: domain section \"${sectionId}\" is not evolvable`)\n }\n const next = [...p.domain]\n next[idx] = { ...target, body: newBody }\n return { ...p, domain: next }\n}\n\n/**\n * Content hash of a single section — its loop identity. Delegates to the\n * campaign provenance `surfaceContentHash` (the same helper the loop's\n * provenance record uses for full surfaces), so a section hash is byte-for-byte\n * comparable with the `sha256:`-prefixed content hashes that record carries.\n * Two sections that render identically (same title + body) share a hash; the\n * `id` and `evolvable` flag are excluded — they are routing metadata, not\n * content.\n */\nexport function sectionHash(section: AgentProfileSection): string {\n return surfaceContentHash(JSON.stringify({ title: section.title, body: section.body }))\n}\n","import type { TraceEmitter } from './trace/emitter'\nimport {\n type AnalyzeTracesInput,\n type AnalyzeTracesOptions,\n type AnalyzeTracesResult,\n analyzeTraces,\n} from './trace-analyst/analyst'\n\nexport interface TracedAnalystOptions {\n emitter: TraceEmitter\n parentSpanId?: string\n}\n\n/** Run a recursive trace investigation and record its engine steps. */\nexport async function tracedAnalyzeTraces(\n input: AnalyzeTracesInput,\n options: AnalyzeTracesOptions,\n traceOptions: TracedAnalystOptions,\n): Promise<AnalyzeTracesResult> {\n const parentSpan = await traceOptions.emitter.span({\n kind: 'custom',\n name: 'analyst:analyze-traces',\n parentSpanId: traceOptions.parentSpanId,\n attributes: {\n 'analyst.engine': options.engine.id,\n 'analyst.question_length': input.question.length,\n 'analyst.max_iterations': options.limits?.maxIterations ?? 12,\n 'analyst.max_llm_calls': options.limits?.maxLlmCalls ?? 8,\n 'eval.phase': 'analyst',\n },\n })\n\n try {\n const result = await analyzeTraces(input, options)\n for (const [index, step] of result.trajectory.entries()) {\n const encoded = JSON.stringify(step)\n const stepSpan = await traceOptions.emitter.span({\n kind: 'custom',\n name: `analyst:step-${index + 1}`,\n parentSpanId: parentSpan.span.spanId,\n attributes: {\n 'analyst.step': index + 1,\n 'analyst.step_bytes': Buffer.byteLength(encoded),\n 'eval.phase': 'analyst',\n },\n })\n await stepSpan.end()\n }\n await parentSpan.end({\n attributes: {\n 'analyst.engine': options.engine.id,\n 'analyst.model_calls': result.modelCalls,\n 'analyst.tool_calls': result.toolCalls,\n 'analyst.step_count': result.trajectory.length,\n 'analyst.finding_count': result.findings.length,\n 'analyst.answer_length': result.answer.length,\n 'eval.phase': 'analyst',\n },\n } as Record<string, unknown>)\n return result\n } catch (error) {\n await parentSpan.fail(error instanceof Error ? error : String(error))\n throw error\n }\n}\n","/**\n * Traced judge wrappers — instruments every LLM call inside the judge\n * ensemble with child spans so OTEL sinks see per-judge latency, model,\n * token counts, and score dimensions.\n *\n * The ensemble parent span groups all individual judge spans; each judge\n * gets its own child span with model + score as attributes.\n */\n\nimport type { ChatClient } from './analyst/chat-client'\nimport { JudgeParseError } from './judges'\nimport type { TraceEmitter } from './trace/emitter'\nimport type { JudgeFn, JudgeInput, JudgeScore } from './types'\n\nexport interface TracedJudgeOptions {\n /** TraceEmitter to emit spans into. */\n emitter: TraceEmitter\n /** Parent span id for the ensemble. If omitted, uses the emitter stack. */\n parentSpanId?: string\n}\n\n/**\n * Wrap a single JudgeFn so its LLM call emits a traced span.\n */\nexport function traceJudge(judge: JudgeFn, judgeName: string, opts: TracedJudgeOptions): JudgeFn {\n return async (chat: ChatClient, input: JudgeInput): Promise<JudgeScore[]> => {\n const span = await opts.emitter.span({\n kind: 'llm',\n name: `judge:${judgeName}`,\n parentSpanId: opts.parentSpanId,\n attributes: {\n 'judge.name': judgeName,\n 'eval.phase': 'judge',\n },\n })\n try {\n const scores = await judge(chat, input)\n const composite =\n scores.length > 0 ? scores.reduce((sum, s) => sum + s.score, 0) / scores.length : 0\n await span.end({\n attributes: {\n 'judge.name': judgeName,\n 'judge.composite_score': composite,\n 'judge.dimension_count': scores.length,\n 'eval.phase': 'judge',\n },\n } as Record<string, unknown>)\n return scores\n } catch (err) {\n await span.fail(err instanceof Error ? err : String(err))\n throw err\n }\n }\n}\n\n/**\n * Wrap an array of JudgeFns with tracing, running them inside an ensemble\n * parent span. Returns a single function that calls all judges and merges\n * their scores.\n */\nexport function traceJudgeEnsemble(\n judges: JudgeFn[],\n judgeNames: string[],\n opts: TracedJudgeOptions,\n): JudgeFn {\n return async (chat: ChatClient, input: JudgeInput) => {\n const ensembleSpan = await opts.emitter.span({\n kind: 'custom',\n name: 'judge:ensemble',\n parentSpanId: opts.parentSpanId,\n attributes: {\n 'judge.ensemble_size': judges.length,\n 'eval.phase': 'judge',\n },\n })\n try {\n const allScores: JudgeScore[] = []\n let failedJudges = 0\n for (let i = 0; i < judges.length; i++) {\n const judge = judges[i]!\n const name = judgeNames[i] ?? `judge_${i}`\n const tracedFn = traceJudge(judge, name, {\n emitter: opts.emitter,\n parentSpanId: ensembleSpan.span.spanId,\n })\n try {\n const scores = await tracedFn(chat, input)\n allScores.push(...scores)\n } catch (err) {\n // One unparseable judge must not sink the whole ensemble — its\n // child span is already marked failed by traceJudge; record it and\n // keep scoring with the surviving judges. Anything else (network,\n // abort) still aborts the ensemble.\n if (!(err instanceof JudgeParseError)) throw err\n failedJudges++\n }\n }\n const composite =\n allScores.length > 0 ? allScores.reduce((sum, s) => sum + s.score, 0) / allScores.length : 0\n await ensembleSpan.end({\n attributes: {\n 'judge.ensemble_size': judges.length,\n 'judge.composite_score': composite,\n 'judge.total_dimensions': allScores.length,\n 'judge.failed_judges': failedJudges,\n 'eval.phase': 'judge',\n },\n } as Record<string, unknown>)\n return allScores\n } catch (err) {\n await ensembleSpan.fail(err instanceof Error ? err : String(err))\n throw err\n }\n }\n}\n","/**\n * Program cost report — a thin projection over `CostLedger.summary()` that\n * adds the per-model rollup the summary lacks, plus `attachCostToReport`, the\n * one way every artifact (capsules, campaign results, diagnose reports) gets\n * its cost stamp.\n *\n * Honesty contract carried through from the ledger: `total.unknownEntries`\n * and `perModel[].unpriced` surface the costUnknown axis — a $0 from an\n * unpriced model is a lower bound, never a measured zero.\n */\n\nimport type { ChannelRollup, CostLedgerHandle } from './cost-ledger'\nimport { ValidationError } from './errors'\n\nexport interface ModelCostRollup {\n model: string\n usd: number\n entries: number\n /** ≥1 entry for this model was costUnknown — `usd` is a lower bound. An\n * `actualCostUsd` override clears the flag for that entry (the dollars are\n * observed, even when the model has no pricing). */\n unpriced: boolean\n}\n\nexport interface CostReport {\n /** Per-channel breakdown — `CostLedgerSummary.byChannel` verbatim. */\n perChannel: ChannelRollup[]\n total: {\n usd: number\n /** Entries whose cost was unknown — non-zero means `usd` is a lower bound. */\n unknownEntries: number\n }\n /** Per-model spend, sorted by model id. */\n perModel: ModelCostRollup[]\n}\n\n/** Project a ledger into the program cost report. Pure — no I/O, no clock. */\nexport function costReport(ledger: CostLedgerHandle): CostReport {\n const summary = ledger.summary()\n const perModel = new Map<string, ModelCostRollup>()\n for (const entry of ledger.list()) {\n const roll = perModel.get(entry.model) ?? {\n model: entry.model,\n usd: 0,\n entries: 0,\n unpriced: false,\n }\n roll.usd += entry.costUsd\n roll.entries += 1\n if (entry.costUnknown) roll.unpriced = true\n perModel.set(entry.model, roll)\n }\n return {\n perChannel: summary.byChannel,\n total: {\n usd: summary.totalCostUsd,\n unknownEntries: summary.byChannel.reduce((sum, c) => sum + c.unpricedCalls, 0),\n },\n perModel: [...perModel.values()].sort((a, b) => a.model.localeCompare(b.model)),\n }\n}\n\n/**\n * Stamp a report-shaped object with its cost projection under the `cost` key.\n * Generic so capsules, campaign results, and diagnose reports all stamp the\n * same way. Throws when the report already carries a `cost` key — silently\n * overwriting an existing stamp would corrupt the artifact's provenance.\n */\nexport function attachCostToReport<R extends object>(\n report: R,\n ledger: CostLedgerHandle,\n): R & { cost: CostReport } {\n if ('cost' in report) {\n throw new ValidationError(\n \"attachCostToReport: report already has a 'cost' key — refusing to overwrite an existing stamp\",\n )\n }\n return { ...report, cost: costReport(ledger) }\n}\n","/**\n * ModelSeats — the program's model seating chart.\n *\n * One object names which model fills each role in an eval program: the worker\n * under evaluation, the judge panel, the analyst, the reflection/driver model,\n * and the verifier. Re-tiering an entire program (economy ↔ frontier) is one\n * swapped object instead of a hunt through call sites.\n *\n * Wiring points — consumers thread seats; this module implements none of them\n * (those files belong to other surfaces):\n * - `judges` → `ensembleJudge({ models: seats.judges, … })` (src/judge-panel.ts)\n * and the `JudgeConfig`s handed to `makeEvalTools({ judges })`\n * (src/eval-tools.ts).\n * - `reflection` → the model configured by a custom `SurfaceProposer` or\n * external optimization engine.\n * - `worker` → the dispatch model the agent itself calls — the model an\n * `AgentProfile` declares.\n * - `analyst` → the LLM behind `analyzeRuns` / analyst-registry kinds.\n * - `verifier` → completion-verifier / objective-checker model.\n * - campaign cells thread `judges` + driver models the same way; that wiring\n * lands with the campaign surface, not here.\n *\n * `resolveSeat` is the only read path: an unset seat with no explicit fallback\n * throws — a model id is a budget decision, never a silent default.\n */\n\nimport { ConfigError, ValidationError } from './errors'\n\nexport interface ModelSeats {\n /** The model under evaluation — what the agent itself dispatches with. */\n worker?: string\n /** Judge-panel model ids — thread into `ensembleJudge({ models })`. */\n judges?: string[]\n /** Analyst model — `analyzeRuns` / analyst-registry LLM calls. */\n analyst?: string\n /** Reflection or candidate-generation model. */\n reflection?: string\n /** Verifier model — completion/objective checking. */\n verifier?: string\n}\n\nexport type SeatName = keyof ModelSeats\n\nexport type SeatPresetName = keyof typeof seatPresets\n\n/**\n * Tier presets — plain data, swap or spread freely.\n *\n * A preset names REQUESTED ids, and a requested id is NOT a guarantee of\n * family, of provider, or of liveness. A routing gateway can accept any id\n * below and answer from a different model on HTTP 200, with only the response\n * body's `model` field betraying the swap. The served assertion is the\n * guarantee: gate a run on `assertModelsServed({ probe: true })` and assert\n * `assertServedModel` per call. `assertCrossFamily` over these ids proves the\n * configuration is diverse; only `assertCrossFamilyServed` over the ids that\n * ANSWERED proves the run was.\n *\n * `economy` names ids a live router probe answered from the provider their\n * name implies, so the judge trio spanned three provider families (deepseek /\n * zhipu / google) as configured and, at that probe, as served. A preset is\n * only as good as its last probe: ids go dead and start resolving elsewhere\n * without notice, so re-probe rather than trusting this list.\n *\n * `frontier` is deliberately EMPTY: entitled frontier ids vary per router\n * account, and a hardcoded claude/gpt-5 id 401s on keys that lack it. Supply\n * your own: `{ ...seatPresets.frontier, worker: '<your-frontier-id>', … }` —\n * `resolveSeat` throws on every seat you haven't filled.\n */\nexport const seatPresets: Record<'economy' | 'frontier', ModelSeats> = {\n economy: {\n worker: 'zai/glm-5.2',\n judges: ['deepseek-v4-pro', 'zai/glm-5.2', 'google/gemini-2.5-flash'],\n analyst: 'zai/glm-5.2',\n reflection: 'zai/glm-5.2',\n verifier: 'deepseek-v4-pro',\n },\n frontier: {},\n}\n\n/** Thrown by `resolveSeat` when a seat is unset and no fallback was given. */\nexport class SeatUnsetError extends ConfigError {\n constructor(public readonly seat: SeatName) {\n super(\n `ModelSeats: seat '${seat}' is unset and no fallback was given — ` +\n 'name a model explicitly (a model id is a budget decision, never a silent default)',\n )\n }\n}\n\n/**\n * Read one seat. Blank strings and empty arrays count as unset (env-var\n * plumbing produces them); malformed values (non-string seat, non-array or\n * blank-entry `judges`) throw `ValidationError`. When the seat is unset, an\n * explicit `fallback` is returned (`[fallback]` for `judges` — a one-model\n * panel); without one, `SeatUnsetError`.\n */\nexport function resolveSeat(seats: ModelSeats, seat: 'judges', fallback?: string): string[]\nexport function resolveSeat(\n seats: ModelSeats,\n seat: Exclude<SeatName, 'judges'>,\n fallback?: string,\n): string\nexport function resolveSeat(seats: ModelSeats, seat: SeatName, fallback?: string): string | string[]\nexport function resolveSeat(\n seats: ModelSeats,\n seat: SeatName,\n fallback?: string,\n): string | string[] {\n const value = seats[seat]\n if (seat === 'judges') {\n if (value !== undefined && !Array.isArray(value)) {\n throw new ValidationError(`ModelSeats: seat 'judges' must be a string[], got ${typeof value}`)\n }\n const models = Array.isArray(value) ? value : []\n if (models.length > 0) {\n const blank = models.findIndex((m) => typeof m !== 'string' || m.trim() === '')\n if (blank >= 0) {\n throw new ValidationError(\n `ModelSeats: judges[${blank}] is blank — every panel model must be a non-empty id`,\n )\n }\n return [...models]\n }\n } else {\n if (value !== undefined && typeof value !== 'string') {\n throw new ValidationError(`ModelSeats: seat '${seat}' must be a string, got ${typeof value}`)\n }\n if (typeof value === 'string' && value.trim() !== '') return value\n }\n if (fallback !== undefined) {\n if (fallback.trim() === '') {\n throw new ValidationError(`ModelSeats: fallback for seat '${seat}' is blank`)\n }\n return seat === 'judges' ? [fallback] : fallback\n }\n throw new SeatUnsetError(seat)\n}\n","/**\n * Reproducibility attestation for any serializable report object.\n *\n * `attest()` binds a report to its content address (sha-256 over canonical\n * JSON) plus the provenance needed to reproduce it: model versions, seeds,\n * price-table hash, code SHA, inputs hash. `verifyAttestation()` recomputes\n * the address and answers \"is this the exact report that provenance\n * describes?\" — any single-field tamper changes the hash.\n *\n * Layering: content-addressing is the substrate's job; cryptographic SIGNING\n * (who vouches for the attestation, key management, transparency logs) is the\n * consumer's layer on top. An `AttestedReport` is a stable byte-identical\n * payload a consumer can sign — the substrate never holds keys.\n *\n * Generic by design: the report parameter is ANY value `canonicalJson`\n * accepts (campaign results, fuzz capsules, scorecards, cost ledgers). Do not\n * couple this module to a specific report schema.\n */\n\nimport { contentHash } from './verdict-cache'\n\n/** Hash scheme identifier carried by every attestation. A verifier rejects\n * unknown algorithms instead of guessing. */\nexport const ATTESTATION_ALGORITHM = 'sha256/canonical-json' as const\n\nexport interface AttestationProvenance {\n /** Every model involved in producing the report, name → version/id. */\n modelVersions: Record<string, string>\n /** RNG seeds the run was driven by, when seeded. */\n seeds?: number[]\n /** Content hash of the price table used for cost figures — cost numbers\n * are only reproducible against the same prices. */\n priceTableHash?: string\n /** Git SHA of the code that produced the report. */\n codeSha: string\n /** Content hash of the input set (scenarios, dataset manifest, ...). */\n inputsHash?: string\n /** ISO-8601 timestamp, caller-supplied — the substrate stays clock-free\n * so attestation is deterministic and testable. */\n createdAt: string\n}\n\nexport interface AttestedReport {\n /** Hex sha-256 over the canonical JSON of the report. */\n reportHash: string\n provenance: AttestationProvenance\n algorithm: typeof ATTESTATION_ALGORITHM\n}\n\nexport interface AttestationVerification {\n valid: boolean\n /** Populated iff `valid` is false — names the exact mismatch. */\n reason?: string\n}\n\n/**\n * Content-address a report and bind it to its provenance. Throws (via\n * `canonicalJson`) if the report contains undefined / function / symbol /\n * non-finite numbers — a report that cannot be unambiguously serialized\n * cannot be attested.\n */\nexport function attest(report: unknown, provenance: AttestationProvenance): AttestedReport {\n return {\n reportHash: contentHash(report),\n provenance,\n algorithm: ATTESTATION_ALGORITHM,\n }\n}\n\n/**\n * Verify a report against its attestation. Returns a typed outcome rather\n * than throwing: an unverifiable report (e.g. one that no longer\n * canonicalizes) is a verification failure with the cause in `reason`, not a\n * crash — verifiers run in pipelines that must record WHY, not die.\n */\nexport function verifyAttestation(\n report: unknown,\n attested: AttestedReport,\n): AttestationVerification {\n if (attested.algorithm !== ATTESTATION_ALGORITHM) {\n return {\n valid: false,\n reason: `unknown algorithm '${attested.algorithm}' — this verifier only checks '${ATTESTATION_ALGORITHM}'`,\n }\n }\n let recomputed: string\n try {\n recomputed = contentHash(report)\n } catch (err) {\n return {\n valid: false,\n reason: `report is not canonicalizable: ${err instanceof Error ? err.message : String(err)}`,\n }\n }\n if (recomputed !== attested.reportHash) {\n return {\n valid: false,\n reason: `report hash mismatch: attested ${attested.reportHash}, recomputed ${recomputed}`,\n }\n }\n return { valid: true }\n}\n","/**\n * Export side of the product benchmark bundle contract: convert product\n * eval run directories (`records.jsonl` of `RunRecord` rows + trace/raw\n * artifacts) into a portable `product-benchmark-manifest.json` +\n * `product-benchmark-records.jsonl` bundle that\n * `validateProductBenchmarkRun` accepts.\n *\n * Product-specific policy (safety-split detection, tool-call recovery,\n * profile id fallback, artifact materialization) enters through explicit\n * options; everything else is the shared union of the tax/legal/creative\n * exporters. Scenario catalogs, smoke runners, and CLIs stay in the\n * products.\n *\n * Input rows are checked structurally, not with `validateRunRecord`:\n * product harnesses record bare model aliases and partial provenance, and\n * the bundle contract's own validators re-check every field that matters\n * on the way out.\n */\n\nimport { spawnSync } from 'node:child_process'\nimport { createHash } from 'node:crypto'\nimport { cpSync, existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs'\nimport { basename, dirname, isAbsolute, join, relative, resolve } from 'node:path'\nimport { ValidationError } from '../errors'\nimport { type RunRecord, runTaskScore } from '../run-record'\nimport type {\n ProductBenchmarkManifest,\n ProductBenchmarkRecord,\n ProductBenchmarkSplit,\n RuntimeResolution,\n} from './index'\nimport { validateProductBenchmarkManifest, validateProductBenchmarkRecord } from './index'\n\n/** Full mutable-surface superset a product arm may declare. */\nexport const productBenchmarkMutableSurfaces = [\n 'prompt',\n 'resources.files',\n 'tools',\n 'mcp',\n 'hooks',\n 'subagents',\n] as const\n\nexport interface ProductBenchmarkExportOptions {\n /** Source eval run directories, each containing a `records.jsonl` of RunRecord rows. */\n readonly runDirs: readonly string[]\n /** Destination directory for the bundle (manifest + records + materialized source runs). */\n readonly outDir: string\n readonly projectId: string\n readonly benchmarkId: string\n /** Repo-relative path of the product's canonical agent profile source. */\n readonly agentProfilePath: string\n /** Pass threshold applied when a row carries no explicit `outcome.raw.pass`. Default 0.7. */\n readonly passThreshold?: number\n /**\n * First scenario tag. Defaults to `projectId` with a trailing `-agent`\n * stripped (`tax-agent` → `tax`), matching the product exporters.\n */\n readonly scenarioTagPrefix?: string\n /** Profile id used when a row has no `agentProfile.profileId`. Defaults to the row's arm id. */\n readonly fallbackProfileId?: string\n /** Arm mutable surfaces recorded in the manifest. Defaults to the full superset. */\n readonly mutableSurfaces?: readonly string[]\n /**\n * Copy each run dir into `<outDir>/source-runs/` and record\n * bundle-relative artifact paths (portable, self-contained). When false,\n * artifacts keep absolute paths into the original run dirs. Default true.\n */\n readonly materializeSourceRuns?: boolean\n /**\n * Override split classification for a row. Return undefined to fall back\n * to the default (`outcome.raw.safety === 1` → safety, then splitTag).\n */\n readonly classifySplit?: (record: RunRecord) => ProductBenchmarkSplit | undefined\n /** Recovers a tool-call count when the row's raw bag carries none (e.g. from turn artifacts). */\n readonly toolCallFallback?: (record: RunRecord, runDir: string) => number\n /** Backend version recorded per row. Defaults to the cwd package.json's `@tangle-network/sandbox` range. */\n readonly backendVersion?: string\n /**\n * Explicit substrate versions for the manifest, merged over what the cwd\n * package.json / node_modules resolve. Use when a substrate package is not\n * installed where the export runs — the validator refuses an `'unknown'`\n * version, so provide the real one rather than shipping the sentinel.\n */\n readonly substrate?: Partial<ProductBenchmarkManifest['substrate']>\n}\n\nexport interface ProductBenchmarkSingleRunExportOptions\n extends Omit<ProductBenchmarkExportOptions, 'runDirs'> {\n readonly runDir: string\n}\n\nexport interface ProductBenchmarkExportResult {\n readonly manifestPath: string\n readonly recordsPath: string\n readonly records: number\n}\n\ninterface ResolvedExportOptions {\n readonly projectId: string\n readonly benchmarkId: string\n readonly agentProfilePath: string\n readonly passThreshold: number\n readonly scenarioTagPrefix: string\n readonly fallbackProfileId?: string\n readonly mutableSurfaces: readonly string[]\n readonly classifySplit?: (record: RunRecord) => ProductBenchmarkSplit | undefined\n readonly toolCallFallback?: (record: RunRecord, runDir: string) => number\n readonly backendVersion: string\n}\n\n// ── Provenance helpers ───────────────────────────────────────────────\n\nfunction sha256(value: string): string {\n return `sha256:${createHash('sha256').update(value).digest('hex')}`\n}\n\nfunction safePathPart(value: string): string {\n return (\n value\n .replace(/[^a-zA-Z0-9_.-]+/g, '-')\n .replace(/^-+|-+$/g, '')\n .slice(0, 80) || 'artifact'\n )\n}\n\nfunction git(args: readonly string[], fallback: string): string {\n const res = spawnSync('git', args, { cwd: process.cwd(), encoding: 'utf8' })\n const value = res.status === 0 ? res.stdout.trim() : ''\n return value.length > 0 ? value : fallback\n}\n\nfunction knownEnv(name: string): string | undefined {\n const value = process.env[name]?.trim()\n return value && value !== 'unknown' ? value : undefined\n}\n\nfunction ciBranchName(): string | undefined {\n const direct =\n knownEnv('GITHUB_HEAD_REF') ?? knownEnv('GITHUB_REF_NAME') ?? knownEnv('VERCEL_GIT_COMMIT_REF')\n if (direct) return direct\n const ref = knownEnv('GITHUB_REF')\n return ref?.startsWith('refs/heads/') ? ref.slice('refs/heads/'.length) : undefined\n}\n\nfunction repoBranch(): string {\n const ci = ciBranchName()\n if (ci) return ci\n const branch = git(['branch', '--show-current'], '')\n if (branch) return branch\n const name = git(['name-rev', '--name-only', '--exclude=tags/*', 'HEAD'], '')\n if (name && name !== 'undefined') return name\n return `detached:${git(['rev-parse', '--short', 'HEAD'], 'unknown')}`\n}\n\n/** Repo identity from the exporting process's cwd. `'unknown'` values are flagged by `validateProductBenchmarkRun`. */\nexport function productBenchmarkRepoIdentity(): ProductBenchmarkManifest['repo'] {\n return {\n url: git(['config', '--get', 'remote.origin.url'], 'unknown'),\n commit: git(['rev-parse', 'HEAD'], 'unknown'),\n branch: repoBranch(),\n }\n}\n\n/** The declared range from the cwd package.json when present, else the\n * INSTALLED version read from node_modules (covers transitive installs —\n * a product that gets sandbox via agent-runtime still records real\n * provenance), else the `'unknown'` sentinel the validator refuses. */\nfunction packageVersion(name: string): string {\n const pkg = JSON.parse(readFileSync(resolve('package.json'), 'utf8')) as {\n name?: string\n version?: string\n dependencies?: Record<string, string>\n devDependencies?: Record<string, string>\n }\n if (pkg.name === name && pkg.version) return pkg.version\n const declared = pkg.dependencies?.[name] ?? pkg.devDependencies?.[name]\n if (declared) return declared\n const installed = resolve('node_modules', name, 'package.json')\n if (existsSync(installed)) {\n const installedPkg = JSON.parse(readFileSync(installed, 'utf8')) as { version?: string }\n if (installedPkg.version) return installedPkg.version\n }\n return 'unknown'\n}\n\n// ── Run record ingestion ─────────────────────────────────────────────\n\nfunction readRunRecords(path: string): RunRecord[] {\n const lines = readFileSync(path, 'utf8')\n .split('\\n')\n .map((line) => line.trim())\n .filter(Boolean)\n return lines.map((line, index) => {\n let parsed: unknown\n try {\n parsed = JSON.parse(line)\n } catch (err) {\n throw new ValidationError(\n `${path}:${index + 1}: ${err instanceof Error ? err.message : String(err)}`,\n { cause: err },\n )\n }\n return expectRunRecordShape(parsed, `${path}:${index + 1}`)\n })\n}\n\nfunction expectRunRecordShape(value: unknown, path: string): RunRecord {\n if (!value || typeof value !== 'object' || Array.isArray(value)) {\n throw new ValidationError(`${path}: run record must be an object`)\n }\n const obj = value as Record<string, unknown>\n for (const key of ['runId', 'model'] as const) {\n if (typeof obj[key] !== 'string' || obj[key].length === 0) {\n throw new ValidationError(`${path}: run record ${key} must be a non-empty string`)\n }\n }\n for (const key of ['costUsd', 'wallMs'] as const) {\n if (typeof obj[key] !== 'number' || !Number.isFinite(obj[key])) {\n throw new ValidationError(`${path}: run record ${key} must be a finite number`)\n }\n }\n const tokenUsage = obj.tokenUsage as Record<string, unknown> | undefined\n if (\n !tokenUsage ||\n typeof tokenUsage.input !== 'number' ||\n typeof tokenUsage.output !== 'number'\n ) {\n throw new ValidationError(`${path}: run record tokenUsage.input/output must be numbers`)\n }\n const outcome = obj.outcome as Record<string, unknown> | undefined\n if (!outcome?.raw || typeof outcome.raw !== 'object') {\n throw new ValidationError(`${path}: run record outcome.raw must be an object`)\n }\n return value as RunRecord\n}\n\n// ── Row mapping ──────────────────────────────────────────────────────\n\nfunction clamp01(value: number): number {\n return Math.max(0, Math.min(1, value))\n}\n\nfunction splitOf(record: RunRecord, opts: ResolvedExportOptions): ProductBenchmarkSplit {\n const custom = opts.classifySplit?.(record)\n if (custom) return custom\n if ((record.outcome.raw as Record<string, number>).safety === 1) return 'safety'\n if (record.splitTag === 'holdout') return 'holdout'\n if (record.splitTag === 'dev') return 'dev'\n return 'practice'\n}\n\n/** Ungated: a published benchmark record is audit evidence, so the score must\n * stay the measured one. KNOWN HOLE: a realness-gated run still publishes with\n * `pass: true`. The fix mirrors `RolloutLine` — carry the gate as a field on\n * `ProductBenchmarkRecord` and force `pass: false` — which is a schema change,\n * not a call swap, and is tracked separately from this correctness fix. */\nfunction scoreOf(record: RunRecord): number {\n const score = runTaskScore(record)\n if (score !== undefined) return clamp01(score)\n if (\n (record.outcome.judgeScores?.failedJudges?.length ?? 0) > 0 ||\n (record.outcome.raw.judge_error_count ?? 0) > 0\n ) {\n throw new ValidationError(\n `Run ${record.runId} has incomplete judge evidence; product benchmark rows require a complete task score`,\n )\n }\n throw new ValidationError(\n `Run ${record.runId} has no task score; product benchmark rows require an explicit score`,\n )\n}\n\nfunction rawPassOf(record: RunRecord): boolean | null {\n const rawPass = (record.outcome.raw as Record<string, unknown>).pass\n if (typeof rawPass === 'boolean') return rawPass\n if (typeof rawPass === 'number' && Number.isFinite(rawPass)) return rawPass >= 1\n return null\n}\n\nfunction passOf(record: RunRecord, score: number, threshold: number): boolean {\n const rawPass = rawPassOf(record)\n const hasTaskFailure = record.failureClass !== undefined && record.failureClass !== 'success'\n if (rawPass !== null) return rawPass && !hasTaskFailure\n return score >= threshold && !hasTaskFailure\n}\n\nfunction failureOf(\n record: RunRecord,\n score: number,\n threshold: number,\n): Pick<ProductBenchmarkRecord['outcome'], 'failureClass' | 'failureDetail'> {\n if (record.failureClass !== undefined && record.failureClass !== 'success') {\n return {\n failureClass: record.failureClass,\n failureDetail: record.failureMode ?? null,\n }\n }\n const belowThreshold = `quality-below-threshold: ${Math.round(score * 100)}% < ${Math.round(threshold * 100)}%`\n if (rawPassOf(record) === false) {\n return {\n failureClass: 'unknown',\n failureDetail: score < threshold ? belowThreshold : 'product-pass-failed',\n }\n }\n if (passOf(record, score, threshold)) {\n return { failureClass: null, failureDetail: null }\n }\n return { failureClass: 'unknown', failureDetail: belowThreshold }\n}\n\nfunction numericDimensions(record: RunRecord): Record<string, number> {\n const dimensions: Record<string, number> = {}\n for (const [key, value] of Object.entries(record.outcome.raw ?? {})) {\n if (typeof value === 'number' && Number.isFinite(value)) dimensions[key] = value\n }\n if (Object.keys(dimensions).length === 0) dimensions.score = scoreOf(record)\n return dimensions\n}\n\nfunction armIdOf(record: RunRecord): string {\n if (record.candidateId) return record.candidateId\n const variant = record.agentProfile?.dimensions?.variant\n if (typeof variant === 'string' && variant.length > 0) return variant\n const variantId = record.agentProfile?.dimensions?.variantId\n if (typeof variantId === 'string' && variantId.length > 0) return variantId\n return 'production-profile'\n}\n\nfunction backendOf(record: RunRecord): string {\n const backend = record.agentProfile?.dimensions?.backend\n return typeof backend === 'string' && backend.length > 0 ? backend : 'unknown'\n}\n\nfunction modelProvider(record: RunRecord): string {\n const backend = backendOf(record)\n if (backend === 'cli-bridge') return 'cli-bridge'\n if (backend === 'sandbox') return 'router'\n if (record.model.startsWith('router/')) return 'router'\n return backend === 'unknown' ? 'router' : backend\n}\n\nfunction runtimeResolution(record: RunRecord, opts: ResolvedExportOptions): RuntimeResolution {\n const reasoningEffort = record.agentProfile?.dimensions?.reasoningLevel\n return {\n model: record.agentProfile?.model ?? record.model,\n harness: record.agentProfile?.harness?.id ?? `${opts.projectId}-canonical-eval`,\n backend: backendOf(record),\n ...(typeof reasoningEffort === 'string' && reasoningEffort.length > 0\n ? { reasoningEffort }\n : {}),\n }\n}\n\nfunction sourceProfileHash(record: RunRecord): string {\n return (\n record.agentProfile?.sourceProfile?.hash ??\n record.agentProfile?.cellId ??\n sha256(\n JSON.stringify({\n candidateId: record.candidateId,\n promptHash: record.promptHash,\n configHash: record.configHash,\n }),\n )\n )\n}\n\nfunction materializedProfileHash(record: RunRecord, runtime: RuntimeResolution): string {\n return sha256(\n JSON.stringify({ sourceProfileHash: sourceProfileHash(record), model: runtime.model }),\n )\n}\n\nfunction profileIdOf(\n record: RunRecord,\n armId: string,\n runtime: RuntimeResolution,\n opts: ResolvedExportOptions,\n): string {\n const base = record.agentProfile?.profileId ?? opts.fallbackProfileId ?? armId\n const withArm = base.endsWith(`:${armId}`) ? base : `${base}:${armId}`\n return `${withArm}:${runtime.model}`\n}\n\nfunction toolCallsOf(record: RunRecord, runDir: string, opts: ResolvedExportOptions): number {\n const raw = record.outcome.raw as Record<string, unknown>\n const primary = Number(raw.tool_call_count ?? raw.tool_calls ?? raw.toolCalls ?? 0)\n if (Number.isFinite(primary) && primary > 0) return primary\n const fallback = opts.toolCallFallback?.(record, runDir)\n if (fallback !== undefined && Number.isFinite(fallback) && fallback > 0) return fallback\n return Number.isFinite(primary) ? primary : 0\n}\n\n// ── Artifact layout ──────────────────────────────────────────────────\n\nconst TRACE_CANDIDATES = ['traces.jsonl', 'traces', 'trace', 'trace-store'] as const\nconst RAW_CANDIDATES = ['raws.jsonl', 'raw-events'] as const\nconst SCORE_CANDIDATES = ['scores.json', 'manifest.json'] as const\n\nfunction firstExisting(runDir: string, candidates: readonly string[]): string {\n return candidates.find((candidate) => existsSync(join(runDir, candidate))) ?? candidates[0]!\n}\n\nfunction relativeArtifacts(runDir: string): ProductBenchmarkRecord['artifacts'] {\n return {\n records: 'records.jsonl',\n traces: firstExisting(runDir, TRACE_CANDIDATES),\n raws: firstExisting(runDir, RAW_CANDIDATES),\n scores: firstExisting(runDir, SCORE_CANDIDATES),\n workspace: existsSync(join(runDir, 'workspace')) ? 'workspace' : '.',\n }\n}\n\nfunction absoluteArtifacts(runDir: string): ProductBenchmarkRecord['artifacts'] {\n const rel = relativeArtifacts(runDir)\n return {\n records: resolve(runDir, rel.records),\n traces: resolve(runDir, rel.traces),\n raws: resolve(runDir, rel.raws),\n scores: resolve(runDir, rel.scores),\n workspace: resolve(runDir, rel.workspace),\n }\n}\n\nfunction materializeRunArtifacts(\n runDir: string,\n outDir: string,\n index: number,\n): ProductBenchmarkRecord['artifacts'] {\n if (resolve(runDir) === resolve(outDir)) return relativeArtifacts(runDir)\n const rel = relative(runDir, outDir)\n if (rel && !rel.startsWith('..') && !isAbsolute(rel)) {\n throw new ValidationError(`outDir must not be nested inside runDir: ${outDir}`)\n }\n const id = `${String(index + 1).padStart(2, '0')}-${safePathPart(basename(runDir))}-${sha256(runDir).slice(7, 19)}`\n const destRel = join('source-runs', id)\n const destAbs = join(outDir, destRel)\n mkdirSync(dirname(destAbs), { recursive: true })\n cpSync(runDir, destAbs, { recursive: true, force: true })\n const source = relativeArtifacts(runDir)\n return {\n records: join(destRel, source.records),\n traces: join(destRel, source.traces),\n raws: join(destRel, source.raws),\n scores: join(destRel, source.scores),\n workspace: source.workspace === '.' ? destRel : join(destRel, source.workspace),\n }\n}\n\nfunction existsArtifact(artifactRoot: string, value: string): boolean {\n return existsSync(resolve(artifactRoot, value))\n}\n\n// ── Record + manifest construction ───────────────────────────────────\n\n/** Map one RunRecord row to a validated product benchmark record. */\nexport function runRecordToProductBenchmarkRecord(\n record: RunRecord,\n runDir: string,\n artifactRoot: string,\n artifacts: ProductBenchmarkRecord['artifacts'],\n options: ProductBenchmarkExportOptions | ProductBenchmarkSingleRunExportOptions,\n): ProductBenchmarkRecord {\n const opts = resolveOptions(options)\n const runtime = runtimeResolution(record, opts)\n const score = scoreOf(record)\n const failure = failureOf(record, score, opts.passThreshold)\n const armId = armIdOf(record)\n const inputTokens = record.tokenUsage.input\n const outputTokens = record.tokenUsage.output\n const toolCallCount = toolCallsOf(record, runDir, opts)\n const dimensions = numericDimensions(record)\n if (record.costUsd === null) {\n throw new ValidationError(\n `run '${record.runId}' has no USD cost; product benchmark exports require priced runs`,\n )\n }\n const costUsd = record.costUsd\n if (!('tool_calls' in dimensions)) dimensions.tool_calls = toolCallCount\n const product: ProductBenchmarkRecord = {\n schemaVersion: 1,\n projectId: opts.projectId,\n benchmarkId: opts.benchmarkId,\n runId: record.runId,\n scenarioId: record.scenarioId,\n split: splitOf(record, opts),\n armId,\n rep: Number(record.seed ?? 0) + 1,\n agentProfile: {\n id: profileIdOf(record, armId, runtime, opts),\n hash: materializedProfileHash(record, runtime),\n path: opts.agentProfilePath,\n declared: runtime,\n resolved: runtime,\n },\n model: { provider: modelProvider(record), id: record.model },\n backend: { kind: backendOf(record), version: opts.backendVersion },\n outcome: {\n pass: passOf(record, score, opts.passThreshold),\n score,\n dimensions,\n ...failure,\n },\n usage: {\n inputTokens,\n outputTokens,\n costUsd,\n // Rounded: the bundle contract requires integer milliseconds.\n wallMs: Math.round(record.wallMs),\n toolCalls: toolCallCount,\n },\n integrity: {\n realBackend: inputTokens + outputTokens > 0,\n rawCapture: existsArtifact(artifactRoot, artifacts.raws),\n traceCapture: existsArtifact(artifactRoot, artifacts.traces),\n noStubRows: inputTokens + outputTokens > 0,\n priced: costUsd > 0,\n profileMaterialized: Boolean(record.agentProfile?.cellId),\n },\n artifacts,\n }\n return validateProductBenchmarkRecord(product)\n}\n\n/** One record per arm id, failing loud when records sharing an arm id\n * disagree on any attribute the manifest arm carries (profile, model,\n * backend, harness, reasoning effort) — an id-only dedup would silently\n * keep one policy and misrepresent the rest. */\nfunction uniqueArmRecords(records: readonly ProductBenchmarkRecord[]): ProductBenchmarkRecord[] {\n const byArm = new Map<string, ProductBenchmarkRecord>()\n for (const record of records) {\n const prior = byArm.get(record.armId)\n if (!prior) {\n byArm.set(record.armId, record)\n continue\n }\n const fields = [\n ['profileId', prior.agentProfile.id, record.agentProfile.id],\n ['model', prior.agentProfile.resolved.model, record.agentProfile.resolved.model],\n ['backend', prior.agentProfile.resolved.backend, record.agentProfile.resolved.backend],\n ['harness', prior.agentProfile.resolved.harness, record.agentProfile.resolved.harness],\n [\n 'reasoningEffort',\n prior.agentProfile.resolved.reasoningEffort,\n record.agentProfile.resolved.reasoningEffort,\n ],\n ] as const\n for (const [name, a, b] of fields) {\n if (a !== b) {\n throw new ValidationError(\n `records for arm '${record.armId}' disagree on ${name} (${String(a)} vs ${String(b)}) — one arm id must map to one policy`,\n )\n }\n }\n }\n return [...byArm.values()]\n}\n\n/** One record per scenario id, failing loud on a divergent split — the\n * manifest scenario carries one split, so two records disagreeing would be\n * silently misfiled. */\nfunction uniqueScenarioRecords(\n records: readonly ProductBenchmarkRecord[],\n): ProductBenchmarkRecord[] {\n const byScenario = new Map<string, ProductBenchmarkRecord>()\n for (const record of records) {\n const prior = byScenario.get(record.scenarioId)\n if (!prior) {\n byScenario.set(record.scenarioId, record)\n continue\n }\n if (prior.split !== record.split) {\n throw new ValidationError(\n `records for scenario '${record.scenarioId}' disagree on split (${prior.split} vs ${record.split})`,\n )\n }\n }\n return [...byScenario.values()]\n}\n\n/** Derive the bundle manifest from already-normalized records. */\nexport function buildProductBenchmarkManifest(\n records: readonly ProductBenchmarkRecord[],\n options: Pick<\n ProductBenchmarkExportOptions,\n 'outDir' | 'projectId' | 'benchmarkId' | 'scenarioTagPrefix' | 'mutableSurfaces' | 'substrate'\n >,\n): ProductBenchmarkManifest {\n if (records.length === 0) {\n throw new ValidationError('cannot build a product benchmark manifest from zero records')\n }\n const scenarioTagPrefix = options.scenarioTagPrefix ?? defaultScenarioTagPrefix(options.projectId)\n const mutableSurfaces = options.mutableSurfaces ?? productBenchmarkMutableSurfaces\n const byProfile = new Map<string, ProductBenchmarkManifest['profiles'][number]>()\n for (const record of records) {\n byProfile.set(record.agentProfile.id, {\n id: record.agentProfile.id,\n profileHash: record.agentProfile.hash,\n agentProfilePath: record.agentProfile.path,\n })\n }\n const manifest: ProductBenchmarkManifest = {\n schemaVersion: 1,\n projectId: options.projectId,\n benchmarkId: options.benchmarkId,\n repo: productBenchmarkRepoIdentity(),\n substrate: {\n agentEval: packageVersion('@tangle-network/agent-eval'),\n agentRuntime: packageVersion('@tangle-network/agent-runtime'),\n agentInterface: packageVersion('@tangle-network/agent-interface'),\n sandbox: packageVersion('@tangle-network/sandbox'),\n ...options.substrate,\n },\n profiles: [...byProfile.values()],\n arms: uniqueArmRecords(records).map((record) => ({\n id: record.armId,\n profileId: record.agentProfile.id,\n mutableSurfaces: [...mutableSurfaces],\n policyAxes: {\n carrier: record.armId.includes('policy') ? 'resource-file' : 'profile',\n model: record.agentProfile.resolved.model,\n backend: record.agentProfile.resolved.backend,\n harness: record.agentProfile.resolved.harness,\n ...(record.agentProfile.resolved.reasoningEffort !== undefined\n ? { reasoningEffort: record.agentProfile.resolved.reasoningEffort }\n : {}),\n },\n })),\n scenarios: uniqueScenarioRecords(records).map((record) => ({\n id: record.scenarioId,\n split: record.split,\n tags: [scenarioTagPrefix, options.benchmarkId, record.split],\n sourceAllowedForSynthesis: false,\n })),\n budgets: {\n maxUsd: records.reduce((sum, record) => sum + record.usage.costUsd, 0),\n maxCells: records.length,\n maxWallMs: records.reduce((sum, record) => sum + record.usage.wallMs, 0),\n },\n expectedArtifactDir: resolve(options.outDir),\n }\n return validateProductBenchmarkManifest(manifest)\n}\n\n// ── Entry points ─────────────────────────────────────────────────────\n\n/** Single-run convenience wrapper over `exportProductBenchmarkRuns`. */\nexport function exportProductBenchmark(\n options: ProductBenchmarkSingleRunExportOptions,\n): ProductBenchmarkExportResult {\n const { runDir, ...rest } = options\n return exportProductBenchmarkRuns({ ...rest, runDirs: [runDir] })\n}\n\n/**\n * Export one or more product eval run dirs into a validated product\n * benchmark bundle at `outDir`. Both the manifest and every record are\n * run through the contract validators before anything is written.\n */\nexport function exportProductBenchmarkRuns(\n options: ProductBenchmarkExportOptions,\n): ProductBenchmarkExportResult {\n const opts = resolveOptions(options)\n const outDir = resolve(options.outDir)\n const runDirs = options.runDirs.map((runDir) => resolve(runDir))\n if (runDirs.length === 0) throw new ValidationError('export requires at least one run directory')\n const materialize = options.materializeSourceRuns !== false\n const rows = runDirs.flatMap((runDir) => {\n const sourceRecordsPath = join(runDir, 'records.jsonl')\n if (!existsSync(sourceRecordsPath)) throw new ValidationError(`missing ${sourceRecordsPath}`)\n const records = readRunRecords(sourceRecordsPath)\n if (records.length === 0) throw new ValidationError(`${sourceRecordsPath} is empty`)\n return records.map((record) => ({ record, runDir }))\n })\n mkdirSync(outDir, { recursive: true })\n const artifactsByRunDir = new Map<string, ProductBenchmarkRecord['artifacts']>()\n for (const [index, runDir] of runDirs.entries()) {\n artifactsByRunDir.set(\n runDir,\n materialize ? materializeRunArtifacts(runDir, outDir, index) : absoluteArtifacts(runDir),\n )\n }\n const artifactRoot = materialize ? outDir : '/'\n const normalized = rows.map(({ record, runDir }) =>\n runRecordToProductBenchmarkRecord(\n record,\n runDir,\n artifactRoot,\n artifactsByRunDir.get(runDir)!,\n { ...options, runDirs, backendVersion: opts.backendVersion },\n ),\n )\n const manifest = buildProductBenchmarkManifest(normalized, {\n outDir,\n projectId: opts.projectId,\n benchmarkId: opts.benchmarkId,\n scenarioTagPrefix: opts.scenarioTagPrefix,\n mutableSurfaces: opts.mutableSurfaces,\n ...(options.substrate !== undefined ? { substrate: options.substrate } : {}),\n })\n const manifestPath = join(outDir, 'product-benchmark-manifest.json')\n const recordsPath = join(outDir, 'product-benchmark-records.jsonl')\n writeFileSync(manifestPath, `${JSON.stringify(manifest, null, 2)}\\n`)\n writeFileSync(recordsPath, `${normalized.map((record) => JSON.stringify(record)).join('\\n')}\\n`)\n return { manifestPath, recordsPath, records: normalized.length }\n}\n\nfunction defaultScenarioTagPrefix(projectId: string): string {\n return projectId.replace(/-agent$/, '') || projectId\n}\n\nfunction resolveOptions(\n options: ProductBenchmarkExportOptions | ProductBenchmarkSingleRunExportOptions,\n): ResolvedExportOptions {\n return {\n projectId: options.projectId,\n benchmarkId: options.benchmarkId,\n agentProfilePath: options.agentProfilePath,\n passThreshold: options.passThreshold ?? 0.7,\n scenarioTagPrefix: options.scenarioTagPrefix ?? defaultScenarioTagPrefix(options.projectId),\n ...(options.fallbackProfileId !== undefined\n ? { fallbackProfileId: options.fallbackProfileId }\n : {}),\n mutableSurfaces: options.mutableSurfaces ?? productBenchmarkMutableSurfaces,\n ...(options.classifySplit !== undefined ? { classifySplit: options.classifySplit } : {}),\n ...(options.toolCallFallback !== undefined\n ? { toolCallFallback: options.toolCallFallback }\n : {}),\n backendVersion: options.backendVersion ?? packageVersion('@tangle-network/sandbox'),\n }\n}\n","import { existsSync, readFileSync, statSync } from 'node:fs'\nimport { dirname, join } from 'node:path'\nimport { ValidationError } from '../errors'\nimport { FAILURE_CLASSES, type FailureClass } from '../trace/schema'\n\nexport const productBenchmarkSplits = ['practice', 'dev', 'holdout', 'safety', 'sentinel'] as const\n\nexport type ProductBenchmarkSplit = (typeof productBenchmarkSplits)[number]\n\nexport interface ProductBenchmarkRepoRef {\n readonly url: string\n readonly commit: string\n readonly branch: string\n}\n\nexport interface ProductBenchmarkSubstrateVersions {\n readonly agentEval: string\n readonly agentRuntime: string\n readonly agentInterface: string\n readonly sandbox: string\n readonly agentBench?: string\n}\n\nexport interface ProductBenchmarkProfileRef {\n readonly id: string\n readonly profileHash: string\n readonly agentProfilePath: string\n}\n\nexport interface ProductBenchmarkArm {\n readonly id: string\n readonly profileId: string\n readonly mutableSurfaces: readonly string[]\n readonly policyAxes: Record<string, unknown>\n}\n\nexport interface ProductBenchmarkScenario {\n readonly id: string\n readonly split: ProductBenchmarkSplit\n readonly tags: readonly string[]\n readonly sourceAllowedForSynthesis: boolean\n}\n\nexport interface ProductBenchmarkBudgets {\n readonly maxUsd: number\n readonly maxCells: number\n readonly maxWallMs: number\n}\n\nexport interface ProductBenchmarkManifest {\n readonly schemaVersion: 1\n readonly projectId: string\n readonly benchmarkId: string\n readonly repo: ProductBenchmarkRepoRef\n readonly substrate: ProductBenchmarkSubstrateVersions\n readonly profiles: readonly ProductBenchmarkProfileRef[]\n readonly arms: readonly ProductBenchmarkArm[]\n readonly scenarios: readonly ProductBenchmarkScenario[]\n readonly budgets: ProductBenchmarkBudgets\n readonly expectedArtifactDir: string\n}\n\nexport interface AgentProfileRuntimeReceipt {\n readonly model: string\n readonly harness: string\n readonly backend: string\n readonly reasoningEffort?: string\n}\n\nexport type RuntimeResolution = AgentProfileRuntimeReceipt\n\nexport interface ProductBenchmarkRecord {\n readonly schemaVersion: 1\n readonly projectId: string\n readonly benchmarkId: string\n readonly runId: string\n readonly scenarioId: string\n readonly split: ProductBenchmarkSplit\n readonly armId: string\n readonly rep: number\n readonly agentProfile: {\n readonly id: string\n readonly hash: string\n readonly path: string\n readonly declared: RuntimeResolution\n readonly resolved: RuntimeResolution\n }\n readonly model: {\n readonly provider: string\n readonly id: string\n }\n readonly backend: {\n readonly kind: string\n readonly version: string\n }\n readonly outcome: {\n readonly pass: boolean\n readonly score: number\n readonly dimensions: Record<string, number>\n readonly failureClass: Exclude<FailureClass, 'success'> | null\n readonly failureDetail: string | null\n }\n readonly usage: {\n readonly inputTokens: number\n readonly outputTokens: number\n readonly costUsd: number\n readonly wallMs: number\n readonly toolCalls: number\n }\n readonly integrity: {\n readonly realBackend: boolean\n readonly rawCapture: boolean\n readonly traceCapture: boolean\n readonly noStubRows: boolean\n readonly priced: boolean\n readonly profileMaterialized: boolean\n }\n readonly artifacts: {\n readonly records: string\n readonly traces: string\n readonly raws: string\n readonly scores: string\n readonly workspace: string\n }\n}\n\nexport interface ProductBenchmarkRunInput {\n readonly manifestPath: string\n readonly recordsPath: string\n readonly artifactRoot?: string\n readonly checkArtifacts?: boolean\n}\n\nexport interface ProductBenchmarkValidationReport {\n readonly manifestPath: string\n readonly recordsPath: string\n readonly records: number\n /** Manifest repo fields that are empty or the `'unknown'` export sentinel. */\n readonly repoFailures: readonly string[]\n /** Manifest substrate versions that are empty or the `'unknown'` export\n * sentinel — a bundle without substrate identity is not reproducible. */\n readonly substrateFailures: readonly string[]\n readonly projects: readonly string[]\n readonly benchmarks: readonly string[]\n readonly arms: readonly string[]\n readonly scenarios: readonly string[]\n readonly passed: number\n readonly failed: number\n readonly inputTokens: number\n readonly outputTokens: number\n readonly costUsd: number\n readonly wallMs: number\n readonly integrityFailures: readonly string[]\n readonly missingArtifacts: readonly string[]\n}\n\nexport interface ProductBenchmarkArtifactPaths {\n readonly manifestPath: string\n readonly recordsPath: string\n}\n\nfunction isObject(value: unknown): value is Record<string, unknown> {\n return Boolean(value) && typeof value === 'object' && !Array.isArray(value)\n}\n\nfunction fail(path: string, message: string): never {\n throw new ValidationError(`${path}: ${message}`)\n}\n\nfunction wrapValidationError(path: string, err: unknown): never {\n if (err instanceof ValidationError) {\n throw new ValidationError(`${path}: ${err.message}`, { cause: err })\n }\n throw new ValidationError(`${path}: ${err instanceof Error ? err.message : String(err)}`, {\n cause: err,\n })\n}\n\nfunction expectObject(value: unknown, path: string): Record<string, unknown> {\n if (!isObject(value)) fail(path, 'must be an object')\n return value\n}\n\nfunction expectString(value: unknown, path: string): string {\n if (typeof value !== 'string' || value.trim().length === 0)\n fail(path, 'must be a non-empty string')\n return value\n}\n\nfunction expectFailureClass(value: unknown, path: string): Exclude<FailureClass, 'success'> {\n const parsed = expectString(value, path)\n if (parsed === 'success' || !FAILURE_CLASSES.includes(parsed as FailureClass)) {\n fail(path, `expected a non-success FailureClass, received ${JSON.stringify(parsed)}`)\n }\n return parsed as Exclude<FailureClass, 'success'>\n}\n\nfunction expectBoolean(value: unknown, path: string): boolean {\n if (typeof value !== 'boolean') fail(path, 'must be a boolean')\n return value\n}\n\nfunction expectNumber(\n value: unknown,\n path: string,\n opts: { readonly min?: number; readonly max?: number; readonly integer?: boolean } = {},\n): number {\n if (typeof value !== 'number' || !Number.isFinite(value)) fail(path, 'must be a finite number')\n if (opts.integer && !Number.isInteger(value)) fail(path, 'must be an integer')\n if (opts.min !== undefined && value < opts.min) fail(path, `must be >= ${opts.min}`)\n if (opts.max !== undefined && value > opts.max) fail(path, `must be <= ${opts.max}`)\n return value\n}\n\nfunction expectStringArray(value: unknown, path: string): string[] {\n if (!Array.isArray(value)) fail(path, 'must be an array')\n return value.map((entry, index) => expectString(entry, `${path}[${index}]`))\n}\n\nfunction expectObjectArray(value: unknown, path: string): Record<string, unknown>[] {\n if (!Array.isArray(value)) fail(path, 'must be an array')\n return value.map((entry, index) => expectObject(entry, `${path}[${index}]`))\n}\n\nfunction expectSplit(value: unknown, path: string): ProductBenchmarkSplit {\n const split = expectString(value, path)\n if (!productBenchmarkSplits.includes(split as ProductBenchmarkSplit)) {\n fail(path, `must be one of ${productBenchmarkSplits.join(', ')}`)\n }\n return split as ProductBenchmarkSplit\n}\n\nfunction optionalString(value: unknown, path: string): string | undefined {\n if (value === undefined) return undefined\n return expectString(value, path)\n}\n\nfunction expectDimensions(value: unknown, path: string): Record<string, number> {\n const obj = expectObject(value, path)\n const out: Record<string, number> = {}\n for (const [key, raw] of Object.entries(obj)) out[key] = expectNumber(raw, `${path}.${key}`)\n return out\n}\n\nfunction expectRuntimeResolution(value: unknown, path: string): RuntimeResolution {\n const obj = expectObject(value, path)\n return {\n model: expectString(obj.model, `${path}.model`),\n harness: expectString(obj.harness, `${path}.harness`),\n backend: expectString(obj.backend, `${path}.backend`),\n ...(obj.reasoningEffort !== undefined\n ? { reasoningEffort: optionalString(obj.reasoningEffort, `${path}.reasoningEffort`) }\n : {}),\n }\n}\n\nexport function validateProductBenchmarkManifest(value: unknown): ProductBenchmarkManifest {\n const obj = expectObject(value, 'manifest')\n if (obj.schemaVersion !== 1) fail('manifest.schemaVersion', 'must be 1')\n const repo = expectObject(obj.repo, 'manifest.repo')\n const substrate = expectObject(obj.substrate, 'manifest.substrate')\n const profiles = expectObjectArray(obj.profiles, 'manifest.profiles').map((profile, index) => ({\n id: expectString(profile.id, `manifest.profiles[${index}].id`),\n profileHash: expectString(profile.profileHash, `manifest.profiles[${index}].profileHash`),\n agentProfilePath: expectString(\n profile.agentProfilePath,\n `manifest.profiles[${index}].agentProfilePath`,\n ),\n }))\n const arms = expectObjectArray(obj.arms, 'manifest.arms').map((arm, index) => ({\n id: expectString(arm.id, `manifest.arms[${index}].id`),\n profileId: expectString(arm.profileId, `manifest.arms[${index}].profileId`),\n mutableSurfaces: expectStringArray(\n arm.mutableSurfaces,\n `manifest.arms[${index}].mutableSurfaces`,\n ),\n policyAxes: expectObject(arm.policyAxes, `manifest.arms[${index}].policyAxes`),\n }))\n const scenarios = expectObjectArray(obj.scenarios, 'manifest.scenarios').map(\n (scenario, index) => ({\n id: expectString(scenario.id, `manifest.scenarios[${index}].id`),\n split: expectSplit(scenario.split, `manifest.scenarios[${index}].split`),\n tags: expectStringArray(scenario.tags, `manifest.scenarios[${index}].tags`),\n sourceAllowedForSynthesis: expectBoolean(\n scenario.sourceAllowedForSynthesis,\n `manifest.scenarios[${index}].sourceAllowedForSynthesis`,\n ),\n }),\n )\n const budgets = expectObject(obj.budgets, 'manifest.budgets')\n if (profiles.length === 0) fail('manifest.profiles', 'must contain at least one profile')\n if (arms.length === 0) fail('manifest.arms', 'must contain at least one arm')\n if (scenarios.length === 0) fail('manifest.scenarios', 'must contain at least one scenario')\n assertUnique(\n profiles.map((profile) => profile.id),\n 'manifest.profiles.id',\n )\n assertUnique(\n arms.map((arm) => arm.id),\n 'manifest.arms.id',\n )\n assertUnique(\n scenarios.map((scenario) => scenario.id),\n 'manifest.scenarios.id',\n )\n const profileIds = new Set(profiles.map((profile) => profile.id))\n for (const arm of arms) {\n if (!profileIds.has(arm.profileId))\n fail(`manifest.arms.${arm.id}.profileId`, `unknown profile ${arm.profileId}`)\n }\n return {\n schemaVersion: 1,\n projectId: expectString(obj.projectId, 'manifest.projectId'),\n benchmarkId: expectString(obj.benchmarkId, 'manifest.benchmarkId'),\n repo: {\n url: expectString(repo.url, 'manifest.repo.url'),\n commit: expectString(repo.commit, 'manifest.repo.commit'),\n branch: expectString(repo.branch, 'manifest.repo.branch'),\n },\n substrate: {\n agentEval: expectString(substrate.agentEval, 'manifest.substrate.agentEval'),\n agentRuntime: expectString(substrate.agentRuntime, 'manifest.substrate.agentRuntime'),\n agentInterface: expectString(substrate.agentInterface, 'manifest.substrate.agentInterface'),\n sandbox: expectString(substrate.sandbox, 'manifest.substrate.sandbox'),\n ...(substrate.agentBench !== undefined\n ? { agentBench: expectString(substrate.agentBench, 'manifest.substrate.agentBench') }\n : {}),\n },\n profiles,\n arms,\n scenarios,\n budgets: {\n maxUsd: expectNumber(budgets.maxUsd, 'manifest.budgets.maxUsd', { min: 0 }),\n maxCells: expectNumber(budgets.maxCells, 'manifest.budgets.maxCells', {\n min: 0,\n integer: true,\n }),\n maxWallMs: expectNumber(budgets.maxWallMs, 'manifest.budgets.maxWallMs', {\n min: 0,\n integer: true,\n }),\n },\n expectedArtifactDir: expectString(obj.expectedArtifactDir, 'manifest.expectedArtifactDir'),\n }\n}\n\nexport function validateProductBenchmarkRecord(value: unknown): ProductBenchmarkRecord {\n const obj = expectObject(value, 'record')\n if (obj.schemaVersion !== 1) fail('record.schemaVersion', 'must be 1')\n const agentProfile = expectObject(obj.agentProfile, 'record.agentProfile')\n const model = expectObject(obj.model, 'record.model')\n const backend = expectObject(obj.backend, 'record.backend')\n const outcome = expectObject(obj.outcome, 'record.outcome')\n const usage = expectObject(obj.usage, 'record.usage')\n const integrity = expectObject(obj.integrity, 'record.integrity')\n const artifacts = expectObject(obj.artifacts, 'record.artifacts')\n const outcomePass = expectBoolean(outcome.pass, 'record.outcome.pass')\n const failureClass =\n outcome.failureClass === null\n ? null\n : expectFailureClass(outcome.failureClass, 'record.outcome.failureClass')\n const failureDetail =\n outcome.failureDetail === null\n ? null\n : expectString(outcome.failureDetail, 'record.outcome.failureDetail')\n if (outcomePass && (failureClass !== null || failureDetail !== null)) {\n fail('record.outcome', 'a passing row cannot carry failure evidence')\n }\n if (!outcomePass && failureClass === null) {\n fail('record.outcome.failureClass', 'a failed row requires a failure class')\n }\n if (failureClass === null && failureDetail !== null) {\n fail('record.outcome.failureDetail', 'failure detail requires a failure class')\n }\n const record: ProductBenchmarkRecord = {\n schemaVersion: 1,\n projectId: expectString(obj.projectId, 'record.projectId'),\n benchmarkId: expectString(obj.benchmarkId, 'record.benchmarkId'),\n runId: expectString(obj.runId, 'record.runId'),\n scenarioId: expectString(obj.scenarioId, 'record.scenarioId'),\n split: expectSplit(obj.split, 'record.split'),\n armId: expectString(obj.armId, 'record.armId'),\n rep: expectNumber(obj.rep, 'record.rep', { min: 1, integer: true }),\n agentProfile: {\n id: expectString(agentProfile.id, 'record.agentProfile.id'),\n hash: expectString(agentProfile.hash, 'record.agentProfile.hash'),\n path: expectString(agentProfile.path, 'record.agentProfile.path'),\n declared: expectRuntimeResolution(agentProfile.declared, 'record.agentProfile.declared'),\n resolved: expectRuntimeResolution(agentProfile.resolved, 'record.agentProfile.resolved'),\n },\n model: {\n provider: expectString(model.provider, 'record.model.provider'),\n id: expectString(model.id, 'record.model.id'),\n },\n backend: {\n kind: expectString(backend.kind, 'record.backend.kind'),\n version: expectString(backend.version, 'record.backend.version'),\n },\n outcome: {\n pass: outcomePass,\n score: expectNumber(outcome.score, 'record.outcome.score', { min: 0, max: 1 }),\n dimensions: expectDimensions(outcome.dimensions, 'record.outcome.dimensions'),\n failureClass,\n failureDetail,\n },\n usage: {\n inputTokens: expectNumber(usage.inputTokens, 'record.usage.inputTokens', {\n min: 0,\n integer: true,\n }),\n outputTokens: expectNumber(usage.outputTokens, 'record.usage.outputTokens', {\n min: 0,\n integer: true,\n }),\n costUsd: expectNumber(usage.costUsd, 'record.usage.costUsd', { min: 0 }),\n wallMs: expectNumber(usage.wallMs, 'record.usage.wallMs', { min: 0, integer: true }),\n toolCalls: expectNumber(usage.toolCalls, 'record.usage.toolCalls', { min: 0, integer: true }),\n },\n integrity: {\n realBackend: expectBoolean(integrity.realBackend, 'record.integrity.realBackend'),\n rawCapture: expectBoolean(integrity.rawCapture, 'record.integrity.rawCapture'),\n traceCapture: expectBoolean(integrity.traceCapture, 'record.integrity.traceCapture'),\n noStubRows: expectBoolean(integrity.noStubRows, 'record.integrity.noStubRows'),\n priced: expectBoolean(integrity.priced, 'record.integrity.priced'),\n profileMaterialized: expectBoolean(\n integrity.profileMaterialized,\n 'record.integrity.profileMaterialized',\n ),\n },\n artifacts: {\n records: expectString(artifacts.records, 'record.artifacts.records'),\n traces: expectString(artifacts.traces, 'record.artifacts.traces'),\n raws: expectString(artifacts.raws, 'record.artifacts.raws'),\n scores: expectString(artifacts.scores, 'record.artifacts.scores'),\n workspace: expectString(artifacts.workspace, 'record.artifacts.workspace'),\n },\n }\n if (record.integrity.realBackend && record.usage.inputTokens + record.usage.outputTokens === 0) {\n fail('record.usage', 'realBackend rows must carry non-zero token usage')\n }\n return record\n}\n\nexport function productBenchmarkIntegrityFailures(record: ProductBenchmarkRecord): string[] {\n const failures: string[] = []\n for (const [key, value] of Object.entries(record.integrity)) {\n if (!value) failures.push(`${record.runId}:${key}=false`)\n }\n return failures\n}\n\nexport function readProductBenchmarkRecords(path: string): ProductBenchmarkRecord[] {\n const lines = readFileSync(path, 'utf8')\n .split('\\n')\n .map((line) => line.trim())\n .filter(Boolean)\n const records: ProductBenchmarkRecord[] = []\n for (const [index, line] of lines.entries()) {\n try {\n records.push(validateProductBenchmarkRecord(JSON.parse(line)))\n } catch (err) {\n wrapValidationError(`${path}:${index + 1}`, err)\n }\n }\n return records\n}\n\nexport function readProductBenchmarkManifest(path: string): ProductBenchmarkManifest {\n try {\n return validateProductBenchmarkManifest(JSON.parse(readFileSync(path, 'utf8')))\n } catch (err) {\n wrapValidationError(path, err)\n }\n}\n\nexport function validateProductBenchmarkRun(\n input: ProductBenchmarkRunInput,\n): ProductBenchmarkValidationReport {\n const manifest = readProductBenchmarkManifest(input.manifestPath)\n const records = readProductBenchmarkRecords(input.recordsPath)\n const manifestProjectBench = `${manifest.projectId}/${manifest.benchmarkId}`\n const integrityFailures = records.flatMap(productBenchmarkIntegrityFailures)\n const missingArtifacts =\n input.checkArtifacts === false\n ? []\n : records.flatMap((record) =>\n missingArtifactsForRecord(record, input.artifactRoot ?? dirname(input.recordsPath)),\n )\n for (const [index, record] of records.entries()) {\n const recordProjectBench = `${record.projectId}/${record.benchmarkId}`\n if (recordProjectBench !== manifestProjectBench) {\n fail(\n `records[${index}]`,\n `project/benchmark ${recordProjectBench} does not match manifest ${manifestProjectBench}`,\n )\n }\n if (!manifest.arms.some((arm) => arm.id === record.armId))\n fail(`records[${index}].armId`, `unknown arm ${record.armId}`)\n if (!manifest.scenarios.some((scenario) => scenario.id === record.scenarioId)) {\n fail(`records[${index}].scenarioId`, `unknown scenario ${record.scenarioId}`)\n }\n }\n const repoFailures = (['url', 'commit', 'branch'] as const)\n .filter((key) => manifest.repo[key].trim().length === 0 || manifest.repo[key] === 'unknown')\n .map((key) => `manifest.repo.${key}`)\n const substrateFailures = (['agentEval', 'agentRuntime', 'agentInterface', 'sandbox'] as const)\n .filter(\n (key) => manifest.substrate[key].trim().length === 0 || manifest.substrate[key] === 'unknown',\n )\n .map((key) => `manifest.substrate.${key}`)\n return {\n manifestPath: input.manifestPath,\n recordsPath: input.recordsPath,\n records: records.length,\n repoFailures,\n substrateFailures,\n projects: sortedUnique(records.map((record) => record.projectId)),\n benchmarks: sortedUnique(records.map((record) => record.benchmarkId)),\n arms: sortedUnique(records.map((record) => record.armId)),\n scenarios: sortedUnique(records.map((record) => record.scenarioId)),\n passed: records.filter((record) => record.outcome.pass).length,\n failed: records.filter((record) => !record.outcome.pass).length,\n inputTokens: sum(records, (record) => record.usage.inputTokens),\n outputTokens: sum(records, (record) => record.usage.outputTokens),\n costUsd: sum(records, (record) => record.usage.costUsd),\n wallMs: sum(records, (record) => record.usage.wallMs),\n integrityFailures,\n missingArtifacts,\n }\n}\n\nfunction missingArtifactsForRecord(record: ProductBenchmarkRecord, artifactRoot: string): string[] {\n const missing: string[] = []\n for (const [key, value] of Object.entries(record.artifacts)) {\n const path = resolveArtifactPath(value, artifactRoot)\n if (!existsSync(path)) missing.push(`${record.runId}:${key}:${value}`)\n }\n return missing\n}\n\nfunction resolveArtifactPath(value: string, artifactRoot: string): string {\n return value.startsWith('/') ? value : join(artifactRoot, value)\n}\n\nfunction assertUnique(values: readonly string[], path: string): void {\n const seen = new Set<string>()\n for (const value of values) {\n if (seen.has(value)) fail(path, `duplicate ${value}`)\n seen.add(value)\n }\n}\n\nfunction sortedUnique(values: readonly string[]): string[] {\n return [...new Set(values)].sort()\n}\n\nfunction sum<T>(items: readonly T[], fn: (item: T) => number): number {\n return items.reduce((total, item) => total + fn(item), 0)\n}\n\nexport function findProductBenchmarkArtifacts(\n runDir: string,\n): ProductBenchmarkArtifactPaths | null {\n const manifestPath = join(runDir, 'product-benchmark-manifest.json')\n const recordsPath = join(runDir, 'product-benchmark-records.jsonl')\n if (\n existsSync(manifestPath) &&\n statSync(manifestPath).isFile() &&\n existsSync(recordsPath) &&\n statSync(recordsPath).isFile()\n ) {\n return { manifestPath, recordsPath }\n }\n return null\n}\n\n/**\n * Fail-loud gate over a bundle directory: locates the manifest + records,\n * runs `validateProductBenchmarkRun`, and throws with every repo,\n * integrity, and artifact failure listed. Returns the report when clean.\n */\nexport function assertProductBenchmarkRun(runDir: string): ProductBenchmarkValidationReport {\n const artifacts = findProductBenchmarkArtifacts(runDir)\n if (!artifacts) {\n fail(runDir, 'missing product-benchmark-manifest.json or product-benchmark-records.jsonl')\n }\n const report = validateProductBenchmarkRun({ ...artifacts, artifactRoot: runDir })\n const failures = [\n ...report.repoFailures,\n ...report.substrateFailures,\n ...report.integrityFailures,\n ...report.missingArtifacts,\n ]\n if (failures.length > 0) {\n fail(runDir, `product benchmark validation failed:\\n${failures.join('\\n')}`)\n }\n return report\n}\n\nexport type {\n ProductBenchmarkExportOptions,\n ProductBenchmarkExportResult,\n ProductBenchmarkSingleRunExportOptions,\n} from './export'\nexport {\n buildProductBenchmarkManifest,\n exportProductBenchmark,\n exportProductBenchmarkRuns,\n productBenchmarkMutableSurfaces,\n productBenchmarkRepoIdentity,\n runRecordToProductBenchmarkRecord,\n} from './export'\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2FA,SAAS,qBAAqB,OAA+C;CAC3E,IAAI,CAAC,MAAM,KAAK,MAAM,KAAK,KAAK,CAAC,MAAM,KAAK,KAAK,KAAK,GACpD,MAAM,IAAI,gBAAgB,kDAAkD;CAE9E,IAAI,CAAC,MAAM,WAAW,KAAK,KAAK,KAAK,KAAK,MAAM,UAAU,GACxD,MAAM,IAAI,gBACR,uEACF;CAEF,IAAI,MAAM,gBAAgB,MAAM,cAAc,SAC5C,MAAM,IAAI,gBAAgB,uDAAuD;CAEnF,IAAI,MAAM,YAAY,WAAW,GAC/B,MAAM,IAAI,gBAAgB,8CAA8C;CAE1E,MAAM,4BAAY,IAAI,IAAY;CAClC,KAAK,MAAM,UAAU,MAAM,aAAa;EACtC,IAAI,CAAC,OAAO,KAAK,KAAK,KAAK,OAAO,KAAK,SAAS,IAAI,KAAK,OAAO,KAAK,WAAW,GAAG,GACjF,MAAM,IAAI,gBACR,qCAAqC,OAAO,KAAK,2BACnD;EAEF,IAAI,UAAU,IAAI,OAAO,IAAI,GAC3B,MAAM,IAAI,gBAAgB,uCAAuC,OAAO,KAAK,EAAE;EAEjF,UAAU,IAAI,OAAO,IAAI;CAC3B;CACA,IAAI,CAAC,MAAM,MAAM,KAAK,GACpB,MAAM,IAAI,gBAAgB,wCAAwC;AAEtE;;;;;;;;;AA8CA,SAAgB,iBAAiB,MAA6C;CAC5E,MAAM,YAAY,KAAK,aAAa;CACpC,MAAM,WAAW,KAAK,WAAW,yBAAA,CAA0B,QAAQ,QAAQ,EAAE;CAC7E,MAAM,MAAM,KAAK,8BAAc,IAAI,KAAK;CAExC,eAAe,IACb,QACA,MACA,MACA,YAAY,OACO;EACnB,MAAM,MAAM,MAAM,UAAU,GAAG,UAAU,QAAQ;GAC/C;GACA,SAAS;IACP,QAAQ;IACR,gBAAgB;IAChB,eAAe,UAAU,KAAK;IAC9B,wBAAwB;GAC1B;GACA,MAAM,SAAS,KAAA,IAAY,KAAA,IAAY,KAAK,UAAU,IAAI;EAC5D,CAAC;EACD,IAAI,aAAa,IAAI,WAAW,KAAK,OAAO;EAC5C,IAAI,CAAC,IAAI,IAAI;GACX,MAAM,OAAO,MAAM,IAAI,KAAK,CAAC,CAAC,YAAY,EAAE;GAC5C,MAAM,IAAI,YACR,yBAAyB,OAAO,GAAG,KAAK,KAAK,IAAI,OAAO,GAAG,KAAK,MAAM,GAAG,GAAG,GAC9E;EACF;EACA,OAAQ,MAAM,IAAI,KAAK;CACzB;CAEA,OAAO,EACL,MAAM,cAAc,OAAO;EACzB,qBAAqB,KAAK;EAC1B,MAAM,aAAa,MAAM,cAAc;EACvC,MAAM,WAAW,UAAU,MAAM,KAAK,MAAM,GAAG,MAAM,KAAK;EAE1D,IAAI,MAAM,QACR,OAAO;GACL,OAAO,sBAAsB,MAAM,KAAK,MAAM,GAAG,MAAM,KAAK,KAAK,WAAW,WAAW,KAAK,MAAM;GAClG,YAAY,MAAM;GAClB,SAAS;GACT,QAAQ;EACV;EAIF,MAAM,UAAU,MAAM,IAAW,OAAO,GAAG,SAAS,iBAAiB,YAAY;EACjF,IAAI,CAAC,SACH,MAAM,IAAI,YAAY,+BAA+B,WAAW,YAAY;EAE9E,MAAM,UAAU,QAAQ,OAAO;EAC/B,MAAM,aAAa,MAAM,IAAc,OAAO,GAAG,SAAS,eAAe,SAAS;EAClF,IAAI,CAAC,YACH,MAAM,IAAI,YAAY,8BAA8B,QAAQ,6BAA6B;EAI3F,MAAM,cAAc,CAAC;EACrB,KAAK,MAAM,UAAU,MAAM,aAAa;GACtC,MAAM,OAAO,MAAM,IAAY,QAAQ,GAAG,SAAS,aAAa;IAC9D,SAAS,OAAO;IAChB,UAAU;GACZ,CAAC;GACD,IAAI,CAAC,MAAM,MAAM,IAAI,YAAY,4CAA4C;GAC7E,YAAY,KAAK;IACf,MAAM,OAAO;IACb,MAAM;IACN,MAAM;IACN,KAAK,KAAK;GACZ,CAAC;EACH;EAGA,MAAM,OAAO,MAAM,IAAY,QAAQ,GAAG,SAAS,aAAa;GAC9D,WAAW,WAAW,KAAK;GAC3B,MAAM;EACR,CAAC;EACD,IAAI,CAAC,MAAM,MAAM,IAAI,YAAY,4CAA4C;EAG7E,MAAM,SACJ,MAAM,cAAc,MAAM,cACtB;GAAE,MAAM,MAAM;GAAY,OAAO,MAAM;GAAa,MAAM,IAAI,CAAC,CAAC,YAAY;EAAE,IAC9E,KAAA;EACN,MAAM,gBAAgB,oBAAoB,KAAK;EAC/C,MAAM,SAAS,MAAM,IAAc,QAAQ,GAAG,SAAS,eAAe;GACpE,SAAS;GACT,MAAM,KAAK;GACX,SAAS,CAAC,OAAO;GACjB,GAAI,SAAS;IAAE;IAAQ,WAAW;GAAO,IAAI,CAAC;EAChD,CAAC;EACD,IAAI,CAAC,QAAQ,MAAM,IAAI,YAAY,8CAA8C;EAGjF,MAAM,WAAW,MAAM,IACrB,OACA,GAAG,SAAS,iBAAiB,MAAM,cACnC,KAAA,GACA,IACF;EACA,IAAI,CAAC,UACH,MAAM,IAAI,QAAQ,GAAG,SAAS,YAAY;GACxC,KAAK,cAAc,MAAM;GACzB,KAAK,OAAO;EACd,CAAC;OACI,IAAI,SAAS,OAAO,QAAQ,OAAO,KACxC,MAAM,IAAI,SAAS,GAAG,SAAS,kBAAkB,MAAM,cAAc;GACnE,KAAK,OAAO;GACZ,OAAO;EACT,CAAC;EAIH,MAAM,UAAU,MAAM,IACpB,OACA,GAAG,SAAS,yBAAyB,mBAAmB,GAAG,MAAM,KAAK,MAAM,GAAG,MAAM,YAAY,GACnG;EACA,IAAI;EACJ,IAAI,WAAW,QAAQ,SAAS,GAC9B,KAAK,QAAQ;OACR;GACL,MAAM,UAAU,MAAM,IAAmB,QAAQ,GAAG,SAAS,SAAS;IACpE,OAAO,MAAM;IACb,MAAM,MAAM;IACZ,MAAM,MAAM;IACZ,MAAM;GACR,CAAC;GACD,IAAI,CAAC,SAAS,MAAM,IAAI,YAAY,0CAA0C;GAC9E,KAAK;EACP;EAEA,IAAI,MAAM,aAAa,MAAM,UAAU,SAAS,GAC9C,MAAM,IACJ,QACA,GAAG,SAAS,SAAS,GAAG,OAAO,uBAC/B,EAAE,WAAW,MAAM,UAAU,GAC7B,IACF,CAAC,CAAC,YAAY,CAEd,CAAC;EAEH,IAAI,MAAM,UAAU,MAAM,OAAO,SAAS,GACxC,MAAM,IACJ,QACA,GAAG,SAAS,UAAU,GAAG,OAAO,UAChC,EAAE,QAAQ,MAAM,OAAO,GACvB,IACF,CAAC,CAAC,YAAY,CAEd,CAAC;EAGH,OAAO;GACL,OAAO,GAAG;GACV,YAAY,MAAM;GAClB,SAAS,OAAO;GAChB,QAAQ;EACV;CACF,EACF;AACF;;;;;;;;;;AA0BA,SAAgB,YAAY,OAA2B,CAAC,GAAiB;CACvE,MAAM,MAAM,KAAK,OAAO;CACxB,MAAM,MAAM,KAAK,OAAO,QAAQ,IAAI;CACpC,MAAM,OAAO,KAAK,QAAQ;CAE1B,eAAe,IACb,KACA,MACA,OAC6C;EAC7C,MAAM,IAAI,MAAM,KAAK,KAAK,MAAM;GAAE;GAAK;EAAM,CAAC;EAC9C,IAAI,EAAE,aAAa,GACjB,MAAM,IAAI,YACR,kBAAkB,IAAI,GAAG,KAAK,KAAK,GAAG,EAAE,WAAW,EAAE,SAAS,KAAK,EAAE,OAAO,KAAK,KAAK,EAAE,OAAO,KAAK,GACtG;EAEF,OAAO;CACT;CAEA,OAAO,EACL,MAAM,cAAc,OAAO;EACzB,qBAAqB,KAAK;EAC1B,MAAM,aAAa,MAAM,cAAc;EACvC,IAAI,MAAM,QACR,OAAO;GACL,OAAO,sBAAsB,MAAM,KAAK,MAAM,GAAG,MAAM,KAAK,KAAK,WAAW,WAAW,KAAK,MAAM;GAClG,YAAY,MAAM;GAClB,SAAS;GACT,QAAQ;EACV;EAIF,MAAM,IAAI,OAAO;GAAC;GAAS;GAAU;EAAU,CAAC;EAChD,MAAM,IAAI,OAAO,CAAC,YAAY,UAAU,CAAC;EACzC,MAAM,IAAI,OAAO;GAAC;GAAS;GAAU,UAAU;EAAY,CAAC;EAG5D,MAAM,KAAK,OAAO;GAAC;GAAU;GAAM,MAAM;EAAU,GAAG,EAAE,IAAI,CAAC;EAC7D,MAAM,IAAI,OAAO;GAAC;GAAY;GAAM,MAAM;EAAU,CAAC;EAGrD,MAAM,EAAE,OAAO,cAAc,MAAM,OAAO;EAC1C,MAAM,EAAE,SAAS,MAAM,YAAY,MAAM,OAAO;EAChD,KAAK,MAAM,UAAU,MAAM,aAAa;GACtC,MAAM,MAAM,QAAQ,KAAK,OAAO,IAAI;GACpC,MAAM,MAAM,QAAQ,GAAG,GAAG,EAAE,WAAW,KAAK,CAAC;GAC7C,MAAM,UAAU,KAAK,OAAO,UAAU,MAAM;GAC5C,MAAM,IAAI,OAAO,CAAC,OAAO,KAAK,OAAO,IAAI,CAAC,CAAC;EAC7C;EAGA,MAAM,MAA8B,CAAC;EACrC,IAAI,MAAM,YAAY,IAAI,kBAAkB,MAAM;EAClD,IAAI,MAAM,aAAa,IAAI,mBAAmB,MAAM;EACpD,IAAI,MAAM,YAAY,IAAI,qBAAqB,MAAM;EACrD,IAAI,MAAM,aAAa,IAAI,sBAAsB,MAAM;EAEvD,MAAM,IAAI,OAAO;GAAC;GAAU;GADZ,oBAAoB,KACI;EAAC,CAAC;EAG1C,MAAM,WAAU,MADM,IAAI,OAAO,CAAC,aAAa,MAAM,CAAC,EAAA,CAC9B,OAAO,KAAK;EAGpC,MAAM,IAAI,OAAO;GAAC;GAAQ;GAAM;GAAU,MAAM;EAAU,CAAC;EAG3D,MAAM,WAAW,MAAM,KACrB,KACA;GACE;GACA;GACA;GACA;GACA;GACA,MAAM;GACN;GACA;GACA;GACA;EACF,GACA,EAAE,IAAI,CACR;EACA,IAAI,QAAQ;EACZ,IAAI,SAAS,aAAa,KAAK,SAAS,OAAO,KAAK,GAAG;GACrD,MAAM,SAAS,KAAK,MAAM,SAAS,MAAM;GACzC,IAAI,OAAO,SAAS,KAAK,OAAO,IAAI,QAAQ,OAAO,EAAE,CAAC;EACxD;EACA,IAAI,CAAC,OAAO;GACV,MAAM,OAAO;IACX;IACA;IACA;IACA,MAAM;IACN;IACA,MAAM;IACN;IACA;GACF;GACA,IAAI,MAAM,aAAa,MAAM,UAAU,SAAS,GAC9C,KAAK,KAAK,cAAc,MAAM,UAAU,KAAK,GAAG,CAAC;GAEnD,IAAI,MAAM,UAAU,MAAM,OAAO,SAAS,GACxC,KAAK,KAAK,WAAW,MAAM,OAAO,KAAK,GAAG,CAAC;GAE7C,MAAM,IAAI,MAAM,IAAI,KAAK,IAAI;GAC7B,MAAM,QAAQ,EAAE,OAAO,MAAM,gBAAgB;GAC7C,QAAQ,QAAQ,MAAM,KAAK,EAAE,OAAO,KAAK;EAC3C;EAEA,OAAO;GAAE;GAAO,YAAY,MAAM;GAAY;GAAS,QAAQ;EAAM;CACvE,EACF;AACF;AAEA,eAAe,YACb,KACA,MACA,MAC+D;CAC/D,MAAM,EAAE,UAAU,MAAM,OAAO;CAC/B,OAAO,IAAI,SAAS,gBAAgB;EAClC,MAAM,QAAQ,MAAM,KAAK,MAAM,EAAE,KAAK,KAAK,IAAI,CAAC;EAChD,IAAI,SAAS;EACb,IAAI,SAAS;EACb,MAAM,OAAO,GAAG,SAAS,MAAM;GAC7B,UAAU,EAAE,SAAS;EACvB,CAAC;EACD,MAAM,OAAO,GAAG,SAAS,MAAM;GAC7B,UAAU,EAAE,SAAS;EACvB,CAAC;EACD,IAAI,KAAK,OAAO,MAAM,MAAM,IAAI,KAAK,KAAK;EAC1C,MAAM,GAAG,UAAU,QAAQ;GACzB,YAAY;IAAE;IAAQ,QAAQ,GAAG,SAAS,IAAI;IAAW,UAAU;GAAE,CAAC;EACxE,CAAC;EACD,MAAM,GAAG,UAAU,SAAS;GAC1B,YAAY;IAAE;IAAQ;IAAQ,UAAU,QAAQ;GAAE,CAAC;EACrD,CAAC;CACH,CAAC;AACH;AAEA,SAAS,oBAAoB,OAAiD;CAC5E,MAAM,QAAQ,CAAC,MAAM,OAAO,EAAE;CAC9B,KAAK,MAAM,UAAU,MAAM,aACzB,IAAI,OAAO,WAAW,MAAM,KAAK,KAAK,OAAO,KAAK,IAAI,OAAO,WAAW;CAE1E,IAAI,MAAM,MAAM,SAAS,OAAO,IAAI,MAAM,KAAK,EAAE;CACjD,MAAM,KAAK,MAAM,KAAK,KAAK,CAAC;CAC5B,OAAO,MAAM,KAAK,IAAI,CAAC,CAAC,KAAK;AAC/B;;;AChcA,SAAS,WAAW,KAAsB;CACxC,IAAI,eAAe,OAAO,OAAO,GAAG,IAAI,KAAK,IAAI,IAAI;CACrD,OAAO,OAAO,GAAG;AACnB;;;;;;AAcA,eAAsB,gBACpB,MACA,UACA,QACyB;CACzB,MAAM,YAAY,KAAK,IAAI;CAC3B,MAAM,QAAQ,OAAO,SAAS;CAC9B,MAAM,aAAa,OAAO,cAAc,IAAI,WAAW;CACvD,MAAM,WAAW;EACf,GAAG,OAAO;EACV,YAAY,SAAS;EACrB,aAAa,WAAW,OAAO,WAAW;CAC5C;CAMA,MAAM,WAA0B,CAAC;EAAE,MAAM;EAAU,SAJ9B,CAAC,OAAO,cAAc,SAAS,sBAAsB,EAAE,CAAC,CAC1E,OAAO,OAAO,CAAC,CACf,KAAK,MAE+D;CAAE,CAAC;CAE1E,MAAM,QAAsB,CAAC;CAC7B,MAAM,gBAAsD,CAAC;CAC7D,MAAM,YAAgE,CAAC;CACvE,MAAM,eAAyB,CAAC;CAEhC,MAAM,UAAU,OAAO,gBAAgB;CAEvC,KAAK,IAAI,IAAI,GAAG,IAAI,SAAS,MAAM,QAAQ,KAAK;EAC9C,MAAM,OAAO,SAAS,MAAM;EAC5B,MAAM,YAAY,KAAK,IAAI;EAE3B,SAAS,KAAK;GAAE,MAAM;GAAQ,SAAS,KAAK;EAAK,CAAC;EAElD,MAAM,UAAU;GACd;GACA;GACA,aAAa;GACb,WAAW;EACb;EACA,MAAM,OAAO,MAAM,WAAW,YAAY;GACxC,SAAS;GACT,OAAO,OAAO,aAAa;GAC3B,OAAO;GACP;GACA,eACE,KAAK,oBAAoB,KAAA,IACrB,KAAA,IACA,2BAA2B,SAAS,EAAE,iBAAiB,KAAK,gBAAgB,CAAC;GACnF,MAAM;GACN,QAAQ,OAAO;GACf,UAAU,QAAQ,WAAW,KAAK,KAAK,SAAS;IAAE;IAAQ,gBAAgB;GAAO,CAAC;GAClF,SAAS;GACT,kBAAkB;EACpB,CAAC;EACD,IAAI,CAAC,KAAK,WAAW,MAAM,KAAK;EAQhC,kBAAkB,OAAQ,KAAK,MAA0C,aAAa;GACpF,iBAAiB;GACjB,SAAS,oBAAoB,SAAS,GAAG,SAAS;EACpD,CAAC;EACD,MAAM,aAAc,KAAK,MAAgC;EACzD,IAAI,OAAO,eAAe,UACxB,MAAM,IAAI,sBACR,+BAA+B,SAAS,GAAG,SAAS,EAAE,sDAElD,eAAe,OAAO,SAAS,OAAO,YAE5C;EAEF,MAAM,UAAU;EAEhB,SAAS,KAAK;GAAE,MAAM;GAAa;EAAQ,CAAC;EAG5C,MAAM,SAAS;EACf,IAAI,YAAoC,OAAO,KAAK,OAAO;EAC3D,OAAO,cAAc,MAAM;GACzB,cAAc,KAAK;IAAE,UAAU,UAAU,MAAM;IAAQ,MAAM,UAAU,MAAM;GAAG,CAAC;GACjF,YAAY,OAAO,KAAK,OAAO;EACjC;EAGA,MAAM,aAAgD,CAAC;EACvD,MAAM,eAAe,IAAI,OAAO,QAAQ,QAAQ,QAAQ,KAAK;EAC7D,IAAI,aAAqC,aAAa,KAAK,OAAO;EAClE,OAAO,eAAe,MAAM;GAC1B,MAAM,SAAiC,CAAC;GACxC,KAAK,MAAM,SAAS,WAAW,MAAM,GAAA,CAAI,MAAM,IAAI,GAAG;IACpD,MAAM,MAAM,KAAK,QAAQ,GAAG;IAC5B,IAAI,MAAM,GAAG,OAAO,KAAK,MAAM,GAAG,GAAG,CAAC,CAAC,KAAK,KAAK,KAAK,MAAM,MAAM,CAAC,CAAC,CAAC,KAAK;GAC5E;GACA,MAAM,YAAY,WAAW,MAAM;GACnC,UAAU,KAAK;IAAE,MAAM;IAAW;GAAO,CAAC;GAC1C,WAAW,KAAK;IAAE,MAAM;IAAW,OAAO,OAAO,SAAS;GAAG,CAAC;GAC9D,aAAa,aAAa,KAAK,OAAO;EACxC;EAGA,IAAI,cAAc;EAClB,IAAI,OAAO,kBACT,KAAK,MAAM,WAAW,OAAO,kBAAkB;GAC7C,MAAM,KAAK,IAAI,OAAO,QAAQ,QAAQ,QAAQ,KAAK;GACnD,IAAI,YAAoC,GAAG,KAAK,OAAO;GACvD,OAAO,cAAc,MAAM;IACzB,aAAa,KAAK,UAAU,EAAE;IAC9B,cAAc;IACd,YAAY,GAAG,KAAK,OAAO;GAC7B;EACF;EAGF,MAAM,KAAK;GACT,WAAW;GACX,aAAa,KAAK;GAClB,eAAe;GACf,YAAY,KAAK,IAAI,IAAI;GACzB,iBAAiB;GACjB,cAAc,cAAc,SAAS;GACrC,kBAAkB;EACpB,CAAC;CACH;CAEA,MAAM,YAAgC;EACpC,YAAY,CAAC;EACb,iBAAiB;EACjB,YAAY;EACZ,WAAW;CACb;CAGA,MAAM,kBAAkB,SAAS,eAAe,KAAK,UAAU;EAE7D,IAAI,OAAO,iBAAiB;GAC1B,MAAM,SAAS,OAAO,gBAAgB,OAAO,SAAS;GACtD,IAAI,QAAQ,OAAO;IAAE;IAAO,GAAG;GAAO;EACxC;EAEA,QAAQ,MAAM,MAAd;GACE,KAAK,mBAAmB;IACtB,MAAM,QAAQ,UAAU,QAAQ,MAAM,EAAE,SAAS,MAAM,MAAM,CAAC,CAAC;IAC/D,OAAO;KACL;KACA,QAAQ,UAAU,MAAM,YAAY;KACpC,QAAQ,SAAS,MAAM,GAAG,MAAM,OAAO,gBAAgB,MAAM,YAAY,EAAE;IAC7E;GACF;GACA,KAAK,cAAc;IACjB,MAAM,UAAU,cAAc,MAC3B,MAAM,EAAE,aAAa,MAAM,UAAU,EAAE,KAAK,SAAS,MAAM,MAAM,CACpE;IACA,OAAO;KAAE;KAAO,QAAQ;KAAS,QAAQ,UAAU,qBAAqB;IAAmB;GAC7F;GACA,SACE,OAAO;IACL;IACA,QAAQ;IACR,QAAQ,eAAe,MAAM,KAAK;GACpC;EACJ;CACF,CAAC;CAMD,MAAM,aAAa;EACjB;EACA;EACA;EACA;EACA,WAAW,OAAO,aAAa;EAC/B;EACA,QAAQ,OAAO;CACjB;CACA,MAAM,eAA+B,CAAC;CACtC,IAAI,eAAe;CACnB,MAAM,gBAAgC,CAAC;CACvC,MAAM,QAAQ,OAAO,WAAW,OAAe,IAAI,SAAe,MAAM,WAAW,GAAG,EAAE,CAAC;CAEzF,KAAK,IAAI,IAAI,GAAG,IAAI,OAAO,OAAO,QAAQ,KAAK;EAC7C,MAAM,QAAQ,OAAO,OAAO;EAC5B,MAAM,YAAY,MAAM,QAAQ,SAAS,EAAE;EAC3C,IAAI;EACJ,IAAI,eAAe;EACnB,KAAK,IAAI,UAAU,GAAG,UAAU,GAAG,WAAW;GAC5C,eAAe,UAAU;GACzB,IAAI;IACF,IAAI,UAAU,GAAG;KACf,MAAM,OAAO,UAAU;KACvB,QAAQ,IAAI,OAAO,UAAU,SAAS,QAAQ,cAAc,OAAO,IAAK,GAAG;KAC3E,MAAM,MAAM,IAAI;IAClB;IACA,MAAM,SAAS,MAAM,MAAM,MAAM,UAAU;IAC3C,aAAa,KAAK,MAAM;IACxB,MAAM,MAAM,GAAI;IAChB,YAAY,KAAA;IACZ;GACF,SAAS,KAAK;IACZ,YAAY;IACZ,IAAI,eAAe,iBAAiB;KAGlC,QAAQ,MAAM,OAAO,UAAU,2BAA2B,WAAW,GAAG,GAAG;KAC3E;IACF;IACA,QAAQ,MAAM,OAAO,UAAU,WAAW,QAAQ,WAAW,WAAW,GAAG,GAAG;IAI9E,IAAI,CAAC,oBAAoB,GAAG,GAAG;GACjC;EACF;EACA,IAAI,cAAc,KAAA,GAAW;GAC3B;GACA,cAAc,KAAK;IACjB,OAAO;IACP,UAAU;IACV,QAAQ,WAAW,SAAS;GAC9B,CAAC;EACH;CACF;CAEA,MAAM,YAAY,aAAa,KAAK;CAEpC,MAAM,cAAc,UAAU,QAC3B,MAAM,EAAE,cAAc,iBAAiB,EAAE,cAAc,OAC1D;CAIA,MAAM,aAAa,gBAHC,UAAU,QAC3B,MAAM,EAAE,cAAc,iBAAiB,EAAE,cAAc,OAEb,CAAC;CAG9C,MAAM,4BAAY,IAAI,IAAoB;CAC1C,KAAK,MAAM,OAAO,SAAS,YACzB,UAAU,IAAI,KAAK,CAAC;CAGtB,MAAM,eAAe,aACnB,WAAW,KAAK,OAAO;EACrB,OAAO,EAAE;EACT,QAAQ,UAAU,IAAI,EAAE,SAAS,KAAK;CACxC,EAAE,CACJ;CAKA,MAAM,SAA8D;EAClE,YAAY,SAAS;EACrB,SAAS,SAAS;EAClB;EACA;EACA,aAAa;EACb,aAAa,YAAY,SAAS;EAClC;EACA,iBAAiB,KAAK,IAAI,IAAI;EAC9B;EACA,MAAM,WAAW,QAAQ,EAAE,MAAM,SAAS,CAAC;CAC7C;CACA,IAAI,cAAc,SAAS,GAAG,OAAO,gBAAgB;CACrD,OAAO;AACT;;;;;;;;AC1UA,IAAa,kBAAb,MAA6B;CAC3B;CACA;CAEA,YAAY,MAAkB,QAA+B;EAC3D,KAAK,OAAO;EACZ,KAAK,SAAS;CAChB;CAEA,MAAM,IAAI,WAAkD;EAC1D,MAAM,QAAQ,aAAa,KAAK,OAAO;EACvC,MAAM,gBAAgB,KAAK,OAAO,iBAAiB;EACnD,MAAM,aAAa,KAAK,OAAO,cAAc,IAAI,WAAW;EAC5D,MAAM,WAAW,EAAE,gBAAgB,WAAW,OAAO,WAAW,EAAE;EAElE,QAAQ,IAAI,IAAI,OAAO,EAAE,CAAC;EAC1B,QAAQ,IAAI,yBAAyB;EACrC,QAAQ,IAAI,2CAA2C;EACvD,QAAQ,IAAI,IAAI,OAAO,EAAE,CAAC;EAC1B,QAAQ,IAAI,cAAc,MAAM,QAAQ;EACxC,QAAQ,IAAI,WAAW,KAAK,OAAO,OAAO,QAAQ;EAClD,QAAQ,IAAI,UAAU,KAAK,OAAO,SAAS,UAAU;EACrD,QAAQ,IAAI;EAEZ,MAAM,UAA4B,CAAC;EAEnC,KAAK,IAAI,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;GACrC,MAAM,WAAW,MAAM;GACvB,QAAQ,IAAI,IAAI,IAAI,EAAE,GAAG,MAAM,OAAO,IAAI,SAAS,GAAG,IAAI,SAAS,QAAQ,EAAE;GAC7E,QAAQ,IAAI,aAAa,SAAS,QAAQ;GAC1C,QAAQ,IAAI,YAAY,SAAS,MAAM,QAAQ;GAE/C,MAAM,SAAS,MAAM,gBAAgB,KAAK,MAAM,UAAU;IACxD,cAAc,KAAK,OAAO;IAC1B,OAAO,KAAK,OAAO;IACnB,QAAQ,KAAK,OAAO;IACpB;IACA;GACF,CAAC;GACD,QAAQ,KAAK,MAAM;GAGnB,KAAK,MAAM,QAAQ,OAAO,OAAO;IAC/B,MAAM,WAAW,KAAK,eAAe,WAAW;IAChD,MAAM,WAAW,KAAK,mBAAmB,WAAW;IACpD,MAAM,aAAa,KAAK,gBAAgB;IACxC,MAAM,YAAY,aAAa,IAAI,WAAW,WAAW,KAAK;IAC9D,QAAQ,IACN,UAAU,KAAK,YAAY,EAAE,KAAK,KAAK,aAAa,IAAA,CAAM,QAAQ,CAAC,EAAE,IAAI,SAAS,GAAG,SAAS,GAAG,UAAU,IAAI,KAAK,cAAc,OAAO,QAC3I;GACF;GAGA,KAAK,MAAM,MAAM,OAAO,iBAAiB;IACvC,MAAM,OAAO,GAAG,SAAS,MAAM;IAC/B,QAAQ,IAAI,gBAAgB,KAAK,IAAI,GAAG,MAAM,YAAY,KAAK,GAAG,QAAQ;GAC5E;GAGA,QAAQ,IAAI,WAAW;GACvB,MAAM,UAAsE,CAAC;GAC7E,KAAK,MAAM,MAAM,OAAO,aAAa;IACnC,MAAM,QAAQ,QAAQ,GAAG,cAAc;KAAE,QAAQ,CAAC;KAAG,YAAY,CAAC;IAAE;IACpE,MAAM,OAAO,KAAK,GAAG,KAAK;IAC1B,MAAM,WAAW,KAAK,GAAG,GAAG,UAAU,GAAG,GAAG,OAAO;IACnD,QAAQ,GAAG,aAAa;GAC1B;GACA,KAAK,MAAM,CAAC,MAAM,SAAS,OAAO,QAAQ,OAAO,GAAG;IAClD,MAAM,OAAO,KAAK,OAAO,QAAQ,GAAG,MAAM,IAAI,GAAG,CAAC,IAAI,KAAK,OAAO,OAAA,CAAQ,QAAQ,CAAC;IACnF,QAAQ,IAAI,OAAO,KAAK,OAAO,EAAE,EAAE,OAAO,IAAI,KAAK,KAAK,WAAW,KAAK,IAAI,EAAE,EAAE;GAClF;GAEA,QAAQ,IACN,cAAc,OAAO,aAAa,QAAQ,CAAC,EAAE,QAAQ,OAAO,kBAAkB,IAAA,CAAM,QAAQ,CAAC,EAAE,GACjG;GACA,QAAQ,IAAI;EACd;EAGA,MAAM,YAA4E,CAAC;EACnF,MAAM,cAAiE,CAAC;EAExE,KAAK,MAAM,KAAK,SAAS;GACvB,MAAM,eAAe,UAAU,EAAE,YAAY;IAAE,KAAK;IAAG,QAAQ;IAAG,OAAO;GAAE;GAC3E,aAAa;GACb,aAAa,OAAO,EAAE;GACtB,IAAI,EAAE,gBAAgB,eAAe,aAAa;GAClD,UAAU,EAAE,WAAW;GAEvB,KAAK,MAAM,MAAM,EAAE,aAAa;IAC9B,MAAM,WAAW,YAAY,GAAG,cAAc;KAAE,KAAK;KAAG,QAAQ,CAAC;IAAE;IACnE,SAAS,OAAO,KAAK,GAAG,KAAK;IAC7B,YAAY,GAAG,aAAa;GAC9B;EACF;EAEA,KAAK,MAAM,KAAK,OAAO,OAAO,SAAS,GACrC,EAAE,MAAM,EAAE,QAAQ,IAAI,EAAE,MAAM,EAAE,QAAQ;EAE1C,KAAK,MAAM,KAAK,OAAO,OAAO,WAAW,GACvC,EAAE,MAAM,EAAE,OAAO,SAAS,IAAI,EAAE,OAAO,QAAQ,GAAG,MAAM,IAAI,GAAG,CAAC,IAAI,EAAE,OAAO,SAAS;EAGxF,MAAM,SAAS,CAAC,GAAG,OAAO,CAAC,CAAC,MAAM,GAAG,MAAM,EAAE,eAAe,EAAE,YAAY;EAC1E,MAAM,UAAU,OAAO,MAAM,GAAG,CAAC,CAAC,CAAC,KAAK,OAAO;GAC7C,UAAU,EAAE;GACZ,OAAO,EAAE;GACT,QACE,EAAE,YACC,QAAQ,MAAM,EAAE,QAAQ,aAAa,CAAC,CACtC,KAAK,MAAM,GAAG,EAAE,UAAU,GAAG,EAAE,OAAO,CAAC,CACvC,KAAK,IAAI,KAAK;EACrB,EAAE;EACF,MAAM,YAAY,OACf,MAAM,EAAE,CAAC,CACT,QAAQ,CAAC,CACT,KAAK,OAAO;GACX,UAAU,EAAE;GACZ,OAAO,EAAE;GACT,QACE,EAAE,YACC,QAAQ,MAAM,EAAE,SAAS,CAAC,CAAC,CAC3B,KAAK,MAAM,GAAG,EAAE,UAAU,GAAG,EAAE,OAAO,CAAC,CACvC,KAAK,IAAI,KAAK;EACrB,EAAE;EAGJ,QAAQ,IAAI,IAAI,OAAO,EAAE,CAAC;EAC1B,QAAQ,IAAI,UAAU;EACtB,QAAQ,IAAI,IAAI,OAAO,EAAE,CAAC;EAE1B,MAAM,aACJ,QAAQ,SAAS,IAAI,QAAQ,QAAQ,GAAG,MAAM,IAAI,EAAE,cAAc,CAAC,IAAI,QAAQ,SAAS;EAE1F,QAAQ,IAAI,YAAY,WAAW,QAAQ,CAAC,EAAE,IAAI;EAClD,QAAQ,IAAI;EAEZ,QAAQ,IAAI,aAAa;EACzB,KAAK,MAAM,CAAC,MAAM,SAAS,OAAO,QAAQ,SAAS,GACjD,QAAQ,IACN,KAAK,KAAK,OAAO,EAAE,EAAE,GAAG,KAAK,IAAI,QAAQ,CAAC,EAAE,QAAQ,KAAK,OAAO,GAAG,KAAK,MAAM,SAChF;EAEF,QAAQ,IAAI;EAEZ,QAAQ,IAAI,eAAe;EAC3B,MAAM,aAAa,OAAO,QAAQ,WAAW,CAAC,CAAC,MAAM,GAAG,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,GAAG;EACjF,KAAK,MAAM,CAAC,MAAM,SAAS,YAAY;GACrC,MAAM,MAAM,KAAK,IAAI,GAAG,KAAK,MAAM;GACnC,MAAM,MAAM,KAAK,IAAI,GAAG,KAAK,MAAM;GACnC,QAAQ,IACN,KAAK,KAAK,OAAO,EAAE,EAAE,OAAO,KAAK,IAAI,QAAQ,CAAC,EAAE,WAAW,IAAI,GAAG,IAAI,OAAO,KAAK,OAAO,QAC3F;EACF;EACA,QAAQ,IAAI;EAEZ,IAAI,QAAQ,SAAS,GAAG;GACtB,QAAQ,IAAI,UAAU;GACtB,KAAK,MAAM,KAAK,SACd,QAAQ,IAAI,KAAK,EAAE,SAAS,IAAI,EAAE,MAAM,QAAQ,CAAC,EAAE,KAAK,EAAE,QAAQ;GAEpE,QAAQ,IAAI;EACd;EAEA,OAAO;GACL,4BAAW,IAAI,KAAK,EAAA,CAAE,YAAY;GAClC,YAAY,KAAK,OAAO,cAAc;GACtC,eAAe,KAAK,OAAO,iBAAiB;GAC5C,eAAe,MAAM;GACrB;GACA,MAAM,WAAW,QAAQ,EAAE,MAAM,SAAS,CAAC;GAC3C,SAAS;IAAE;IAAY;IAAW;IAAa;IAAS;GAAU;EACpE;CACF;AACF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACjGA,SAAgB,mBACd,MACA,OAAkC,CAAC,GACT;CAC1B,MAAM,gBAAgB,KAAK,iBAAiB;CAC5C,IAAI,CAAC,OAAO,SAAS,aAAa,KAAK,gBAAgB,KAAK,iBAAiB,GAC3E,MAAM,IAAI,gBACR,4DAA4D,eAC9D;CAEF,IAAI,KAAK,WAAW,GAClB,MAAM,IAAI,gBACR,8FACF;CAIF,MAAM,yBAAS,IAAI,IAA0D;CAC7E,KAAK,MAAM,OAAO,MAAM;EACtB,IACE,IAAI,oBAAoB,UACxB,IAAI,oBAAoB,UACxB,IAAI,oBAAoB,WAExB,MAAM,IAAI,gBACR,qDAAqD,IAAI,gBAAgB,cAAc,IAAI,OAAO,yCACpG;EAEF,MAAM,MAAM,OAAO,IAAI,IAAI,MAAM,KAAK;GAAE,GAAG;GAAG,QAAQ;GAAG,OAAO;EAAE;EAClE,IAAI;EACJ,IAAI,IAAI,oBAAoB,WAAW;GACrC,IAAI;GACJ,IAAI,IAAI,oBAAoB,QAAQ,IAAI;EAC1C;EACA,OAAO,IAAI,IAAI,QAAQ,GAAG;CAC5B;CAEA,MAAM,QAAwB,CAAC,GAAG,OAAO,QAAQ,CAAC,CAAC,CAChD,MAAM,CAAC,IAAI,CAAC,OAAQ,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,CAAE,CAAC,CAChD,KAAK,CAAC,QAAQ,SAAS;EACtB,IAAI,IAAI,UAAU,GAChB,OAAO;GACL;GACA,GAAG,IAAI;GACP,QAAQ;GACR,kBAAkB;GAClB,UAAU;EACZ;EAEF,MAAM,mBAAmB,IAAI,SAAS,IAAI;EAC1C,OAAO;GACL;GACA,GAAG,IAAI;GACP,QAAQ,IAAI;GACZ;GACA,UAAU,oBAAoB,gBAAiB,QAAmB;EACpE;CACF,CAAC;CAQH,OAAO;EAAE;EAAO,SAAA;GALd,cAAc,MAAM,QAAQ,MAAM,EAAE,aAAa,KAAK,CAAC,CAAC;GACxD,gBAAgB,MAAM,QAAQ,MAAM,EAAE,aAAa,WAAW,CAAC,CAAC;GAChE,cAAc,MAAM,QAAQ,MAAM,EAAE,aAAa,SAAS,CAAC,CAAC;GAC5D,aAAa,MAAM,QAAQ,KAAK,MAAM,OAAO,EAAE,IAAI,EAAE,SAAS,CAAC;EAE3C;CAAE;AAC1B;;;;;;;AAaA,SAAgB,yBACd,QACA,OAAwC,CAAC,GACnC;CACN,MAAM,kBAAkB,KAAK,mBAAmB;CAChD,IAAI,CAAC,OAAO,UAAU,eAAe,KAAK,kBAAkB,GAC1D,MAAM,IAAI,gBACR,yEAAyE,iBAC3E;CAEF,MAAM,EAAE,cAAc,gBAAgB,iBAAiB,OAAO;CAC9D,IAAI,eAAe,iBAAiB;EAClC,MAAM,QAAQ,OAAO,MAAM;EAC3B,MAAM,IAAI,gBACR,kCAAkC,aAAa,MAAM,MAAM,0CAC9C,gBAAgB,KAAK,eAAe,wCAC5C,aAAa,+LAGpB;CACF;AACF;;;;;;;;ACrLA,MAAM,yBAAS,IAAI,IAAY;;AAG/B,SAAgB,mBAAmB,KAAa,SAAuB;CACrE,IAAI,OAAO,IAAI,GAAG,GAAG;CACrB,OAAO,IAAI,GAAG;CACd,QAAQ,KAAK,4BAA4B,SAAS;AACpD;;AAGA,SAAgB,2BAAiC;CAC/C,OAAO,MAAM;AACf;;;ACfA,MAAM,6BAA6B;;;;;;;;;;AAWnC,IAAa,gBAAb,MAA2B;CACzB;CACA;CACA,UAA0B;CAC1B;CAEA,YAAY,QAA6B;EACvC,mBACE,iBACA,iHACF;EACA,KAAK,UAAU,OAAO,QAAQ,QAAQ,QAAQ,EAAE;EAChD,KAAK,SAAS,OAAO;EACrB,KAAK,YAAY,OAAO,aAAa;CACvC;CAEA,MAAc,MAA8B;EAC1C,MAAM,OAAO,KAAK,OAAO;EACzB,IAAI,CAAC,MAAM,MAAM,IAAI,MAAM,UAAU,KAAK,iBAAiB;EAC3D,OAAO;CACT;;;;;;;;CASA,MAAc,QACZ,QACA,MACA,MACkC;EAClC,MAAM,aAAa,IAAI,gBAAgB;EACvC,MAAM,UAAU,iBAAiB,WAAW,MAAM,GAAG,KAAK,SAAS;EACnE,IAAI;EACJ,IAAI;GACF,MAAM,MAAM,MAAM,GAAG,KAAK,UAAU,QAAQ;IAC1C;IACA,SAAS;KACP,GAAI,OAAO,EAAE,gBAAgB,mBAAmB,IAAI,CAAC;KACrD,QAAQ,KAAK;KACb,QAAQ,KAAK;IACf;IACA,GAAI,OAAO,EAAE,MAAM,KAAK,UAAU,IAAI,EAAE,IAAI,CAAC;IAC7C,QAAQ,WAAW;GACrB,CAAC;EACH,UAAU;GACR,aAAa,OAAO;EACtB;EACA,IAAI,CAAC,IAAI,IAAI;GACX,MAAM,OAAO,MAAM,IAAI,KAAK,CAAC,CAAC,YAAY,EAAE;GAC5C,MAAM,IAAI,MAAM,GAAG,OAAO,GAAG,KAAK,gBAAgB,IAAI,OAAO,KAAK,KAAK,MAAM,GAAG,GAAG,GAAG;EACxF;EACA,OAAO,IAAI,KAAK;CAClB;;;;;;CAOA,aAAwB,KAA8B,OAAoB;EACxE,MAAM,QAAQ,IAAI;EAClB,IAAI,CAAC,MAAM,QAAQ,KAAK,GACtB,MAAM,IAAI,MACR,iCAAiC,MAAM,SAAS,OAAO,MAAM,IAAI,KAAK,UAAU,KAAK,CAAC,EAAE,MAAM,GAAG,GAAG,EAAE,EACxG;EAEF,OAAO;CACT;CAEA,MAAM,OAAO,MAAc,OAAe,UAA+C;EACvF,MAAM,MAAM,MAAM,KAAK,KAAK,KAAK,MAAM,QAAQ,GAAG;GAAE;GAAM;GAAO;EAAS,CAAC;EAC3E,MAAM,OAAO,IAAI;EACjB,IAAI,CAAC,MAAM,IAAI,MAAM,IAAI,MAAM,kBAAkB,KAAK,UAAU,GAAG,GAAG;EACtE,OAAO,EAAE,QAAQ,KAAK,GAAa;CACrC;CAEA,MAAM,MAAM,OAAe,UAAiC;EAC1D,MAAM,MAAM,MAAM,MAAM,GAAG,KAAK,UAAU,KAAK,MAAM,OAAO,KAAK;GAC/D,QAAQ;GACR,SAAS;IAAE,gBAAgB;IAAoB,QAAQ,KAAK;GAAQ;GACpE,MAAM,KAAK,UAAU;IAAE;IAAO;GAAS,CAAC;GACxC,UAAU;EACZ,CAAC;EACD,MAAM,YAAY,IAAI,QAAQ,IAAI,YAAY;EAC9C,IAAI,WACF,KAAK,UAAU,UAAU,MAAM,GAAG,CAAC,CAAC,MAAM;EAE5C,MAAM,OAAQ,MAAM,IAAI,KAAK;EAC7B,IAAI,CAAC,KAAK,MAAM,MAAM,IAAI,MAAM,iBAAiB,KAAK,UAAU,IAAI,GAAG;CACzE;CAEA,MAAM,gBAAgB,MAAc,OAAO,WAA4B;EACrE,MAAM,MAAM,MAAM,KAAK,KAAK,KAAK,MAAM,YAAY,GAAG;GAAE;GAAM;EAAK,CAAC;EACpE,MAAM,KAAK,IAAI;EACf,IAAI,CAAC,IAAI,IAAI,MAAM,IAAI,MAAM,8BAA8B,KAAK,UAAU,GAAG,GAAG;EAChF,OAAO,GAAG;CACZ;CAEA,MAAM,aAAa,aAAsC;EACvD,MAAM,MAAM,MAAM,KAAK,KAAK,KAAK,MAAM,SAAS,GAAG,EAAE,YAAY,CAAC;EAClE,MAAM,SAAS,IAAI;EACnB,IAAI,CAAC,QAAQ,IAAI,MAAM,IAAI,MAAM,2BAA2B,KAAK,UAAU,GAAG,GAAG;EACjF,OAAO,OAAO;CAChB;CAEA,MAAM,KACJ,aACA,UACA,SACA,OACsE;EACtE,MAAM,MAAM,MAAM,MAAM,GAAG,KAAK,UAAU,KAAK,MAAM,MAAM,KAAK;GAC9D,QAAQ;GACR,SAAS;IACP,gBAAgB;IAChB,QAAQ,KAAK;IACb,QAAQ,KAAK;GACf;GACA,MAAM,KAAK,UAAU;IAAE;IAAa;IAAU;GAAQ,CAAC;EACzD,CAAC;EAED,IAAI,CAAC,IAAI,MAAM,CAAC,IAAI,MAAM,MAAM,IAAI,MAAM,gBAAgB,IAAI,QAAQ;EAGtE,MAAM,SAAS,IAAI,KAAK,UAAU;EAClC,MAAM,UAAU,IAAI,YAAY;EAChC,IAAI,MAAM;EACV,IAAI,OAAO;EACX,MAAM,SAA4C,CAAC;EAEnD,OAAO,MAAM;GACX,MAAM,EAAE,MAAM,UAAU,MAAM,OAAO,KAAK;GAC1C,IAAI,MAAM;GACV,OAAO,QAAQ,OAAO,OAAO,EAAE,QAAQ,KAAK,CAAC;GAC7C,MAAM,QAAQ,IAAI,MAAM,IAAI;GAC5B,MAAM,MAAM,IAAI,KAAK;GACrB,KAAK,MAAM,QAAQ,OAAO;IACxB,IAAI,CAAC,KAAK,KAAK,GAAG;IAClB,IAAI;KACF,MAAM,QAAQ,KAAK,MAAM,IAAI;KAC7B,IAAI,MAAM,SAAS,0BAA0B,MAAM,MAAM,OACvD,QAAQ,MAAM,KAAK;IAEvB,QAAQ,CAER;GACF;EACF;EAGA,MAAM,UAAU;EAChB,IAAI,QAAgC,QAAQ,KAAK,IAAI;EACrD,OAAO,UAAU,MAAM;GACrB,MAAM,SAAiC,CAAC;GACxC,KAAK,MAAM,QAAQ,MAAM,EAAE,CAAE,MAAM,IAAI,GAAG;IACxC,MAAM,MAAM,KAAK,QAAQ,GAAG;IAC5B,IAAI,MAAM,GAAG,OAAO,KAAK,MAAM,GAAG,GAAG,CAAC,CAAC,KAAK,KAAK,KAAK,MAAM,MAAM,CAAC,CAAC,CAAC,KAAK;GAC5E;GACA,OAAO,KAAK;IAAE,MAAM,MAAM;IAAK,OAAO,OAAO,SAAS;GAAG,CAAC;GAC1D,QAAQ,QAAQ,KAAK,IAAI;EAC3B;EAEA,OAAO;GAAE;GAAM;EAAO;CACxB;CAEA,MAAM,SACJ,aAC4E;EAC5E,MAAM,MAAM,MAAM,KAAK,IAAI,GAAG,KAAK,MAAM,OAAO,EAAE,eAAe,aAAa;EAC9E,OAAO,KAAK,aACV,KACA,OACF;CACF;CAEA,MAAM,UAAU,aAA6E;EAC3F,MAAM,MAAM,MAAM,KAAK,IAAI,GAAG,KAAK,MAAM,QAAQ,EAAE,eAAe,aAAa;EAC/E,OAAO,KAAK,aAA0D,KAAK,QAAQ;CACrF;CAEA,MAAM,aACJ,aACwE;EACxE,MAAM,MAAM,MAAM,KAAK,IAAI,GAAG,KAAK,MAAM,WAAW,EAAE,eAAe,aAAa;EAClF,OAAO,KAAK,aACV,KACA,SACF;CACF;CAEA,MAAM,aAAa,aAAwC;EACzD,MAAM,MAAM,MAAM,KAAK,IAAI,GAAG,KAAK,MAAM,OAAO,EAAE,eAAe,aAAa;EAC9E,MAAM,QAAkB,CAAC;EACzB,SAAS,QAAQ,OAAkB;GACjC,KAAK,MAAM,KAAK,OAAO;IACrB,MAAM,OAAO;IACb,IAAI,KAAK,SAAS,UAAU,KAAK,MAAM,MAAM,KAAK,KAAK,IAAI;IAC3D,IAAI,KAAK,UAAU,QAAQ,KAAK,QAAQ;GAC1C;EACF;EACA,QAAQ,KAAK,aAAsB,KAAK,MAAM,CAAC;EAC/C,OAAO;CACT;CAEA,MAAM,cAAc,aAAqB,IAA2B;EAClE,MAAM,KAAK,MAAM,KAAK,MAAM,WAAW,GAAG;GAAE;GAAa;GAAI,QAAQ;EAAW,CAAC;CACnF;CAEA,MAAM,aAAa,aAAqB,IAAY,QAA+B;EACjF,MAAM,KAAK,MAAM,KAAK,MAAM,WAAW,GAAG;GAAE;GAAa;GAAI,QAAQ;GAAY;EAAO,CAAC;CAC3F;CAEA,MAAM,eACJ,aACyD;EACzD,MAAM,MAAM,MAAM,KAAK,IAAI,GAAG,KAAK,MAAM,aAAa,EAAE,eAAe,aAAa;EACpF,OAAO,KAAK,aAA2D,KAAK,aAAa;CAC3F;;CAGA,MAAM,IAAI,MAAgD;EACxD,OAAO,KAAK,QAAQ,OAAO,IAAI;CACjC;;CAGA,MAAM,KAAK,MAAc,MAAiE;EACxF,OAAO,KAAK,QAAQ,QAAQ,MAAM,IAAI;CACxC;;CAGA,MAAM,MAAM,MAAc,MAAiE;EACzF,OAAO,KAAK,QAAQ,SAAS,MAAM,IAAI;CACzC;AACF;;;;;;;AAQA,eAAsB,eACpB,QACA,MACA,UACqB;CACrB,MAAM,QAAQ,KAAK,IAAI;CACvB,MAAM,SAAwB,CAAC;CAE/B,IAAI;EACF,MAAM,UAAU,MAAM,SAAS,MAAM;EACrC,OAAO,KAAK,GAAG,OAAO;CACxB,SAAS,KAAK;EACZ,OAAO,KAAK;GACV,MAAM;GACN,QAAQ;GACR,UAAU;GACV,QAAQ,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;EACzD,CAAC;CACH;CAEA,OAAO;EACL;EACA,QAAQ,OAAO,OAAO,MAAM,EAAE,MAAM;EACpC,UAAU,KAAK,IAAI,IAAI;EACvB,QAAQ,GAAG,OAAO,QAAQ,MAAM,EAAE,MAAM,CAAC,CAAC,OAAO,GAAG,OAAO,OAAO;EAClE;CACF;AACF;;;;;;;;;ACtRA,IAAa,qBAAb,MAAgC;CAC9B;CACA,UAIM,CAAC;CAEP,YAAY,UAAiC;EAC3C,KAAK,WAAW;CAClB;;CAGA,OACE,MACA,OAKA;EACA,MAAM,iBAAmD,CAAC;EAC1D,IAAI,cAAc;EAElB,KAAK,MAAM,aAAa,KAAK,UAC3B,IAAI,UAAU,UAAU;GACtB,MAAM,SAAS,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,UAAU,SAAS,KAAK,CAAC,CAAC;GACjE,eAAe,UAAU,QAAQ;GACjC,eAAe;EACjB,OAAO;GACL,MAAM,SAAS,UAAU,MAAM,KAAK;GACpC,eAAe,UAAU,QAAQ;GACjC,eAAe,SAAS,IAAI;EAC9B;EAGF,MAAM,oBACJ,KAAK,SAAS,SAAS,IAAK,cAAc,KAAK,SAAS,SAAU,MAAM;EAE1E,KAAK,QAAQ,KAAK;GAAE;GAAM;GAAmB;EAAe,CAAC;EAE7D,OAAO;GACL;GACA,UAAU,eAAe,KAAK,SAAS;GACvC;EACF;CACF;;CAGA,WAAqB;EACnB,OAAO,KAAK,QAAQ,KAAK,MAAM,EAAE,iBAAiB;CACpD;;CAGA,aAAa;EACX,OAAO,CAAC,GAAG,KAAK,OAAO;CACzB;;CAGA,sBAAqC;EAEnC,OADc,KAAK,QAAQ,MAAM,MAAM,EAAE,sBAAsB,GACpD,CAAC,EAAE,QAAQ;CACxB;AACF;;;;;;;AC5CA,MAAM,eAA6C;CACjD,aACE;CACF,WACE;CACF,YACE;AACJ;;;;;;;;;;;;;AAcA,IAAa,cAAb,MAAyB;CACvB;CACA;CACA;CACA;CACA;CAEA,YAAY,MAAkB,QAA2B;EACvD,mBACE,eACA,+GACF;EACA,KAAK,OAAO;EACZ,KAAK,SAAS,OAAO;EACrB,KAAK,cAAc,OAAO,eAAe;EACzC,KAAK,iBAAiB,OAAO,kBAAkB;EAC/C,KAAK,aAAa,OAAO,cAAc,IAAI,WAAW;CACxD;;;;;;;CAQA,MAAM,IAAI,SAA+C;EACvD,MAAM,WAAW,EAAE,aAAa,WAAW,OAAO,WAAW,EAAE;EAE/D,MAAM,QAAQ,eAAe,KAAK,IAAI,EAAE;EACxC,MAAM,KAAK,OAAO,OAAO,UAAU,QAAQ,QAAQ,OAAO,kBAAkB;EAC5E,MAAM,KAAK,OAAO,MAAM,OAAO,kBAAkB;EACjD,MAAM,cAAc,MAAM,KAAK,OAAO,gBAAgB,GAAG,QAAQ,KAAK,MAAM;EAC5E,MAAM,WAAW,MAAM,KAAK,OAAO,aAAa,WAAW;EAE3D,MAAM,UAAU,IAAI,iBAAiB,KAAK,QAAQ,WAAW;EAC7D,MAAM,cAAc,IAAI,mBAAmB,QAAQ,kBAAkB;EACrE,MAAM,cAA6B,CAAC;EACpC,MAAM,sBAA2D,CAAC;EAElE,IAAI,YAAY;EAChB,IAAI,oBAAmC;EACvC,IAAI,oBAAmC;EAEvC,KAAK,IAAI,OAAO,GAAG,QAAQ,QAAQ,UAAU,QAAQ;GAEnD,MAAM,QAAQ,MAAM,QAAQ,SAAS;GAGrC,MAAM,cAAc,MAAM,KAAK,kBAC7B,SACA,OACA,qBACA,QACF;GAEA,IAAI,gBAAgB,QAAQ;IAC1B,YAAY;IACZ,oBAAoB,OAAO;IAC3B,QAAQ,IAAI,6BAA6B,QAAQ,KAAK,cAAc,OAAO,GAAG;IAC9E;GACF;GAGA,MAAM,YAAY,KAAK,IAAI;GAC3B,MAAM,WAAW,MAAM,KAAK,OAAO,KAAK,aAAa,UAAU,WAAW;GAC1E,MAAM,UAAU,KAAK,IAAI,IAAI;GAE7B,oBAAoB,KAClB;IAAE,MAAM;IAAQ,SAAS;GAAY,GACrC;IAAE,MAAM;IAAa,SAAS,SAAS;GAAK,CAC9C;GAGA,MAAM,IAAI,SAAS,MAAM,WAAW,GAAG,GAAI,CAAC;GAG5C,MAAM,KAAK,gBAAgB,SAAS,aAAa,KAAK;GAGtD,MAAM,YAAY,MAAM,QAAQ,SAAS;GACzC,MAAM,OAAO,YAAY,OAAO,MAAM,SAAS;GAG/C,MAAM,kBAAkB,SAAS,KAAK,MAAM,WAAW,KAAK,CAAC,EAAA,CAAG;GAChE,MAAM,IAAI,MAAM,QAAQ,QACtB,MACA,SACA,SAAS,KAAK,QACd,gBACA,SAAS,OAAO,QAChB,OAAO,OAAO,KAAK,cAAc,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC,QACnD,QAAQ,mBAAmB,MAC7B;GACA,YAAY,KAAK,CAAC;GAGlB,MAAM,cAAc,OAAO,QAAQ,KAAK,cAAc,CAAC,CACpD,KAAK,CAAC,GAAG,OAAO,GAAG,EAAE,GAAG,IAAI,MAAM,KAAK,CAAC,CACxC,KAAK,GAAG;GACX,QAAQ,IACN,WAAW,KAAK,IAAI,KAAK,kBAAkB,QAAQ,CAAC,EAAE,MAAM,YAAY,KAAK,UAAU,IAAA,CAAM,QAAQ,CAAC,EAAE,GAC1G;GAKA,IAAI,KAAK,YAAY,sBAAsB,MAAM;IAC/C,oBAAoB;IACpB,QAAQ,IAAI,0BAA0B,KAAK,qCAAqC;GAClF;EACF;EAEA,MAAM,aAAa,MAAM,QAAQ,SAAS;EAE1C,OAAO;GACL,WAAW,QAAQ;GACnB;GACA;GACA;GACA,YAAY,YAAY;GACxB,SAAS;GACT;GACA,kBAAkB,YAAY,SAAS;GACvC,cAAc,KAAK,WAAW,QAAQ,EAAE,MAAM,SAAS,CAAC,CAAC,CAAC;GAC1D,mBAAmB;EACrB;CACF;;CAGA,MAAc,kBACZ,SACA,OACA,SACA,UACiB;EACjB,OAAO,mBAAmB,KAAK,MAAM;GACnC;GACA;GACA;GACA,gBAAgB,KAAK;GACrB,OAAO,KAAK;GACZ,YAAY,KAAK;GACjB;EACF,CAAC;CACH;;CAGA,MAAc,gBACZ,SACA,aACA,QACe;EAEf,MAAM,WAAU,MADQ,KAAK,OAAO,aAAa,WAAW,EAAA,CAClC,QAAQ,MAAM,EAAE,WAAW,SAAS;EAE9D,KAAK,MAAM,UAAU,SAAS;GAE5B,MAAM,YAAY,QAAQ,kBAAkB,MAAM,OAAO;IAEvD,OADc,OAAO,MAAM,YAChB,CAAC,CAAC,SAAS,GAAG,QAAQ,YAAY,CAAC;GAChD,CAAC;GAED,IAAI,WAAW;IACb,MAAM,KAAK,OAAO,aAAa,aAAa,OAAO,IAAI,UAAU,QAAQ;IACzE,QAAQ,IAAI,iBAAiB,OAAO,MAAM,KAAK,UAAU,SAAS,MAAM,GAAG,EAAE,GAAG;GAClF,OAAO;IACL,MAAM,KAAK,OAAO,cAAc,aAAa,OAAO,EAAE;IACtD,QAAQ,IAAI,iBAAiB,OAAO,OAAO;GAC7C;EACF;CACF;AACF;;AAGA,SAAS,mBAAmB,SAAwB,OAA4B;CAC9E,MAAM,UAAU,QAAQ,mBAAmB,KAAK,MAAM;EACpD,MAAM,MAAM,EAAE,MAAM,KAAK;EACzB,OAAO,GAAG,EAAE,KAAK,IAAI,MAAM,QAAQ;CACrC,CAAC;CAED,OAAO,GADU,QAAQ,QAAQ,MAAM,EAAE,SAAS,KAAK,KAAK,CAAC,EAAE,SAAS,KAAK,CAAC,CAAC,CAAC,OAC7D,GAAG,QAAQ,mBAAmB,OAAO,KAAK,QAAQ,KAAK,IAAI;AAChF;;;;;;;;;;;;;;AAeA,SAAgB,wBACd,SACA,OACA,iBAAiB,IACT;CACR,mBACE,2BACA,kIACF;CACA,MAAM,QAAsB,QAAQ,SAAS;CAC7C,MAAM,YAAY,QAAQ,YAAY,YAAY,QAAQ,UAAU,KAAK;CAEzE,MAAM,WACJ,QAAQ,kBAAkB,QAAQ,eAAe,SAAS,IACtD,iBAAiB,QAAQ,KAAK,gDAAgD,QAAQ,eACnF,KAAK,MAAM,OAAO,GAAG,CAAC,CACtB,KACC,IACF,EAAE,mKACJ;CAEN,MAAM,aACJ,QAAQ,cAAc,QAAQ,WAAW,SAAS,IAC9C,yHAAyH,QAAQ,WAC9H,KAAK,MAAM,OAAO,GAAG,CAAC,CACtB,KAAK,IAAI,EAAE,MACd;CAEN,OAAO,+BAA+B,QAAQ,KAAK,yCAAyC,UAAU;kBACtF,QAAQ,KAAK;;;EAG7B,aAAa,OAAO;EACpB,iBAAiB,qBAAqB,eAAe,MAAM,GAAG;WACrD,MAAM,MAAM,aAAa,MAAM,OAAO;uBAC1B,MAAM,UAAU,QAAQ,aAAa,MAAM,UAAU,SAAS,aAAa,MAAM,UAAU,SAAS;iBAC1G,MAAM,WAAW,OAAO,KAAK,MAAM,WAAW,MAAM,GAAG,EAAE,CAAC,CAAC,KAAK,IAAI,IAAI,MAAM,WAAW,SAAS,KAAK,OAAO,GAAG;2BACvG,mBAAmB,SAAS,KAAK,EAAE;EAC5D,WAAW,WAAW;;wDAEgC,QAAQ,KAAK;;;8BAGvC,QAAQ,KAAK;;;;oDAIS,QAAQ,KAAK;;;AAGjE;;;;;;;;;;;;AA4BA,eAAsB,mBACpB,MACA,MACiB;CACjB,mBACE,sBACA,4HACF;CACA,MAAM,EAAE,SAAS,OAAO,SAAS,iBAAiB,IAAI,QAAQ,wBAAwB;CAEtF,MAAM,eACJ,QAAQ,SAAS,IACb,QAAQ,QAAQ,SAAS,EAAE,CAAE,QAAQ,MAAM,GAAG,GAAI,IAClD;CAEN,MAAM,gBAAgB,QACnB,MAAM,EAAE,CAAC,CACT,KAAK,MAAM,GAAG,EAAE,KAAK,IAAI,EAAE,QAAQ,MAAM,GAAG,GAAG,GAAG,CAAC,CACnD,KAAK,MAAM;CAEd,MAAM,UAAU;EACd;EACA,UAAU,CACR;GAAE,MAAM;GAAU,SAAS,wBAAwB,SAAS,OAAO,cAAc;EAAE,GACnF;GACE,MAAM;GACN,SAAS,gBACL,yBAAyB,cAAc,oCAAoC,iBAC3E;EACN,CACF;EACA,aAAa;EACb,WAAW;CACb;CACA,MAAM,OAAO,OAAO,KAAK,cAAc,IAAI,WAAW,EAAA,CAAG,YAAY;EACnE,SAAS;EACT,OAAO;EACP,OAAO;EACP;EACA,MAAM,KAAK;EACX,eACE,KAAK,oBAAoB,KAAA,IACrB,KAAA,IACA,2BAA2B,SAAS,EAAE,iBAAiB,KAAK,gBAAgB,CAAC;EACnF,UAAU,QAAQ,WAAW,KAAK,KAAK,SAAS;GAAE;GAAQ,gBAAgB;EAAO,CAAC;EAClF,SAAS;EACT,kBAAkB;CACpB,CAAC;CACD,IAAI,CAAC,KAAK,WAAW,MAAM,KAAK;CAKhC,kBAAkB,OAAO,KAAK,MAAM,aAAa;EAC/C,iBAAiB;EACjB,SAAS;CACX,CAAC;CACD,OAAO,KAAK,MAAM,QAAQ,KAAK;AACjC;;;AC5KA,MAAM,uBAAsD;CAC1D,UAAU;CACV,QAAQ;CACR,SAAS;CACT,YAAY;AACd;AAEA,IAAa,kCAAb,MAAgF;CAC9E,+BAAgC,IAAI,IAAgC;CAEpE,MAAM,KAAK,YAA+C;EACxD,KAAK,aAAa,IAAI,WAAW,IAAI,gBAAgB,UAAU,CAAC;CAClE;CAEA,MAAM,IAAI,IAAgD;EACxD,MAAM,aAAa,KAAK,aAAa,IAAI,EAAE;EAC3C,OAAO,aAAa,gBAAgB,UAAU,IAAI;CACpD;CAEA,MAAM,KAAK,SAAmC,CAAC,GAAkC;EAC/E,OAAO,CAAC,GAAG,KAAK,aAAa,OAAO,CAAC,CAAC,CACnC,QAAQ,eAAe,cAAc,YAAY,MAAM,CAAC,CAAC,CACzD,IAAI,eAAe;CACxB;CAEA,MAAM,cAAc,IAAY,SAAuD;EACrF,MAAM,aAAa,KAAK,aAAa,IAAI,EAAE;EAC3C,IAAI,CAAC,YACH,MAAM,IAAI,MAAM,8DAA8D,GAAG,EAAE;EACrF,MAAM,OAAO,gBAAgB;GAC3B,GAAG;GACH,UAAU,CAAC,GAAG,WAAW,UAAU,OAAO;GAC1C,WAAW,QAAQ;EACrB,CAAC;EACD,KAAK,aAAa,IAAI,IAAI,IAAI;EAC9B,OAAO,gBAAgB,IAAI;CAC7B;CAEA,MAAM,YACJ,IACA,OACA,WAC6B;EAC7B,MAAM,aAAa,KAAK,aAAa,IAAI,EAAE;EAC3C,IAAI,CAAC,YACH,MAAM,IAAI,MAAM,4DAA4D,GAAG,EAAE;EACnF,MAAM,WAAW,YACb,WAAW,SAAS,KAAK,YACvB,QAAQ,OAAO,YACX;GAAE,GAAG;GAAS,UAAU,CAAC,GAAI,QAAQ,YAAY,CAAC,GAAI,KAAK;EAAE,IAC7D,OACN,IACA,WAAW;EACf,MAAM,OAAO,gBAAgB;GAC3B,GAAG;GACH;GACA,QAAQ,YAAY,WAAW,SAAS,CAAC,GAAG,WAAW,QAAQ,KAAK;GACpE,WAAW,MAAM;EACnB,CAAC;EACD,KAAK,aAAa,IAAI,IAAI,IAAI;EAC9B,OAAO,gBAAgB,IAAI;CAC7B;AACF;AAEA,IAAa,oCAAb,MAAkF;CAChF;CACA,SAA0B,IAAI,gCAAgC;CAC9D,SAAiB;CAEjB,YAAY,SAA0B;EACpC,KAAK,MAAM,QAAQ;CACrB;CAEA,MAAM,KAAK,YAA+C;EACxD,MAAM,KAAK,KAAK;EAChB,MAAM,KAAK,OAAO,KAAK,UAAU;EACjC,MAAM,KAAK,OAAO;GAAE,IAAI;GAAQ;EAAW,CAAC;CAC9C;CAEA,MAAM,IAAI,IAAgD;EACxD,MAAM,KAAK,KAAK;EAChB,OAAO,KAAK,OAAO,IAAI,EAAE;CAC3B;CAEA,MAAM,KAAK,SAAmC,CAAC,GAAkC;EAC/E,MAAM,KAAK,KAAK;EAChB,OAAO,KAAK,OAAO,KAAK,MAAM;CAChC;CAEA,MAAM,cAAc,IAAY,SAAuD;EACrF,MAAM,KAAK,KAAK;EAChB,MAAM,OAAO,MAAM,KAAK,OAAO,cAAc,IAAI,OAAO;EACxD,MAAM,KAAK,OAAO;GAAE,IAAI;GAAiB;GAAI;EAAQ,CAAC;EACtD,OAAO;CACT;CAEA,MAAM,YACJ,IACA,OACA,WAC6B;EAC7B,MAAM,KAAK,KAAK;EAChB,MAAM,OAAO,MAAM,KAAK,OAAO,YAAY,IAAI,OAAO,SAAS;EAC/D,MAAM,KAAK,OAAO;GAAE,IAAI;GAAe;GAAI;GAAO;EAAU,CAAC;EAC7D,OAAO;CACT;CAEA,MAAc,OAAO,QAAgC;EACnD,MAAM,EAAE,YAAY,UAAU,MAAM,OAAO;EAC3C,MAAM,EAAE,SAAS,MAAM,OAAO;EAC9B,MAAM,MAAM,KAAK,KAAK,EAAE,WAAW,KAAK,CAAC;EACzC,MAAM,WACJ,KAAK,KAAK,KAAK,8BAA8B,GAC7C,GAAG,KAAK,UAAU,MAAM,EAAE,KAC1B,MACF;CACF;CAEA,MAAc,OAAsB;EAClC,IAAI,KAAK,QAAQ;EACjB,MAAM,EAAE,aAAa,MAAM,OAAO;EAClC,MAAM,EAAE,SAAS,MAAM,OAAO;EAC9B,MAAM,OAAO,KAAK,KAAK,KAAK,8BAA8B;EAC1D,IAAI;GACF,MAAM,MAAM,MAAM,SAAS,MAAM,MAAM;GACvC,KAAK,MAAM,QAAQ,IAAI,MAAM,IAAI,GAAG;IAClC,IAAI,CAAC,KAAK,KAAK,GAAG;IAClB,IAAI;KACF,MAAM,SAAS,KAAK,MAAM,IAAI;KAI9B,IAAI,OAAO,OAAO,QAAQ,MAAM,KAAK,OAAO,KAAK,OAAO,UAAU;KAClE,IAAI,OAAO,OAAO,iBAChB,MAAM,KAAK,OAAO,cAAc,OAAO,IAAI,OAAO,OAAO;KAC3D,IAAI,OAAO,OAAO,eAChB,MAAM,KAAK,OAAO,YAAY,OAAO,IAAI,OAAO,OAAO,OAAO,SAAS;IAC3E,QAAQ,CAER;GACF;EACF,QAAQ,CAER;EACA,KAAK,SAAS;CAChB;AACF;AAEA,SAAgB,yBAAyB,OAYlB;CACrB,MAAM,YAAY,MAAM,8BAAa,IAAI,KAAK,EAAA,CAAE,YAAY;CAI5D,OAAO;EACL,IAHA,MAAM,MACN,MAAM,WAAW,GAAG,MAAM,aAAa,GAAG,GAAG,MAAM,cAAc,GAAG,GAAG,MAAM,KAAK,OAAO,GAAG,WAAW,CAAC,CAAC,SAAS,EAAE;EAGpH,WAAW,MAAM;EACjB,YAAY,MAAM;EAClB,MAAM,MAAM;EACZ,UAAU,MAAM,YAAY,CAAC;EAC7B,QAAQ,MAAM,UAAU,CAAC;EACzB,SAAS,MAAM;EACf,OAAO,MAAM;EACb,MAAM,MAAM;EACZ;EACA,UAAU,MAAM;CAClB;AACF;;AAGA,SAAgB,+BACd,KACA,SACoB;CACpB,MAAM,cAAc,mBAAmB,KAAK,gBAAgB,IAAI,OAAO,EAAE;CACzE,MAAM,YAAY,iBAAiB,WAAW;CAC9C,MAAM,WAAW,YAAY;CAE7B,uBADmB,SAAS,KAAK,YAAY,QAAQ,UACrB,CAAC;CACjC,MAAM,aAAa,CACjB,mBAAG,IAAI,IAAI,CACT,GAAG,SAAS,KAAK,YAAY,QAAQ,UAAU,GAC/C,GAAG,YAAY,YAAY,KAAK,YAAY,QAAQ,UAAU,CAChE,CAAC,CACH;CACA,MAAM,kBAAkB,+BAA+B;EACrD,OAAO,YAAY;EACnB;EACA;EACA;EACA,WAAW,QAAQ,mBAAmB,CAAC;CACzC,CAAC;CACD,MAAM,iBACJ,QAAQ,mBAAmB,KAAA,IACvB,KAAA,IACA,8BAA8B,aAAa,QAAQ,cAAc;CACvE,MAAM,YAAY,QAAQ,aAAa,YAAY;CACnD,MAAM,eAAe,YAAY;CACjC,MAAM,eACJ,YAAY,uBAAuB,SAAS,eACxC,KAAA,IACA,YAAY;CAClB,OAAO,yBAAyB;EAC9B,IAAI,QAAQ;EACZ,WAAW,QAAQ;EACnB,YAAY,QAAQ;EACpB,MAAM,QAAQ;EACd,UAAU,CACR;GACE,IAAI,YAAY,YAAY;GAC5B,WAAW;GACX,cAAc;GACd,UAAU;IACR,MAAM;IACN,cAAc,YAAY;IAC1B;IACA,eAAe,YAAY;IAC3B;IACA;IACA,GAAI,oBAAoB,cAAc,EAAE,eAAe,YAAY,eAAe,IAAI,CAAC;IACvF,GAAI,gBAAgB,cAAc,EAAE,YAAY,YAAY,WAAW,IAAI,CAAC;GAC9E;GACA;GACA,UAAU;IACR,YAAY,YAAY;IACxB,OAAO,QAAQ;IACf;GACF;EACF,CACF;EACA,QAAQ,CAAC,GAAI,QAAQ,UAAU,CAAC,CAAE;EAClC,SAAS,QAAQ,UACb;GACE,GAAG,QAAQ;GACX,SAAS,QAAQ,QAAQ,WAAW;EACtC,IACA,iBAAiB,KAAA,IACf,KAAA,IACA;GAAE,SAAS;GAAc,YAAY,YAAY;EAAS;EAChE,OAAO,QAAQ;EACf,MAAM,QAAQ;EACd;EACA,UAAU;GACR,GAAG,QAAQ;GACX,UAAU;IACR,MAAM;IACN,OAAO,YAAY;IACnB;IACA,WAAW,YAAY;IACvB,SAAS,YAAY;IACrB;IACA,gBAAgB,YAAY;IAC5B;GACF;EACF;CACF,CAAC;AACH;;AAGA,SAAgB,2BACd,KACA,UAAkC,CAAC,GACX;CACxB,MAAM,cAAc,mBAAmB,KAAK,gBAAgB,IAAI,OAAO,EAAE;CACzE,MAAM,YAAY,iBAAiB,WAAW;CAC9C,MAAM,YAAY,QAAQ,8BAAa,IAAI,KAAK,EAAA,CAAE,YAAY;CAC9D,OAAO,YAAY,SAAS,KAAK,aAAa;EAC5C,IAAI,uBAAuB,WAAW,QAAQ,UAAU;EACxD,OAAO,YAAY;EACnB;EACA,WAAW,QAAQ;EACnB,eAAe,qBAAqB,OAAO;EAC3C,WAAW,QAAQ;EACnB,MAAM,QAAQ;EACd,OAAO,QAAQ;EACf,UAAU,QAAQ;EAClB,mBAAmB,QAAQ;EAC3B,gBAAgB,QAAQ;EACxB,UAAU,4BAA4B,OAAO;EAC7C,YAAY,QAAQ;EACpB;CACF,EAAE;AACJ;AAEA,SAAS,8BACP,KACA,UACwB;CACxB,MAAM,YAAY,iBAAiB,GAAG;CACtC,MAAM,eAAe,IAAI,IAAI,IAAI,SAAS,KAAK,YAAY,CAAC,QAAQ,YAAY,OAAO,CAAC,CAAC;CACzF,MAAM,iCAAiB,IAAI,IAAY;CACvC,OAAO,SAAS,KAAK,SAAS,UAAU;EACtC,IAAI,QAAQ,UAAU,IAAI,QACxB,MAAM,IAAI,UAAU,0BAA0B,MAAM,iBAAiB;EAEvE,IAAI,QAAQ,cAAc,WACxB,MAAM,IAAI,UAAU,0BAA0B,MAAM,qBAAqB;EAE3E,MAAM,UAAU,aAAa,IAAI,QAAQ,SAAS;EAClD,IAAI,CAAC,SACH,MAAM,IAAI,UACR,0BAA0B,MAAM,kCAAkC,QAAQ,UAAU,EACtF;EAEF,IAAI,eAAe,IAAI,QAAQ,SAAS,GACtC,MAAM,IAAI,UAAU,oDAAoD,QAAQ,UAAU,EAAE;EAE9F,eAAe,IAAI,QAAQ,SAAS;EACpC,IAAI,QAAQ,kBAAkB,qBAAqB,OAAO,GACxD,MAAM,IAAI,UAAU,0BAA0B,MAAM,yBAAyB;EAE/E,IAAI,QAAQ,OAAO,uBAAuB,WAAW,QAAQ,SAAS,GACpE,MAAM,IAAI,UAAU,0BAA0B,MAAM,aAAa;EAEnE,OAAO;CACT,CAAC;AACH;AAEA,SAAS,uBAAuB,WAA+B,WAA2B;CACxF,OAAO,WAAW,UAAU,GAAG;AACjC;AAEA,SAAgB,oBACd,YACA,SAA8B,CAAC,GACjB;CACd,MAAM,QAAQ;EAAE,GAAG;EAAsB,GAAG;CAAO;CACnD,MAAM,QAAQ,MAAM,WAAW,MAAM,SAAS,MAAM,UAAU,MAAM;CACpE,IAAI,SAAS,GAAG,MAAM,IAAI,MAAM,4DAA4D;CAC5F,MAAM,SACJ,WACE,GAAG,WAAW,aAAa,GAAG,GAAG,WAAW,cAAc,GAAG,GAAG,WAAW,GAAG,GAAG,WAAW,KAAK,QACnG,IAAI;CACN,IAAI,SAAS,MAAM,UAAU,OAAO;CACpC,IAAI,SAAS,MAAM,WAAW,MAAM,QAAQ,OAAO;CACnD,IAAI,SAAS,MAAM,WAAW,MAAM,SAAS,MAAM,SAAS,OAAO;CACnE,OAAO;AACT;AAEA,SAAgB,0BACd,YACA,QACoB;CACpB,OAAO;EACL,GAAG;EACH,OAAO,WAAW,SAAS,oBAAoB,YAAY,MAAM;CACnE;AACF;AAEA,SAAgB,oCACd,YACiB;CACjB,MAAM,YAAY,0BAA0B,UAAU;CACtD,OAAO;EACL,IAAI,UAAU,cAAc,UAAU;EACtC,OAAO,UAAU;EACjB,SAAS;EACT,MAAM;GACJ,GAAI,UAAU,YAAY,EAAE,WAAW,UAAU,UAAU,IAAI,CAAC;GAChE,GAAI,UAAU,QAAQ,CAAC;GACvB,QAAQ;EACV;CACF;AACF;AAEA,SAAgB,uCACd,cACmB;CACnB,OAAO,aAAa,IAAI,mCAAmC;AAC7D;AAEA,SAAgB,iCACd,YACsB;CACtB,MAAM,SAAS,UAAU,UAAU;CACnC,MAAM,gBAAgB,kBAAkB,UAAU;CAClD,MAAM,iBAAiB,gBAAgB,8BAA8B,aAAa,IAAI,KAAA;CACtF,MAAM,mBAAmB,gBACrB,cAAc,gBAAgB,KAAK,aAAgC;EACjE,IAAI,SAAS,YAAY,YAAY,OAAO;EAC5C,IAAI,SAAS,YAAY,2BAA2B,SAAS,aAAa,SAAS,GACjF,OAAO;EAET,OAAO;CACT,CAAC,IACD,CAAC;CACL,OAAO;EACL,YAAY,WAAW,cAAc,WAAW;EAChD,cAAc,WAAW;EACzB,YAAY,CAAC,mBAAG,IAAI,IAAI,CAAC,GAAG,OAAO,KAAK,UAAU,MAAM,IAAI,GAAG,GAAG,gBAAgB,CAAC,CAAC;EACpF,OAAO,gBAAgB,MAAM,WAAW,SAAS,SAAS,gBAAgB,MAAM;EAChF,UAAU;GACR,WAAW,WAAW;GACtB,OAAO,WAAW;GAClB,QAAQ,WAAW,KAAK;GACxB,UAAU,WAAW,SAAS;GAC9B,SAAS,WAAW;GACpB;GACA,GAAI,gBACA,EACE,eAAe;IACb,YAAY,cAAc;IAC1B,gBAAgB,cAAc,SAAS,KAAK,aAAa;KACvD,WAAW,QAAQ;KACnB,eAAe,qBAAqB,OAAO;IAC7C,EAAE;IACF,WAAW,cAAc;IACzB,WAAW,gBAAgB;IAC3B,QAAQ,gBAAgB;IACxB,IAAI,gBAAgB;IACpB,QAAQ,gBAAgB;GAC1B,EACF,IACA,CAAC;EACP;CACF;AACF;AAEA,SAAgB,oCACd,cACwB;CACxB,OAAO,aAAa,IAAI,gCAAgC;AAC1D;AAEA,eAAsB,yBACpB,YACA,SAC+B;CAC/B,IAAI;EACF,MAAM,SAAS,MAAM,QAAQ,OAAO,UAAU;EAC9C,OAAO;GACL,cAAc,WAAW;GACzB,GAAG;EACL;CACF,SAAS,KAAK;EACZ,MAAM,6BAAY,IAAI,KAAK,EAAA,CAAE,YAAY;EACzC,MAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;EAC/D,OAAO;GACL,cAAc,WAAW;GACzB,MAAM;GACN,QAAQ,CACN;IACE,QAAQ;IACR,MAAM;IACN,OAAO;IACP,QAAQ;IACR,UAAU;IACV;GACF,CACF;GACA,SAAS;IACP,SAAS;IACT,OAAO;IACP,QAAQ;IACR,YAAY;GACd;GACA,UAAU,EAAE,aAAa,KAAK;EAChC;CACF;AACF;AAEA,eAAsB,2BACpB,cACA,SACiC;CACjC,MAAM,UAAkC,CAAC;CACzC,KAAK,MAAM,cAAc,cACvB,QAAQ,KAAK,MAAM,yBAAyB,YAAY,OAAO,CAAC;CAElE,OAAO;AACT;AAEA,SAAgB,0BACd,cACA,UAAmC,CAAC,GACX;CACzB,MAAM,aAAa,QAAQ,cAAc;CACzC,MAAM,UAAmC,CAAC;CAC1C,KAAK,MAAM,cAAc,cACvB,KAAK,MAAM,SAAS,UAAU,UAAU,GAAG;EACzC,MAAM,cAAc,qBAAqB,YAAY,KAAK;EAC1D,IAAI,CAAC,aAAa;EAClB,QAAQ,KAAK;GACX;GACA,WAAW,MAAM,UAAU,GAAG,MAAM,KAAK,cAAc,MAAM;GAC7D,QAAQ,eAAe,KAAK;GAC5B,oBAAoB,WAAW;GAC/B,eAAe,MAAM;GACrB,UAAU,MAAM;EAClB,CAAC;CACH;CAGF,MAAM,gCAAgB,IAAI,IAAmC;CAC7D,KAAK,MAAM,SAAS,SAAS;EAC3B,MAAM,MAAM,MAAM,YAAY,YAAY,CAAC,CAAC,QAAQ,QAAQ,GAAG,CAAC,CAAC,KAAK;EACtE,MAAM,WAAW,cAAc,IAAI,GAAG;EACtC,IAAI,CAAC,YAAY,MAAM,SAAS,SAAS,QAAQ,cAAc,IAAI,KAAK,KAAK;CAC/E;CACA,OAAO,CAAC,GAAG,cAAc,OAAO,CAAC,CAAC,CAAC,MAAM,GAAG,MAAM,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC,MAAM,GAAG,UAAU;AAC5F;AAEA,SAAgB,+BAA+B,SAA0C;CACvF,MAAM,QAAQ,CAAC,uBAAuB,EAAE;CACxC,KAAK,MAAM,SAAS,SAAS;EAC3B,MAAM,KAAK,KAAK,MAAM,aAAa;EACnC,MAAM,KAAK,gBAAgB,MAAM,WAAW;EAC5C,MAAM,KAAK,aAAa,MAAM,oBAAoB;EAClD,MAAM,KAAK,EAAE;CACf;CACA,OAAO,GAAG,MAAM,KAAK,IAAI,CAAC,CAAC,KAAK,EAAE;AACpC;AAEA,SAAgB,mCAAmC,cAA4C;CAC7F,OAAO,GAAG,aACP,MAAM,CAAC,CACP,MAAM,GAAG,MAAM,EAAE,GAAG,cAAc,EAAE,EAAE,CAAC,CAAC,CACxC,KAAK,eAAe,KAAK,UAAUA,eAAa,UAAU,CAAC,CAAC,CAAC,CAC7D,KAAK,IAAI,EAAE;AAChB;AAEA,SAAgB,+BAA+B,OAAqC;CAClF,MAAM,eAAqC,CAAC;CAC5C,KAAK,MAAM,QAAQ,MAAM,MAAM,IAAI,GAAG;EACpC,IAAI,CAAC,KAAK,KAAK,GAAG;EAClB,aAAa,KAAK,KAAK,MAAM,IAAI,CAAuB;CAC1D;CACA,OAAO;AACT;AAEA,SAAgB,+BACd,KACA,UASI,CAAC,GACe;CACpB,MAAM,YAAY,QAAQ,8BAAa,IAAI,KAAK,EAAA,CAAE,YAAY;CAC9D,MAAM,eACJ,IAAI,SAAS,cAAc,WAAW,GAAG,IAAI,OAAO,GAAG,WAAW,CAAC,CAAC,SAAS,EAAE;CACjF,OAAO,yBAAyB;EAC9B,IAAI;EACJ,WAAW,QAAQ;EACnB,YAAY,QAAQ;EACpB,MAAM,EAAE,QAAQ,IAAI,OAAO;EAC3B;EACA,UAAU,IAAI,MAAM,KAAK,UAAU;GACjC,IAAI,GAAG,aAAa,QAAQ,KAAK;GACjC,WAAW,KAAK;GAChB,cAAc,QAAQ,gBAAgB;GACtC,UAAU,QAAQ,mBAAmB,IAAI,KAAK,KAAK,eAAe,UAAU,KAAK;GACjF,gBAAgB,QAAQ,yBAAyB,IAAI;GACrD,OAAO,KAAK;GACZ,WAAW,KAAK;GAChB,UAAU;IACR,UAAU,KAAK;IACf,eAAe,KAAK;GACtB;EACF,EAAE;EACF,QAAQ,CACN;GACE,QAAQ;GACR,MAAM,IAAI,OAAO,YAAY;GAC7B,OAAO,IAAI;GACX,QAAQ,IAAI;GACZ,UAAU,IAAI,OAAO,SAAS;GAC9B;EACF,CACF;EACA,SAAS;GACP,SAAS,IAAI;GACb,OAAO,IAAI;GACX,SAAS,IAAI;GACb,QAAQ,IAAI;GACZ,YAAY;GACZ,UAAU;IACR,WAAW,IAAI;IACf,cAAc,IAAI;GACpB;EACF;CACF,CAAC;AACH;AAEA,SAAS,UAAU,YAAiD;CAClE,MAAM,SAAS,CACb,GAAG,WAAW,QACd,GAAG,WAAW,SAAS,SAAS,YAAY,QAAQ,YAAY,CAAC,CAAC,CACpE;CACA,MAAM,uBAAO,IAAI,IAAY;CAC7B,OAAO,OAAO,QAAQ,UAAU;EAC9B,MAAM,MACJ,MAAM,MAAM,GAAG,MAAM,OAAO,GAAG,MAAM,KAAK,GAAG,MAAM,UAAU,GAAG,KAAK,UAAU,MAAM,KAAK;EAC5F,IAAI,KAAK,IAAI,GAAG,GAAG,OAAO;EAC1B,KAAK,IAAI,GAAG;EACZ,OAAO;CACT,CAAC;AACH;AAEA,SAAS,4BAA4B,SAA2C;CAC9E,QAAQ,QAAQ,UAAhB;EACE,KAAK,YACH,OAAO;EACT,KAAK,QACH,OAAO;EACT,KAAK,UACH,OAAO;EACT,SACE,OAAO;CACX;AACF;AAEA,SAAS,gBAAgB,QAA6C;CACpE,IAAI,CAAC,OAAO,QAAQ,OAAO,KAAA;CAC3B,MAAM,SAAS,OACZ,KAAK,UAAU;EACd,IAAI,MAAM,SAAS,aAAa,MAAM,SAAS,UAAU,OAAO;EAChE,IAAI,MAAM,SAAS,YAAY,MAAM,SAAS,gBAAgB,OAAO;EACrE,IAAI,MAAM,SAAS,UAAU,OAAO,MAAM,UAAU,UAClD,OAAO,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,MAAM,KAAK,CAAC;CAE/C,CAAC,CAAC,CACD,QAAQ,UAA2B,OAAO,UAAU,QAAQ;CAC/D,IAAI,CAAC,OAAO,QAAQ,OAAO,KAAA;CAC3B,OAAO,KAAK,MAAO,OAAO,QAAQ,KAAK,UAAU,MAAM,OAAO,CAAC,IAAI,OAAO,SAAU,GAAI,IAAI;AAC9F;AAEA,SAAS,qBACP,YACA,OACoB;CACpB,IAAI,MAAM,SAAS,YAAY,MAAM,QACnC,OAAO,uBAAuB,QAAQ,WAAW,KAAK,QAAQ,EAAE,EAAE,UAAU,MAAM;CACpF,IAAI,MAAM,SAAS,sBAAsB,MAAM,QAC7C,OAAO,oCAAoC,MAAM;CACnD,IAAI,MAAM,SAAS,YAAY,MAAM,QACnC,OAAO,gCAAgC,QAAQ,WAAW,KAAK,QAAQ,EAAE,EAAE,aAAa,MAAM;CAChG,IAAI,MAAM,SAAS,aAAa,MAAM,QACpC,OAAO,oCAAoC,QAAQ,WAAW,KAAK,QAAQ,EAAE,EAAE,KAAK,MAAM;CAC5F,IAAI,MAAM,SAAS,aAAa,MAAM,QAAQ,OAAO,MAAM;AAE7D;AAEA,SAAS,eAAe,OAA8B;CAepD,QAbE,MAAM,aAAa,aACf,IACA,MAAM,aAAa,UACjB,IACA,MAAM,aAAa,YACjB,IACA,MAER,MAAM,WAAW,SACb,IACA,MAAM,WAAW,YAAY,MAAM,WAAW,gBAC5C,IACA;AAEV;AAEA,SAAS,cAAc,YAAgC,QAA2C;CAChG,IAAI,OAAO,aAAa,WAAW,cAAc,OAAO,WAAW,OAAO;CAC1E,IAAI,OAAO,cAAc,WAAW,eAAe,OAAO,YAAY,OAAO;CAC7E,IAAI,OAAO,SAAS,WAAW,UAAU,OAAO,OAAO,OAAO;CAC9D,IAAI,OAAO,KAAK;EACd,MAAM,CAAC,KAAK,SAAS,OAAO;EAC5B,IAAI,WAAW,OAAO,SAAS,OAAO,OAAO;CAC/C;CACA,OAAO;AACT;AAEA,SAAS,gBAAgB,YAAoD;CAC3E,OAAO,KAAK,MAAM,KAAK,UAAU,UAAU,CAAC;AAC9C;AAEA,SAAS,QAAQ,OAAe,KAAqB;CACnD,MAAM,aAAa,MAAM,QAAQ,QAAQ,GAAG,CAAC,CAAC,KAAK;CACnD,OAAO,WAAW,SAAS,MAAM,GAAG,WAAW,MAAM,GAAG,GAAG,CAAC,CAAC,KAAK,EAAE,OAAO;AAC7E;AAEA,SAAS,WAAW,OAAuB;CACzC,IAAI,OAAO;CACX,KAAK,IAAI,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK,GAAG;EACxC,QAAQ,MAAM,WAAW,CAAC;EAC1B,OAAO,KAAK,KAAK,MAAM,QAAQ;CACjC;CACA,OAAO,SAAS;AAClB;AAEA,SAASA,eAAa,OAAyB;CAC7C,IAAI,UAAU,QAAQ,OAAO,UAAU,UAAU,OAAO;CACxD,IAAI,MAAM,QAAQ,KAAK,GAAG,OAAO,MAAM,IAAIA,cAAY;CACvD,MAAM,MAA+B,CAAC;CACtC,KAAK,MAAM,OAAO,OAAO,KAAK,KAAgC,CAAC,CAAC,KAAK,GACnE,IAAI,OAAOA,eAAc,MAAkC,IAAI;CAEjE,OAAO;AACT;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACl3BA,MAAM,6BAA6B;AAoEnC,SAASC,aAAW,KAAqB;CACvC,OAAO,IAAI,QAAQ,QAAQ,EAAE;AAC/B;;AAGA,SAAS,aAAa,MAA8B;CAClD,IAAI,QAAQ,QAAQ,OAAO,SAAS,UAAU,OAAO;CACrD,MAAM,IAAI;CACV,IAAI,EAAE,SAAS,OAAO,EAAE,MAAM,YAAY,UAAU,OAAO,EAAE,MAAM;CACnE,IAAI,OAAO,EAAE,YAAY,UAAU,OAAO,EAAE;CAC5C,OAAO;AACT;;;;;;;;;;;AAYA,eAAsB,gBAAgB,MAAyD;CAC7F,MAAM,YAAY,KAAK,aAAa;CACpC,MAAM,UAAUA,aAAW,KAAK,OAAO;CACvC,MAAM,cAAc,EAAE,eAAe,UAAU,KAAK,SAAS;CAC7D,MAAM,YAAY,KAAK,kBAAA;CACvB,IAAI,CAAC,OAAO,UAAU,SAAS,KAAK,aAAa,GAC/C,OAAO;EACL,WAAW;EACX,OAAO;EACP,OAAO,mEAAmE;CAC5E;CAGF,IAAI;CACJ,IAAI;EACF,MAAM,MAAM,MAAM,UAAU,GAAG,QAAQ,UAAU;GAAE,QAAQ;GAAO,SAAS;EAAY,CAAC;EACxF,IAAI,CAAC,IAAI,IAAI;GACX,MAAM,OAAO,MAAM,IAAI,KAAK,CAAC,CAAC,YAAY,EAAE;GAC5C,OAAO;IACL,WAAW;IACX,OAAO;IACP,OAAO,wBAAwB,QAAQ,YAAY,IAAI,OAAO,GAAG,KAAK,MAAM,GAAG,GAAG;GACpF;EACF;EACA,MAAM,OAAQ,MAAM,IAAI,KAAK;EAC7B,MAAM,MAAM,MAAM,QAAQ,KAAK,IAAI,IAAI,KAAK,OAAO,CAAC;EACpD,SAAS,IAAI,IAAI,IAAI,KAAK,MAAM,EAAE,EAAE,CAAC,CAAC,QAAQ,OAAqB,OAAO,OAAO,QAAQ,CAAC;CAC5F,SAAS,KAAK;EACZ,OAAO;GACL,WAAW;GACX,OAAO;GACP,OAAO,wBAAwB,QAAQ,mBAAmB,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;EAC3G;CACF;CAEA,MAAM,UAA4B,CAAC;CACnC,KAAK,MAAM,SAAS,KAAK,QAAQ;EAC/B,MAAM,SAAS,OAAO,IAAI,KAAK;EAC/B,IAAI,CAAC,KAAK,OAAO;GACf,QAAQ,KAAK;IACX;IACA;IACA,QAAQ;IACR,QAAQ;IACR,QAAQ;IACR,iBAAiB;IACjB,cAAc;GAChB,CAAC;GACD;EACF;EACA,IAAI;GACF,MAAM,MAAM,MAAM,UAAU,GAAG,QAAQ,oBAAoB;IACzD,QAAQ;IACR,SAAS;KAAE,GAAG;KAAa,gBAAgB;IAAmB;IAC9D,MAAM,KAAK,UAAU;KACnB;KACA,UAAU,CAAC;MAAE,MAAM;MAAQ,SAAS;KAAO,CAAC;KAC5C,YAAY;IACd,CAAC;GACH,CAAC;GACD,IAAI,SAAwB;GAC5B,IAAI,eAAwC;GAC5C,IAAI,kBAAkB;GACtB,MAAM,OAAO,MAAM,IAAI,KAAK,CAAC,CAAC,YAAY,IAAI;GAC9C,IAAI,IAAI,IAAI;IACV,MAAM,SAAU,MAA+B;IAC/C,eAAe,iBACb,OACA,OAAO,WAAW,YAAY,OAAO,KAAK,MAAM,KAAK,SAAS,IAChE;GACF,OAAO;IACL,SAAS,aAAa,IAAI;IAC1B,kBAAkB,WAAW,QAAQ,2BAA2B,KAAK,MAAM;IAI3E,IAAI,iBAAiB,eAAe,iBAAiB,OAAO,IAAI;GAClE;GACA,QAAQ,KAAK;IACX;IACA;IACA,QAAQ,IAAI,MAAM;IAClB,QAAQ,IAAI;IACZ;IACA;IACA;GACF,CAAC;EACH,SAAS,KAAK;GACZ,OAAO;IACL,WAAW;IACX,OAAO;IACP,OAAO,+BAA+B,QAAQ,2BAA2B,MAAM,aAAa,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;GAC7I;EACF;CACF;CAEA,OAAO;EAAE,WAAW;EAAM,OAAO;EAAS,OAAO;CAAK;AACxD;AAEA,IAAa,yBAAb,cAA4C,eAAe;CAGvC;CAFlB,YACE,SACA,SACA;EACA,MAAM,UAAU,OAAO;EAFP,KAAA,UAAA;EAGhB,KAAK,OAAO;CACd;AACF;AAEA,SAAS,gBAAgB,GAA2B;CAClD,IAAI,CAAC,EAAE,QAAQ;EACb,MAAM,YACJ,EAAE,WAAW,QAAQ,WAAW,EAAE,SAAS,EAAE,SAAS,KAAK,EAAE,WAAW,GAAG,KAAK;EAClF,OAAO,GAAG,EAAE,MAAM,kBAAkB;CACtC;CACA,IAAI,EAAE,WAAW,OACf,OAAO,GAAG,EAAE,MAAM,qBAAqB,EAAE,SAAS,EAAE,SAAS,MAAM,EAAE,WAAW;CAElF,IAAI,EAAE,iBACJ,OACE,GAAG,EAAE,MAAM,4DAA4D,EAAE,SACtE,EAAE,SAAS,KAAK,EAAE,WAAW,GAAG;CAKvC,MAAM,IAAI,EAAE;CACZ,IAAI,GAAG,YAAY,cACjB,OAAO,GAAG,EAAE,MAAM;CAEpB,OAAO,GAAG,EAAE,MAAM,sBAAsB,GAAG,OAAO,IAAI,GAAG,QAAQ;AACnE;;;;;;;;;;;;AA0BA,eAAsB,mBACpB,MAC2B;CAC3B,MAAM,UAAU,MAAM,gBAAgB,IAAI;CAC1C,IAAI,CAAC,QAAQ,aAAa,QAAQ,UAAU,MAC1C,MAAM,IAAI,YACR,QAAQ,SAAS,+DACnB;CAEF,MAAM,MAAM,QAAQ,MAAM,QACvB,MACC,CAAC,EAAE,UACH,EAAE,WAAW,SACZ,EAAE,iBAAiB,QAAQ,CAAC,sBAAsB,EAAE,cAAc,IAAI,CAC3E;CACA,IAAI,IAAI,SAAS,GACf,MAAM,IAAI,uBACR,uBAAuB,IAAI,OAAO,GAAG,QAAQ,MAAM,OAAO,qCAAqC,IAC5F,IAAI,eAAe,CAAC,CACpB,KAAK,IAAI,KACZ,QAAQ,KACV;CAEF,OAAO,QAAQ;AACjB;;;;;;;;;;;;;;;;;;ACzPA,IAAa,qBAAb,cAAwC,eAAe;CAGnC;CAFlB,YACE,SACA,QACA;EACA,MAAM,qBAAqB,OAAO;EAFlB,KAAA,SAAA;EAGhB,KAAK,OAAO;CACd;AACF;AAEA,SAAS,WAAW,KAAqB;CACvC,OAAO,IAAI,QAAQ,QAAQ,EAAE;AAC/B;;;;;;AAOA,SAAgB,oBACd,OACA,OACA,OAAmC,CAAC,GACf;CACrB,MAAM,cAAyC,CAAC;CAEhD,IAAI,MAAM,SAAS,MAAM,MACvB,YAAY,KAAK;EAAE,OAAO;EAAQ,OAAO,MAAM;EAAM,OAAO,MAAM;CAAK,CAAC;CAE1E,IAAI,WAAW,MAAM,OAAO,MAAM,WAAW,MAAM,OAAO,GACxD,YAAY,KAAK;EAAE,OAAO;EAAW,OAAO,MAAM;EAAS,OAAO,MAAM;CAAQ,CAAC;CAEnF,IAAI,MAAM,UAAU,MAAM,OACxB,YAAY,KAAK;EAAE,OAAO;EAAS,OAAO,MAAM;EAAO,OAAO,MAAM;CAAM,CAAC;CAG7E,IAAI,MAAM,aAAa,MAAM,UAC3B,YAAY,KAAK;EAAE,OAAO;EAAY,OAAO,MAAM;EAAU,OAAO,MAAM;CAAS,CAAC;CAGtF,MAAM,cAAc,QAAQ,MAAM,MAAM;CACxC,MAAM,cAAc,QAAQ,MAAM,MAAM;CACxC,IAAI,gBAAgB,aAClB,YAAY,KAAK;EACf,OAAO;EACP,OAAO,cAAc,QAAQ;EAC7B,OAAO,cAAc,QAAQ;CAC/B,CAAC;CAGH,MAAM,WAAW,KAAK,SAAS,cAAc,YAAY,QAAQ,MAAM,EAAE,UAAU,OAAO;CAC1F,MAAM,KAAK,SAAS,WAAW;CAC/B,MAAM,SAA8B;EAAE;EAAI;CAAY;CAEtD,IAAI,CAAC,IAAI;EACP,MAAM,aAAa,KAAK,cAAc;EACtC,MAAM,aAAa,KAAK,cAAc;EAItC,MAAM,IAAI,mBACR,mBAAmB,WAAW,OAAO,WAAW,2FAJnC,SACZ,KAAK,MAAM,GAAG,EAAE,MAAM,IAAI,WAAW,GAAG,EAAE,SAAS,IAAI,MAAM,WAAW,GAAG,EAAE,SAAS,KAAK,CAAC,CAC5F,KAAK,IAGoD,EAAO,IACjE,MACF;CACF;CAEA,OAAO;AACT;;;AC3GA,SAAgB,wBACd,SAC0B;CAC1B,MAAM,MAAM,QAAQ,uBAAO,IAAI,KAAK;CACpC,MAAM,eAAe,QAAQ,aAAa,IAAI,oBAAoB;CAClE,MAAM,UAAU,aAAa,QAAQ,gBAAgB,qBAAqB,aAAa,GAAG,CAAC;CAC3F,MAAM,8BAA8B,QAAQ,OAAO,aAAa;CAChE,MAAM,kBAAkB,QAAQ,QAAQ,gBAAgB,CAAC,cAAc,WAAW,CAAC;CACnF,MAAM,iBAAiB,oBAAoB,cAAc,GAAG;CAC5D,MAAM,SAA0B;EAC9B,QAAQ,QAAQ;EAChB;EACA,aAAa,OAAO,CAClB,GAAI,QAAQ,eAAe,CAAC,GAC5B,GAAG,aAAa,SAAS,MAAM,EAAE,WAAW,CAC9C,CAAC;EACD,UAAU,OAAO,QAAQ,YAAY,CAAC,CAAC;EACvC,aAAa,OAAO,QAAQ,eAAe,CAAC,CAAC;EAC7C,aAAa,QAAQ,eAAe,CAAC;EACrC;EACA;EACA,UAAU,QAAQ;CACpB;CACA,MAAM,oBAAoB,wBAAwB,6BAA6B,eAAe;CAC9F,MAAM,WACJ,4BAA4B,SAAS,IACjC,aACA,gBAAgB,MAAM,QAAQ,IAAI,eAAe,MAAM,IACrD,YACA;CACR,MAAM,SACJ,4BAA4B,SAAS,IACjC,GAAG,4BAA4B,OAAO,mDACtC,gBAAgB,SAAS,IACvB,GAAG,gBAAgB,OAAO,0CAC1B;CAER,OAAO;EACL,QAAQ,QAAQ;EAChB;EACA;EACA;EACA;EACA;EACA;EACA;CACF;AACF;AAEA,SAAgB,sBACd,QACA,UAA0E,CAAC,GACxD;CACnB,MAAM,eAAe,QAAQ,gBAAgB;CAC7C,MAAM,SACJ,OAAO,4BAA4B,WAAW,KAAK,OAAO,kBAAkB;CAC9E,IAAI,QAAQ,SACV,QAAa,QACV,KAAK;EACJ,MAAM;EACN,SAAS,+BAA+B,QAAQ;GAAE;GAAQ;EAAa,CAAC;CAC1E,CAAC,CAAC,CACD,YAAY,KAAA,CAAS;CAE1B,OAAO,cAAc;EACnB,IAAI,QAAQ,MAAM;EAClB;EACA,OAAO,OAAO;EACd,UAAU,SAAS,SAAS,OAAO;EACnC,QAAQ,OAAO;EACf,UAAU,OAAO,4BAA4B,KAAK,MAAM,EAAE,EAAE,CAAC,CAAC,KAAK,IAAI,KAAK,KAAA;EAC5E,UAAU,EAAE,oBAAoB,OAAO;CACzC,CAAC;AACH;AAEA,SAAgB,+BACd,QACA,UAAuD,CAAC,GAC/B;CACzB,OAAO;EACL,MAAM;EACN,QAAQ,OAAO;EACf,QAAQ,QAAQ,UAAU,OAAO,4BAA4B,WAAW;EACxE,gBAAgB,OAAO;EACvB,cAAc,QAAQ;EACtB,wBAAwB,OAAO,4BAA4B,KAAK,MAAM,EAAE,EAAE;EAC1E,2BAA2B,OAAO,gBAAgB,KAAK,MAAM,EAAE,EAAE;EACjE,mBAAmB,OAAO;EAC1B,UAAU,OAAO;EACjB,QAAQ,OAAO;CACjB;AACF;AAEA,SAAgB,8BAA8B,MAA8C;CAC1F,OAAO,KACJ,QAAQ,QAAQ,IAAI,oBAAoB,cAAc,IAAI,mBAAmB,KAAK,CAAC,CACnF,KAAK,SAAS;EACb,IAAI,YAAY,IAAI;EACpB,UAAU,mBAAmB,IAAI;EACjC,QAAQ,gBAAgB,IAAI,YAAY,KAAK,IAAI,KAAK,WAAW;EACjE,eAAe,IAAI;EACnB,YAAY,IAAI;EAChB,YAAY,IAAI,gBAAgB,WAAW,eAAe;EAC1D,iBAAiB,UAAU,GAAG;CAChC,EAAE;AACN;AAEA,SAAgB,iCACd,MACuB;CACvB,MAAM,yBAAS,IAAI,IAAoC;CACvD,KAAK,MAAM,OAAO,MAAM;EACtB,MAAM,OAAO,SAAS,IAAI,eAAe;EACzC,IAAI,CAAC,MAAM;EACX,MAAM,SAAS,OAAO,IAAI,IAAI,KAAK,CAAC;EACpC,OAAO,KAAK,GAAG;EACf,OAAO,IAAI,MAAM,MAAM;CACzB;CACA,OAAO,CAAC,GAAG,OAAO,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,mBAAmB;EAC1D,IAAI,WAAW;EACf,gBAAgB,aAAa,KAAK,MAAM,EAAE,EAAE;EACtC;EACN,aAAa,mBAAmB,MAAqC,YAAY;EACjF,UAAU,cAAc,aAAa,KAAK,MAAM,EAAE,UAAU,CAAC;EAC7D,WAAW,SAAS,aAAa,8BAA8B,YAAY,IAAI,KAAA;CACjF,EAAE;AACJ;AAEA,SAAS,qBAAqB,aAAyD;CACrF,OAAO;EACL,GAAG;EACH,kBAAkBC,UAAQ,YAAY,gBAAgB;EACtD,mBAAmBA,UAAQ,YAAY,iBAAiB;EACxD,aAAa,OAAO,YAAY,WAAW;CAC7C;AACF;AAEA,SAAS,oBAAoB,cAAsC,KAAmB;CACpF,IAAI,aAAa,WAAW,GAAG,OAAO;CACtC,IAAI,YAAY;CAChB,IAAI,WAAW;CACf,KAAK,MAAM,eAAe,cAAc;EACtC,MAAM,SAAS,iBAAiB,YAAY,UAAU;EACtD,MAAM,QAAQ,UAAU,aAAa,GAAG,IACpC,IACA,YAAY,oBAAoB,IAC9B,IACA,KAAK,IAAI,GAAG,YAAY,oBAAoB,YAAY,gBAAgB;EAC9E,aAAa;EACb,YAAY,SAAS;CACvB;CACA,OAAOA,UAAQ,WAAW,SAAS;AACrC;AAEA,SAAS,qBAAqB,aAAmC,KAAoB;CACnF,OAAO,UAAU,aAAa,GAAG,KAAK,YAAY,oBAAoB,YAAY;AACpF;AAEA,SAAS,UAAU,aAAmC,KAAoB;CACxE,IAAI,CAAC,YAAY,YAAY,OAAO;CACpC,MAAM,WAAW,KAAK,MAAM,YAAY,UAAU;CAClD,IAAI,CAAC,OAAO,SAAS,QAAQ,GAAG,OAAO;CACvC,OAAO,YAAY,IAAI,QAAQ;AACjC;AAEA,SAAS,cAAc,aAA4C;CACjE,OACE,YAAY,eAAe,cAC3B,YAAY,mBAAmB,WAC/B,YAAY,gBAAgB;AAEhC;AAEA,SAAS,wBACP,UACA,aAC4B;CAC5B,MAAM,OAAO,SAAS,SAAS,IAAI,WAAW;CAC9C,IAAI,KAAK,WAAW,GAAG,OAAO;CAC9B,IAAI,KAAK,MAAM,QAAQ,IAAI,oBAAoB,cAAc,IAAI,mBAAmB,KAAK,GACvF,OAAO;CACT,IAAI,KAAK,MAAM,QAAQ,IAAI,oBAAoB,iBAAiB,GAAG,OAAO;CAC1E,IACE,KAAK,MACF,QAAQ,IAAI,oBAAoB,kBAAkB,IAAI,oBAAoB,aAC7E,GAEA,OAAO;CACT,IAAI,KAAK,MAAM,QAAQ,IAAI,oBAAoB,YAAY,GAAG,OAAO;CACrE,IAAI,KAAK,MAAM,QAAQ,IAAI,oBAAoB,eAAe,GAAG,OAAO;CACxE,IAAI,YAAY,MAAM,QAAQ,IAAI,eAAe,MAAM,GAAG,OAAO;CACjE,OAAO;AACT;AAEA,SAAS,SAAS,MAAoE;CACpF,IAAI,SAAS,0BAA0B,SAAS,iBAAiB,OAAO;CACxE,OAAO;AACT;AAEA,SAAS,mBACP,MACA,cACQ;CACR,MAAM,SAAS,aAAa,KAAK,MAAM,EAAE,WAAW,CAAC,CAAC,KAAK,IAAI;CAC/D,IAAI,SAAS,YAAY,OAAO,qBAAqB;CACrD,IAAI,SAAS,cAAc,OAAO,4CAA4C;CAC9E,IAAI,SAAS,mBAAmB,OAAO,oCAAoC;CAC3E,IAAI,SAAS,gBAAgB,OAAO,mCAAmC;CACvE,IAAI,SAAS,eAAe,OAAO,kCAAkC;CACrE,OAAO,mCAAmC;AAC5C;AAEA,SAAS,UAAU,aAA2C;CAC5D,IAAI,YAAY,mBAAmB,SAAS,OAAO;CACnD,IAAI,YAAY,mBAAmB,wBACjC,OAAO;CACT,IAAI,YAAY,mBAAmB,eACjC,OAAO;CACT,OAAO;AACT;AAEA,SAAS,cAAc,QAAoD;CAEzE,OAAO;EAD+B;EAAY;EAAQ;EAAU;CACzD,CAAC,CAAC,MAAM,UAAU,OAAO,SAAS,KAAK,CAAC,KAAK;AAC1D;AAEA,SAAS,iBAAiB,YAAyC;CACjE,IAAI,eAAe,YAAY,OAAO;CACtC,IAAI,eAAe,QAAQ,OAAO;CAClC,IAAI,eAAe,UAAU,OAAO;CACpC,OAAO;AACT;AAEA,SAASA,UAAQ,OAAuB;CACtC,IAAI,CAAC,OAAO,SAAS,KAAK,GAAG,OAAO;CACpC,OAAO,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,KAAK,CAAC;AACvC;AAEA,SAAS,OAAU,OAAiB;CAClC,OAAO,CAAC,GAAG,IAAI,IAAI,KAAK,CAAC;AAC3B;;;ACjMA,eAAsB,aAAa,QAAmD;CACpF,MAAM,YAAY,KAAK,IAAI;CAC3B,MAAM,SAAwB,CAAC;CAC/B,MAAM,YAAiC,CAAC;CACxC,MAAM,SAA0B,CAAC;CACjC,MAAM,aAA6C,CAAC;CACpD,MAAM,WAAW;EAAE,GAAI,OAAO,YAAY,CAAC;EAAI,MAAM;CAAK;CAC1D,MAAM,UAA4B;EAChC,WAAW,OAAO;EAClB,YAAY,OAAO;EACnB,MAAM,OAAO;EACb;EACA;EACA;EACA;EACA;EACA,WAAW,UAAU,OAAO,KAAK,KAAK;EACtC,cAAc,aAAa,UAAU,KAAK,QAAQ;EAClD,WAAW,UACT,OAAO,KAAK;GAAE,GAAG;GAAO,WAAW,MAAM,8BAAa,IAAI,KAAK,EAAA,CAAE,YAAY;EAAE,CAAC;EAClF,UAAU,SAAS,WAAW,KAAK;GAAE,GAAG;GAAM,IAAI,KAAK,uBAAM,IAAI,KAAK,EAAA,CAAE,YAAY;EAAE,CAAC;CACzF;CAEA,IAAI;EACF,MAAM,OAAO,MAAM,OAAO;EAC1B,MAAM,mBAAmB,MAAM,OAAO,WAAW,OAAO;EACxD,IAAI,kBAAkB,OAAO,KAAK,GAAG,gBAAgB;CACvD,SAAS,KAAK;EACZ,OAAO,KAAK;GACV,MAAM;GACN,QAAQ;GACR,UAAU;GACV,QAAQ,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;EACzD,CAAC;CACH;CAEA,KAAK,MAAM,QAAQ,OAAO,qBAAqB,CAAC,GAC9C,OAAO,KAAK;EACV,MAAM,YAAY;EAClB,QAAQ,UAAU,MAAM,aAAa,SAAS,SAAS,IAAI;EAC3D,UAAU,iBAAiB;EAC3B,QAAQ,UAAU,KAAK,aAAa,SAAS,IAAI,CAAC,CAAC,KAAK,IAAI,KAAK;CACnE,CAAC;CAGH,MAAM,WACJ,OAAO,WAAW,IAAI,IAAI,OAAO,QAAQ,UAAU,MAAM,MAAM,CAAC,CAAC,SAAS,OAAO;CACnF,IAAI,OAAO,gBAAgB,KAAA,GACzB,OAAO,KAAK;EACV,MAAM;EACN,QAAQ,YAAY,OAAO;EAC3B,UAAU,gBAAgB,OAAO;EACjC,QAAQ,SAAS,QAAQ,CAAC;CAC5B,CAAC;CAGH,MAAM,SAAS,OAAO,SAAS,KAAK,OAAO,OAAO,UAAU,MAAM,MAAM;CACxE,MAAM,WAAW,KAAK,IAAI,IAAI;CAC9B,MAAM,aAAa,yBAAyB;EAC1C,WAAW,OAAO;EAClB,YAAY,OAAO;EACnB,MAAM,EAAE,QAAQ,OAAO,KAAK;EAC5B;EACA,SAAS;GACP,SAAS;GACT,OACE,OAAO,WAAW,IAAI,IAAI,OAAO,QAAQ,UAAU,MAAM,MAAM,CAAC,CAAC,SAAS,OAAO;GACnF,QAAQ,GAAG,OAAO,QAAQ,UAAU,MAAM,MAAM,CAAC,CAAC,OAAO,GAAG,OAAO,OAAO;GAC1E,6BAAY,IAAI,KAAK,EAAA,CAAE,YAAY;GACnC,UAAU;IACR;IACA;GACF;EACF;EACA;CACF,CAAC;CACD,MAAM,OAAO,iBAAiB,KAAK,UAAU;CAE7C,MAAM,oBAAoB,OAAO,oBAC7B,0BAA0B;EACxB,GAAG,OAAO;EACV,QAAQ,CAAC,wBAAwB,QAAQ,YAAY,QAAQ,CAAC;EAC9D,YAAY;GACV,eAAe;GACf,gBAAgB;GAChB,kBAAkB;GAClB,eAAe;GACf,gBAAgB;GAChB,uBAAuB;GACvB,GAAI,OAAO,kBAAkB,cAAc,CAAC;EAC9C;CACF,CAAC,IACD,KAAA;CAEJ,OAAO;EACL,MAAM,OAAO;EACb,QAAQ,WAAW,oBAAoB,kBAAkB,WAAW,SAAS;EAC7E;EACA,QAAQ,GAAG,OAAO,QAAQ,UAAU,MAAM,MAAM,CAAC,CAAC,OAAO,GAAG,OAAO,OAAO;EAC1E;EACA,WAAW,OAAO;EAClB,YAAY,OAAO;EACnB;EACA;EACA;EACA;EACA;CACF;AACF;AAEA,SAAS,wBACP,QACA,YACA,YACsB;CACtB,OAAO;EACL,YAAY,OAAO;EACnB,aAAa,OAAO,mBAAmB;EACvC,OACE,WAAW,UAAU,YAAY,YAAY,WAAW,UAAU,QAAQ,QAAQ;EACpF,OAAO,WAAW,SAAS;EAC3B,IAAI,WAAW,SAAS;EACxB,WAAW,MAAM,QAAQ,WAAW,SAAS,UAAU,UAAU,IAC7D,WAAW,QAAQ,SAAS,WAAW,SACvC,KAAA;EACJ;EACA,UAAU;GACR,WAAW,OAAO;GAClB,WAAW,WAAW,SAAS,UAAU;EAC3C;CACF;AACF;;;ACnGA,MAAa,kCAAwD;CACnE,QAAQ;CACR,WAAW;CACX,eAAe;CACf,qBAAqB;CACrB,UAAU;AACZ;AAEA,SAAgB,kBACd,WACA,QACmB;CACnB,OAAO,UAAU,SAAS,QAAQ,YAAY,QAAQ,WAAW,MAAM;AACzE;AAEA,SAAgB,oBACd,WACA,QACA,UAAyC,CAAC,GAC3B;CACf,OAAO,sBAAsB,WAAW,kBAAkB,WAAW,MAAM,GAAG,QAAQ,OAAO;AAC/F;AAEA,SAAgB,sBACd,WACA,UACA,QACA,UAAyC,CAAC,GAC3B;CACf,MAAM,kBAAkB,uBAAuB,UAAU,mBAAmB,QAAQ;CACpF,MAAM,oBAAoB,IAAI,IAAI,gBAAgB,KAAK,UAAU,MAAM,SAAS,CAAC;CACjF,MAAM,mBAAmB,SAAS,QAAQ,YAAY,kBAAkB,QAAQ,OAAO,CAAC;CACxF,MAAM,mBAAmB,SAAS,QAAQ,YAAY,kBAAkB,QAAQ,OAAO,CAAC;CACxF,MAAM,qBAAqB,SAAS,OAAO,mBAAmB;CAC9D,MAAM,mBAAmB,SAAS,QAAQ,YAAY,QAAQ,QAAQ;CACtE,MAAM,kBAAkB,iBAAiB,QAAQ,YAC/C,kBAAkB,SAAS,UAAU,mBAAmB,eAAe,CACzE;CAEA,MAAM,SAAS,UAAU,kBAAkB,SACvC,gBAAgB,SAAS,UAAU,kBAAkB,SACrD,SAAS,WAAW,IAClB,IACA;CAEN,MAAM,uBAAuB,iBAAiB,SAAS,iBAAiB;CACxE,MAAM,YACJ,uBAAuB,IACnB,iBAAiB,SAAS,uBAC1B,SAAS,SAAS,IAChB,kBAAkB,OAAO,SAAS,SAClC,UAAU,kBAAkB,WAAW,IACrC,IACA;CAEV,MAAM,gBAAgB,SAAS,SAAS,mBAAmB,SAAS,SAAS,SAAS;CACtF,MAAM,sBAAsB,iBAAiB,SACzC,gBAAgB,SAAS,iBAAiB,SAC1C,gBAAgB,SACd,KACA;CACN,MAAM,WAAW,SAAS,SAAS,IAAI,iBAAiB,SAAS,SAAS,SAAS;CACnF,MAAM,YAAY,uBAChB;EAAE;EAAQ;EAAW;EAAe;EAAqB;CAAS,GAClE,OACF;CAEA,OAAO;EACL,QAAQ,UAAU;EAClB;EACA,cAAc,SAAS;EACvB,gBAAgB,UAAU,kBAAkB;EAC5C;EACA;EACA;EACA;EACA;EACA;EACA;EACA,OAAO,gBAAgB;GACrB;GACA,gBAAgB,UAAU,kBAAkB;GAC5C;GACA;GACA;EACF,CAAC;CACH;AACF;AAEA,SAAgB,2BAA2B,QAAqD;CAC9F,MAAM,2BAAW,IAAI,IAAqC;CAC1D,KAAK,MAAM,SAAS,QAClB,SAAS,IAAI,MAAM,QAAQ,CAAC,GAAI,SAAS,IAAI,MAAM,MAAM,KAAK,CAAC,GAAI,KAAK,CAAC;CAE3E,OAAO,CAAC,GAAG,SAAS,QAAQ,CAAC,CAAC,CAC3B,KAAK,CAAC,QAAQ,mBAAmB;EAChC;EACA,WAAW,aAAa;EACxB,cAAcC,MAAI,aAAa,KAAK,UAAU,MAAM,YAAY,CAAC;EACjE,eAAeC,OAAK,aAAa,KAAK,UAAU,MAAM,SAAS,CAAC;EAChE,YAAYA,OAAK,aAAa,KAAK,UAAU,MAAM,MAAM,CAAC;EAC1D,eAAeA,OAAK,aAAa,KAAK,UAAU,MAAM,SAAS,CAAC;EAChE,mBAAmBA,OAAK,aAAa,KAAK,UAAU,MAAM,aAAa,CAAC;EACxE,yBAAyBA,OAAK,aAAa,KAAK,UAAU,MAAM,mBAAmB,CAAC;EACpF,cAAcA,OAAK,aAAa,KAAK,UAAU,MAAM,QAAQ,CAAC;CAChE,EAAE,CAAC,CACF,MAAM,GAAG,MAAM,EAAE,gBAAgB,EAAE,aAAa;AACrD;AAEA,SAAgB,uBACd,YAIA,UAAyC,CAAC,GAClC;CACR,MAAM,SAAS;EAAE,GAAG;EAAiC,GAAG;CAAQ;CAChE,MAAM,YAAY,OAAO,OAAO,MAAM,CAAC,CAAC,QAAQ,OAAO,UAAU,QAAQ,KAAK,IAAI,GAAG,KAAK,GAAG,CAAC;CAC9F,IAAI,aAAa,GAAG,OAAO;CAC3B,QACG,OAAO,SAAS,QAAQ,WAAW,MAAM,IACxC,OAAO,YAAY,QAAQ,WAAW,SAAS,IAC/C,OAAO,gBAAgB,QAAQ,WAAW,aAAa,IACvD,OAAO,sBAAsB,QAAQ,WAAW,mBAAmB,IACnE,OAAO,WAAW,QAAQ,WAAW,QAAQ,KAC/C;AAEJ;AAEA,SAAS,uBACP,YACA,UAC0B;CAC1B,MAAM,UAAoC,CAAC;CAC3C,MAAM,iCAAiB,IAAI,IAAY;CAEvC,KAAK,MAAM,aAAa,YAAY;EAMlC,MAAM,OALa,SAChB,QAAQ,YAAY,CAAC,eAAe,IAAI,QAAQ,EAAE,CAAC,CAAC,CACpD,KAAK,aAAa;GAAE;GAAS,OAAO,WAAW,WAAW,OAAO;EAAE,EAAE,CAAC,CACtE,QAAQ,EAAE,YAAY,SAAS,GAAI,CAAC,CACpC,MAAM,GAAG,MAAM,EAAE,QAAQ,EAAE,KACR,CAAC,CAAC;EACxB,IAAI,CAAC,MAAM;EACX,eAAe,IAAI,KAAK,QAAQ,EAAE;EAClC,QAAQ,KAAK;GAAE,aAAa,UAAU;GAAI,WAAW,KAAK,QAAQ;GAAI,OAAO,KAAK;EAAM,CAAC;CAC3F;CAEA,OAAO;AACT;AAEA,SAAS,WAAW,WAAqC,SAAkC;CACzF,IAAI,QAAQ;CACZ,IAAI,UAAU,kBAAkB,SAAS,QAAQ,EAAE,GAAG,SAAS;CAC/D,IACE,UAAU,QACV,QAAQ,QACR,cAAc,UAAU,IAAI,MAAM,cAAc,QAAQ,IAAI,GAE5D,SAAS;CAEX,IAAI,UAAU,QAAQ,QAAQ,QAAQ,KAAK,IAAI,UAAU,OAAO,QAAQ,IAAI,KAAK,GAAG,SAAS;CAE7F,MAAM,QAAQ,CAAC,GAAI,UAAU,YAAY,CAAC,GAAI,GAAG,SAAS,UAAU,KAAK,CAAC;CAC1E,MAAM,cAAc,CAAC,GAAG,IAAI,IAAI,MAAM,IAAI,aAAa,CAAC,CAAC,QAAQ,SAAS,KAAK,UAAU,CAAC,CAAC,CAAC;CAC5F,IAAI,YAAY,SAAS,GAAG;EAC1B,MAAM,YAAY,IAAI,IAAI,SAAS,QAAQ,IAAI,CAAC,CAAC,IAAI,aAAa,CAAC;EACnE,MAAM,UAAU,YAAY,QAAQ,SAAS,UAAU,IAAI,IAAI,CAAC,CAAC,CAAC;EAClE,SAAS,MAAO,UAAU,YAAY;CACxC;CAEA,OAAO,QAAQ,KAAK;AACtB;AAEA,SAAS,oBAAoB,SAAmC;CAC9D,MAAM,OAAO,QAAQ,KAAK,KAAK;CAC/B,IAAI,CAAC,QAAQ,QAAQ,CAAC,+DAA+D,KAAK,IAAI,GAC5F,OAAO;CAET,OAAO,+FAA+F,KACpG,IACF;AACF;AAEA,SAAS,kBACP,SACA,YACA,SACS;CACT,IAAI,CAAC,QAAQ,UAAU,OAAO;CAC9B,MAAM,QAAQ,QAAQ,MAAM,cAAc,UAAU,cAAc,QAAQ,EAAE;CAC5E,IAAI,CAAC,OAAO,OAAO,QAAQ,aAAa,SAAS,QAAQ,aAAa;CACtE,MAAM,YAAY,WAAW,MAAM,cAAc,UAAU,OAAO,MAAM,WAAW;CACnF,IAAI,CAAC,WAAW,OAAO;CACvB,OAAO,KAAK,IAAI,aAAa,QAAQ,QAAQ,IAAI,aAAa,UAAU,QAAQ,CAAC,KAAK;AACxF;AAEA,SAAS,gBAAgB,OAMZ;CACX,MAAM,QAAkB,CAAC;CACzB,IAAI,MAAM,iBAAiB,KAAK,MAAM,gBAAgB,WAAW,GAC/D,MAAM,KAAK,+BAA+B;CAE5C,IAAI,MAAM,iBAAiB,SAAS,GAClC,MAAM,KAAK,GAAG,MAAM,iBAAiB,OAAO,8CAA8C;CAE5F,IAAI,MAAM,SAAS,SAAS,KAAK,MAAM,mBAAmB,WAAW,GACnE,MAAM,KAAK,iEAAiE;CAE9E,OAAO;AACT;AAEA,SAAS,kBAAkB,SAA+C;CACxE,OAAO,YAAY,cAAc,YAAY;AAC/C;AAEA,SAAS,kBAAkB,SAA+C;CACxE,OAAO,YAAY,cAAc,YAAY,eAAe,YAAY;AAC1E;AAEA,SAAS,aAAa,UAAoC;CACxD,QAAQ,UAAR;EACE,KAAK,YACH,OAAO;EACT,KAAK,QACH,OAAO;EACT,KAAK,UACH,OAAO;EACT,KAAK,OACH,OAAO;EACT,KAAK,OACH,OAAO;CACX;AACF;AAEA,SAAS,SAAS,OAAyB;CACzC,OAAO,MAAM,MAAM,oBAAoB,KAAK,CAAC;AAC/C;AAEA,SAAS,cAAc,OAAuB;CAC5C,OAAO,MAAM,YAAY,CAAC,CAAC,QAAQ,8BAA8B,EAAE;AACrE;AAEA,SAAS,cAAc,OAAuB;CAC5C,OAAO,MAAM,QAAQ,UAAU,EAAE;AACnC;AAEA,SAASA,OAAK,QAA0B;CACtC,OAAO,OAAO,SAASD,MAAI,MAAM,IAAI,OAAO,SAAS;AACvD;AAEA,SAASA,MAAI,QAA0B;CACrC,OAAO,OAAO,QAAQ,OAAO,UAAU,QAAQ,OAAO,CAAC;AACzD;;;;;;;;;ACjWA,IAAa,mBAAb,MAA8B;CAC5B,YAAgC,CAAC;CACjC,gBAAwC,CAAC;;CAGzC,cAAc,OAA6B;EACzC,KAAK,cAAc,KAAK,GAAG,KAAK;EAChC,KAAK,UAAU,KAAK,GAAG,MAAM,IAAI,UAAU,CAAC;CAC9C;;CAGA,SAAS,WAA6B;EACpC,KAAK,UAAU,KAAK,GAAG,SAAS;CAClC;;CAGA,MAAkB;EAChB,OAAO,CAAC,GAAG,KAAK,SAAS;CAC3B;;CAGA,WAAW,UAA8B;EAEvC,OADkB,KAAK,cAAc,QAAQ,OAAO,GAAG,aAAa,QAAQ,CAAC,CAAC,IAAI,UACnE;CACjB;;CAGA,iBAAwD;EACtD,MAAM,SAAiC,CAAC;EACxC,KAAK,MAAM,MAAM,KAAK,eACpB,OAAO,GAAG,aAAa,OAAO,GAAG,aAAa,KAAK;EAErD,OAAO,OAAO,QAAQ,MAAM,CAAC,CAAC,KAAK,CAAC,UAAU,YAAY;GAAE;GAAU;EAAM,EAAE;CAChF;;CAGA,UAAU,SAA6B;EACrC,OAAO,KAAK,UAAU,QAAQ,MAAM,EAAE,YAAY,OAAO;CAC3D;;CAGA,KAAK,IAAkC;EACrC,OAAO,KAAK,UAAU,MAAM,MAAM,EAAE,OAAO,EAAE;CAC/C;;CAGA,IAAI,QAAgB;EAClB,OAAO,KAAK,UAAU;CACxB;AACF;;AAGA,SAAS,WAAW,IAA4B;CAC9C,OAAO;EACL,IAAI,GAAG;EACP,SAAS,GAAG;EACZ,OAAO,GAAG;EACV,QAAQ,GAAG;EACX,YAAY,CAAC;EACb,OAAO,GAAG;EACV,gBAAgB,GAAG;EACnB,oBAAoB,GAAG,YAAY,oCAAoC,KAAA;CACzE;AACF;;;;;;;;;;AC7DA,SAAgB,sBAAsB,QAAiC;CACrE,MAAM,QAAkB,CAAC;CAEzB,MAAM,KAAK,oBAAoB;CAC/B,MAAM,KAAK,EAAE;CACb,MAAM,KAAK,aAAa,OAAO,WAAW;CAC1C,MAAM,KAAK,mBAAmB,OAAO,YAAY;CACjD,MAAM,KAAK,uBAAuB,OAAO,eAAe;CACxD,MAAM,KAAK,kBAAkB,OAAO,eAAe;CACnD,MAAM,KAAK,sBAAsB,OAAO,QAAQ,WAAW,QAAQ,CAAC,EAAE,IAAI;CAC1E,MAAM,KAAK,EAAE;CAGb,MAAM,KAAK,eAAe;CAC1B,MAAM,KAAK,EAAE;CACb,MAAM,KAAK,oCAAoC;CAC/C,MAAM,KAAK,oCAAoC;CAC/C,KAAK,MAAM,CAAC,MAAM,SAAS,OAAO,QAAQ,OAAO,QAAQ,SAAS,GAChE,MAAM,KAAK,KAAK,KAAK,KAAK,KAAK,IAAI,QAAQ,CAAC,EAAE,KAAK,KAAK,OAAO,KAAK,KAAK,MAAM,GAAG;CAEpF,MAAM,KAAK,EAAE;CAGb,MAAM,KAAK,iBAAiB;CAC5B,MAAM,KAAK,EAAE;CACb,MAAM,KAAK,iCAAiC;CAC5C,MAAM,KAAK,iCAAiC;CAC5C,MAAM,aAAa,OAAO,QAAQ,OAAO,QAAQ,WAAW,CAAC,CAAC,MAAM,GAAG,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,GAAG;CAChG,KAAK,MAAM,CAAC,MAAM,SAAS,YAAY;EACrC,MAAM,MAAM,KAAK,IAAI,GAAG,KAAK,MAAM;EACnC,MAAM,MAAM,KAAK,IAAI,GAAG,KAAK,MAAM;EACnC,MAAM,KAAK,KAAK,KAAK,KAAK,KAAK,IAAI,QAAQ,CAAC,EAAE,KAAK,IAAI,GAAG,IAAI,KAAK,KAAK,OAAO,OAAO,GAAG;CAC3F;CACA,MAAM,KAAK,EAAE;CAGb,IAAI,OAAO,QAAQ,QAAQ,SAAS,GAAG;EACrC,MAAM,KAAK,sBAAsB;EACjC,MAAM,KAAK,EAAE;EACb,KAAK,MAAM,KAAK,OAAO,QAAQ,SAC7B,MAAM,KAAK,OAAO,EAAE,SAAS,MAAM,EAAE,MAAM,QAAQ,CAAC,EAAE,KAAK,EAAE,QAAQ;EAEvE,MAAM,KAAK,EAAE;CACf;CAGA,IAAI,OAAO,QAAQ,UAAU,SAAS,GAAG;EACvC,MAAM,KAAK,wBAAwB;EACnC,MAAM,KAAK,EAAE;EACb,KAAK,MAAM,KAAK,OAAO,QAAQ,WAC7B,MAAM,KAAK,OAAO,EAAE,SAAS,MAAM,EAAE,MAAM,QAAQ,CAAC,EAAE,KAAK,EAAE,QAAQ;EAEvE,MAAM,KAAK,EAAE;CACf;CAEA,OAAO,MAAM,KAAK,IAAI;AACxB;;AAGA,SAAgB,mBAAmB,SAAiC;CAClE,MAAM,QAAkB,CAAC;CAEzB,MAAM,KAAK,uBAAuB;CAClC,MAAM,KAAK,EAAE;CAEb,KAAK,MAAM,KAAK,SAAS;EACvB,MAAM,KAAK,eAAe,EAAE,WAAW;EACvC,MAAM,KAAK,EAAE;EACb,MAAM,KAAK,oBAAoB,EAAE,YAAY,QAAQ,MAAM;EAC3D,MAAM,KAAK,8BAA8B,EAAE,qBAAqB,OAAO;EACvE,MAAM,KAAK,sBAAsB,EAAE,YAAY;EAC/C,MAAM,KACJ,sBAAsB,EAAE,WAAW,MAAM,UAAU,EAAE,WAAW,OAAO,WAAW,EAAE,WAAW,WAAW,OAAO,aACnH;EACA,MAAM,KAAK,EAAE;EAGb,MAAM,KAAK,iBAAiB;EAC5B,MAAM,KAAK,EAAE;EACb,MAAM,KAAK,KAAK;EAChB,KAAK,IAAI,IAAI,GAAG,IAAI,EAAE,iBAAiB,QAAQ,KAAK;GAClD,MAAM,MAAM,EAAE,iBAAiB;GAC/B,MAAM,MAAM,IAAI,OAAO,KAAK,MAAM,MAAM,CAAC,CAAC;GAC1C,MAAM,KAAK,UAAU,OAAO,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,IAAI,IAAI,GAAG,IAAI,QAAQ,CAAC,EAAE,EAAE;EAC7E;EACA,MAAM,KAAK,KAAK;EAChB,MAAM,KAAK,EAAE;EAGb,IAAI,EAAE,QAAQ,SAAS,GAAG;GACxB,MAAM,KAAK,sBAAsB;GACjC,MAAM,KAAK,EAAE;GACb,MAAM,KAAK,0DAA0D;GACrE,MAAM,KAAK,0DAA0D;GACrE,KAAK,MAAM,KAAK,EAAE,SAChB,MAAM,KACJ,KAAK,EAAE,KAAK,KAAK,EAAE,MAAM,KAAK,EAAE,OAAO,KAAK,EAAE,WAAW,MAAM,EAAE,oBAAoB,IAAA,CAAM,QAAQ,CAAC,EAAE,MAAM,EAAE,kBAAkB,QAAQ,CAAC,EAAE,IAC7I;GAEF,MAAM,KAAK,EAAE;EACf;CACF;CAEA,OAAO,MAAM,KAAK,IAAI;AACxB;;AAGA,SAAgB,mBAAmB,SAA+B;CAChE,QAAQ,IAAI,IAAI,OAAO,EAAE,CAAC;CAC1B,QAAQ,IAAI,yBAAyB;CACrC,QAAQ,IAAI,IAAI,OAAO,EAAE,CAAC;CAE1B,KAAK,MAAM,KAAK,SAAS;EACvB,MAAM,SAAS,EAAE,YAAY,aAAa;EAC1C,MAAM,QAAQ,EAAE,qBAAqB,EAAE;EACvC,QAAQ,IACN,KAAK,EAAE,UAAU,OAAO,EAAE,EAAE,GAAG,OAAO,OAAO,EAAE,EAAE,SAAS,MAAM,UAAU,EAAE,WAAW,MAAM,WAAW,EAAE,WAAW,OAAO,UAAU,EAAE,WAAW,WAAW,QAChK;CACF;CAEA,QAAQ,IAAI;CACZ,MAAM,iBAAiB,QAAQ,QAAQ,MAAM,EAAE,SAAS,CAAC,CAAC;CAC1D,QAAQ,IAAI,GAAG,eAAe,GAAG,QAAQ,OAAO,oBAAoB;AACtE;;;;;;;AChDA,SAAgB,qBACd,OACA,OAA6B,CAAC,GACf;CACf,MAAM,WAAW,KAAK,2BAA2B;CAEjD,IAAI,gBAAgB;CACpB,IAAI,eAAe;CACnB,KAAK,MAAM,CAAC,MAAM,UAAU,OAAO,QAAQ,MAAM,aAAa,GAAG;EAC/D,MAAM,IAAI,OAAO,SAAS,KAAK,KAAK,QAAQ,IAAI,QAAQ;EACxD,iBAAiB;EACjB,IAAI,IAAI,KAAK,MAAM,QAAQ,IAAI,GAAG,gBAAgB;CACpD;CAEA,IAAI,kBAAkB,GACpB,OAAO,WACH;EACE,SAAS;EACT,OAAO;EACP,QAAQ;EACR,cAAc;EACd,eAAe;CACjB,IACA;EACE,SAAS;EACT,OAAO;EACP,QAAQ;EACR,cAAc;EACd,eAAe;CACjB;CAGN,IAAI,iBAAiB,GACnB,OAAO;EACL,SAAS;EACT,OAAO;EACP,QAAQ,+BAA+B,cAAc;EACrD,cAAc;EACd;CACF;CAGF,OAAO;EAAE,SAAS;EAAM,OAAO;EAAO;EAAc;CAAc;AACpE;;;;;;AAOA,SAAgB,yBACd,SACA,SACA,MACe;CACf,OAAO,qBAAqB;EAAE,eAAe,QAAQ;EAAe;CAAQ,GAAG,IAAI;AACrF;;;;;;AAOA,SAAgB,uBACd,OACA,SACA,MACe;CACf,OAAO,yBAAyB,oBAAoB,KAAK,GAAG,SAAS,IAAI;AAC3E;;;;;;AAOA,SAAgB,2BACd,WACA,SACA,MACe;CACf,MAAM,gBAAwC,CAAC;CAC/C,KAAK,MAAM,KAAK,WACd,IAAI,EAAE,UAAU,cAAc,EAAE,aAAa,cAAc,EAAE,aAAa,KAAK;CAEjF,OAAO,qBAAqB;EAAE;EAAe;CAAQ,GAAG,IAAI;AAC9D;;;;;;;;;AAgBA,SAAgB,kBAAkB,SAAoB,MAAqC;CACzF,OAAO,KAAK,QAAQ,0BAA0B;AAChD;;;;;;;;;;;;;;;;;;;;;;;;;;ACrKA,MAAa,yBAAyB;;;;;;;;;;;;;;;;;;;;;;AAuBtC,MAAa,iBAAyC;CACpD,eAAe;EACb;EACA;EACA;EACA;EACA;CACF,CAAC,CAAC,KAAK,IAAI;CACX,OAAO;EACL;EACA;EACA;EACA;CACF,CAAC,CAAC,KAAK,IAAI;CACX,UAAU;EACR;EACA;EACA;CACF,CAAC,CAAC,KAAK,IAAI;CACX,gBAAgB;EACd;EACA;EACA;CACF,CAAC,CAAC,KAAK,IAAI;AACb;;;AChBA,MAAM,iBAA2B;CAC/B;CACA;CACA;CACA;AACF;AAEA,MAAM,oBAA8B;CAClC;CACA;CACA;AACF;;AAGA,SAAgB,oBAAoB,SAAyB,CAAC,GAAY;CACxE,MAAM,OAEF;EACF,QAAQ,OAAO,UAAU;EACzB,eAAe,OAAO,iBAAiB,CAAC;EACxC,gBAAgB,OAAO,kBAAkB,CAAC;EAC1C,iBAAiB,OAAO,mBAAmB;EAC3C,iBAAiB,OAAO,mBAAmB;EAC3C,qBAAqB,OAAO,uBAAuB;EACnD,WAAW,OAAO,aAAa;EAC/B,WAAW,OAAO,aAAa;EAC/B,gBAAgB;GACd,eAAe;GACf,gBAAgB;GAChB,SAAS;GACT,SAAS;GACT,YAAY;GACZ,QAAQ;GACR,GAAG,OAAO;EACZ;CACF;CAEA,MAAM,QAAiB,OAAO,KAAK,UAA6C;EAE9E,MAAM,SAAS,gBADC,MAAM,MAAM,KAAK,MAAM,EAAE,iBAAiB,EACrB,GAAG,IAAI;EAC5C,OAAO,CACL;GACE,WAAW,aAAa,KAAK,OAAO;GACpC,WAAW;GACX,OAAO,OAAO;GACd,WAAW,OAAO,OAAO,SACrB,OAAO,OACJ,MAAM,GAAG,CAAC,CAAC,CACX,KAAK,MAAM,GAAG,EAAE,SAAS,IAAI,EAAE,QAAQ,CAAC,CACxC,KAAK,IAAI,IACZ;GACJ,UAAU,OAAO,OAAO,EAAE,EAAE;EAC9B,CACF;CACF;CACA,OAAO;AACT;;;;;AAoBA,SAAgB,gBACd,SACA,QAGgB;CAChB,MAAM,SAA0B,CAAC;CACjC,MAAM,SAAuC;EAC3C,eAAe;EACf,gBAAgB;EAChB,SAAS;EACT,SAAS;EACT,YAAY;EACZ,QAAQ;CACV;CAEA,KAAK,MAAM,UAAU,SAAS;EAC5B,IAAI,CAAC,QAAQ;EACb,MAAM,QAAQ,OAAO,YAAY;EAEjC,KAAK,MAAM,UAAU,OAAO,eAAe;GACzC,MAAM,SAAS,OAAO,YAAY;GAClC,IAAI,MAAM,MAAM,QAAQ,QAAQ,CAAC;GACjC,OAAO,QAAQ,IAAI;IACjB,OAAO,iBAAiB;IACxB,IAAI,OAAO,SAAS,IAClB,OAAO,KAAK;KACV,UAAU;KACV,QAAQ,IAAI,OAAO;KACnB,SAAS,QAAQ,QAAQ,KAAK,OAAO,MAAM;IAC7C,CAAC;IAEH,MAAM,MAAM,QAAQ,QAAQ,MAAM,OAAO,MAAM;GACjD;EACF;EAEA,KAAK,MAAM,MAAM,OAAO,gBACtB,IAAI,GAAG,KAAK,MAAM,GAAG;GACnB,OAAO,kBAAkB;GACzB,OAAO,KAAK;IAAE,UAAU;IAAkB,QAAQ,GAAG;IAAQ,SAAS,OAAO,MAAM,GAAG,EAAE;GAAE,CAAC;EAC7F;EAGF,KAAK,MAAM,MAAM,OAAO,iBAAiB;GACvC,MAAM,UAAU,OAAO,MACrB,IAAI,OAAO,IAAI,GAAG,MAAM,SAAS,GAAG,IAAI,GAAG,QAAQ,GAAG,GAAG,MAAM,EAAE,CACnE;GACA,IAAI,SAAS;IACX,OAAO,WAAW,QAAQ;IAC1B,OAAO,KAAK;KACV,UAAU;KACV,QAAQ,GAAG,QAAQ,OAAO,IAAI,GAAG;KACjC,SAAS,QAAQ;IACnB,CAAC;GACH;EACF;EAEA,KAAK,MAAM,MAAM,OAAO,iBAAiB;GACvC,MAAM,UAAU,OAAO,MACrB,IAAI,OAAO,IAAI,GAAG,MAAM,SAAS,GAAG,IAAI,GAAG,QAAQ,GAAG,GAAG,MAAM,EAAE,CACnE;GACA,IAAI,SAAS;IACX,OAAO,WAAW,QAAQ;IAC1B,OAAO,KAAK;KACV,UAAU;KACV,QAAQ,GAAG,QAAQ,OAAO,IAAI,GAAG;KACjC,SAAS,QAAQ;IACnB,CAAC;GACH;EACF;EAGA,MAAM,YAAY,eAAe,MAAM;EACvC,IAAI,UAAU,UAAU,GAAG;GACzB,MAAM,uBAAO,IAAI,IAAoB;GACrC,KAAK,MAAM,KAAK,WAAW;IACzB,MAAM,MAAM,iBAAiB,CAAC;IAC9B,IAAI,CAAC,KAAK;IACV,KAAK,IAAI,MAAM,KAAK,IAAI,GAAG,KAAK,KAAK,CAAC;GACxC;GACA,IAAI,QAAQ;GACZ,KAAK,MAAM,KAAK,KAAK,OAAO,GAAG,IAAI,IAAI,GAAG,SAAS,IAAI;GACvD,MAAM,QAAQ,QAAQ,UAAU;GAChC,IAAI,QAAQ,OAAO,qBAAqB;IACtC,OAAO,cAAc;IACrB,OAAO,KAAK;KACV,UAAU;KACV,QAAQ,IAAI,QAAQ,IAAA,CAAK,QAAQ,CAAC,EAAE,2BAA2B,OAAO,sBAAsB,IAAA,CAAK,QAAQ,CAAC,EAAE;IAC9G,CAAC;GACH;EACF;EAGA,IAAI,OAAO,SAAS,OAAO,WAAW;GACpC,OAAO,UAAU;GACjB,OAAO,KAAK;IACV,UAAU;IACV,QAAQ,cAAc,OAAO,OAAO,KAAK,OAAO,UAAU;GAC5D,CAAC;EACH,OAAO,IAAI,OAAO,SAAS,OAAO,WAAW;GAC3C,OAAO,UAAU;GACjB,OAAO,KAAK;IACV,UAAU;IACV,QAAQ,aAAa,OAAO,OAAO,KAAK,OAAO,UAAU;GAC3D,CAAC;EACH;CACF;CAIA,IAAI,UAAU;CACd,KAAK,MAAM,OAAO,OAAO,KAAK,MAAM,GAClC,WAAW,OAAO,QAAQ,OAAO,eAAe,QAAQ;CAI1D,OAAO;EAAE,OAFK,KAAK,IAAI,GAAG,KAAK,IAAI,IAAI,KAAK,OAAO,CAEtC;EAAG;EAAQ;CAAO;AACjC;AAEA,SAAS,QAAQ,QAAgB,IAAY,KAAqB;CAChE,MAAM,MAAM;CACZ,MAAM,QAAQ,KAAK,IAAI,GAAG,KAAK,GAAG;CAClC,MAAM,MAAM,KAAK,IAAI,OAAO,QAAQ,KAAK,MAAM,GAAG;CAClD,QAAQ,QAAQ,IAAI,MAAM,MAAM,OAAO,MAAM,OAAO,GAAG,KAAK,MAAM,OAAO,SAAS,MAAM;AAC1F;AAEA,SAAS,eAAe,MAAwB;CAE9C,OAAO,KACJ,MAAM,UAAU,CAAC,CACjB,KAAK,MAAM,EAAE,KAAK,CAAC,CAAC,CACpB,QAAQ,MAAM,EAAE,SAAS,CAAC;AAC/B;AAEA,SAAS,iBAAiB,GAAmB;CAC3C,OAAO,EACJ,YAAY,CAAC,CACb,QAAQ,QAAQ,GAAG,CAAC,CACpB,QAAQ,eAAe,EAAE,CAAC,CAC1B,KAAK;AACV;;;;;;;AC1MA,SAAgB,kBACd,YACA,SACmB;CACnB,MAAM,UAAU,SAAS,WAAW,WAAW,UAAU,CAAC;CAC1D,IAAI,QAAQ,WAAW,WAAW,QAChC,MAAM,IAAI,MAAM,4CAA4C;CAE9D,MAAM,cAAc,QAAQ,QAAQ,GAAG,MAAM,IAAI,GAAG,CAAC,KAAK;CAC1D,OAAO;EACL,MAAM,SAAS,QAAQ,WAAW,KAAK,MAAM,EAAE,IAAI,CAAC,CAAC,KAAK,GAAG;EAC7D,MAAM,SAAS,UAAU,KAAK;GAC5B,MAAM,UAAU,MAAM,QAAQ,IAAI,WAAW,KAAK,MAAM,EAAE,SAAS,UAAU,GAAG,CAAC,CAAC;GAGlF,OAAO;IACL,MAHW,QAAQ,OAAO,MAAM,EAAE,IAG/B;IACH,OAHY,QAAQ,QAAQ,KAAK,GAAG,MAAM,MAAM,EAAE,QAAQ,QAAQ,IAAK,CAAC,IAAI;IAI5E,QAAQ,QAAQ,SAAS,GAAG,MAC1B,EAAE,OAAO,KAAK,WAAW;KACvB,GAAG;KACH,OAAO,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAE,KAAK,GAAG,MAAM,UAAU,WAAW,EAAE,CAAE;IAChF,EAAE,CACJ;IACA,UAAU,OAAO,YAAY,QAAQ,KAAK,GAAG,MAAM,CAAC,WAAW,EAAE,CAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;GACvF;EACF;CACF;AACF;;AAOA,SAAgB,WAAW,MAAc,SAAoC;CAC3E,OAAO;EACL;EACA,MAAM,SAAS,UAAU;GACvB,MAAM,OAAO,SAAS,WAAW;GACjC,MAAM,KAAK,QAAQ,KAAK,IAAI;GAC5B,OAAO;IACL,MAAM;IACN,OAAO,KAAK,IAAI;IAChB,QAAQ,KACJ,CAAC,IACD,CAAC;KAAE,UAAU;KAAS,SAAS,kCAAkC;IAAU,CAAC;GAClF;EACF;CACF;AACF;;AAGA,SAAgB,YAAY,MAAc,eAA4C;CACpF,OAAO;EACL;EACA,MAAM,SAAS,UAAU;GACvB,MAAM,OAAO,SAAS,WAAW;GACjC,IAAI;GACJ,IAAI;IACF,SAAS,KAAK,MAAM,IAAI;GAC1B,SAAS,KAAK;IACZ,OAAO;KACL,MAAM;KACN,OAAO;KACP,QAAQ,CACN;MACE,UAAU;MACV,SAAS,iBAAiB,eAAe,QAAQ,IAAI,UAAU;KACjE,CACF;IACF;GACF;GACA,MAAM,UAAoB,CAAC;GAC3B,KAAK,MAAM,QAAQ,eACjB,IAAI,CAAC,WAAW,QAAQ,IAAI,GAAG,QAAQ,KAAK,IAAI;GAGlD,OAAO;IACL,MAFW,QAAQ,WAAW;IAG9B,OAAO,IAAI,QAAQ,SAAS,KAAK,IAAI,GAAG,cAAc,MAAM;IAC5D,QAAQ,QAAQ,KAAK,OAAO;KAC1B,UAAU;KACV,SAAS,iBAAiB;KAC1B,OAAO;IACT,EAAE;GACJ;EACF;CACF;AACF;;AAGA,SAAgB,gBAAgB,MAAc,KAAa,KAAgC;CACzF,OAAO;EACL;EACA,MAAM,SAAS,UAAU;GACvB,MAAM,OACJ,SAAS,OAAO,cAAc,IAAI,YAAY,CAAC,CAAC,OAAO,SAAS,WAAW,EAAE,CAAC,CAAC;GACjF,MAAM,OAAO,QAAQ,OAAO,QAAQ;GAEpC,OAAO;IACL;IACA,OAHY,OAAO,IAAI,OAAO,MAAM,KAAK,IAAI,GAAG,OAAO,GAAG,IAAI,KAAK,IAAI,GAAG,MAAM,IAAI;IAIpF,QAAQ,OACJ,CAAC,IACD,CAAC;KAAE,UAAU;KAAS,SAAS,QAAQ,KAAK,YAAY,IAAI,IAAI,IAAI;IAAG,CAAC;GAC9E;EACF;CACF;AACF;;AAGA,SAAgB,YACd,MACA,UACA,SACmB;CACnB,MAAM,KAAK,SAAS,iBAAiB;CACrC,OAAO;EACL;EACA,MAAM,SAAS,UAAU;GACvB,MAAM,OAAO,KAAM,SAAS,WAAW,MAAO,SAAS,WAAW,GAAA,CAAI,YAAY;GAClF,MAAM,UAAoB,CAAC;GAC3B,KAAK,MAAM,UAAU,UAAU;IAC7B,MAAM,QAAQ,KAAK,SAAS,OAAO,YAAY;IAC/C,IAAI,CAAC,KAAK,SAAS,KAAK,GAAG,QAAQ,KAAK,MAAM;GAChD;GAEA,OAAO;IACL,MAFW,QAAQ,WAAW;IAG9B,OAAO,IAAI,QAAQ,SAAS,KAAK,IAAI,GAAG,SAAS,MAAM;IACvD,QAAQ,QAAQ,KAAK,OAAO;KAC1B,UAAU;KACV,SAAS,sBAAsB;IACjC,EAAE;GACJ;EACF;CACF;AACF;AAMA,SAAS,WAAW,KAAc,MAAuB;CACvD,MAAM,QAAQ,KAAK,MAAM,GAAG;CAC5B,IAAI,UAAmB;CACvB,KAAK,MAAM,QAAQ,OAAO;EACxB,IAAI,YAAY,QAAQ,OAAO,YAAY,UAAU,OAAO;EAC5D,MAAM,MAAM,QAAQ,KAAK,IAAI,IAAI,OAAO,IAAI,IAAI;EAChD,UAAW,QAAoC;EAC/C,IAAI,YAAY,KAAA,GAAW,OAAO;CACpC;CACA,OAAO;AACT;;;AClJA,IAAa,iBAAb,MAA4B;CAC1B,MAAM,IAAI,QAAwD;EAChE,MAAM,YAAY,OAAO,aAAa;EACtC,MAAM,YAAY,OAAO,wBAAwB;EAEjD,IAAI,OAAO,UAAU,WAAW,GAC9B,MAAM,IAAI,MAAM,6CAA6C;EAG/D,MAAM,UAAqC,CAAC;EAE5C,KAAK,MAAM,YAAY,OAAO,WAAW;GACvC,MAAM,UAA4B,CAAC;GACnC,IAAI,YAAY;GAChB,IAAI,mBAAkC;GACtC,IAAI,gBAAgB;GACpB,IAAI,YAAY;GAChB,IAAI;GAEJ,KAAK,IAAI,IAAI,GAAG,IAAI,WAAW,KAAK;IAClC,MAAM,gBAAgB,QAAQ,QAAQ,SAAS,EAAE,EAAE;IACnD,MAAM,WAAW,MAAM,OAAO,QAAQ;KACpC;KACA,YAAY;KACZ;KACA;IACF,CAAC;IACD,MAAM,EAAE,UAAU,qBAAqB,MAAM,OAAO,SAAS;KAC3D;KACA,YAAY;KACZ;IACF,CAAC;IAED,IAAI,CAAC,OAAO,SAAS,gBAAgB,KAAK,mBAAmB,KAAK,mBAAmB,GACnF,MAAM,IAAI,MACR,uDAAuD,iBAAiB,gBAAgB,SAAS,GAAG,SAAS,GAC/G;IAGF,MAAM,QAAwB;KAC5B,YAAY;KACZ;KACA;KACA;IACF;IACA,QAAQ,KAAK,KAAK;IAClB,OAAO,kBAAkB;KAAE,YAAY,SAAS;KAAI;IAAM,CAAC;IAE3D,gBAAgB;IAChB,YAAY;IACZ,gBAAgB;IAEhB,IAAI,oBAAoB,WAAW;KACjC,YAAY;KACZ,mBAAmB,IAAI;KACvB;IACF;GACF;GAEA,QAAQ,KAAK;IACX,YAAY,SAAS;IACrB;IACA;IACA;IACA;IACA,YAAY;GACd,CAAC;EACH;EAEA,MAAM,mBAAmB,QAAQ,QAAQ,MAAM,EAAE,SAAS;EAU1D,OAAO;GACL,WAAW;GACX,WAAW;IAAE,iBAXS,QAAQ,SAAS,iBAAiB,SAAS,QAAQ,SAAS;IAWpD,qBAVJ,iBAAiB,SACzC,iBAAiB,QAAQ,KAAK,MAAM,OAAO,EAAE,oBAAoB,IAAI,CAAC,IACtE,iBAAiB,SACjB;IAOiD,eAN/B,QAAQ,SAC1B,QAAQ,QAAQ,KAAK,MAAM,MAAM,EAAE,YAAY,CAAC,IAAI,QAAQ,SAC5D;GAI+D;GACjE,QAAQ;IAAE;IAAW,sBAAsB;GAAU;EACvD;CACF;AACF;;;;;;;;;;;;;;;;;;AClHA,SAAgB,aAAa,KAG3B;CACA,OAAO;EACL,MAAM;EACN,UAAU;GAAE,MAAM,IAAI;GAAM,aAAa,IAAI;GAAa,YAAY,IAAI;EAAW;CACvF;AACF;;;;;;AAOA,SAAgB,cAAc,KAAyC;CACrE,MAAM,QAAuB,CAAC;CAC9B,IAAI,IAAI,QAAQ,MAAM,KAAK,cAAc,IAAI,MAAM,CAAC;CACpD,IAAI,IAAI,YAAY,MAAM,KAAK,qBAAqB,IAAI,WAAW,gBAAgB,CAAC;CACpF,IAAI,IAAI,SAAS,MAAM,KAAK,gBAAgB,IAAI,OAAO,CAAC;CACxD,OAAO;AACT;AAIA,SAAS,cAAc,QAAkD;CACvE,IAAI,OAAO,WAAW,GACpB,MAAM,IAAI,MAAM,wEAAwE;CAE1F,MAAM,QAAQ,OAAO,KAAK,MAAM,EAAE,IAAI;CACtC,OAAO;EACL,MAAM;EACN,aACE,iDAAiD,MAAM,KAAK,IAAI,EAAE;EAGpE,YAAY;GACV,MAAM;GACN,YAAY;IACV,OAAO;KACL,MAAM;KACN,MAAM;KACN,aAAa;IACf;IACA,UAAU,EACR,aAAa,gEACf;IACA,UAAU,EACR,aAAa,qDACf;GACF;GACA,UAAU,CAAC,UAAU;GACrB,sBAAsB;EACxB;EACA,SAAS,OAAO,MAAM,QAAQ;GAC5B,MAAM,IAAI,kBAAkB,cAAc,IAAI;GAC9C,IAAI,EAAE,cAAc,IAClB,MAAM,IAAI,MAAM,uCAAuC;GAEzD,IAAI,WAAW;GACf,IAAI,EAAE,UAAU,KAAA,GAAW;IACzB,IAAI,OAAO,EAAE,UAAU,UAAU,MAAM,IAAI,MAAM,yCAAyC;IAC1F,WAAW,OAAO,QAAQ,MAAM,EAAE,SAAS,EAAE,KAAK;IAClD,IAAI,SAAS,WAAW,GACtB,MAAM,IAAI,MACR,8BAA8B,EAAE,MAAM,kBAAkB,MAAM,KAAK,IAAI,GACzE;GAEJ;GACA,MAAM,SAAS,KAAK,UAAU,IAAI,gBAAgB,CAAC,CAAC;GACpD,MAAM,WAAW,EAAE;GACnB,MAAM,SAAqC,CAAC;GAC5C,KAAK,MAAM,SAAS,UAAU;IAC5B,IAAI,aAAa,KAAA,KAAa,MAAM,aAAa,CAAC,MAAM,UAAU,QAAQ,GAAG;IAC7E,OAAO,MAAM,QAAQ,MAAM,MAAM,MAAM;KAAE,UAAU,EAAE;KAAU;KAAU;IAAO,CAAC;GACnF;GACA,OAAO,EAAE,OAAO;EAClB;CACF;AACF;AAIA,SAAS,qBAAqB,kBAAmD;CAC/E,OAAO;EACL,MAAM;EACN,aACE;EAIF,YAAY;GACV,MAAM;GACN,YAAY;IACV,MAAM;KACJ,MAAM;KACN,aAAa;IACf;IACA,OAAO;KACL,MAAM;KACN,aAAa;IACf;GACF;GACA,UAAU,CAAC,QAAQ,OAAO;GAC1B,sBAAsB;EACxB;EACA,SAAS,OAAO,SAAqC;GACnD,MAAM,IAAI,kBAAkB,qBAAqB,IAAI;GACrD,IAAI,OAAO,EAAE,SAAS,YAAY,EAAE,SAAS,MAC3C,MAAM,IAAI,MAAM,qDAAqD;GAEvE,IAAI,OAAO,EAAE,UAAU,YAAY,EAAE,UAAU,MAC7C,MAAM,IAAI,MAAM,2DAA2D;GAE7E,OAAO,iBAAiB,EAAE,MAAkB,EAAE,OAAwB,gBAAgB;EACxF;CACF;AACF;AAIA,SAAS,gBAAgB,aAA4D;CACnF,OAAO;EACL,MAAM;EACN,aACE;EAIF,YAAY;GACV,MAAM;GACN,YAAY;IACV,MAAM;KACJ,MAAM;KACN,OAAO,EAAE,MAAM,SAAS;KACxB,aAAa;IACf;IACA,MAAM;KACJ,MAAM;KACN,aAAa;IACf;GACF;GACA,sBAAsB;EACxB;EACA,SAAS,OAAO,SAAS;GACvB,MAAM,IAAI,kBAAkB,gBAAgB,IAAI;GAChD,MAAM,UAAU,MAAM,QAAQ,EAAE,IAAI;GAEpC,IAAI,aADY,OAAO,EAAE,SAAS,YAAY,EAAE,KAAK,SAAS,IAE5D,MAAM,IAAI,MAAM,2EAA2E;GAE7F,MAAM,OAAO,UAAW,EAAE,OAAuB,MAAM,eAAe,EAAE,IAAc;GACtF,IAAI,KAAK,WAAW,GAClB,MAAM,IAAI,MAAM,kCAAkC;GAEpD,OAAO,YAAY;IAAE,GAAG;IAAa;GAAK,CAAC;EAC7C;CACF;AACF;AAEA,eAAe,eAAe,MAAoC;CAEhE,MAAM,WAAU,MADG,SAAS,MAAM,MAAM,EAAA,CACnB,KAAK;CAC1B,IAAI,QAAQ,WAAW,GACrB,MAAM,IAAI,MAAM,uBAAuB,KAAK,WAAW;CAEzD,IAAI,QAAQ,WAAW,GAAG,GAAG;EAC3B,MAAM,SAAS,KAAK,MAAM,OAAO;EACjC,IAAI,CAAC,MAAM,QAAQ,MAAM,GACvB,MAAM,IAAI,MAAM,uBAAuB,KAAK,4BAA4B;EAE1E,OAAO;CACT;CAGA,OAAO,QAAQ,MAAM,IAAI,CAAC,CAAC,SAAS,MAAM,MAAM;EAC9C,MAAM,IAAI,KAAK,KAAK;EACpB,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC;EAC5B,IAAI;GACF,OAAO,CAAC,KAAK,MAAM,CAAC,CAAc;EACpC,SAAS,KAAK;GACZ,MAAM,IAAI,MACR,uBAAuB,KAAK,SAAS,IAAI,EAAE,sBAAsB,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,GAClH;EACF;CACF,CAAC;AACH;AAEA,SAAS,kBAAkB,MAAc,MAAwC;CAC/E,IAAI,OAAO,SAAS,YAAY,SAAS,QAAQ,MAAM,QAAQ,IAAI,GACjE,MAAM,IAAI,MAAM,GAAG,KAAK,yBAAyB;CAEnD,OAAO;AACT;;;AC9IA,MAAa,6BAAqE;CAChF;EAAE,MAAM;EAAa,WAAW;EAAY,QAAQ,MAAM,EAAE;CAAc;CAC1E;EAAE,MAAM;EAAa,WAAW;EAAY,QAAQ,MAAM,EAAE;CAAS;CACrE;EAAE,MAAM;EAAQ,WAAW;EAAY,QAAQ,MAAM,EAAE;CAAY;CACnE;EAAE,MAAM;EAAQ,WAAW;EAAY,QAAQ,MAAM,EAAE;CAAgB;AACzE;AAEA,eAAsB,qBACpB,QACkC;CAClC,MAAM,OAAO,UAAU,MAAM;CAC7B,MAAM,SAAS,IAAI,UAAU,EAAE,SAAS,OAAO,QAAQ,CAAC;CACxD,MAAM,QAAQ,OAAO,WAAW,UAAoB,OAAO,WAAW,KAAK;CAC3E,MAAM,UAAU,MAAM,SAAS,MAAM,OAAO,eAAe,GAAG,OAAO,YAAY;EAC/E,MAAM,QAAQ,MAAM,OAAO,QAAQ,IAAI,OAAO;EAC9C,MAAM,WAAW,MAAM,MAAM,OAAO,OAAO;EAC3C,MAAM,SAA2B;GAC/B,SAAS,QAAQ;GACjB,UAAU,QAAQ;GAClB,YAAY,QAAQ;GACpB;GACA,OAAO;GACP,WAAW,kBAAkB,UAAU,OAAO,OAAO;EACvD;EACA,MAAM,OAAO,WAAW,MAAM;EAC9B,OAAO;CACT,CAAC;CACD,OAAO;EAAE;EAAS,WAAW,qBAAqB,SAAS,OAAO,UAAU;CAAE;AAChF;AAEA,SAAgB,qBACd,SACA,aAAqD,4BACnC;CAClB,MAAM,UAAU,wBAAwB,OAAO;CAC/C,IAAI,QAAQ,WAAW,GAAG,MAAM,IAAI,MAAM,kCAAkC;CAC5E,MAAM,WAAW,eAAe,SAAS,UAAU;CAEnD,MAAM,SAAS,CAAC,GADG,SAAS,SAAS,SAAS,SAAS,WAAW,OACrC,CAAC,CAAC,MAAM,GAAG,MAAM,EAAE,gBAAgB,EAAE,aAAa,CAAC,CAAC;CACjF,IAAI,CAAC,QAAQ,MAAM,IAAI,MAAM,iCAAiC;CAC9D,OAAO;EAAE;EAAQ;EAAU;CAAQ;AACrC;AAEA,SAAgB,wBAAwB,SAAqD;CAC3F,MAAM,4BAAY,IAAI,IAAgC;CACtD,KAAK,MAAM,UAAU,SACnB,UAAU,IAAI,OAAO,QAAQ,IAAI,CAAC,GAAI,UAAU,IAAI,OAAO,QAAQ,EAAE,KAAK,CAAC,GAAI,MAAM,CAAC;CAExF,OAAO,CAAC,GAAG,UAAU,OAAO,CAAC,CAAC,CAC3B,KAAK,SAAS;EACb,MAAM,UAAU,KAAK,EAAE,EAAE;EACzB,IAAI,CAAC,SAAS,MAAM,IAAI,MAAM,+CAA+C;EAC7E,OAAO;GACL;GACA;GACA,eAAeE,OAAK,KAAK,KAAK,MAAM,EAAE,SAAS,CAAC;GAChD,UAAUA,OAAK,KAAK,KAAK,MAAM,EAAE,MAAM,OAAO,CAAC;GAC/C,aAAaA,OAAK,KAAK,KAAK,MAAM,EAAE,MAAM,OAAO,CAAC;GAClD,iBAAiBA,OAAK,KAAK,KAAK,MAAM,EAAE,MAAM,WAAW,CAAC;GAC1D,WAAW,aAAa,KAAK,KAAK,MAAM,EAAE,KAAK,CAAC;EAClD;CACF,CAAC,CAAC,CACD,MAAM,GAAG,MAAM,EAAE,gBAAgB,EAAE,aAAa;AACrD;AAEA,SAAS,UAAU,QAAsD;CACvE,IAAI,OAAO,SAAS,WAAW,GAC7B,MAAM,IAAI,MAAM,qDAAqD;CACvE,IAAI,OAAO,UAAU,WAAW,GAC9B,MAAM,IAAI,MAAM,sDAAsD;CACxE,MAAM,SAAS,KAAK,IAAI,GAAG,KAAK,MAAM,OAAO,qBAAqB,CAAC,CAAC;CACpE,MAAM,OAA4B,CAAC;CACnC,KAAK,MAAM,WAAW,OAAO,UAC3B,KAAK,MAAM,YAAY,OAAO,WAC5B,KAAK,IAAI,aAAa,GAAG,aAAa,QAAQ,cAC5C,KAAK,KAAK;EAAE;EAAS;EAAU;CAAW,CAAC;CAIjD,OAAO;AACT;AAEA,eAAe,SACb,OACA,OACA,IACc;CACd,MAAM,UAAe,IAAI,MAAM,MAAM,MAAM;CAC3C,IAAI,OAAO;CACX,MAAM,cAAc,KAAK,IAAI,GAAG,KAAK,IAAI,KAAK,MAAM,KAAK,GAAG,MAAM,MAAM,CAAC;CACzE,MAAM,QAAQ,IACZ,MAAM,KAAK,EAAE,QAAQ,YAAY,GAAG,YAAY;EAC9C,OAAO,OAAO,MAAM,QAAQ;GAC1B,MAAM,QAAQ;GACd,MAAM,OAAO,MAAM;GACnB,IAAI,SAAS,KAAA,GAAW;GACxB,QAAQ,SAAS,MAAM,GAAG,IAAI;EAChC;CACF,CAAC,CACH;CACA,OAAO;AACT;AAEA,SAASA,OAAK,QAA0B;CACtC,OAAO,OAAO,SAAS,OAAO,QAAQ,KAAK,UAAU,MAAM,OAAO,CAAC,IAAI,OAAO,SAAS;AACzF;AAEA,SAAS,aAAa,QAA8B;CAClD,OAAO;EACL,SAASA,OAAK,OAAO,KAAK,MAAM,EAAE,OAAO,CAAC;EAC1C,cAAcA,OAAK,OAAO,KAAK,MAAM,EAAE,YAAY,CAAC;EACpD,kBAAkBA,OAAK,OAAO,KAAK,MAAM,EAAE,gBAAgB,CAAC;EAC5D,cAAcA,OAAK,OAAO,KAAK,MAAM,EAAE,YAAY,CAAC;EACpD,gBAAgBA,OAAK,OAAO,KAAK,MAAM,EAAE,cAAc,CAAC;EACxD,cAAcA,OAAK,OAAO,KAAK,MAAM,EAAE,YAAY,CAAC;EACpD,aAAaA,OAAK,OAAO,KAAK,MAAM,EAAE,WAAW,CAAC;EAClD,WAAWA,OAAK,OAAO,KAAK,MAAM,EAAE,SAAS,CAAC;EAC9C,kBAAkBA,OAAK,OAAO,KAAK,MAAM,EAAE,gBAAgB,CAAC;EAC5D,SAASA,OAAK,OAAO,KAAK,MAAM,EAAE,OAAO,CAAC;EAC1C,aAAaA,OAAK,OAAO,KAAK,MAAM,EAAE,WAAW,CAAC;EAClD,OAAO,OAAO,SAAS,MAAM,EAAE,SAAS,CAAC,CAAC;CAC5C;AACF;;;;;;;;;;;;;;AC1JA,SAAgB,uBACd,UACA,eACA,SACsB;CACtB,IAAI,SAAS,WAAW,GACtB,MAAM,IAAI,MAAM,kDAAkD;CAEpE,IAAI,cAAc,WAAW,GAC3B,MAAM,IAAI,MAAM,gDAAgD;CAGlE,MAAM,WAA8C,CAAC;CACrD,MAAM,eAAyB,CAAC;CAChC,MAAM,SAAS,CAAC;CAChB,KAAK,MAAM,KAAK,eAAe,OAAO,KAAK,CAAC;CAC5C,IAAI,YAAY;CAKhB,MAAM,4BAAY,IAAI,IAAoB;CAC1C,MAAM,UAAU,UAA0B;EACxC,MAAM,KAAK,UAAU,IAAI,KAAK,KAAK,KAAK;EACxC,UAAU,IAAI,OAAO,CAAC;EACtB,OAAO,MAAM,IAAI,QAAQ,GAAG,MAAM,GAAG;CACvC;CAEA,KAAK,MAAM,KAAK,UAAU;EACxB,MAAM,MAAM,OAAO,EAAE,KAAK;EAC1B,IAAI,CAAC,EAAE,cAAc;GACnB,aAAa,KAAK,GAAG;GACrB;EACF;EACA,MAAM,OAAO,CAAC;EACd,KAAK,MAAM,KAAK,eAAe,KAAK,KAAK,QAAQ,OAAO,EAAE,aAAa,EAAE,CAAC;EAC1E,SAAS,OAAO;EAChB,KAAK,MAAM,KAAK,eAAe,OAAO,EAAE,CAAC,KAAK,KAAK,EAAE;EACrD,IAAI,CAAC,aAAa,OAAO,EAAE,cAAc,YAAY,EAAE,WAAW,YAAY,EAAE;CAClF;CAEA,IAAI,aAAa,WAAW,SAAS,QACnC,MAAM,IAAI,MAAM,+BAA+B,SAAS,OAAO,eAAe;CAGhF,MAAM,eAAe,CAAC;CACtB,KAAK,MAAM,KAAK,eAAe;EAC7B,MAAM,OAAO,OAAO;EACpB,aAAa,KAAK,KAAK,WAAW,IAAI,IAAI,KAAK,QAAQ,GAAG,MAAM,IAAI,GAAG,CAAC,IAAI,KAAK;CACnF;CAEA,IAAI,kBAAkB;CACtB,KAAK,MAAM,KAAK,eAAe;EAC7B,MAAM,OAAO,OAAO;EACpB,IAAI,KAAK,SAAS,GAAG;EACrB,MAAM,SAAS,KAAK,IAAI,GAAG,IAAI,IAAI,KAAK,IAAI,GAAG,IAAI;EACnD,IAAI,SAAS,iBAAiB,kBAAkB;CAClD;CAEA,MAAM,IAA4B,CAAC;CACnC,IAAI,SACG;OAAA,MAAM,CAAC,GAAG,WAAW,OAAO,QAAQ,OAAO,GAC9C,IAAI,WAAW,KAAA,GAAW,EAAE,KAAK;CAAA,OAGnC,KAAK,MAAM,KAAK,eAAe,EAAE,KAAK,IAAI,cAAc;CAI1D,OAAO;EACL;EACA,WAJgB,kBAAkB;GAAE,MAAM;GAAc,SAAS;EAAE,CAAC,CAAC,CAAC;EAKtE;EACA;EACA;EACA,WAAW,aAAa;EACxB,UAAU,CAAC,GAAG,QAAQ;CACxB;AACF;;;;;;;;;;;;;;ACvFA,MAAM,uBAAuB;AAC7B,MAAM,qBAAqB;AAE3B,SAAS,MAAM,IAA2B;CACxC,OAAO,IAAI,SAAS,YAAY,WAAW,SAAS,EAAE,CAAC;AACzD;;;;;;;;;;;;AAaA,eAAsB,eACpB,SACA,SAA2B,CAAC,GACG;CAC/B,MAAM,cAAc,OAAO,eAAe;CAC1C,MAAM,YAAY,OAAO,aAAa;CACtC,MAAM,UAAU,OAAO,aAAa;CACpC,MAAM,cAAc,OAAO,eAAe;CAC1C,MAAM,SACJ,OAAO,UAAU,OAAO,OAAO,SAAS,IAAI,OAAO,SAAS,CAAC,KAAA,CAA8B;CAE7F,IAAI,gBAAgB;CACpB,MAAM,gBAAuD,CAAC;CAC9D,IAAI;CAEJ,KAAK,MAAM,SAAS,QAClB,KAAK,IAAI,UAAU,GAAG,UAAU,aAAa,WAAW;EACtD,iBAAiB;EACjB,MAAM,aAAa,IAAI,gBAAgB;EACvC,MAAM,QAAQ,iBAAiB,WAAW,sBAAM,IAAI,MAAM,cAAc,CAAC,GAAG,SAAS;EACrF,IAAI;GACF,MAAM,QAAQ,MAAM,QAAQ,OAAiB,WAAW,MAAM;GAC9D,aAAa,KAAK;GAClB,OAAO;IACL;IACA,WAAW;IACX,UAAU;IACV,WAAW;IACX;GACF;EACF,SAAS,KAAK;GACZ,aAAa,KAAK;GAClB,MAAM,SAAS,eAAe,QAAQ,MAAM,IAAI,MAAM,OAAO,GAAG,CAAC;GACjE,YAAY;GACZ,cAAc,KAAK;IACjB,SAAS;IACT,OAAO,SAAS;IAChB,OAAO,OAAO;GAChB,CAAC;GACD,IAAI,CAAC,YAAY,MAAM,GAIrB,OAAO;IACL,OAAO;IACP,WAAW;IACX,UAAU;IACV,OAAO;IACP;GACF;GAEF,IAAI,UAAU,cAAc,GAC1B,MAAM,MAAM,QAAQ,OAAO,CAAC;EAEhC;CACF;CAMF,OAAO;EACL,OAAO;EACP,WAAW;EACX,UAAU;EACV,OAAO;EACP;CACF;AACF;;;;;;;;;;;;;ACzDA,SAAgB,cACd,MACsB;CACtB,IAAI,KAAK,OAAO,WAAW,GACzB,MAAM,IAAI,MAAM,kBAAkB,KAAK,KAAK,2CAA2C;CAEzF,IAAI,KAAK,WAAW,WAAW,GAC7B,MAAM,IAAI,MAAM,kBAAkB,KAAK,KAAK,0CAA0C;CAExF,IAAI,KAAK,gBAAgB,OACvB,kBAAkB,KAAK,MAAM;CAE/B,MAAM,uBAAuB,KAAK,cAAc,KAAK;CACrD,IAAI,KAAK,iBAAiB,KAAA,KAAa,CAAC,sBACtC,MAAM,IAAI,MAAM,kBAAkB,KAAK,KAAK,gDAAgD;CAE9F,MAAM,eACJ,wBACA,YAAY;EACV,MAAM;EACN,QAAQ,KAAK;EACb,YAAY,KAAK;EACjB,SAAS,KAAK,WAAW;EACzB,aAAa,KAAK,eAAe;EACjC,eACE,OAAO,KAAK,kBAAkB,aAC1B,KAAK,cAAc,SAAS,IAC3B,KAAK,iBAAiB;EAC7B,OAAO,KAAK,QACR;GACE,aAAa,KAAK,MAAM,eAAe;GACvC,WAAW,KAAK,MAAM,aAAa;GACnC,QAAQ,KAAK,MAAM,UAAU;GAC7B,WAAW,KAAK,MAAM,WAAW,SAAS,KAAK;GAC/C,aAAa,KAAK,MAAM,aAAa,SAAS,KAAK;EACrD,IACA;EACJ,WAAW,KAAK,UAAU,SAAS;CACrC,CAAC;CACH,MAAM,mBAAmB,KAAK,cAAc,IAAI,WAAW;CAE3D,MAAM,WAAW,OAAO,SAQQ;EAC9B,MAAM,UAAU,MAAM,eACpB,OAAO,OAAO,gBAAgB;GAC5B,MAAM,OAAO,MAAM,KAAK,WAAW,YAAY;IAC7C,SAAS;IACT,OAAO,KAAK;IACZ,OAAO,GAAG,KAAK,KAAK,GAAG;IACvB;IACA,eACE,OAAO,KAAK,kBAAkB,aAC1B,KAAK,cAAc,KAAK,IACxB,KAAK;IACX,MAAM,KAAK;IACX,QAAQ,YAAY,IAAI,CAAC,KAAK,QAAQ,WAAW,CAAC;IAClD,UAAU,WACR,KAAK,UAAU,OAAO;KAAE,UAAU,KAAK;KAAU,UAAU,KAAK;KAAU;IAAO,CAAC;IACpF,UAAU,YAAY;KACpB,MAAM,eAAe,QAAQ,OAAO,sBAAsB;KAC1D,MAAM,eAAe,CAAC,QAAQ,SAAS,QAAQ,MAAM,aAAa;KAClE,OAAO;MACL,OAAO,QAAQ;MACf,aAAa,KAAK,IAAI,IAAI,QAAQ,OAAO,gBAAgB,KAAK,YAAY;MAC1E,cAAc,QAAQ,OAAO,oBAAoB;MACjD,cAAc,eAAe,IAAI,eAAe,KAAA;MAChD;MACA,GAAI,QAAQ,YAAY,KAAA,IAAY,CAAC,IAAI,EAAE,eAAe,QAAQ,QAAQ;KAC5E;IACF;IACA,mBAAmB,UAAU,KAAK,mBAAmB,OAAO,KAAK;GACnE,CAAC;GACD,IAAI,CAAC,KAAK,WAAW,MAAM,KAAK;GAChC,OAAO,KAAK;EACd,GACA,KAAK,QACD;GAAE,GAAG,KAAK;GAAO,QAAQ,CAAC,KAAK,KAAK;EAAE,IACtC;GAAE,aAAa;GAAG,QAAQ,CAAC,KAAK,KAAK;GAAG,mBAAmB;EAAM,CACvE;EACA,IAAI,CAAC,QAAQ,aAAa,QAAQ,UAAU,MAC1C,OAAO;GACL,OAAO,KAAK;GACZ,cAAc;GACd,WAAW,QAAQ,OAAO,WAAW;EACvC;EAEF,OAAO,QAAQ;CACjB;CAEA,OAAO;EACL,MAAM,KAAK;EACX,YAAY,KAAK,WAAW,KAAK,OAAO;GAAE,KAAK;GAAG,aAAa;EAAE,EAAE;EACnE;EACA,MAAM,MAAM,EACV,UACA,UACA,QACA,YACA,WACA,YACsB;GAetB,MAAM,MAAM,uBAAuB,MAdZ,QAAQ,IAC7B,KAAK,OAAO,KAAK,UACf,SAAS;IACP;IACA;IACA;IACA;IACA,YAAY,cAAc;IAC1B,WAAW,aAAa;IACxB;GACF,CAAC,CACH,CACF,GAE6C,KAAK,YAAY,KAAK,OAAO;GAC1E,MAAM,QAAoB;IACxB,YAAY,IAAI;IAChB,WAAW,IAAI;IACf,OAAO,IAAI;IACX,iBAAiB,IAAI;IACrB,UAAU,IAAI;GAChB;GACA,IAAI,IAAI,aAAa,SAAS,GAAG,MAAM,eAAe,IAAI;GAC1D,OAAO;EACT;CACF;AACF;;;ACtLA,IAAa,cAAb,MAAyB;CACvB;CAEA,YAAY,SAAwB,IAAI,wBAAwB,GAAG;EACjE,KAAK,SAAS;CAChB;CAEA,MAAM,IAAI,MAAqD;EAE7D,MAAM,UAAU,IAAI,aAAa,IADf,mBACmB,GAAG,EAAE,OAAO,SAAS,KAAK,KAAK,CAAC;EACrE,MAAM,QAAQ,SAAS;GACrB,YAAY,KAAK;GACjB,OAAO;GACP,WAAW;EACb,CAAC;EAED,MAAM,SAAS,MAAM,IADD,eAAe,KAAK,MACb,CAAC,CAAC,IAAI,KAAK,QAAQ,OAAO;EACrD,MAAM,QAAQ,OAAO;GAAE,MAAM,OAAO;GAAQ,OAAO,OAAO;GAAO,OAAO,GAAG,KAAK,KAAK;EAAQ,CAAC;EAC9F,OAAO;GACL,IAAI,KAAK;GACT,MAAM,KAAK;GACX,QAAQ,OAAO;GACf,OAAO,OAAO;GACd,SAAS,mBAAmB,KAAK,MAAM,MAAM;GAC7C;EACF;CACF;AACF;AAEA,eAAsB,cACpB,OACA,UAA6B,CAAC,GACC;CAC/B,MAAM,SAAS,IAAI,YAAY,QAAQ,MAAM;CAC7C,IAAI,QAAQ,aAAa,OAAO;EAC9B,MAAM,UAAgC,CAAC;EACvC,KAAK,MAAM,QAAQ,OAAO,QAAQ,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC;EAC7D,OAAO;CACT;CACA,MAAM,cAAc,KAAK,IAAI,GAAG,QAAQ,eAAe,KAAK,CAAC,CAAC,MAAM;CACpE,MAAM,UAAgC,IAAI,MAAM,MAAM,MAAM;CAC5D,IAAI,SAAS;CACb,eAAe,SAAwB;EACrC,OAAO,MAAM;GACX,MAAM,IAAI;GACV,IAAI,KAAK,MAAM,QAAQ;GACvB,QAAQ,KAAK,MAAM,OAAO,IAAI,MAAM,EAAG;EACzC;CACF;CACA,MAAM,QAAQ,IAAI,MAAM,KAAK,EAAE,QAAQ,KAAK,IAAI,aAAa,MAAM,MAAM,EAAE,SAAS,OAAO,CAAC,CAAC;CAC7F,OAAO;AACT;;AAGA,SAAgB,cAAc,IAAY,QAAyC;CACjF,OAAO;EAAE;EAAI,MAAM;EAAY;CAAO;AACxC;;AAGA,SAAgB,UAAU,IAAY,QAAyC;CAC7E,OAAO;EAAE;EAAI,MAAM;EAAQ;CAAO;AACpC;;AAGA,SAAgB,YAAY,IAAY,QAAyC;CAC/E,OAAO;EAAE;EAAI,MAAM;EAAU;CAAO;AACtC;;AAGA,SAAgB,cAAc,IAAY,QAAyC;CACjF,OAAO;EAAE;EAAI,MAAM;EAAY;CAAO;AACxC;AAEA,SAAS,mBAAmB,MAAwB,QAAsC;CACxF,IAAI,CAAC,OAAO,QAAQ,OAAO,GAAG,KAAK;CACnC,IAAI,OAAO,MAAM,YACf,OAAO,GAAG,KAAK,gBAAgB,OAAO,KAAK,YAAY,GAAG,OAAO,KAAK,WAAW;CACnF,OAAO,GAAG,KAAK;AACjB;;;ACxGA,SAAgB,gBACd,SACA,UAAmC,CAAC,GAC1B;CACV,MAAM,aAAa,QAAQ,cAAc;CACzC,MAAM,gCAAgB,IAAI,IAA2B;CAErD,KAAK,MAAM,SAAS,SAAS;EAC3B,MAAM,MAAM,qBAAqB,MAAM,WAAW;EAClD,MAAM,WAAW,cAAc,IAAI,GAAG;EACtC,IAAI,CAAC,aAAa,MAAM,UAAU,MAAM,SAAS,UAAU,IACzD,cAAc,IAAI,KAAK;GAAE,GAAG;GAAO,aAAa,qBAAqB,MAAM,WAAW;EAAE,CAAC;CAE7F;CAMA,OAAO,EAAE,SAJS,CAAC,GAAG,cAAc,OAAO,CAAC,CAAC,CAC1C,MAAM,GAAG,OAAO,EAAE,UAAU,MAAM,EAAE,UAAU,EAAE,CAAC,CACjD,MAAM,GAAG,UAEc,EAAE;AAC9B;AAEA,SAAgB,uBAAuB,UAA4B;CACjE,MAAM,QAAQ,CAAC,cAAc,EAAE;CAC/B,KAAK,MAAM,SAAS,SAAS,SAAS;EACpC,MAAM,KAAK,KAAK,MAAM,aAAa;EACnC,MAAM,KAAK,gBAAgB,MAAM,WAAW;EAC5C,IAAI,MAAM,UAAU,MAAM,KAAK,eAAe,MAAM,UAAU;EAC9D,IAAI,MAAM,UAAU,MAAM,KAAK,eAAe,MAAM,UAAU;EAC9D,IAAI,MAAM,aAAa,MAAM,KAAK,iBAAiB,MAAM,aAAa;EACtE,MAAM,KAAK,EAAE;CACf;CACA,OAAO,GAAG,MAAM,KAAK,IAAI,CAAC,CAAC,KAAK,EAAE;AACpC;AAEA,SAAS,qBAAqB,OAAuB;CACnD,OAAO,MAAM,KAAK,CAAC,CAAC,YAAY,CAAC,CAAC,QAAQ,QAAQ,GAAG;AACvD;AAEA,SAAS,qBAAqB,OAAuB;CACnD,MAAM,aAAa,MAAM,KAAK,CAAC,CAAC,QAAQ,QAAQ,GAAG;CACnD,OAAO,WAAW,WAAW,IAAI,aAAa,WAAW,EAAE,CAAE,YAAY,IAAI,WAAW,MAAM,CAAC;AACjG;;;AChCA,IAAa,iBAAb,MAA4B;CAC1B,0BAA2B,IAAI,IAA0B;;;;;;CAOzD,MAAM,SAAS,IAAY,SAAiB,SAAwC;EAClF,WAAW,EAAE;EACb,gBAAgB,OAAO;EAEvB,MAAM,MAAM,QAAQ,IAAI,OAAO;EAC/B,MAAM,OAAO,MAAM,YAAY,OAAO;EACtC,MAAM,WAAW,KAAK,QAAQ,IAAI,GAAG;EACrC,IAAI,UAAU;GACZ,IAAI,SAAS,SAAS,MACpB,MAAM,IAAI,MACR,UAAU,IAAI,6CAA6C,SAAS,KAAK,MAAM,KAAK,qBACtF;GAEF,OAAO;EACT;EACA,MAAM,SAAuB;GAAE;GAAI;GAAS;GAAM;EAAQ;EAC1D,KAAK,QAAQ,IAAI,KAAK,MAAM;EAC5B,OAAO;CACT;;CAGA,IAAI,IAAY,SAA+B;EAC7C,MAAM,MAAM,QAAQ,IAAI,OAAO;EAC/B,MAAM,SAAS,KAAK,QAAQ,IAAI,GAAG;EACnC,IAAI,CAAC,QAAQ,MAAM,IAAI,MAAM,UAAU,IAAI,gBAAgB;EAC3D,OAAO;CACT;;CAGA,aAAa,IAA4B;EACvC,OAAO,CAAC,GAAG,KAAK,QAAQ,OAAO,CAAC,CAAC,CAC9B,QAAQ,MAAM,EAAE,OAAO,EAAE,CAAC,CAC1B,MAAM,GAAG,MAAM,EAAE,QAAQ,cAAc,EAAE,OAAO,CAAC;CACtD;;CAGA,OAAuB;EACrB,OAAO,CAAC,GAAG,KAAK,QAAQ,OAAO,CAAC;CAClC;;CAGA,WAAW,IAAY,SAAiB,cAAsC;EAC5E,MAAM,SAAS,KAAK,QAAQ,IAAI,QAAQ,IAAI,OAAO,CAAC;EACpD,IAAI,CAAC,QAAQ,OAAO;EACpB,OAAO,OAAO,SAAS;CACzB;AACF;;AAGA,eAAsB,YAAY,SAAkC;CAClE,MAAM,QAAQ,IAAI,YAAY,CAAC,CAAC,OAAO,OAAO;CAC9C,MAAM,SAAS,MAAM,OAAO,OAAO,OAAO,WAAW,KAAK;CAI1D,OAHa,MAAM,KAAK,IAAI,WAAW,MAAM,CAAC,CAAC,CAC5C,KAAK,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC,SAAS,GAAG,GAAG,CAAC,CAAC,CAC3C,KAAK,EACE,CAAC,CAAC,MAAM,GAAG,EAAE;AACzB;AAEA,SAAS,QAAQ,IAAY,SAAyB;CACpD,OAAO,GAAG,GAAG,GAAG;AAClB;AAEA,MAAM,QAAQ;AACd,SAAS,WAAW,IAAkB;CACpC,IAAI,CAAC,MAAM,KAAK,EAAE,GAChB,MAAM,IAAI,MAAM,sBAAsB,GAAG,gBAAgB,OAAO;AAEpE;AAEA,SAAS,gBAAgB,SAAuB;CAC9C,IAAI,CAAC,WAAW,QAAQ,SAAS,IAC/B,MAAM,IAAI,MAAM,oBAAoB,QAAQ,sBAAsB;AAEtE;;;AChFA,SAAgB,oBAAoB,MAAsB,OAAsC;CAC9F,OAAO;EACL,GAAG;EACH,GAAI,MAAM,gBAAgB,KAAA,IAAY,EAAE,aAAa,MAAM,YAAY,IAAI,CAAC;EAC5E,GAAI,MAAM,mBAAmB,KAAA,IAAY,EAAE,gBAAgB,MAAM,eAAe,IAAI,CAAC;EACrF,iBAAiB;GACf,GAAI,KAAK,mBAAmB,CAAC;GAC7B,GAAI,MAAM,mBAAmB,CAAC;EAChC;EACA,QAAQ,MAAM,UAAU,KAAK;EAC7B,aAAa;GACX,GAAI,KAAK,eAAe,CAAC;GACzB,GAAI,MAAM,eAAe,CAAC;EAC5B;EACA,UAAU;GACR,GAAI,KAAK,YAAY,CAAC;GACtB,GAAI,MAAM,YAAY,CAAC;EACzB;CACF;AACF;AAEA,SAAgB,mBAAmB,QAAgC;CACjE,MAAM,QAAkB,CAAC,UAAU,OAAO,IAAI;CAC9C,IAAI,OAAO,aAAa,MAAM,KAAK,SAAS,OAAO,aAAa;CAChE,IAAI,OAAO,gBAAgB,MAAM,KAAK,YAAY,OAAO,gBAAgB;CACzE,MAAM,YAAY,OAAO,QAAQ,OAAO,mBAAmB,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,OACzE,EAAE,cAAc,CAAC,CACnB;CACA,KAAK,MAAM,CAAC,MAAM,WAAW,WAAW,MAAM,KAAK,YAAY,KAAK,GAAG,QAAQ;CAC/E,MAAM,QAAQ,OAAO,QAAQ,OAAO,eAAe,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC;CAC5F,KAAK,MAAM,CAAC,MAAM,SAAS,OACzB,MAAM,KAAK,QAAQ,KAAK,UAAU,KAAK,UAAU,GAAG,UAAU,KAAK,UAAU,IAAI;CAEnF,MAAM,SAAS,CAAC,GAAI,OAAO,UAAU,CAAC,CAAE,CAAC,CAAC,KAAK;CAC/C,IAAI,OAAO,QAAQ,MAAM,KAAK,UAAU,OAAO,KAAK,GAAG,GAAG;CAC1D,OAAO,MAAM,KAAK,IAAI;AACxB;;;;;;;;;ACrBA,IAAa,4BAAb,MAAuC;CACrC,SACE,MACA,SAAkC,CAAC,GACP;EAC5B,MAAM,WAAW,SAAS,MAAM,OAAO,OAAO;EAC9C,IAAI,SAAS,WAAW,GAAG,MAAM,IAAI,MAAM,+BAA+B;EAC1E,OAAO;GACL,SAAS;GACT,sBAAsB,SAAS,EAAE,CAAE;GACnC,WAAW,0CAA0C,KAAK,OAAO;GACjE;EACF;CACF;AACF;AAEA,SAAS,SACP,MACA,SAC0D;CAC1D,MAAM,0BAAU,IAAI,IAAsB;CAC1C,KAAK,MAAM,OAAO,MAAM;EACtB,MAAM,SAAS,QAAQ,IAAI,IAAI,SAAS,KAAK,CAAC;EAC9C,OAAO,KAAK,kBAAkB,IAAI,OAAO,OAAO,CAAC;EACjD,QAAQ,IAAI,IAAI,WAAW,MAAM;CACnC;CACA,OAAO,CAAC,GAAG,QAAQ,QAAQ,CAAC,CAAC,CAC1B,KAAK,CAAC,WAAW,aAAa;EAC7B;EACA,MAAM,OAAO,QAAQ,KAAK,UAAU,MAAM,OAAO,CAAC,IAAI,OAAO;EAC7D,MAAM,OAAO;CACf,EAAE,CAAC,CACF,MAAM,GAAG,MAAM,EAAE,OAAO,EAAE,IAAI;AACnC;;;AClCA,IAAa,6BAAb,MAAsE;CACpE,OAAgB;CAChB,4BAA6B,IAAI,IAA+B;CAEhE,IAAI,SAAiB,UAAmC;EACtD,KAAK,UAAU,IAAI,SAAS,QAAQ;CACtC;CAEA,MAAM,SAAS,SAAuD;EACpE,OAAO,KAAK,UAAU,IAAI,QAAQ,OAAO,KAAK;GAAE,OAAO,CAAC;GAAG,MAAM,CAAC;GAAG,IAAI,CAAC;EAAE;CAC9E;AACF;AAmBA,SAAgB,WAAW,MAAkC;CAC3D,OAAO;EACL,MAAM,eAAe;EACrB,MAAM,UAAU;GACd,MAAM,OAAO,QAAQ,SAAS;GAC9B,OAAO;IACL;IACA,OAAO,OAAO,IAAI;IAClB,QAAQ,OAAO,KAAA,IAAY,cAAc;GAC3C;EACF;CACF;AACF;AAEA,SAAgB,aAAa,MAAc,QAAoC;CAC7E,OAAO;EACL,MAAM,iBAAiB,KAAK,GAAG;EAC/B,MAAM,UAAU;GACd,MAAM,UAAU,SAAS,MAAM;GAC/B,IAAI,YAAY,KAAA,GACd,OAAO;IAAE,MAAM;IAAO,OAAO;IAAG,QAAQ,QAAQ,KAAK;GAAU;GAEjE,MAAM,OAAO,QAAQ,SAAS,MAAM;GACpC,OAAO;IACL;IACA,OAAO,OAAO,IAAI;IAClB,QAAQ,OAAO,KAAA,IAAY,QAAQ,KAAK,sBAAsB,OAAO;GACvE;EACF;CACF;AACF;AAEA,SAAgB,SAAS,OAAe,KAAa,KAAkC;CACrF,OAAO;EACL,MAAM,aAAa,MAAM,IAAI,IAAI,GAAG,OAAO,IAAI;EAC/C,MAAM,UAAU;GAEd,MAAM,SADO,SAAS,KAAK,UAAU,CAAC,EAAA,CACnB;GACnB,MAAM,QAAQ,OAAO;GACrB,MAAM,OAAO,SAAS,OAAO,SAAS;GAEtC,OAAO;IACL;IACA,OAHY,OAAO,IAAI,QAAQ,MAAM,KAAK,IAAI,GAAG,QAAQ,GAAG,IAAI,KAAK,IAAI,GAAG,QAAQ,KAAK;IAIzF,QAAQ,OACJ,KAAA,IACA,SAAS,MAAM,OAAO,MAAM,mBAAmB,IAAI,IAAI,OAAO,IAAI;GACxE;EACF;CACF;AACF;AAEA,SAAgB,SACd,OACA,WACA,SACoB;CACpB,MAAM,MAAM,SAAS,OAAO;CAC5B,OAAO;EACL,MAAM,aAAa;EACnB,MAAM,UAAU;GAEd,MAAM,YADQ,SAAS,KAAK,UAAU,CAAC,EAAA,CACjB,OAAO,SAAS,CAAC,CAAC;GACxC,MAAM,OAAO,YAAY;GACzB,OAAO;IACL;IACA,OAAO,OAAO,IAAI,KAAK,IAAI,GAAG,WAAW,GAAG;IAC5C,QAAQ,OACJ,KAAA,IACA,SAAS,MAAM,OAAO,SAAS,6BAA6B;GAClE;EACF;CACF;AACF;;AAGA,SAAgB,cACd,UACA,YAKA;CACA,MAAM,UAAU,WAAW,KAAK,OAAO;EAAE,WAAW,EAAE;EAAM,QAAQ,EAAE,MAAM,QAAQ;CAAE,EAAE;CAKxF,OAAO;EAAE,MAJI,QAAQ,OAAO,MAAM,EAAE,OAAO,IAI/B;EAAG,OAHD,QAAQ,SAClB,QAAQ,QAAQ,KAAK,MAAM,MAAM,EAAE,OAAO,OAAO,CAAC,IAAI,QAAQ,SAC9D;EACkB;CAAQ;AAChC;;;;;;;;;;;;AChJA,IAAa,oBAAb,cAAuC,eAAe;CAE3C;CACA;CACA;CAHT,YACE,WACA,OACA,WACA;EACA,MAAM,gBAAgB,oBAAoB,UAAU,cAAc,UAAU,YAAY,OAAO;EAJxF,KAAA,YAAA;EACA,KAAA,QAAA;EACA,KAAA,YAAA;CAGT;AACF;AAEA,IAAa,cAAb,MAAyB;CACvB,WAAqD;EAAE,QAAQ;EAAG,QAAQ;EAAG,OAAO;EAAG,KAAK;CAAE;CAC9F;CACA;CACA;CAEA,YAAY,SAAuB,QAAoB,YAA0B,KAAK,IAAI,GAAG;EAC3F,KAAK,UAAU;EACf,KAAK,SAAS;EACd,KAAK,YAAY,IAAI;CACvB;;CAGA,MAAM,OAAO,OAAkD,QAAgC;EAC7F,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,KAAK,GAAwC;GACrF,IAAI,CAAC,OAAO,SAAS,KAAK,KAAK,QAAQ,GACrC,MAAM,IAAI,MAAM,8CAA8C,IAAI,GAAG,OAAO;GAE9E,KAAK,SAAS,QAAQ;GACtB,MAAM,QAAQ,KAAK,OAAO;GAC1B,MAAM,WAAW,KAAK,SAAS;GAC/B,MAAM,YAAY,UAAU,KAAA,IAAY,WAAW,QAAQ;GAC3D,MAAM,WAAW,UAAU,KAAA,KAAa,WAAW;GACnD,IAAI,UAAU,KAAA,GACZ,MAAM,KAAK,QAAQ,aAAa;IAC9B,WAAW;IACX;IACA;IACA;IACA;IACA;GACF,CAAC;GAEH,IAAI,UACF,MAAM,IAAI,kBAAkB,KAAK,OAAQ,QAAQ;EAErD;CACF;;CAGA,MAAM,SAAS,OAAe,QAAgC;EAC5D,MAAM,UAAU,QAAQ,KAAK;EAC7B,MAAM,UAAU,KAAK,SAAS;EAC9B,MAAM,QAAQ,KAAK,IAAI,GAAG,UAAU,OAAO;EAC3C,IAAI,QAAQ,GAAG,MAAM,KAAK,OAAO,EAAE,QAAQ,MAAM,GAAG,MAAM;CAC5D;CAEA,IAAI,QAA0C;EAC5C,OAAO,EAAE,GAAG,KAAK,SAAS;CAC5B;AACF;;;;ACZA,MAAM,qCAAoD,IAAI,IAAsB,CAClF,gBACA,YACF,CAAC;;AAGD,SAAgB,oBAAoB,aAAwC;CAC1E,OAAO,mBAAmB,IAAI,WAAW;AAC3C;;;;;;;;AAyBA,SAAgB,YACd,SACA,QACe;CACf,MAAM,MAAqB,CAAC;CAC5B,KAAK,MAAM,QAAQ,OAAO,KAAK,OAAO,GAAc;EAClD,MAAM,QAAQ,OAAO;EACrB,IAAI,UAAU,KAAA,GACZ,MAAM,IAAI,gBACR,iBAAiB,KAAK,2EACxB;EAEF,IAAI,KAAK;GAAE;GAAM;GAAO,aAAa,QAAQ;EAAM,CAAC;CACtD;CACA,OAAO;AACT;;;;;;;;;;;;AA0BA,SAAgB,mBACd,QACA,cACA,OAAsB,CAAC,GACC;CACxB,MAAM,SAAS,KAAK,kBAAkB;CACtC,MAAM,QAAsB,CAAC;CAC7B,KAAK,MAAM,SAAS,QAAQ;EAC1B,IAAI,CAAC,oBAAoB,MAAM,WAAW,GAAG;EAC7C,MAAM,SAAS,MAAM,MAAM,KAAK;EAChC,IAAI,OAAO,SAAS,QAAQ;EAC5B,IAAI,aAAa,SAAS,MAAM,GAC9B,MAAM,KAAK;GAAE,OAAO,MAAM;GAAM,aAAa,MAAM;EAAY,CAAC;CAEpE;CACA,IAAI,MAAM,SAAS,GAAG;EACpB,MAAM,SAAS,MAAM,KAAK,MAAM,IAAI,EAAE,MAAM,KAAK,EAAE,YAAY,EAAE,CAAC,CAAC,KAAK,IAAI;EAC5E,MAAM,IAAI,gBACR,sCAAsC,MAAM,OAAO,8CAA8C,QACnG;CACF;CACA,OAAO;AACT;;;;;;AAOA,SAAgB,mBAAmB,QAA+C;CAChF,OAAO,OAAO,QAAQ,MAAM,CAAC,oBAAoB,EAAE,WAAW,CAAC;AACjE;;;;AAsCA,SAAgB,YAAY,QAAgB,OAAe,OAAmC;CAC5F,MAAM,IAAI,OAAO,SAAS,MAAM,KAAK,SAAS,IAAI,KAAK,MAAM,MAAM,IAAI;CACvE,MAAM,IAAI,OAAO,SAAS,KAAK,KAAK,QAAQ,IAAI,KAAK,MAAM,KAAK,IAAI;CACpE,MAAM,WAAW,IAAI,IAAI,KAAK,IAAI,GAAG,IAAI,CAAC,IAAI;CAC9C,OAAO;EAAE,QAAQ,KAAK,IAAI,GAAG,IAAI,IAAI,IAAI,CAAC;EAAG,OAAO;EAAG;EAAU;CAAM;AACzE;;;;;;;;;;AAWA,eAAsB,cAAkC,MAOzB;CAC7B,mBAAmB,KAAK,SAAS,QAAQ,KAAK,SAAS,cAAc,KAAK,SAAS,OAAO;CAC1F,MAAM,SAAS,MAAM,KAAK,OAAO,KAAK,UAAU,KAAK,gBAAgB,KAAK,MAAM;CAChF,OAAO,YAAY,OAAO,QAAQ,OAAO,OAAO,OAAO,KAAK;AAC9D;;;AAeA,MAAa,sBAAoC;CAAE,SAAS;CAAK,OAAO;AAAI;AAW5E,SAAS,iBAAiB,SAA2D;CACnF,MAAM,IAAI,OAAO,SAAS,QAAQ,OAAO,KAAK,QAAQ,WAAW,IAAI,QAAQ,UAAU;CACvF,MAAM,IAAI,OAAO,SAAS,QAAQ,KAAK,KAAK,QAAQ,SAAS,IAAI,QAAQ,QAAQ;CACjF,MAAM,MAAM,IAAI;CAChB,IAAI,OAAO,GACT,MAAM,IAAI,gBACR,qGACF;CAEF,OAAO;EAAE,SAAS,IAAI;EAAK,OAAO,IAAI;CAAI;AAC5C;;;;;;;;;AAUA,SAAgB,aACd,iBACA,YACA,UAAwB,qBAChB;CACR,MAAM,IAAI,iBAAiB,OAAO;CAClC,MAAM,UAAU,UAAU,eAAe;CACzC,MAAM,QAAQ,UAAU,UAAU;CAClC,OAAO,EAAE,UAAU,UAAU,EAAE,QAAQ;AACzC;;;;;;;;;;;;;;AAeA,SAAgB,iBACd,OACA,iBACA,UAAwB,qBACoC;CAC5D,OAAO,OAAO,UAA2D;EACvE,MAAM,OAAO,MAAM,MAAM,KAAK;EAC9B,IAAI,KAAK,QAAQ,OAAO;EACxB,MAAM,OAAO,UAAU,gBAAgB,MAAM,QAAQ,CAAC;EACtD,MAAM,YAAY,aAAa,MAAM,KAAK,WAAW,OAAO;EAC5D,MAAM,IAAI,iBAAiB,OAAO;EAClC,OAAO;GACL,GAAG;GACH;GACA,OACE,aAAa,UAAU,QAAQ,CAAC,EAAE,cACpB,OAAO,IAAA,CAAK,QAAQ,CAAC,EAAE,MAAM,EAAE,QAAQ,QAAQ,CAAC,EAAE,aACrD,KAAK,UAAU,QAAQ,CAAC,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC,EAAE,MAC5D,KAAK,QAAQ,MAAM,KAAK,UAAU;EACvC;CACF;AACF;AAEA,SAAS,UAAU,OAAuB;CACxC,IAAI,CAAC,OAAO,SAAS,KAAK,GAAG,OAAO;CACpC,OAAO,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,KAAK,CAAC;AACvC;;;ACnRA,MAAM,oBAAiC;AAEvC,SAAgB,iCACd,SACqC;CACrC,MAAM,cAAwB,CAAC;CAC/B,MAAM,2BAAW,IAAI,IAAwC;CAC7D,MAAM,SAAuC,CAAC;CAC9C,IAAI,+BAA+B;CACnC,IAAI,sBAAsB;CAE1B,KAAK,IAAI,cAAc,GAAG,cAAc,QAAQ,QAAQ,QAAQ,eAAe,GAAG;EAChF,MAAM,SAAS,QAAQ,QAAQ;EAC/B,MAAM,MAAM,2BAA2B,QAAQ,aAAa,QAAQ,UAAU;EAC9E,MAAM,WAAW,OAAO,YAAY,QAAQ,mBAAmB;EAC/D,IAAI,OAAO,aAAa,KAAA,GAAW,uBAAuB;EAE1D,MAAM,YAAY,OAAO;EACzB,IAAI,CAAC,MAAM,QAAQ,SAAS,GAAG;GAC7B,YAAY,KACV,GAAG,IAAI,sEACT;GACA;EACF;EACA,IAAI,UAAU,WAAW,GAAG;GAC1B,YAAY,KAAK,GAAG,IAAI,yDAAyD;GACjF;EACF;EACA,gCAAgC;EAEhC,KAAK,IAAI,QAAQ,GAAG,QAAQ,UAAU,QAAQ,SAAS,GAAG;GACxD,MAAM,QAAQ,gCAAgC,UAAU,MAAM;GAC9D,IAAI,CAAC,OAAO;IACV,YAAY,KAAK,GAAG,IAAI,kBAAkB,MAAM,4BAA4B;IAC5E;GACF;GACA,OAAO,KAAK,KAAK;GAEjB,MAAM,aACJ,MAAM,cACN,kBAAkB,QAAQ,eAAe,QAAQ,WAAW,CAAC,KAC7D,kBAAkB,OAAO,UAAU;GACrC,MAAM,QAAQ,SAAS,IAAI,MAAM,KAAK;GACtC,IAAI,CAAC,OAAO;IACV,SAAS,IAAI,MAAM,OAAO;KAAE,OAAO,MAAM;KAAO;KAAY;IAAS,CAAC;IACtE;GACF;GACA,IAAI,MAAM,eAAe,cAAc,MAAM,aAAa,UACxD,YAAY,KAAK,GAAG,IAAI,UAAU,MAAM,MAAM,yCAAyC;EAE3F;CACF;CAEA,MAAM,OAAO,CAAC,GAAG,SAAS,OAAO,CAAC;CAClC,OAAO;EACL;EACA;EACA,SAAS;GACP,aAAa,QAAQ,QAAQ;GAC7B;GACA,iBAAiB,KAAK;GACtB,qBAAqB,OAAO;GAC5B;EACF;EACA;CACF;AACF;AAEA,SAAgB,gCAAgC,OAAmD;CACjG,IAAI,CAAC,SAAS,KAAK,GAAG,OAAO;CAC7B,IAAI,OAAO,MAAM,OAAO,YAAY,MAAM,GAAG,WAAW,GAAG,OAAO;CAClE,IAAI,OAAO,MAAM,UAAU,YAAY,MAAM,MAAM,WAAW,GAAG,OAAO;CACxE,IAAI,OAAO,MAAM,WAAW,YAAY,MAAM,OAAO,WAAW,GAAG,OAAO;CAC1E,IAAI,OAAO,MAAM,UAAU,YAAY,MAAM,MAAM,WAAW,GAAG,OAAO;CACxE,IAAI,OAAO,MAAM,cAAc,YAAY,CAAC,OAAO,SAAS,MAAM,SAAS,GAAG,OAAO;CAErF,OAAO;EACL,IAAI,MAAM;EACV,OAAO,MAAM;EACb,YAAY,kBAAkB,MAAM,UAAU;EAC9C,QAAQ,MAAM;EACd,OAAO,MAAM;EACb,WAAW,MAAM;EACjB,WAAW,wBAAwB,MAAM,SAAS;EAClD,UAAU,kBAAkB,MAAM,QAAQ;EAC1C,SAAS,MAAM;EACf,UAAU,SAAS,MAAM,QAAQ,IAAI,EAAE,GAAG,MAAM,SAAS,IAAI,KAAA;CAC/D;AACF;AAEA,SAAS,2BACP,QACA,OACA,YACQ;CACR,OACE,kBAAkB,aAAa,QAAQ,KAAK,CAAC,KAC7C,kBAAkB,OAAO,EAAE,KAC3B,UAAU,MAAM;AAEpB;AAEA,SAAS,SAAS,OAAkD;CAClE,OAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAC5E;AAEA,SAAS,kBAAkB,OAAoC;CAC7D,OAAO,OAAO,UAAU,YAAY,MAAM,SAAS,IAAI,QAAQ,KAAA;AACjE;AAEA,SAAS,wBAAwB,OAAoC;CACnE,OAAO,OAAO,UAAU,YAAY,OAAO,SAAS,KAAK,IAAI,QAAQ,KAAA;AACvE;;;;;;;;;;;;;AC5HA,IAAa,cAAb,MAAyB;CACvB,6BAAqB,IAAI,IAA0B;CAEnD,OAAO,OAAyE;EAC9E,MAAM,OAAkB;GAAE,WAAW,MAAM,aAAa,KAAK,IAAI;GAAG,GAAG;EAAM;EAC7E,kBAAkB,KAAK,aAAa,aAAa;EACjD,kBAAkB,KAAK,cAAc,cAAc;EACnD,IAAI,SAAS,KAAK,WAAW,IAAI,KAAK,UAAU;EAChD,IAAI,CAAC,QAAQ;GACX,SAAS;IACP,YAAY,KAAK;IACjB,SAAS,CAAC;IACV,kBAAkB;IAClB,mBAAmB;IACnB,mBAAmB;IACnB,cAAc;GAChB;GACA,KAAK,WAAW,IAAI,KAAK,YAAY,MAAM;EAC7C;EACA,OAAO,QAAQ,KAAK,IAAI;EACxB,OAAO,oBAAoB,KAAK;EAChC,OAAO,qBAAqB,KAAK;EACjC,OAAO,qBAAqB,KAAK,gBAAgB;EACjD,OAAO,gBAAgB,QAAQ,IAAI;EACnC,OAAO;CACT;CAEA,YAAY,YAAoB,WAA0B;EACxD,MAAM,SAAS,KAAK,WAAW,IAAI,UAAU;EAC7C,IAAI,CAAC,QAAQ,MAAM,IAAI,MAAM,8CAA8C,WAAW,EAAE;EACxF,OAAO,YAAY;CACrB;;;;;;;;;;;CAYA,cACE,SAUA,YACA,MACkB;EAClB,IAAI,CAAC,QAAQ,OAAO,OAAO;EAC3B,MAAM,QAAQ,KAAK,OAAO;GACxB;GACA,OAAO,QAAQ,MAAM;GACrB,aAAa,QAAQ,MAAM;GAC3B,cAAc,QAAQ,MAAM;GAC5B,cAAc,QAAQ,MAAM;GAC5B,iBAAiB,QAAQ,MAAM;GAC/B;EACF,CAAC;EACD,KAAK,YAAY,YAAY,QAAQ,YAAY,MAAM;EACvD,OAAO;CACT;CAEA,IAAI,YAA8C;EAChD,OAAO,KAAK,WAAW,IAAI,UAAU;CACvC;CAEA,OAAuB;EACrB,OAAO,CAAC,GAAG,KAAK,WAAW,OAAO,CAAC;CACrC;CAEA,UAAuB;EACrB,MAAM,YAAY,KAAK,KAAK;EAC5B,MAAM,YAAY,UAAU,QAAQ,MAAM,EAAE,cAAc,IAAI;EAC9D,MAAM,YAAY,UAAU,QAAQ,GAAG,MAAM,IAAI,EAAE,cAAc,CAAC;EAClE,MAAM,aAAa,UAAU,QAAQ,GAAG,MAAM,IAAI,EAAE,kBAAkB,CAAC;EACvE,MAAM,cAAc,UAAU,QAAQ,GAAG,MAAM,IAAI,EAAE,mBAAmB,CAAC;EACzE,MAAM,qBAAqB,UAAU,QAAQ,GAAG,MAAM,IAAI,EAAE,cAAc,CAAC;EAC3E,OAAO;GACL,eAAe,UAAU;GACzB,gBAAgB,UAAU;GAC1B,kBAAkB;GAClB,mBAAmB;GACnB,cAAc;GACd,uBAAuB,UAAU,SAAS,YAAY,UAAU,SAAS;GACzE,yBAAyB,UAAU,SAAS,qBAAqB,UAAU,SAAS;EACtF;CACF;AACF;AAaA,SAAS,QAAQ,OAA0B;CACzC,IAAI,OAAO,MAAM,kBAAkB,YAAY,OAAO,SAAS,MAAM,aAAa,GAChF,OAAO,MAAM;CAEf,OAAO,aAAa,MAAM,aAAa,MAAM,cAAc,MAAM,KAAK;AACxE;AAEA,SAAS,kBAAkB,GAAW,MAAoB;CACxD,IAAI,CAAC,OAAO,SAAS,CAAC,KAAK,IAAI,GAC7B,MAAM,IAAI,MAAM,gBAAgB,KAAK,6CAA6C,GAAG;AAEzF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACvHA,SAAgB,SAAS,QAAuC;CAC9D,OAAO,cAAc,MAAM;AAC7B;AAkBA,SAAS,QAAQ,QAAmB,GAA6B;CAC/D,IAAI,EAAE,gBAAgB,OAAO,iBAAiB,EAAE,cAAc,OAAO;CACrE,IAAI,EAAE,eAAe,OAAO,gBAAgB,EAAE,aAAa,OAAO;CAClE,IAAI,EAAE,cAAc,OAAO,eAAe,EAAE,YAAY,OAAO;CAC/D,IAAI,EAAE,SAAS,OAAO,UAAU,EAAE,OAAO,OAAO;CAChD,IAAI,EAAE,YAAY,OAAO,aAAa,EAAE,UAAU,OAAO;CACzD,IAAI,EAAE,aAAa,KAAA,KAAa,EAAE,aAAa,KAAA,GAAW;EACxD,MAAM,QAAQ,SAAS,MAAM;EAC7B,IAAI,UAAU,KAAA,GAAW,OAAO;EAChC,IAAI,EAAE,aAAa,KAAA,KAAa,QAAQ,EAAE,UAAU,OAAO;EAC3D,IAAI,EAAE,aAAa,KAAA,KAAa,QAAQ,EAAE,UAAU,OAAO;CAC7D;CACA,IAAI,EAAE,aAAa,OAAO,QAAQ,IAAI,EAAE,UAAU,SAAS,EAAE,UAAU,OAAO,OAAO;CACrF,IAAI,EAAE,SAAS,CAAC,EAAE,MAAM,MAAM,GAAG,OAAO;CACxC,OAAO;AACT;AAwCA,SAAgB,yBAAyB,UAAuB,CAAC,GAAqB;CACpF,MAAM,OAAO,QAAQ,KAAK,MAAM,kBAAkB,CAAC,CAAC;CACpD,OAAO;EACL,MAAM,OAAO,QAAQ;GACnB,KAAK,KAAK,MAAM;EAClB;EACA,MAAM,OAAO;GACX,OAAO,CAAC,GAAG,IAAI;EACjB;CACF;AACF;;;;;;AAOA,SAAgB,sBACd,MACA,OAAkC,CAAC,GACjB;CAClB,OAAO;EACL,MAAM,OAAO,QAAQ;GACnB,MAAM,KAAK,MAAM,OAAO;GACxB,MAAM,UAAU,MAAM,OAAO;GAC7B,MAAM,GAAG,MAAM,QAAQ,QAAQ,IAAI,GAAG,EAAE,WAAW,KAAK,CAAC;GACzD,MAAM,GAAG,WAAW,MAAM,GAAG,KAAK,UAAU,MAAM,EAAE,KAAK,MAAM;EACjE;EACA,MAAM,OAAO;GACX,MAAM,KAAK,MAAM,OAAO;GACxB,IAAI;GACJ,IAAI;IACF,MAAM,MAAM,GAAG,SAAS,MAAM,MAAM;GACtC,SAAS,KAAK;IACZ,IAAK,IAA8B,SAAS,UAAU,OAAO,CAAC;IAC9D,MAAM;GACR;GACA,MAAM,MAAmB,CAAC;GAC1B,IAAI,SAAS;GACb,KAAK,MAAM,QAAQ,IAAI,MAAM,IAAI,GAAG;IAClC;IACA,IAAI,CAAC,KAAK,KAAK,GAAG;IAClB,IAAI;IACJ,IAAI;KACF,SAAS,KAAK,MAAM,IAAI;IAC1B,SAAS,KAAK;KACZ,IAAI,KAAK,aAAa;KACtB,MAAM,IAAI,gBAAgB,mBAAmB,KAAK,GAAG,OAAO,mBAAmB;IACjF;IACA,IAAI,KAAK,aAAa;KACpB,IAAI,YAAY,MAAM,GAAG,IAAI,KAAK,MAAM;KACxC;IACF;IACA,IAAI;KACF,IAAI,KAAK,kBAAkB,MAAM,CAAC;IACpC,SAAS,KAAK;KACZ,MAAM,IAAI,gBACR,mBAAmB,KAAK,GAAG,OAAO,8BAA+B,IAAc,SACjF;IACF;GACF;GACA,OAAO;EACT;CACF;AACF;;;;;;;;AASA,IAAa,iBAAb,MAA4B;CAC1B;CAEA,YAAY,UAA4B,yBAAyB,GAAG;EAClE,KAAK,UAAU;CACjB;;;CAIA,MAAM,OAAO,QAAkC;EAC7C,MAAM,KAAK,QAAQ,OAAO,kBAAkB,MAAM,CAAC;CACrD;CAEA,MAAM,MAA4B;EAChC,OAAO,KAAK,QAAQ,KAAK;CAC3B;CAEA,MAAM,MAAM,SAA0B,CAAC,GAAyB;EAE9D,QAAO,MADY,KAAK,QAAQ,KAAK,EAAA,CACzB,QAAQ,MAAM,QAAQ,GAAG,MAAM,CAAC;CAC9C;;;;;;;;;;;;CAaA,MAAM,QACJ,YACA,OAAyD,CAAC,GAC/B;EAQ3B,MAAM,UANJ,MAAM,KAAK,MAAM;GACf;GACA,aAAa,KAAK;GAClB,UAAU,KAAK;EACjB,CAAC,EAAA,CACD,QAAQ,MAAM,CAAC,gBAAgB,CAAC,CAChB,CAAC,CAAC,SAAS,WAAW;GACtC,MAAM,QAAQ,SAAS,MAAM;GAC7B,OAAO,UAAU,KAAA,IAAY,CAAC,IAAI,CAAC;IAAE;IAAQ;GAAM,CAAC;EACtD,CAAC;EACD,IAAI,OAAO,WAAW,GAAG,OAAO;EAChC,IAAI,OAAO,OAAO,EAAE,CAAE;EACtB,IAAI,YAAY,OAAO,EAAE,CAAE;EAC3B,KAAK,IAAI,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK;GACtC,MAAM,IAAI,OAAO,EAAE,CAAE;GACrB,IAAI,IAAI,WAAW;IACjB,OAAO,OAAO,EAAE,CAAE;IAClB,YAAY;GACd;EACF;EACA,OAAO;CACT;;;;;;;;;;CAWA,MAAM,YAAY,YAAoB,YAAkD;EACtF,IAAI,eAAe,YACjB,MAAM,IAAI,gBACR,wDAAwD,WAAW,GACrE;EAEF,MAAM,OAAO,MAAM,KAAK,QAAQ,KAAK;EACrC,IAAI,oBAAoB;EACxB,MAAM,kBAAkB,cAA2C;GACjE,MAAM,oBAAI,IAAI,IAAoB;GAClC,KAAK,MAAM,KAAK,MAAM;IACpB,IAAI,EAAE,gBAAgB,WAAW;IACjC,MAAM,MAAM,EAAE;IACd,IAAI,CAAC,KAAK;IACV,IAAI,gBAAgB,CAAC,GAAG;KACtB;KACA;IACF;IACA,MAAM,IAAI,SAAS,CAAC;IACpB,IAAI,MAAM,KAAA,GAAW;IACrB,MAAM,OAAO,EAAE,IAAI,GAAG;IACtB,IAAI,SAAS,KAAA,KAAa,IAAI,MAAM,EAAE,IAAI,KAAK,CAAC;GAClD;GACA,OAAO;EACT;EACA,MAAM,UAAU,eAAe,UAAU;EACzC,MAAM,UAAU,eAAe,UAAU;EACzC,MAAM,SAAS,CAAC,GAAG,QAAQ,KAAK,CAAC,CAAC,CAAC,QAAQ,QAAQ,QAAQ,IAAI,GAAG,CAAC,CAAC,CAAC,KAAK;EAC1E,IAAI,OAAO,WAAW,GAIpB,MAAM,IAAI,gBACR,oBAAoB,IAChB,gCAAgC,WAAW,SAAS,WAAW,sDAC1B,kBAAkB,gCACvD,gCAAgC,WAAW,SAAS,WAAW,iDACrE;EAEF,IAAI,OAAO;EACX,IAAI,OAAO;EACX,IAAI,QAAQ;EACZ,IAAI,QAAQ;EACZ,IAAI,OAAO;EACX,KAAK,MAAM,OAAO,QAAQ;GACxB,MAAM,KAAK,QAAQ,IAAI,GAAG;GAC1B,MAAM,KAAK,QAAQ,IAAI,GAAG;GAC1B,QAAQ;GACR,QAAQ;GACR,IAAI,KAAK,IAAI;QACR,IAAI,KAAK,IAAI;QACb;EACP;EACA,MAAM,QAAQ,OAAO,OAAO;EAC5B,MAAM,QAAQ,OAAO,OAAO;EAC5B,OAAO;GACL,GAAG;GACH,GAAG;GACH,mBAAmB;GACnB;GACA;GACA,WAAW,QAAQ;GACnB;GACA;GACA;GACA;EACF;CACF;AACF;;;AC9RA,SAASC,OAAK,IAA6B;CACzC,OAAO,GAAG,SAAS,GAAG,QAAQ,GAAG,MAAM,IAAI,GAAG,CAAC,IAAI,GAAG,SAAS;AACjE;;;;;;AAOA,SAAgB,YAAY,SAAsB,MAA4C;CAC5F,MAAM,QAAQ,KAAK,aAAa,MAAiB,EAAE,cAAc,UAAU;CAC3E,MAAM,yBAAS,IAAI,IAAyB;CAC5C,KAAK,MAAM,KAAK,SAAS;EACvB,MAAM,IAAI,MAAM,CAAC;EACjB,MAAM,IAAI,OAAO,IAAI,CAAC;EACtB,IAAI,GAAG,EAAE,KAAK,CAAC;OACV,OAAO,IAAI,GAAG,CAAC,CAAC,CAAC;CACxB;CAEA,MAAM,OAAyB,CAAC,GAAG,OAAO,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,QAAQ;EACtE,MAAM,SAAS,GAAG,QAAQ,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC;EAChD,MAAM,KAAK,OAAO,QAAQ,GAAG,MAAM;EACnC,MAAM,UAAU,GAAG,EAAE,CAAE;EACvB,MAAM,UAAU,SAAS,SAAS;EAClC,MAAM,QAAQ,SAAS;EACvB,MAAM,aAAa,GAAG,KAAK,MAAM,EAAE,OAAO,CAAC,CAAC,OAAO,cAAc;EACjE,OAAO;GACL;GACA,OAAO,WAAW,QAAQ,GAAG,QAAQ,KAAK,UAAU;GACpD,GAAI,UAAU,EAAE,QAAQ,IAAI,CAAC;GAC7B,GAAI,QAAQ,EAAE,MAAM,IAAI,CAAC;GACzB,MAAM;GACN,GAAG,GAAG;GACN,UAAU,GAAG;GACb,cAAc,CAAC,GAAG,OAAO,GAAG,KAAK;GACjC,aAAa,WAAW,WAAW,GAAG,SAASA,OAAK,UAAU,IAAI;GAClE,cAAcA,OAAK,GAAG,KAAK,MAAM,EAAE,WAAW,KAAK,CAAC;GACpD,eAAeA,OAAK,GAAG,KAAK,MAAM,EAAE,WAAW,MAAM,CAAC;GACtD,YAAYA,OAAK,GAAG,KAAK,MAAM,EAAE,MAAM,CAAC;EAC1C;CACF,CAAC;CAED,KAAK,MACF,GAAG,MAAM,EAAE,WAAW,EAAE,aAAa,EAAE,eAAe,aAAa,EAAE,eAAe,SACvF;CACA,KAAK,SAAS,KAAK,MAAM;EACvB,IAAI,OAAO,IAAI;CACjB,CAAC;CACD,OAAO;AACT;AAEA,SAAS,eAAe,OAAiC;CACvD,OAAO,OAAO,UAAU,YAAY,OAAO,SAAS,KAAK;AAC3D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC5BA,SAAS,OAAO,MAAsB;CACpC,OAAO,KAAK,QAAQ,WAAW,EAAE,CAAC,CAAC,QAAQ,aAAa,EAAE;AAC5D;;AAGA,SAAS,WAAW,MAAuB;CACzC,OAAO,KAAK,SAAS,YAAY;AACnC;;;;;AAMA,MAAa,sBAAqC,MAAM,SAAS;CAC/D,MAAM,MAAwB,CAAC;CAC/B,MAAM,QAAQ,KAAK,MAAM,IAAI;CAC7B,KAAK,IAAI,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;EACrC,MAAM,OAAO,MAAM;EACnB,IAAI,WAAW,IAAI,GAAG;EACtB,MAAM,OAAO,OAAO,IAAI;EACxB,IAAI,CAAC,KAAK,KAAK,GAAG;EAClB,IAAI,YAAY,KAAK,IAAI,KAAK,yCAAyC,KAAK,IAAI,GAC9E,IAAI,KAAK;GACP;GACA,MAAM,IAAI;GACV,UAAU,KAAK,KAAK;GACpB,SAAS;EACX,CAAC;CAEL;CACA,OAAO;AACT;;;;;AAMA,MAAa,uBAAsC,MAAM,SAAS;CAChE,MAAM,MAAwB,CAAC;CAC/B,MAAM,QAAQ,KAAK,MAAM,IAAI;CAC7B,KAAK,IAAI,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;EACrC,MAAM,OAAO,MAAM;EACnB,IAAI,WAAW,IAAI,GAAG;EACtB,MAAM,OAAO,OAAO,IAAI;EACxB,IAAI,CAAC,KAAK,KAAK,GAAG;EAClB,IAAI,iCAAiC,KAAK,IAAI,GAC5C,IAAI,KAAK;GACP;GACA,MAAM,IAAI;GACV,UAAU,KAAK,KAAK;GACpB,SAAS;EACX,CAAC;CAEL;CACA,OAAO;AACT;;;;;;;AAQA,MAAa,6BAA4C,MAAM,SAAS;CACtE,MAAM,MAAwB,CAAC;CAC/B,MAAM,QAAQ,KAAK,MAAM,IAAI;CAC7B,KAAK,IAAI,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;EACrC,MAAM,OAAO,MAAM;EACnB,IAAI,WAAW,IAAI,GAAG;EACtB,MAAM,OAAO,OAAO,IAAI;EACxB,IAAI,CAAC,KAAK,KAAK,GAAG;EAClB,IAAI,sDAAsD,KAAK,IAAI,GACjE,IAAI,KAAK;GACP;GACA,MAAM,IAAI;GACV,UAAU,KAAK,KAAK;GACpB,SACE;EACJ,CAAC;CAEL;CACA,OAAO;AACT;;;;;AAMA,MAAa,8BAA6C,MAAM,SAAS;CACvE,MAAM,MAAwB,CAAC;CAC/B,MAAM,QAAQ,KAAK,MAAM,IAAI;CAC7B,KAAK,IAAI,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;EACrC,MAAM,OAAO,MAAM;EACnB,IAAI,WAAW,IAAI,GAAG;EACtB,MAAM,OAAO,OAAO,IAAI;EACxB,IAAI,CAAC,KAAK,KAAK,GAAG;EAClB,IAAI,2CAA2C,KAAK,IAAI,GACtD,IAAI,KAAK;GACP;GACA,MAAM,IAAI;GACV,UAAU,KAAK,KAAK;GACpB,SAAS;EACX,CAAC;CAEL;CACA,OAAO;AACT;;;;;;AAOA,MAAa,wBAAuC,MAAM,SAAS;CACjE,MAAM,MAAwB,CAAC;CAC/B,MAAM,QAAQ,KAAK,MAAM,IAAI;CAC7B,KAAK,IAAI,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;EACrC,MAAM,OAAO,MAAM;EACnB,IAAI,WAAW,IAAI,GAAG;EACtB,MAAM,OAAO,OAAO,IAAI;EACxB,IAAI,CAAC,KAAK,KAAK,GAAG;EAClB,IAAI,8CAA8C,KAAK,IAAI,GACzD,IAAI,KAAK;GACP;GACA,MAAM,IAAI;GACV,UAAU,KAAK,KAAK;GACpB,SAAS;EACX,CAAC;CAEL;CACA,OAAO;AACT;;;;;AAMA,MAAa,kBAAmC;CAC9C;CACA;CACA;CACA;AACF;;AAGA,MAAa,oBAAqC,CAAC,yBAAyB;;;;;AAM5E,SAAS,oBACP,UACA,OACA,YACA,gBACU;CACV,MAAM,UAAoB,CAAC;CAC3B,MAAM,QAAQ,QAAgB;EAC5B,MAAM,MAAM,KAAK,UAAU,GAAG;EAC9B,IAAI,CAAC,WAAW,GAAG,GAAG;EACtB,KAAK,MAAM,SAAS,YAAY,GAAG,GAAG;GACpC,MAAM,MAAM,KAAK,KAAK,KAAK;GAC3B,MAAM,SAAS,KAAK,UAAU,GAAG;GACjC,IAAI;GACJ,IAAI;IACF,KAAK,SAAS,MAAM;GACtB,QAAQ;IACN;GACF;GACA,IAAI,GAAG,YAAY,GAAG;IACpB,IACE,UAAU,kBACV,UAAU,UACV,UAAU,gBACV,MAAM,WAAW,GAAG,GAEpB;IACF,KAAK,GAAG;GACV,OAAO,IAAI,GAAG,OAAO,KAAK,WAAW,KAAK,KAAK,GAAG;IAChD,IAAI,MAAM,SAAS,UAAU,KAAK,MAAM,SAAS,WAAW,KAAK,MAAM,SAAS,UAAU,GACxF;IACF,IAAI;IACJ,IAAI;KACF,OAAO,aAAa,QAAQ,MAAM;IACpC,QAAQ;KACN;IACF;IACA,IAAI,KAAK,SAAS,cAAc,GAAG,QAAQ,KAAK,GAAG;GACrD;EACF;CACF;CACA,KAAK,MAAM,KAAK,OAAO,KAAK,CAAC;CAC7B,OAAO;AACT;;;;;AAMA,SAAgB,oBAAoB,MAAqC;CACvE,MAAM,WAA6B,CAAC;CACpC,MAAM,0BAAU,IAAI,IAAY;CAGhC,KAAK,MAAM,QAAQ,KAAK,WAAW;EACjC,MAAM,MAAM,KAAK,KAAK,UAAU,IAAI;EACpC,IAAI,CAAC,WAAW,GAAG,GAAG;EACtB,MAAM,OAAO,aAAa,KAAK,MAAM;EACrC,KAAK,MAAM,QAAQ,KAAK,SAAS,SAAS,KAAK,GAAG,KAAK,MAAM,IAAI,CAAC;EAClE,QAAQ,IAAI,IAAI;CAClB;CAGA,IAAI,KAAK,YAAY;EACnB,MAAM,YAAY,oBAChB,KAAK,UACL,KAAK,WAAW,OAChB,KAAK,WAAW,YAChB,KAAK,WAAW,cAClB;EACA,KAAK,MAAM,QAAQ,WAAW;GAC5B,IAAI,QAAQ,IAAI,IAAI,GAAG;GACvB,MAAM,MAAM,KAAK,KAAK,UAAU,IAAI;GACpC,IAAI,CAAC,WAAW,GAAG,GAAG;GACtB,MAAM,OAAO,aAAa,KAAK,MAAM;GACrC,KAAK,MAAM,QAAQ,KAAK,WAAW,kBAAkB,SAAS,KAAK,GAAG,KAAK,MAAM,IAAI,CAAC;EACxF;CACF;CAEA,OAAO;AACT;;;;;AAMA,SAAgB,eAAe,UAAoC;CACjE,IAAI,SAAS,WAAW,GAAG,OAAO;CAClC,OAAO;EACL,SAAS,SAAS,OAAO;EACzB;EACA;EACA,GAAG,SAAS,KAAK,MAAM,KAAK,EAAE,KAAK,GAAG,EAAE,KAAK,KAAK,EAAE,QAAQ,QAAQ,EAAE,UAAU;CAClF,CAAC,CAAC,KAAK,IAAI;AACb;;;ACrRA,SAAgB,eAAe,QAAgB,OAAoC,CAAC,GAAW;CAC7F,MAAM,KAAK,oBAAoB,OAAO;CACtC,OAAO;EACL;EACA,MAAM,KAAK;GACT,MAAM,MAAM,IAAI,QAAQ;GACxB,MAAM,QAAQ,KAAK,gBACf,IAAI,SAAS,MAAM,IACnB,IAAI,YAAY,CAAC,CAAC,SAAS,OAAO,YAAY,CAAC;GACnD,OAAO;IACL;IACA,MAAM;IACN,QAAQ,QAAQ,IAAI,OAAO,WAAW,IAAI,OAAO;IACjD,UAAU,QAAQ,QAAQ,KAAK,QAAQ,KAAK,aAAa,IAAI,KAAA;GAC/D;EACF;CACF;AACF;AAEA,SAAgB,YAAY,UAA0B;CACpD,MAAM,KAAK,gBAAgB,SAAS;CACpC,OAAO;EACL;EACA,MAAM,KAAK;GACT,MAAM,MAAM,IAAI,OAAO;GACvB,MAAM,OAAO,IAAI,YAAY,CAAC,CAAC,SAAS,SAAS,YAAY,CAAC;GAC9D,OAAO;IACL;IACA;IACA,QAAQ,OAAO,WAAW,IAAI,KAAK,QAAQ,IAAI,aAAa,SAAS;IACrE,UAAU;GACZ;EACF;CACF;AACF;AAEA,SAAgB,UAAU,UAA2C;CACnE,MAAM,KAAK,cAAc,OAAO,KAAK,QAAQ,CAAC,CAAC,KAAK,GAAG,EAAE;CACzD,OAAO;EACL;EACA,MAAM,KAAK;GACT,MAAM,OAAO,IAAI;GACjB,IAAI,CAACC,WAAS,IAAI,GAChB,OAAO;IAAE;IAAI,MAAM;IAAO,QAAQ;GAA4C;GAEhF,KAAK,MAAM,CAAC,GAAG,MAAM,OAAO,QAAQ,QAAQ,GAAG;IAC7C,IAAI,EAAE,KAAK,OAAO,OAAO;KAAE;KAAI,MAAM;KAAO,QAAQ,QAAQ,EAAE;IAAW;IACzE,MAAM,SAAU,KAAiC;IACjD,IAAI,OAAO,MAAM,YAAY,EAAE,WAAW,KAAK,GAAG;KAChD,MAAM,KAAK,IAAI,OAAO,EAAE,MAAM,CAAC,CAAC;KAChC,IAAI,OAAO,WAAW,YAAY,CAAC,GAAG,KAAK,MAAM,GAC/C,OAAO;MAAE;MAAI,MAAM;MAAO,QAAQ,QAAQ,EAAE,iBAAiB;KAAI;IAErE,OAAO,IAAI,WAAW,GACpB,OAAO;KACL;KACA,MAAM;KACN,QAAQ,QAAQ,EAAE,MAAM,KAAK,UAAU,MAAM,EAAE,aAAa,KAAK,UAAU,CAAC;IAC9E;GAEJ;GACA,OAAO;IAAE;IAAI,MAAM;IAAM,QAAQ;GAAiB;EACpD;CACF;AACF;AAEA,SAAgB,aAAa,SAAyB;CACpD,MAAM,KAAK,SAAS,QAAQ,OAAO;CACnC,OAAO;EACL;EACA,MAAM,KAAK;GAET,MAAM,KADM,IAAI,QAAQ,GAAA,CACV,MAAM,OAAO;GAC3B,OAAO;IACL;IACA,MAAM,MAAM;IACZ,QAAQ,IAAI,YAAY,EAAE,GAAG,KAAK,WAAW,QAAQ,OAAO;IAC5D,UAAU,IAAI;GAChB;EACF;CACF;AACF;;;;;;;AAQA,SAAgB,aAAqB;CACnC,MAAM,KAAK;CACX,MAAM,UAA+C;EACnD;GAAE,MAAM;GAAc,IAAI;EAA4D;EACtF;GAAE,MAAM;GAAa,IAAI;EAA8C;EACvE;GAAE,MAAM;GAAY,IAAI;EAAY;EACpC;GAAE,MAAM;GAAU,IAAI;EAA2B;EACjD;GAAE,MAAM;GAAc,IAAI;EAAyB;EACnD;GAAE,MAAM;GAAc,IAAI;EAAqC;EAC/D;GAAE,MAAM;GAAiB,IAAI;EAA+B;CAC9D;CACA,OAAO;EACL;EACA,MAAM,KAAK;GACT,MAAM,MAAM,IAAI,QAAQ;GACxB,KAAK,MAAM,EAAE,MAAM,QAAQ,SACzB,IAAI,GAAG,KAAK,GAAG,GACb,OAAO;IACL;IACA,MAAM;IACN,QAAQ,cAAc;IACtB,WAAW,IAAI,MAAM,EAAE,KAAK,CAAC,EAAA,CAAG;GAClC;GAGJ,OAAO;IAAE;IAAI,MAAM;IAAM,QAAQ;GAA6B;EAChE;CACF;AACF;;AAYA,SAAgB,gBAAgB,KAAwB,SAAiC;CACvF,MAAM,UAAU,QAAQ,KAAK,MAAM,EAAE,MAAM,GAAG,CAAC;CAC/C,MAAM,YAAY,QAAQ,QAAQ,MAAM,EAAE,IAAI,CAAC,CAAC;CAChD,MAAM,YAAY,QAAQ,SAAS;CACnC,OAAO;EACL;EACA,MAAM,cAAc,KAAK,QAAQ,SAAS;EAC1C;EACA;EACA,OAAO,QAAQ,SAAS,YAAY,QAAQ,SAAS;CACvD;AACF;AAEA,SAAS,QAAQ,KAAa,QAAgB,gBAAgB,OAAe;CAC3E,MAAM,YAAY,gBAAgB,MAAM,IAAI,YAAY;CACxD,MAAM,eAAe,gBAAgB,SAAS,OAAO,YAAY;CACjE,MAAM,MAAM,UAAU,QAAQ,YAAY;CAC1C,IAAI,QAAQ,IAAI,OAAO;CACvB,MAAM,QAAQ,KAAK,IAAI,GAAG,MAAM,EAAE;CAClC,MAAM,MAAM,KAAK,IAAI,IAAI,QAAQ,MAAM,OAAO,SAAS,EAAE;CACzD,QAAQ,QAAQ,IAAI,MAAM,MAAM,IAAI,MAAM,OAAO,GAAG,KAAK,MAAM,IAAI,SAAS,MAAM;AACpF;AAEA,SAASA,WAAS,GAA0C;CAC1D,OAAO,OAAO,MAAM,YAAY,MAAM,QAAQ,CAAC,MAAM,QAAQ,CAAC;AAChE;;;;;;;;;;;;;;;;;;;;;;ACvKA,SAAgB,QAAQ,OAAuB;CAC7C,IAAI,IAAI;CACR,KAAK,IAAI,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;EACrC,KAAK,MAAM,WAAW,CAAC,IAAI;EAC3B,IAAI,KAAK,KAAK,GAAG,QAAU;CAC7B;CACA,OAAO,MAAM;AACf;;AAGA,SAAgB,WAAW,IAAY,MAAsB;CAE3D,OAAO,QAAQ,GAAG,GAAG,IAAI,MAAM,IAAI;AACrC;;;;;;;;AAoCA,SAAgB,iBACd,IACA,UAAuD,CAAC,GAClC;CACtB,MAAM,OAAO,QAAQ,QAAQ;CAC7B,MAAM,kBAAkB,QAAQ,mBAAmB;CACnD,eAAe,eAAe;CAC9B,OAAO,WAAW,IAAI,IAAI,IAAI,kBAAkB,YAAY;AAC9D;;;;;;;;;;;AAYA,SAAgB,iBACd,KACA,UAAmC,CAAC,GAClB;CAClB,MAAM,OAAO,QAAQ,QAAQ;CAC7B,MAAM,kBAAkB,QAAQ,mBAAmB;CACnD,MAAM,aAAa,QAAQ,cAAc;CACzC,MAAM,YAAY,QAAQ,aAAa;CACvC,eAAe,eAAe;CAC9B,IAAI,IAAI,WAAW,GACjB,MAAM,IAAI,gBAAgB,mCAAmC;CAG/D,MAAM,uBAAO,IAAI,IAAY;CAC7B,MAAM,SAAmB,CAAC;CAC1B,MAAM,UAAoB,CAAC;CAC3B,KAAK,MAAM,MAAM,KAAK;EACpB,IAAI,OAAO,OAAO,YAAY,GAAG,WAAW,GAC1C,MAAM,IAAI,gBACR,wDAAwD,KAAK,UAAU,EAAE,GAC3E;EAEF,IAAI,KAAK,IAAI,EAAE,GACb,MAAM,IAAI,gBACR,mCAAmC,GAAG,8CACxC;EAEF,KAAK,IAAI,EAAE;EACX,IAAI,WAAW,IAAI,IAAI,IAAI,iBAAiB,QAAQ,KAAK,EAAE;OACtD,OAAO,KAAK,EAAE;CACrB;CAEA,IAAI,QAAQ,SAAS,YACnB,MAAM,IAAI,gBACR,qCAAqC,QAAQ,OAAO,6BAA6B,WAAW,MACpF,IAAI,OAAO,oBAAoB,gBAAgB,yCACzD;CAEF,IAAI,OAAO,SAAS,WAClB,MAAM,IAAI,gBACR,oCAAoC,OAAO,OAAO,6BAA6B,UAAU,MACjF,IAAI,OAAO,oBAAoB,gBAAgB,EACzD;CAGF,OAAO;EAAE;EAAQ;EAAS;EAAM;CAAgB;AAClD;AAEA,SAAS,eAAe,GAAiB;CACvC,IAAI,CAAC,OAAO,SAAS,CAAC,KAAK,KAAK,KAAK,KAAK,GACxC,MAAM,IAAI,gBAAgB,4DAA4D,GAAG;AAE7F;;;;;;;;;;;;;;;;;;;AClEA,SAAS,OAAO,IAAsB;CACpC,IAAI,GAAG,WAAW,GAAG,OAAO;CAC5B,MAAM,SAAS,CAAC,GAAG,EAAE,CAAC,CAAC,MAAM,GAAG,MAAM,IAAI,CAAC;CAC3C,MAAM,MAAM,KAAK,MAAM,OAAO,SAAS,CAAC;CACxC,OAAO,OAAO,SAAS,MAAM,KAAK,OAAO,MAAM,KAAM,OAAO,QAAS,IAAI,OAAO;AAClF;;AAOA,SAAS,sBAAsB,MAAuD;CACpF,MAAM,uBAAO,IAAI,IAA8C;CAC/D,KAAK,MAAM,OAAO,MAAM;EACtB,MAAM,OAAO,IAAI,QAAQ,aAAa;EACtC,IAAI,CAAC,MAAM;EACX,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,IAAI,GAAG;GAC/C,IAAI,CAAC,OAAO,SAAS,KAAK,GAAG;GAC7B,MAAM,MAAM,KAAK,IAAI,GAAG,KAAK;IAAE,OAAO;IAAG,OAAO;GAAE;GAClD,IAAI,SAAS;GACb,IAAI,SAAS;GACb,KAAK,IAAI,KAAK,GAAG;EACnB;CACF;CACA,IAAI,KAAK,SAAS,GAAG,OAAO,KAAA;CAC5B,MAAM,MAA8B,CAAC;CACrC,KAAK,MAAM,CAAC,KAAK,QAAQ,MAAM,IAAI,OAAO,IAAI,QAAQ,IAAI;CAC1D,OAAO;AACT;;;;;;;AAQA,SAAgB,WAAW,MAAmB,MAA6C;CACzF,MAAM,cAAc,iBAAiB,KAAK,OAAO;CACjD,MAAM,QAAQ,oBAAoB,KAAK,OAAO;CAC9C,MAAM,YAAY,KAAK,8BAAa,IAAI,KAAK,EAAA,CAAE,YAAY;CAE3D,MAAM,6BAAa,IAAI,IAAyB;CAChD,KAAK,MAAM,OAAO,MAAM;EACtB,MAAM,aAAa,IAAI;EACvB,IAAI,CAAC,YAAY;EACjB,MAAM,SAAS,WAAW,IAAI,UAAU;EACxC,IAAI,QAAQ,OAAO,KAAK,GAAG;OACtB,WAAW,IAAI,YAAY,CAAC,GAAG,CAAC;CACvC;CAEA,MAAM,QAA4B,CAAC;CACnC,KAAK,MAAM,CAAC,YAAY,iBAAiB,YAAY;EACnD,MAAM,SAAS,aACZ,KAAK,SAAS;GAAE;GAAK,OAAO,aAAa,GAAG;EAAE,EAAE,CAAC,CACjD,QAAQ,MAA8C,EAAE,UAAU,KAAA,CAAS;EAC9E,IAAI,OAAO,WAAW,GAAG;EACzB,MAAM,SAAS,OAAO,KAAK,MAAM,EAAE,KAAK;EACxC,MAAM,QAAwB;GAC5B,WAAW,KAAK;GAChB;GACA;GACA,WAAW,OAAO,MAAM;GACxB,QAAQ,OAAO,KAAK,MAAM,EAAE,IAAI,KAAK;EACvC;EACA,MAAM,eAAe,sBAAsB,YAAY;EACvD,IAAI,cAAc,MAAM,eAAe;EACvC,MAAM,KAAK;GACT;GACA;GACA;GACA,SAAS,KAAK;GACd;EACF,CAAC;CACH;CACA,OAAO;AACT;;AAKA,SAAgB,gBAAgB,SAAiB,OAAiC;CAChF,IAAI,MAAM,WAAW,GAAG;CACxB,UAAU,QAAQ,OAAO,GAAG,EAAE,WAAW,KAAK,CAAC;CAC/C,eAAe,SAAS,GAAG,MAAM,KAAK,SAAS,KAAK,UAAU,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,GAAG;AACrF;;AAGA,SAAgB,sBACd,SACA,MACA,MACoB;CACpB,MAAM,QAAQ,WAAW,MAAM,IAAI;CACnC,gBAAgB,SAAS,KAAK;CAC9B,OAAO;AACT;;;;;;AAOA,SAAgB,cAAc,SAA4B;CACxD,IAAI,CAAC,WAAW,OAAO,GAAG,OAAO;EAAE,OAAO,CAAC;EAAG,UAAU,CAAC;CAAE;CAC3D,MAAM,wBAAQ,IAAI,IAA2B;CAC7C,MAAM,WAAyC,CAAC;CAEhD,KAAK,MAAM,OAAO,aAAa,SAAS,MAAM,CAAC,CAAC,MAAM,IAAI,GAAG;EAC3D,MAAM,OAAO,IAAI,KAAK;EACtB,IAAI,CAAC,MAAM;EACX,IAAI;EACJ,IAAI;GACF,SAAS,KAAK,MAAM,IAAI;EAC1B,QAAQ;GACN;EACF;EACA,IAAI,CAAC,QAAQ,cAAc,CAAC,OAAO,eAAe,CAAC,OAAO,OAAO;EACjE,MAAM,MAAM,GAAG,OAAO,WAAW,IAAI,OAAO;EAC5C,IAAI,OAAO,MAAM,IAAI,GAAG;EACxB,IAAI,CAAC,MAAM;GACT,OAAO;IACL,YAAY,OAAO;IACnB,aAAa,OAAO;IACpB,OAAO,OAAO;IACd,UAAU,CAAC;GACb;GACA,MAAM,IAAI,KAAK,IAAI;EACrB;EACA,KAAK,SAAS,KAAK,OAAO,KAAK;EAC/B,IAAI,OAAO,SAAS,SAAS,OAAO,eAAe,OAAO;CAC5D;CAEA,KAAK,MAAM,QAAQ,MAAM,OAAO,GAC9B,KAAK,SAAS,MAAM,GAAG,MAAM,EAAE,UAAU,cAAc,EAAE,SAAS,CAAC;CAErE,OAAO;EAAE,OAAO,CAAC,GAAG,MAAM,OAAO,CAAC;EAAG;CAAS;AAChD;;;;;;;AAkDA,SAAgB,cACd,WACA,OAA6B,CAAC,GACf;CACf,MAAM,YAAY,KAAK,aAAa;CACpC,MAAM,OAAO,KAAK,QAAQ;CAC1B,MAAM,WAAW,KAAK,YAAY;CAElC,MAAM,QAA6B,CAAC;CACpC,KAAK,MAAM,QAAQ,UAAU,OAAO;EAClC,MAAM,WAAW,KAAK;EACtB,IAAI,SAAS,WAAW,GAAG;EAC3B,MAAM,UAAU,SAAS,SAAS,SAAS;EAE3C,MAAM,WAAW,KAAK,iBAClB,CAAC,GAAG,QAAQ,CAAC,CAAC,QAAQ,CAAC,CAAC,MAAM,MAAM,EAAE,cAAc,KAAK,kBAAkB,MAAM,OAAO,IACxF,SAAS,SAAS,SAAS;EAE/B,MAAM,OAGF;GACF,YAAY,KAAK;GACjB,aAAa,KAAK;GAClB,OAAO,KAAK;GACZ,SAAS,QAAQ;GACjB,eAAe,QAAQ;EACzB;EAEA,IAAI,CAAC,UAAU;GACb,MAAM,KAAK;IACT,GAAG;IACH,SAAS;IACT,UAAU;IACV,OAAO;IACP,SAAS;IACT,QAAQ;IACR,gBAAgB;GAClB,CAAC;GACD;EACF;EAEA,MAAM,QAAQ,QAAQ,YAAY,SAAS;EAC3C,MAAM,UAAU,SAAS,OAAO,UAAU,KAAK,QAAQ,OAAO,UAAU;EACxE,IAAI,IAAmB;EACvB,IAAI,IAAmB;EACvB,IAAI;EAEJ,IAAI,SAAS;GACX,IAAI,QAAQ,SAAS,QAAQ,QAAQ,MAAM;GAC3C,MAAM,IAAI,YAAY,SAAS,QAAQ,QAAQ,MAAM;GACrD,IAAI,OAAO,SAAS,EAAE,CAAC,IAAI,EAAE,IAAI;GAMjC,WAFqB,MAAM,QAAQ,KAAK,IAAI,CAAC,KAAK,cACd,MAAM,QAAQ,KAAK,OAC9B,QAAQ,IAAI,aAAa,cAAe;EACnE,OAEE,UAAU,KAAK,IAAI,KAAK,KAAK,WAAY,QAAQ,IAAI,aAAa,cAAe;EAGnF,MAAM,KAAK;GACT,GAAG;GACH;GACA,UAAU,SAAS;GACnB;GACA,SAAS;GACT,QAAQ;GACR,gBAAgB,SAAS;EAC3B,CAAC;CACH;CAEA,MAAM,UAAU;EAAE,UAAU;EAAG,WAAW;EAAG,MAAM;EAAG,KAAK;CAAE;CAC7D,KAAK,MAAM,QAAQ,OAAO,QAAQ,KAAK,YAAY;CACnD,OAAO;EAAE;EAAO;CAAQ;AAC1B;;;;;;AAOA,SAAgB,oBAAoB,MAA6B;CAC/D,MAAM,QAAkB,CAAC;CACzB,MAAM,EAAE,YAAY;CACpB,MAAM,KACJ,cAAc,QAAQ,UAAU,eAAe,QAAQ,SAAS,cAC3D,QAAQ,KAAK,UAAU,QAAQ,IAAI,KAC1C;CAEA,MAAM,OAAO,MAAc,EAAE,QAAQ,CAAC;CACtC,MAAM,aAAa,KAAK,MACrB,QAAQ,MAAM,EAAE,YAAY,eAAe,EAAE,YAAY,UAAU,CAAC,CACpE,MAAM,GAAG,MAAM;EAEd,IAAI,EAAE,YAAY,EAAE,SAAS,OAAO,EAAE,YAAY,cAAc,KAAK;EACrE,OAAO,KAAK,IAAI,EAAE,SAAS,CAAC,IAAI,KAAK,IAAI,EAAE,SAAS,CAAC;CACvD,CAAC;CAEH,KAAK,MAAM,QAAQ,YAAY;EAC7B,MAAM,OAAO,KAAK,YAAY,cAAc,cAAc;EAC1D,MAAM,WACJ,KAAK,UAAU,OAAQ,KAAK,SAAS,IAAI,IAAI,IAAI,KAAK,KAAK,MAAM,IAAI,KAAK,KAAK,IAAK;EACtF,MAAM,OACJ,KAAK,YAAY,OACb,OAAO,KAAK,QAAQ,QAAQ,CAAC,IAAI,KAAK,WAAW,OAAO,OAAO,KAAK,OAAO,QAAQ,CAAC,MAAM,GAAG,KAC7F;EACN,MAAM,KACJ,KAAK,KAAK,IAAI,KAAK,WAAW,KAAK,KAAK,MAAM,KAAK,KAAK,YAAY,MAAM,GAAG,CAAC,EAAE,IAC3E,IAAI,KAAK,YAAY,CAAC,EAAE,KAAK,IAAI,KAAK,OAAO,EAAE,IAAI,WAAW,MACrE;CACF;CAEA,OAAO,MAAM,KAAK,IAAI;AACxB;;;;;;;AC3UA,SAAgB,UAAU,SAAiC,MAAwB;CACjF,MAAM,UAA4B,KAAK,KAAK,QAAQ,MAAM,KAAK,QAAQ,IAAI,OAAO,CAAC;CACnF,MAAM,mBAAmB,QAAQ,QAAQ,MAAM,CAAC,EAAE,UAAU,EAAE,IAAI,aAAa,UAAU;CACzF,MAAM,WAAW,QAAQ,QAAQ,MAAM,CAAC,EAAE,UAAU,EAAE,IAAI,aAAa,SAAS;CAChF,OAAO;EAAE;EAAS,gBAAgB,iBAAiB,WAAW;EAAG;EAAkB;CAAS;AAC9F;AAEA,SAAS,MAAM,KAAU,QAA4C;CACnE,IAAI,WAAW,KAAA,KAAa,CAAC,OAAO,SAAS,MAAM,GACjD,OAAO;EACL;EACA;EACA,QAAQ;EACR,QAAQ;EACR,QAAQ,WAAW,IAAI,OAAO;CAChC;CAEF,IAAI,IAAI,eAAe,OAAO;EAC5B,MAAM,SAAS,UAAU,IAAI;EAE7B,OAAO;GACL;GACA;GACA;GACA,QALa,IAAI,cAAc,IAAK,WAAW,IAAI,WAAW,IAAK,IAAI,YAAY;GAMnF,QAAQ,GAAG,OAAO,KAAK,IAAI,UAAU,IAAI,SAAS,OAAO;EAC3D;CACF;CACA,MAAM,SAAS,UAAU,IAAI;CAE7B,OAAO;EACL;EACA;EACA;EACA,QALa,WAAW,IAAI,IAAI,SAAS,IAAI;EAM7C,QAAQ,GAAG,OAAO,KAAK,IAAI,UAAU,IAAI,SAAS,OAAO;CAC3D;AACF;;AAGA,MAAa,qBAA4B;CACvC;EACE,IAAI;EACJ,aAAa;EACb,QAAQ;EACR,YAAY;EACZ,WAAW;EACX,UAAU;CACZ;CACA;EACE,IAAI;EACJ,aAAa;EACb,QAAQ;EACR,YAAY;EACZ,WAAW;EACX,UAAU;CACZ;CACA;EACE,IAAI;EACJ,aAAa;EACb,QAAQ;EACR,YAAY;EACZ,WAAW;EACX,UAAU;CACZ;CACA;EACE,IAAI;EACJ,aAAa;EACb,QAAQ;EACR,YAAY;EACZ,WAAW;EACX,UAAU;CACZ;CACA;EACE,IAAI;EACJ,aAAa;EACb,QAAQ;EACR,YAAY;EACZ,WAAW;EACX,UAAU;CACZ;AACF;;;ACxFA,SAAgB,gBACd,MACA,QACA,UAAsC,CAAC,GACrB;CAClB,IAAI,OAAO,WAAW,GACpB,MAAM,IAAI,MAAM,4CAA4C;CAE9D,MAAM,gBAAgB,QAAQ,iBAAiB;CAC/C,MAAM,UAAmC,OAAO,KAAK,MAAM;EACzD,MAAM,MAAM,EAAE,MAAM,IAAI;EACxB,MAAM,UAAU,OAAO,SAAS,GAAG,IAAI,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,GAAG,CAAC,IAAI;EACvE,OAAO;GAAE,IAAI,EAAE;GAAI,aAAa,EAAE;GAAa,OAAO;GAAS,MAAM,WAAW;EAAc;CAChG,CAAC;CAED,OAAO;EAAE;EAAS,cADG,QAAQ,QAAQ,GAAG,MAAM,IAAI,EAAE,OAAO,CAAC,IAAI,QAAQ;EACxC,MAAM,QAAQ,OAAO,MAAM,EAAE,IAAI;CAAE;AACrE;;AAGA,SAAgB,aACd,KACoB;CACpB,OAAO;EACL,IAAI,aAAa,IAAI;EACrB,aAAa,IAAI,IAAI;EACrB,QAAQ,EAAE,QAAQ,YAAa,OAAO,SAAS,KAAA,KAAa,OAAO,SAAS,MAAM,OAAO,IAAI;CAC/F;AACF;;AAGA,SAAgB,oBACd,KACA,WAAW,GACS;CACpB,OAAO;EACL,IAAI,wBAAwB,IAAI;EAChC,aAAa,IAAI,IAAI,aAAa,SAAS;EAC3C,QAAQ,EAAE,QAAQ,YAAY;GAC5B,MAAM,IAAI,OAAO;GACjB,MAAM,IAAI,MAAM;GAChB,IAAI,CAAC,MAAM,QAAQ,CAAC,KAAK,CAAC,MAAM,QAAQ,CAAC,GAAG,OAAO;GACnD,IAAI,EAAE,WAAW,GAAG,OAAO,EAAE,WAAW,IAAI,IAAI;GAChD,OAAO,KAAK,IAAI,GAAG,EAAE,UAAU,EAAE,SAAS,SAAS;EACrD;CACF;AACF;;AAGA,SAAgB,eACd,KACA,aACoB;CACpB,OAAO;EACL,IAAI,mBAAmB,IAAI;EAC3B,aAAa,IAAI,IAAI,qBAAqB,YAAY,KAAK,GAAG;EAC9D,QAAQ,EAAE,QAAQ,YAAY;GAC5B,MAAM,KAAK,YAAY,QAAQ,OAAO,OAAO,IAAI,CAAC;GAClD,MAAM,KAAK,YAAY,QAAQ,OAAO,MAAM,IAAI,CAAC;GACjD,IAAI,OAAO,MAAM,OAAO,IAAI,OAAO;GACnC,OAAO,MAAM,KAAK,IAAI;EACxB;CACF;AACF;;;;;;;;;ACJA,MAAa,0BAGT;CACF,SAAS;EACP,aAAa;EACb,aAAa;CACf;CACA,MAAM;EACJ,aAAa;EACb,aACE;CACJ;CACA,QAAQ;EACN,aAAa;EACb,aAAa;CACf;CACA,SAAS;EACP,aAAa;EACb,aAAa;CACf;CACA,OAAO;EACL,aAAa;EACb,aAAa;CACf;CACA,WAAW;EACT,aAAa;EACb,aAAa;CACf;CACA,gBAAgB;EACd,aAAa;EACb,aACE;CACJ;CACA,WAAW;EACT,aAAa;EACb,aACE;CACJ;CACA,aAAa;EACX,aAAa;EACb,aACE;CACJ;CACA,WAAW;EACT,aAAa;EACb,aACE;CACJ;AACF;;AAGA,MAAa,gCAAgC,OAAO,KAClD,uBACF;;;;ACNA,IAAa,2BAAb,cAA8C,MAAM;CAClD;CAeA,YAAY,MAAwC,SAAiB;EACnE,MAAM,OAAO;EACb,KAAK,OAAO;EACZ,KAAK,OAAO;CACd;AACF;;;;;;;;AASA,SAAgB,uBAAuB,MAAwD;CAC7F,IAAI,KAAK,SAAS,GAChB,MAAM,IAAI,yBACR,aACA,uDAAuD,OAAO,KAAK,IAAI,GACzE;CAEF,IAAI,KAAK,UAAU,MACjB,MAAM,IAAI,yBACR,aACA,gGACF;CAEF,IAAI,OAAO,KAAK,aAAa,YAAY,KAAK,SAAS,KAAK,MAAM,IAChE,MAAM,IAAI,yBACR,eACA,0DACF;CAEF,IAAI,CAAC,8BAA8B,SAAS,KAAK,MAAM,GACrD,MAAM,IAAI,yBACR,kBACA,gBAAgB,OAAO,KAAK,MAAM,EAAE,wCACtC;CAEF,OAAO,OAAO,OAAO,EAAE,MAAM,OAAO,OAAO,EAAE,GAAG,KAAK,CAAC,EAAE,CAAC;AAC3D;;;;;;;;;;;;;AAcA,SAAgB,uBACd,YACA,MACA,YACmB;CACnB,WAAW,IAAI;CACf,iBAAiB,UAAU;CAC3B,OAAO,OAAO,OAAO;EACnB,MAAM,WAAW;EACjB,MAAM,OAAO,OAAO,CAAC,OAAO,OAAO,EAAE,GAAG,KAAK,GAAG,CAAC,GAAG,OAAO,OAAO,EAAE,GAAG,KAAK,GAAG,CAAC,CAAC,CAAU;EAC3F,YAAY,OAAO,OAAO,EAAE,GAAG,WAAW,CAAC;CAC7C,CAAC;AACH;;;;;;;;;;;;;;AAeA,eAAsB,oBACpB,YACA,MACA,SAC4B;CAC5B,WAAW,IAAI;CACf,IAAI,QAAQ,aAAa,WAAW,KAAK,QACvC,MAAM,IAAI,yBACR,6BACA,mBAAmB,WAAW,KAAK,OAAO,oCAAoC,QAAQ,SAAS,EACjG;CAEF,MAAM,UAAU,MAAM,QAAQ,MAAM;EAClC,UAAU,WAAW,KAAK;EAC1B,YAAY,CAAC,KAAK,EAAE,CAAC,WAAW,KAAK,EAAE,CAAC,SAAS;CACnD,CAAC;CACD,IAAI,CAAC,QAAQ,WACX,OAAO,uBAAuB,YAAY,MAAM;EAC9C,QAAQ;EACR,kBAAkB,QAAQ;EAC1B,SAAS,QAAQ;CACnB,CAAC;CAEH,MAAM,EAAE,QAAQ,mBAAmB,mBAAmB,QAAQ;CAC9D,OAAO,uBAAuB,YAAY,MAAM;EAC9C;EACA,GAAI,sBAAsB,KAAA,IAAY,CAAC,IAAI,EAAE,kBAAkB;EAC/D,SAAS,QAAQ;EACjB;CACF,CAAC;AACH;AAEA,SAAS,WAAW,MAAuD;CACzE,IAAI,KAAK,WAAW,GAClB,MAAM,IAAI,yBACR,aACA,wDAAwD,KAAK,QAC/D;CAEF,IAAI,KAAK,EAAE,CAAC,UAAU,KAAK,EAAE,CAAC,OAC5B,MAAM,IAAI,yBACR,oBACA,4BAA4B,KAAK,EAAE,CAAC,MAAM,6CAC5C;CAEF,KAAK,MAAM,OAAO,MAAM;EACtB,IAAI,IAAI,UAAU,KAAK,MAAM,IAC3B,MAAM,IAAI,yBACR,eACA,QAAQ,IAAI,MAAM,+BACpB;EAEF,IAAI,IAAI,YAAY,KAAK,MAAM,IAC7B,MAAM,IAAI,yBACR,eACA,QAAQ,IAAI,MAAM,oCACpB;EAEF,IAAI,IAAI,UAAU,gBAAgB,MAChC,MAAM,IAAI,yBACR,iBACA,QAAQ,IAAI,MAAM,2FACpB;EAEF,IAAI,IAAI,UAAU,cAAc,MAC9B,MAAM,IAAI,yBACR,mBACA,QAAQ,IAAI,MAAM,2DACpB;CAEJ;AACF;AAEA,SAAS,iBAAiB,YAAyC;CACjE,MAAM,EAAE,QAAQ,mBAAmB,kBAAkB,mBAAmB;CACxE,IAAI,WAAW,mCAAmC;EAChD,IAAI,OAAO,sBAAsB,YAAY,kBAAkB,KAAK,MAAM,IACxE,MAAM,IAAI,yBACR,mBACA,oGACF;EAEF,IAAI,OAAO,mBAAmB,YAAY,eAAe,KAAK,MAAM,IAClE,MAAM,IAAI,yBACR,oBACA,sDACF;EAEF;CACF;CACA,IAAI,WAAW,UAAU;EACvB,IAAI,sBAAsB,KAAA,GACxB,MAAM,IAAI,yBACR,qBACA,oFACF;EAEF,IAAI,OAAO,mBAAmB,YAAY,eAAe,KAAK,MAAM,IAClE,MAAM,IAAI,yBACR,oBACA,qDACF;EAEF;CACF;CAEA,IAAI,sBAAsB,KAAA,GACxB,MAAM,IAAI,yBACR,yBACA,gGACF;CAEF,IAAI,OAAO,qBAAqB,YAAY,iBAAiB,KAAK,MAAM,IACtE,MAAM,IAAI,yBACR,kBACA,2FACF;AAEJ;;;;AC9TA,MAAa,YAA+B;CAC1C;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF;;AAaA,MAAa,wBAAsD;CACjE;CACA;CACA;CACA;AACF;;;ACsEA,SAAS,kBAAkB,GAAkC;CAC3D,OACE,OAAO,MAAM,YACb,MAAM,QACN,OAAQ,EAAsB,WAAW,YACzC,OAAQ,EAAsB,UAAU;AAE5C;AAEA,SAAS,UAAU,QAA4B,SAA+B;CAC5E,IAAI,OAAO,WAAW,UAAU,OAAO;CACvC,IAAI,OAAO,YAAY,UAAU,OAAO,WAAW;CACnD,IAAI,mBAAmB,QAAQ,OAAO,QAAQ,KAAK,MAAM;CACzD,OAAO,IAAI,OAAO,QAAQ,QAAQ,QAAQ,KAAK,CAAC,CAAC,KAAK,MAAM;AAC9D;AAEA,SAAS,gBAAgB,MAAwC;CAC/D,IAAI,OAAO,KAAK,aAAa,UAAU,OAAO,KAAK;CACnD,MAAM,WAAW,KAAK,aAAa,gBAAgB,KAAK,YAAY;CACpE,IAAI,OAAO,aAAa,UAAU,OAAO;CACzC,IAAI,KAAK,SAAS,UAAU,OAAO,KAAK,SAAS,UAAU,OAAO,KAAK;AAEzE;AAEA,SAAS,gBAAgB,OAAgB,OAA+C;CACtF,IAAI,UAAU,QAAQ,OAAO,UAAU,UACrC,MAAM,IAAI,gBAAgB,GAAG,MAAM,qCAAqC,OAAO,OAAO;CAExF,MAAM,IAAI;CACV,KAAK,MAAM,SAAS,CAAC,QAAQ,MAAM,GAAY;EAC7C,MAAM,IAAI,EAAE;EACZ,IACE,MAAM,KAAA,KACN,OAAO,MAAM,YACb,EAAE,aAAa,WACf,CAAC,kBAAkB,CAAC,GAEpB,MAAM,IAAI,gBAAgB,GAAG,MAAM,KAAK,MAAM,4CAA4C;CAE9F;CACA,IACE,EAAE,SAAS,KAAA,MACV,EAAE,SAAS,QAAQ,OAAO,EAAE,SAAS,YAAY,MAAM,QAAQ,EAAE,IAAI,IAEtE,MAAM,IAAI,gBAAgB,GAAG,MAAM,gCAAgC;CAErE,IAAI,EAAE,kBAAkB,OAAO,EAAE,WAAW,YAC1C,MAAM,IAAI,gBACR,GAAG,MAAM,yJAEX;CAEF,MAAM,UAAU,EAAE,SAAS,KAAA,KAAa,OAAO,KAAK,EAAE,IAAI,CAAC,CAAC,SAAS;CACrE,IAAI,EAAE,SAAS,KAAA,KAAa,EAAE,SAAS,KAAA,KAAa,CAAC,WAAW,OAAO,EAAE,WAAW,YAClF,MAAM,IAAI,gBACR,GAAG,MAAM,+EACX;AAEJ;;AAGA,SAAgB,UAAU,MAAoB,WAAmC;CAC/E,gBAAgB,WAAW,WAAW;CACtC,IAAI,UAAU,SAAS,KAAA,KAAa,CAAC,UAAU,KAAK,MAAM,UAAU,IAAI,GAAG,OAAO;CAClF,IAAI,UAAU,SAAS,KAAA,KAAa,CAAC,UAAU,gBAAgB,IAAI,GAAG,UAAU,IAAI,GAClF,OAAO;CACT,IAAI,UAAU,SAAS,KAAA,GACrB,KAAK,MAAM,CAAC,KAAK,aAAa,OAAO,QAAQ,UAAU,IAAI,GAAG;EAC5D,MAAM,SAAS,KAAK,aAAa;EACjC,IAAI,oBAAoB,UAAU,kBAAkB,QAAQ,GACtD;OAAA,CAAC,UAAU,OAAO,WAAW,WAAW,SAAS,KAAA,GAAW,QAAuB,GACrF,OAAO;EAAA,OAEJ,IAAI,WAAW,UACpB,OAAO;CAEX;CAEF,IAAI,UAAU,WAAW,KAAA,KAAa,CAAC,UAAU,OAAO,IAAI,GAAG,OAAO;CACtE,OAAO;AACT;AAIA,SAAS,gBAAgB,GAAwB;CAC/C,IAAI,OAAO,MAAM,UAAU,OAAO;CAClC,IAAI,aAAa,QAAQ,OAAO,IAAI,EAAE,OAAO,GAAG,EAAE;CAClD,OAAO,IAAI,EAAE,OAAO,GAAG,EAAE;AAC3B;AAEA,SAAS,kBAAkB,GAA0B;CACnD,MAAM,QAAkB,CAAC;CACzB,IAAI,EAAE,SAAS,KAAA,GAAW,MAAM,KAAK,QAAQ,gBAAgB,EAAE,IAAI,GAAG;CACtE,IAAI,EAAE,SAAS,KAAA,GAAW,MAAM,KAAK,QAAQ,gBAAgB,EAAE,IAAI,GAAG;CACtE,IAAI,EAAE,SAAS,KAAA,GACb,KAAK,MAAM,CAAC,GAAG,MAAM,OAAO,QAAQ,EAAE,IAAI,GACxC,MAAM,KACJ,QAAQ,EAAE,GAAG,aAAa,UAAU,kBAAkB,CAAC,IAAI,gBAAgB,CAAgB,IAAI,KAAK,UAAU,CAAC,GACjH;CAGJ,IAAI,OAAO,EAAE,WAAW,YAAY,MAAM,KAAK,UAAU,EAAE,OAAO,QAAQ,MAAM;CAChF,OAAO,MAAM,KAAK,GAAG;AACvB;AAEA,SAAS,iBAAiB,GAA0C;CAClE,OAAO,aAAa,SAAS;EAAE,QAAQ,EAAE;EAAQ,OAAO,EAAE;CAAM,IAAI;AACtE;AAEA,SAAS,mBAAmB,GAAkB,OAA8B;CAC1E,gBAAgB,GAAG,KAAK;CACxB,MAAM,MAAqB,CAAC;CAC5B,IAAI,EAAE,SAAS,KAAA,GAAW,IAAI,OAAO,iBAAiB,EAAE,IAAI;CAC5D,IAAI,EAAE,SAAS,KAAA,GAAW,IAAI,OAAO,iBAAiB,EAAE,IAAI;CAC5D,IAAI,EAAE,SAAS,KAAA,GACb,IAAI,OAAO,OAAO,YAChB,OAAO,QAAQ,EAAE,IAAI,CAAC,CAAC,KAAK,CAAC,GAAG,OAAO,CAAC,GAAG,aAAa,SAAS,iBAAiB,CAAC,IAAI,CAAC,CAAC,CAC3F;CAEF,IAAI,OAAO,EAAE,WAAW,YAAY;EAClC,IAAI,SAAS,EAAE;EACf,IAAI,iBAAiB;CACvB;CACA,OAAO;AACT;AAEA,IAAa,uBAAb,MAAkC;CAGH;CAF7B,QAAyC,CAAC;CAE1C,YAAY,MAA+B;EAAd,KAAA,OAAA;CAAe;;CAG5C,OAAO,GAAkB,OAAsB;EAC7C,MAAM,KAAK,mBAAmB,GAAG,kBAAkB,KAAK,KAAK,UAAU;EACvE,OAAO,KAAK,IAAI;GAAE,MAAM;GAAU,OAAO,SAAS,UAAU,kBAAkB,EAAE,EAAE;GAAI,GAAG;EAAG,CAAC;CAC/F;;CAGA,MAAM,GAAkB,OAAsB;EAC5C,MAAM,KAAK,mBAAmB,GAAG,kBAAkB,KAAK,KAAK,SAAS;EACtE,OAAO,KAAK,IAAI;GAAE,MAAM;GAAS,OAAO,SAAS,SAAS,kBAAkB,EAAE,EAAE;GAAI,GAAG;EAAG,CAAC;CAC7F;;CAGA,WAAW,GAAkB,OAAsB;EACjD,MAAM,KAAK,mBAAmB,GAAG,kBAAkB,KAAK,KAAK,cAAc;EAC3E,OAAO,KAAK,IAAI;GACd,MAAM;GACN,OAAO,SAAS,cAAc,kBAAkB,EAAE,EAAE;GACpD,GAAG;EACL,CAAC;CACH;;CAGA,SAAS,GAAkB,GAAkB,OAAsB;EACjE,MAAM,KAAK,mBAAmB,GAAG,kBAAkB,KAAK,KAAK,gBAAgB;EAC7E,MAAM,KAAK,mBAAmB,GAAG,kBAAkB,KAAK,KAAK,gBAAgB;EAC7E,OAAO,KAAK,IAAI;GACd,MAAM;GACN,OAAO,SAAS,YAAY,kBAAkB,EAAE,EAAE,MAAM,kBAAkB,EAAE,EAAE;GAC9E,GAAG;GACH,GAAG;EACL,CAAC;CACH;;CAGA,YAAY,GAAkB,OAAsB,OAAsB;EACxE,MAAM,KAAK,mBAAmB,GAAG,kBAAkB,KAAK,KAAK,mBAAmB;EAChF,MAAM,SAAS,mBAAmB,OAAO,kBAAkB,KAAK,KAAK,uBAAuB;EAC5F,OAAO,KAAK,IAAI;GACd,MAAM;GACN,OAAO,SAAS,eAAe,kBAAkB,EAAE,EAAE,UAAU,kBAAkB,MAAM,EAAE;GACzF,GAAG;GACH,OAAO;EACT,CAAC;CACH;CAEA,QAAuB;EACrB,IAAI,KAAK,MAAM,WAAW,GACxB,MAAM,IAAI,gBACR,kBAAkB,KAAK,KAAK,8DAC9B;EAEF,OAAO;GAAE,MAAM,KAAK;GAAM,OAAO,CAAC,GAAG,KAAK,KAAK;EAAE;CACnD;CAEA,IAAY,MAA0B;EAGpC,IAAI,QAAQ,KAAK;EACjB,IAAI,IAAI;EACR,OAAO,KAAK,MAAM,MAAM,MAAM,EAAE,UAAU,KAAK,GAAG;GAChD,QAAQ,GAAG,KAAK,MAAM,IAAI;GAC1B,KAAK;EACP;EACA,KAAK,MAAM,KAAK;GAAE,GAAG;GAAM;EAAM,CAAC;EAClC,OAAO;CACT;AACF;AAEA,SAAgB,cAAc,MAAoC;CAChE,IAAI,OAAO,SAAS,YAAY,KAAK,WAAW,GAC9C,MAAM,IAAI,gBAAgB,gDAAgD;CAE5E,OAAO,IAAI,qBAAqB,IAAI;AACtC;AAIA,SAAS,eAAe,UAA+B;CACrD,IAAI,OAAO,UAAU,SAAS,YAAY,SAAS,KAAK,WAAW,GACjE,MAAM,IAAI,gBAAgB,iEAAiE;CAE7F,IAAI,CAAC,MAAM,QAAQ,SAAS,KAAK,KAAK,SAAS,MAAM,WAAW,GAC9D,MAAM,IAAI,gBACR,oCAAoC,SAAS,KAAK,wDACpD;CAEF,MAAM,uBAAO,IAAI,IAAY;CAC7B,KAAK,MAAM,QAAQ,SAAS,OAAO;EACjC,MAAM,QAAQ,aAAa,SAAS,KAAK,UAAU,MAAM,SAAS,cAAc;EAChF,IAAI,OAAO,MAAM,UAAU,YAAY,KAAK,MAAM,WAAW,GAC3D,MAAM,IAAI,gBAAgB,GAAG,MAAM,mCAAmC;EAExE,IAAI,KAAK,IAAI,KAAK,KAAK,GACrB,MAAM,IAAI,gBAAgB,GAAG,MAAM,iDAAiD;EAEtF,KAAK,IAAI,KAAK,KAAK;EACnB,QAAQ,KAAK,MAAb;GACE,KAAK;GACL,KAAK;GACL,KAAK;IACH,gBAAgB,KAAK,GAAG,GAAG,MAAM,KAAK;IACtC;GACF,KAAK;IACH,gBAAgB,KAAK,GAAG,GAAG,MAAM,KAAK;IACtC,gBAAgB,KAAK,GAAG,GAAG,MAAM,KAAK;IACtC;GACF,KAAK;IACH,gBAAgB,KAAK,GAAG,GAAG,MAAM,KAAK;IACtC,gBAAgB,KAAK,OAAO,GAAG,MAAM,SAAS;IAC9C;GACF,SACE,MAAM,IAAI,gBACR,GAAG,MAAM,uBAAuB,OAAQ,KAAsB,IAAI,EAAE,EACtE;EACJ;CACF;AACF;;;;;;;;AASA,SAAS,WAAW,OAAgD;CAClE,MAAM,QAAQ,MAAM,QACjB,MAAM,OAAO,EAAE,cAAc,YAAY,OAAO,SAAS,EAAE,SAAS,CACvE,CAAC,CAAC;CACF,IAAI,UAAU,MAAM,QAClB,OAAO,MACJ,KAAK,MAAM,OAAO;EAAE;EAAM;CAAE,EAAE,CAAC,CAC/B,MAAM,GAAG,MAAM,EAAE,KAAK,YAAa,EAAE,KAAK,aAAc,EAAE,IAAI,EAAE,CAAC,CAAC,CAClE,KAAK,MAAM,EAAE,IAAI;CAEtB,IAAI,UAAU,GAAG,OAAO,CAAC,GAAG,KAAK;CACjC,MAAM,IAAI,gBACR,0BAA0B,MAAM,GAAG,MAAM,OAAO,qGAElD;AACF;AAEA,SAAS,QAAQ,MAAoB,OAAuB;CAC1D,OAAO,KAAK,UAAU,IAAI;AAC5B;AAMA,SAAS,aAAa,MAME;CACtB,MAAM,MAA2B,CAAC;CAClC,IAAI,YAAY;CAChB,KAAK,IAAI,IAAI,GAAG,IAAI,KAAK,QAAQ,QAAQ,KAAK;EAC5C,MAAM,OAAO,KAAK,QAAQ;EAC1B,IAAI,CAAC,aAAa,UAAU,MAAM,KAAK,OAAO,GAC5C,IAAI,KAAK;GAAE,MAAM,KAAK;GAAO,QAAQ,KAAK;GAAQ,QAAQ,KAAK,OAAO,QAAQ,MAAM,CAAC,CAAC;EAAE,CAAC;EAE3F,IAAI,UAAU,MAAM,KAAK,KAAK,GAAG,YAAY;CAC/C;CACA,OAAO;AACT;AAEA,SAAS,UAAU,MAAoB,SAAuD;CAC5F,QAAQ,KAAK,MAAb;EACE,KAAK,UAAU;GACb,MAAM,MAA2B,CAAC;GAClC,KAAK,IAAI,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;IACvC,MAAM,OAAO,QAAQ;IACrB,IAAI,CAAC,UAAU,MAAM,KAAK,CAAE,GAC1B,IAAI,KAAK;KACP,MAAM,KAAK;KACX,QAAQ,KAAK;KACb,QAAQ,QAAQ,QAAQ,MAAM,CAAC,EAAE,KAAK,KAAK,QAAQ,GAAG,kBAAkB,kBAAkB,KAAK,CAAE,EAAE;IACrG,CAAC;GAEL;GACA,OAAO;EACT;EACA,KAAK,SAAS;GACZ,MAAM,MAA2B,CAAC;GAClC,KAAK,IAAI,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;IACvC,MAAM,OAAO,QAAQ;IACrB,IAAI,UAAU,MAAM,KAAK,CAAE,GACzB,IAAI,KAAK;KACP,MAAM,KAAK;KACX,QAAQ,KAAK;KACb,QAAQ,QAAQ,QAAQ,MAAM,CAAC,EAAE,KAAK,KAAK,QAAQ,GAAG,mBAAmB,kBAAkB,KAAK,CAAE,EAAE;IACtG,CAAC;GAEL;GACA,OAAO;EACT;EACA,KAAK,cAEH,OADY,QAAQ,MAAM,SAAS,UAAU,MAAM,KAAK,CAAE,CACjD,IACL,CAAC,IACD,CACE;GACE,MAAM,KAAK;GACX,QAAQ,8BAA8B,kBAAkB,KAAK,CAAE,EAAE,SAAS,QAAQ,OAAO;EAC3F,CACF;EAEN,KAAK,YACH,OAAO,aAAa;GAClB,OAAO,KAAK;GACZ;GACA,OAAO,KAAK;GACZ,SAAS,KAAK;GACd,SAAS,QACP,QAAQ,IAAI,WAAW,kBAAkB,KAAK,CAAE,EAAE,mBAAmB,kBAAkB,KAAK,CAAE,EAAE;EACpG,CAAC;EACH,KAAK,eACH,OAAO,aAAa;GAClB,OAAO,KAAK;GACZ;GACA,OAAO,KAAK;GACZ,SAAS,KAAK;GACd,SAAS,QACP,QAAQ,IAAI,WAAW,kBAAkB,KAAK,CAAE,EAAE,mBAAmB,kBAAkB,KAAK,KAAM,EAAE;EACxG,CAAC;CACL;AACF;;;;;;AAOA,SAAgB,sBACd,UACA,OACiB;CACjB,eAAe,QAAQ;CACvB,MAAM,UAAU,WAAW,KAAK;CAChC,MAAM,SAAiC,CAAC;CACxC,MAAM,aAAkC,CAAC;CACzC,KAAK,MAAM,QAAQ,SAAS,OAAO;EACjC,MAAM,iBAAiB,UAAU,MAAM,OAAO;EAC9C,OAAO,KAAK,SAAS,eAAe,WAAW,IAAI,IAAI;EACvD,WAAW,KAAK,GAAG,cAAc;CACnC;CACA,MAAM,YAAY,SAAS,MAAM;CACjC,MAAM,YAAY,OAAO,OAAO,MAAM,CAAC,CAAC,QAAQ,MAAM,MAAM,CAAC,CAAC,CAAC;CAC/D,OAAO;EACL,UAAU,SAAS;EACnB,OAAO,cAAc;EACrB,OAAO,YAAY;EACnB;EACA;EACA,OAAO,GAAG,UAAU,GAAG,UAAU;CACnC;AACF;;;;;AAMA,SAAgB,oBACd,OACA,WACqB;CACrB,IAAI,UAAU,WAAW,GACvB,MAAM,IAAI,gBACR,8FACF;CAEF,MAAM,WAAW,UAAU,KAAK,MAAM,sBAAsB,GAAG,KAAK,CAAC;CACrE,OAAO;EAAE;EAAU,UAAU,SAAS,OAAO,MAAM,EAAE,KAAK;CAAE;AAC9D;;;;;;AAsBA,SAAgB,cACd,WACA,MACmC;CACnC,IAAI,UAAU,WAAW,GACvB,MAAM,IAAI,gBAAgB,+CAA+C;CAE3E,KAAK,MAAM,KAAK,WAAW,eAAe,CAAC;CAC3C,MAAM,wBAAQ,IAAI,IAAY;CAC9B,KAAK,MAAM,KAAK,WAAW;EACzB,IAAI,MAAM,IAAI,EAAE,IAAI,GAClB,MAAM,IAAI,gBACR,2CAA2C,EAAE,KAAK,kCACpD;EAEF,MAAM,IAAI,EAAE,IAAI;CAClB;CACA,IAAI,OAAO,MAAM,UAAU,YACzB,MAAM,IAAI,gBAAgB,2DAA2D;CAEvF,MAAM,aAA+B,UAAU,KAAK,OAAO;EACzD,KAAK,EAAE;EACP,aAAa,EAAE,MAAM,KAAK,MAAM,EAAE,KAAK,CAAC,CAAC,KAAK,IAAI;CACpD,EAAE;CACF,OAAO;EACL,MAAM,KAAK,QAAQ;EACnB;EACA,MAAM,EAAE,UAAU,YAAY;GAC5B,MAAM,QAAQ,KAAK,MAAM;IAAE;IAAU;GAAS,CAAC;GAC/C,IAAI,CAAC,MAAM,QAAQ,KAAK,GACtB,MAAM,IAAI,gBACR,wDAAwD,OAAO,OACjE;GAEF,MAAM,EAAE,aAAa,oBAAoB,OAAO,SAAS;GACzD,MAAM,OAA+B,CAAC;GACtC,MAAM,aAAkC,CAAC;GACzC,KAAK,MAAM,KAAK,UAAU;IACxB,KAAK,EAAE,YAAY,EAAE;IACrB,WAAW,KAAK,GAAG,EAAE,UAAU;GACjC;GAEA,OAAO;IACL,YAAY;IACZ,WAHgB,SAAS,QAAQ,KAAK,MAAM,MAAM,EAAE,OAAO,CAAC,IAAI,SAAS;IAIzE,OACE,WAAW,WAAW,IAClB,kCACA,WACG,MAAM,GAAG,CAAC,CAAC,CACX,KAAK,MAAM,GAAG,EAAE,KAAK,IAAI,EAAE,QAAQ,CAAC,CACpC,KAAK,IAAI;GACpB;EACF;CACF;AACF;;;;;;;;;;;;;;;;;ACvlBA,IAAa,oBAAb,MAA+B;CAEnB;CACA;CAFV,YACE,OACA,OACA;EAFQ,KAAA,QAAA;EACA,KAAA,QAAA;CACP;CAEH,OAAO,UAAmC;EACxC,OAAO,IAAI,gBAAgB,KAAK,OAAO,KAAK,OAAO,QAAQ;CAC7D;CAEA,SAAS,UAAoB,yBAAsC;EACjE,OAAO;GACL,OAAO,SAAS,KAAK,MAAM;GAC3B,OAAO,YAAY;IAEjB,MAAM,UAAS,MADK,SAAS,KAAK,OAAO,KAAK,KAAK,EAAA,CAC9B,KAAK,MAAM,EAAE,UAAU,EAAE,CAAC,CAAC,KAAK,IAAI;IAEzD,OADY,QAAQ,MAAM,OAAO,GAAG,KAAK,MAAM,CACtC,IACL;KAAE,IAAI;KAAM,QAAQ;IAA0B,IAC9C;KACE,IAAI;KACJ,QAAQ;KACR,UAAU,OAAO,MAAM,GAAG,GAAG;IAC/B;GACN;EACF;CACF;CAEA,cAAc,SAA8B;EAC1C,OAAO;GACL,OAAO,SAAS,KAAK,MAAM,kBAAkB,QAAQ,OAAO;GAC5D,OAAO,YAAY;IAEjB,MAAM,UAAS,MADK,SAAS,KAAK,OAAO,KAAK,KAAK,EAAA,CAC9B,KAAK,MAAM,EAAE,UAAU,EAAE,CAAC,CAAC,KAAK,IAAI;IACzD,MAAM,IAAI,OAAO,MAAM,OAAO;IAC9B,OAAO,IACH;KAAE,IAAI;KAAM,QAAQ,YAAY,EAAE,GAAG;KAAI,UAAU,EAAE;IAAG,IACxD;KAAE,IAAI;KAAO,QAAQ;KAAuB,UAAU,OAAO,MAAM,GAAG,GAAG;IAAE;GACjF;EACF;CACF;CAEA,gBACE,WACa;EACb,OAAO;GACL,OAAO,SAAS,KAAK,MAAM,oBAAoB,OAAO,SAAS,EAAE;GACjE,OAAO,YAAY;IAGjB,QADiB,MADK,KAAK,MAAM,OAAO,KAAK,KAAK,EAAA,CACzB,MAAM,MAAM,EAAE,cAAc,aAAa,EAAE,QACtD,IACV;KAAE,IAAI;KAAO,QAAQ,WAAW,OAAO,SAAS,EAAE;IAAY,IAC9D;KAAE,IAAI;KAAM,QAAQ,iBAAiB,OAAO,SAAS,EAAE;IAAG;GAChE;EACF;CACF;CAEA,iBAAiB,QAID;EACd,OAAO;GACL,OAAO,SAAS,KAAK,MAAM,qBAAqB,KAAK,UAAU,MAAM,EAAE;GACvE,OAAO,YAAY;IACjB,MAAM,MAAM,MAAM,KAAK,MAAM,OAAO,KAAK,KAAK;IAC9C,IAAI,CAAC,KAAK,SAAS,OAAO;KAAE,IAAI;KAAO,QAAQ;IAAwB;IACvE,MAAM,SAAS,IAAI,UAAU,IAAI;IACjC,MAAM,QAAQ,MAAM,UAAU,KAAK,OAAO,KAAK,KAAK,EAAA,CAAG;IACvD,MAAM,OAAO,MAAM,SAAS,KAAK,OAAO,KAAK,KAAK,EAAA,CAAG;IACrD,MAAM,aAAuB,CAAC;IAC9B,IAAI,OAAO,WAAW,KAAA,KAAa,SAAS,OAAO,QACjD,WAAW,KAAK,UAAU,OAAO,KAAK,OAAO,QAAQ;IACvD,IAAI,OAAO,cAAc,KAAA,KAAa,OAAO,OAAO,WAClD,WAAW,KAAK,aAAa,KAAK,KAAK,OAAO,WAAW;IAC3D,IAAI,OAAO,aAAa,KAAA,KAAa,MAAM,OAAO,UAChD,WAAW,KAAK,YAAY,IAAI,KAAK,OAAO,UAAU;IACxD,OAAO,WAAW,WAAW,IACzB;KAAE,IAAI;KAAM,QAAQ,kBAAkB,OAAO,MAAM,KAAK,UAAU,IAAI;IAAS,IAC/E;KAAE,IAAI;KAAO,QAAQ,WAAW,KAAK,IAAI;IAAE;GACjD;EACF;CACF;;;CAIA,kBAAkB,UAAsC;EACtD,OAAO;GACL,OAAO,SAAS,KAAK,MAAM,sBAAsB,SAAS,KAAK;GAC/D,OAAO,YAAY;IAEjB,MAAM,UAAU,sBAAsB,UAAU,MAD5B,KAAK,MAAM,MAAM,EAAE,OAAO,KAAK,MAAM,CAAC,CACL;IACrD,IAAI,QAAQ,OACV,OAAO;KAAE,IAAI;KAAM,QAAQ,aAAa,SAAS,KAAK,KAAK,QAAQ;IAAQ;IAE7E,OAAO;KACL,IAAI;KACJ,QAAQ,QAAQ,WAAW,KAAK,MAAM,GAAG,EAAE,KAAK,IAAI,EAAE,QAAQ,CAAC,CAAC,KAAK,IAAI;KACzE,UAAU,QAAQ,WAAW,MAAM,MAAM,EAAE,MAAM,CAAC,EAAE;IACtD;GACF;EACF;CACF;CAEA,YAAY,UAA+B;EACzC,OAAO;GACL,OAAO,SAAS,KAAK,MAAM,gBAAgB,SAAS;GACpD,OAAO,YAAY;IACjB,MAAM,QAAQ,MAAM,UAAU,KAAK,OAAO,KAAK,OAAO,QAAQ;IAC9D,OAAO,MAAM,WAAW,IACpB;KAAE,IAAI;KAAM,QAAQ,SAAS,SAAS;IAAe,IACrD;KACE,IAAI;KACJ,QAAQ,SAAS,SAAS,WAAW,MAAM,OAAO;KAClD,UAAU,MAAM,EAAE,CAAE;IACtB;GACN;EACF;CACF;AACF;AAEA,IAAa,kBAAb,MAAoD;CAMxC;CACA;CACA;CAPV,cAAyD,CAAC;CAC1D,WAAmB;CACnB,WAAmB;CAEnB,YACE,OACA,OACA,UACA;EAHQ,KAAA,QAAA;EACA,KAAA,QAAA;EACA,KAAA,WAAA;CACP;CAEH,IAAI,QAAgB;EAClB,OAAO,SAAS,KAAK,MAAM,WAAW,KAAK,SAAS;CACtD;CAEA,SAAS,OAA+C;EACtD,KAAK,YAAY,MAAM,SAAS,UAAU,MAAM,KAAK,CAAC;EACtD,OAAO;CACT;CAEA,MAAM,GAAiB;EACrB,KAAK,WAAW;EAChB,KAAK,WAAW;EAChB,OAAO;CACT;CAEA,QAAQ,GAAiB;EACvB,KAAK,WAAW;EAChB,OAAO;CACT;CAEA,OAAO,GAAiB;EACtB,KAAK,WAAW;EAChB,OAAO;CACT;CAEA,MAAM,QAAgC;EAGpC,MAAM,SADW,MADG,UAAU,KAAK,OAAO,KAAK,OAAO,KAAK,QAAQ,EAAA,CAC5C,QAAQ,MAAM,KAAK,YAAY,OAAO,OAAO,GAAG,EAAE,IAAI,CAAC,CACzD,CAAC,CAAC;EACvB,IAAI,QAAQ,KAAK,UACf,OAAO;GACL,IAAI;GACJ,QAAQ,cAAc,KAAK,SAAS,aAAa,KAAK,SAAS,eAAe;EAChF;EACF,IAAI,QAAQ,KAAK,UACf,OAAO;GACL,IAAI;GACJ,QAAQ,cAAc,KAAK,SAAS,aAAa,KAAK,SAAS,eAAe;EAChF;EACF,OAAO;GAAE,IAAI;GAAM,QAAQ,GAAG,MAAM,aAAa,KAAK,SAAS;EAAW;CAC5E;AACF;AAEA,SAAgB,YAAY,OAAmB,OAAkC;CAC/E,OAAO,IAAI,kBAAkB,OAAO,KAAK;AAC3C;;AAGA,eAAsB,gBAAgB,cAKnC;CACD,MAAM,UAAU,MAAM,QAAQ,IAC5B,aAAa,IAAI,OAAO,OAAO;EAAE,OAAO,EAAE;EAAO,QAAQ,MAAM,EAAE,MAAM;CAAE,EAAE,CAC7E;CACA,MAAM,YAAY,QAAQ,QAAQ,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC;CACrD,OAAO;EACL;EACA,MAAM,cAAc,QAAQ;EAC5B;EACA,WAAW,QAAQ,SAAS;CAC9B;AACF;AAEA,MAAM,0BAA0B;CAC9B;CACA;CACA;CACA;AACF;AAEA,SAAS,UAAU,MAAe,OAAkD;CAClF,IAAI,SAAS,QAAQ,OAAO,SAAS,UAAU,OAAO;CACtD,MAAM,SAAS;CACf,KAAK,MAAM,CAAC,GAAG,aAAa,OAAO,QAAQ,KAAK,GAAG;EACjD,MAAM,SAAS,OAAO;EACtB,IAAI,oBAAoB,QAClB;OAAA,OAAO,WAAW,YAAY,CAAC,SAAS,KAAK,MAAM,GAAG,OAAO;EAAA,OAC5D,IAAI,WAAW,UACpB,OAAO;CAEX;CACA,OAAO;AACT;;;ACzMA,eAAsB,iBACpB,OACA,UACyB;CACzB,MAAM,eAAe,MAAM,MAAM,SAAS,SAAS,QAAQ;CAC3D,MAAM,gBAAgB,MAAM,MAAM,SAAS,SAAS,SAAS;CAC7D,IAAI,cAAc,WAAW,GAC3B,OAAO;EACL,MAAM,SAAS;EACf,gBAAgB;GAAE,SAAS,CAAC;GAAG,eAAe;GAAO,aAAa;EAAK;EACvE,UAAU,CAAC,2BAA2B;EACtC,MAAM;CACR;CAGF,MAAM,UAA2B,CAAC;CAClC,MAAM,sBAAgC,CAAC;CACvC,KAAK,MAAM,KAAK,SAAS,SAAS;EAChC,MAAM,UAAU,EAAE,WAAWC,iBAAe,EAAE,MAAM;EACpD,MAAM,WAAW,MAAM,WAAW,cAAc,SAAS,KAAK;EAC9D,MAAM,YAAY,MAAM,WAAW,eAAe,SAAS,KAAK;EAChE,IAAI,SAAS,WAAW,aAAa,UAAU,UAAU,WAAW,cAAc,QAAQ;GACxF,oBAAoB,KAClB,WAAW,EAAE,OAAO,aAAa,UAAU,OAAO,GAAG,cAAc,OAAO,iBACjE,SAAS,OAAO,GAAG,aAAa,OAAO,4DAClD;GACA;EACF;EACA,IAAI,SAAS,SAAS,KAAK,UAAU,SAAS,GAAG;GAC/C,oBAAoB,KAClB,WAAW,EAAE,OAAO,6CAA6C,SAAS,OAAO,cAClE,UAAU,OAAO,0BAClC;GACA;EACF;EACA,QAAQ,KAAK;GAAE,QAAQ,EAAE;GAAQ,gBAAgB,EAAE;GAAgB;GAAU;EAAU,CAAC;CAC1F;CAEA,MAAM,iBACJ,QAAQ,UAAU,IACd,kBAAkB,OAAO,IACzB;EAAE,SAAS,CAAC;EAAG,eAAe;EAAO,aAAa,QAAQ,WAAW;CAAE;CAG7E,IAAI;CACJ,IAAI,SAAS,QAAQ,SAAS,KAAK,SAAS,GAE1C,YAAY,UAAU,MADJ,oBAAoB,eAAe,KAAK,GAC/B,SAAS,IAAI;CAG1C,MAAM,WAAqB,CAAC,GAAG,mBAAmB;CAClD,KAAK,MAAM,UAAU,eAAe,SAAS;EAC3C,MAAM,OAAO,SAAS,QAAQ,MAAM,MAAM,EAAE,WAAW,OAAO,MAAM;EACpE,IAAI,CAAC,MAAM;EACX,IAAI,OAAO,YAAY,aAAa;GAClC,MAAM,YAAY,KAAK,IAAI,OAAO,KAAK;GACvC,IAAI,KAAK,kBAAkB,KAAA,KAAa,YAAY,KAAK,eACvD,SAAS,KACP,WAAW,OAAO,OAAO,iBAAiB,OAAO,MAAM,QAAQ,CAAC,EAAE,MAAM,iBAAiB,OAAO,OAAO,EAAE,MAAM,OAAO,OAAO,cAAc,CAAC,EAAE,EAChJ;EAEJ;CACF;CACA,IAAI,WACF,KAAK,MAAM,KAAK,UAAU,kBACxB,SAAS,KAAK,QAAQ,EAAE,IAAI,GAAG,cAAc,EAAE,QAAQ;CAI3D,OAAO;EAAE,MAAM,SAAS;EAAM;EAAgB;EAAW;EAAU,MAAM,SAAS,WAAW;CAAE;AACjG;AAEA,SAAgB,qBAAqB,SAAmC;CACtE,MAAM,QAAkB,CAAC;CACzB,MAAM,UAAU,QAAQ,OAAO,MAAM,EAAE,IAAI;CAC3C,MAAM,KAAK,UAAU,+BAA+B,4BAA4B;CAChF,MAAM,KAAK,EAAE;CACb,KAAK,MAAM,KAAK,SAAS;EACvB,MAAM,KAAK,OAAO,EAAE,KAAK,GAAG,EAAE,OAAO,MAAM,KAAK;EAChD,IAAI,EAAE,SAAS,SAAS,GAAG;GACzB,MAAM,KAAK,EAAE;GACb,MAAM,KAAK,eAAe;GAC1B,KAAK,MAAM,KAAK,EAAE,UAAU,MAAM,KAAK,KAAK,GAAG;EACjD;EACA,IAAI,EAAE,eAAe,QAAQ,SAAS,GAAG;GACvC,MAAM,KAAK,EAAE;GACb,MAAM,KAAK,+DAA+D;GAC1E,MAAM,KAAK,+BAA+B;GAC1C,KAAK,MAAM,KAAK,EAAE,eAAe,SAC/B,MAAM,KACJ,KAAK,EAAE,OAAO,KAAK,EAAE,aAAa,QAAQ,CAAC,EAAE,KAAK,EAAE,cAAc,QAAQ,CAAC,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC,EAAE,KAAK,iBAAiB,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,cAAc,CAAC,EAAE,KAAK,EAAE,QAAQ,GACtL;EAEJ;EACA,IAAI,EAAE,aAAa,EAAE,UAAU,QAAQ,SAAS,GAAG;GACjD,MAAM,KAAK,EAAE;GACb,MAAM,KAAK,kBAAkB;GAC7B,KAAK,MAAM,KAAK,EAAE,UAAU,SAC1B,MAAM,KAAK,KAAK,EAAE,IAAI,GAAG,IAAI,EAAE,IAAI,SAAS,KAAK,EAAE,SAAS,OAAO,SAAS,KAAK,EAAE,QAAQ;EAE/F;EACA,MAAM,KAAK,EAAE;CACf;CACA,OAAO,MAAM,KAAK,IAAI;AACxB;;AAGA,eAAe,oBACb,MACA,OACiC;CACjC,IAAI,KAAK,WAAW,GAAG,OAAO,CAAC;CAC/B,MAAM,YAAsB,CAAC;CAC7B,MAAM,SAAmB,CAAC;CAC1B,MAAM,SAAmB,CAAC;CAC1B,MAAM,QAAkB,CAAC;CACzB,KAAK,MAAM,KAAK,MAAM;EACpB,IAAI,EAAE,SAAS,UAAU,KAAK,EAAE,UAAU,EAAE,SAAS;EACrD,IAAI,EAAE,SAAS,UAAU,KAAA,GAAW,OAAO,KAAK,EAAE,QAAQ,KAAK;EAC/D,OAAO,KAAK,EAAE,SAAS,SAAS,OAAO,IAAI,CAAC;EAC5C,MAAM,MAAM,MAAM,SAAS,OAAO,EAAE,KAAK;EACzC,MAAM,KAAK,aAAa,GAAG,CAAC,CAAC,OAAO;CACtC;CACA,OAAO;EACL,aAAa,QAAQ,SAAS;EAC9B,cAAc,QAAQ,SAAS;EAC/B,QAAQ,QAAQ,SAAS;EACzB,cAAc,QAAQ,MAAM;EAC5B,UAAU,QAAQ,MAAM;EACxB,SAAS,QAAQ,KAAK;CACxB;AACF;AAEA,SAAS,QAAQ,IAAsB;CACrC,IAAI,GAAG,WAAW,GAAG,OAAO;CAC5B,OAAO,GAAG,QAAQ,GAAG,MAAM,IAAI,GAAG,CAAC,IAAI,GAAG;AAC5C;;;AAIA,SAAS,iBAAiB,GAA0B;CAClD,OAAO,MAAM,OAAO,mCAAmC,EAAE,QAAQ,CAAC;AACpE;AAEA,eAAe,WACb,MACA,SACA,OACmB;CACnB,MAAM,MAAgB,CAAC;CACvB,KAAK,MAAM,KAAK,MAAM;EACpB,MAAM,IAAI,MAAM,QAAQ,GAAG,KAAK;EAChC,IAAI,MAAM,QAAQ,OAAO,SAAS,CAAC,GAAG,IAAI,KAAK,CAAC;CAClD;CACA,OAAO;AACT;AAEA,SAASA,iBAAe,QAAyE;CAC/F,OAAO,OAAO,KAAK,UAAU;EAC3B,QAAQ,QAAR;GACE,KAAK;GACL,KAAK,gBACH,OAAO,IAAI,SAAS,SAAS;GAC/B,KAAK,QACH,OAAO,IAAI,SAAS,SAAS,OAAO,IAAI;GAC1C,KAAK,cACH,OAAO,IAAI,WAAW,IAAI,YAAY,IAAI,UAAU,IAAI,YAAY;GACtE,KAAK,WAEH,OAAO,aAAa,MADF,SAAS,OAAO,IAAI,KAAK,CACpB,CAAC,CAAC;GAE3B,KAAK,gBACH,OAAO,gBAAgB,GAAG,MAAM,YAAY,IAAI;GAClD,SACE,OAAO;EACX;CACF;AACF;;;;;;;;;;;;;;;;;;AC7KA,eAAsB,mBACpB,OACA,OAC2B;CAC3B,MAAM,MAAM,MAAM,MAAM,OAAO,KAAK;CACpC,IAAI,CAAC,KAAK,MAAM,IAAI,cAAc,OAAO,MAAM,WAAW;CAC1D,MAAM,MAAM,MAAM,SAAS,OAAO,KAAK;CAEvC,MAAM,UAAS,MADQ,MAAM,MAAM,EAAE,MAAM,CAAC,EAAA,CACpB,QAAQ,MAA6C,EAAE,SAAS,OAAO;CAE/F,MAAM,cAAoC,IAAI,KAAK,OAAO;EACxD,IAAI,EAAE;EACN,SAAS,IAAI;EACb,MAAM,EAAE;EACR,OAAO,EAAE;EACT,OAAO,EAAE;EACT,QAAQ,EAAE;EACV,WAAW,IAAI,KAAK,EAAE,SAAS,CAAC,CAAC,YAAY;EAC7C,SAAS,IAAI,KAAK,EAAE,WAAW,EAAE,SAAS,CAAC,CAAC,YAAY;EACxD,OAAO;GACL,OAAO,EAAE,eAAe;GACxB,QAAQ,EAAE,gBAAgB;GAC1B,QAAQ,EAAE,eAAe,MAAM,EAAE,gBAAgB;GACjD,WAAW,EAAE,WAAW;EAC1B;EACA,UAAU;GAAE,cAAc,EAAE;GAAc,cAAc,EAAE;EAAa;CACzE,EAAE;CAEF,MAAM,SAA0B,OAAO,KAAK,OAAO;EACjD,IAAI,EAAE;EACN,SAAS,IAAI;EACb,eAAe,EAAE;EACjB,MAAM,GAAG,EAAE,QAAQ,GAAG,EAAE;EACxB,OAAO,EAAE;EACT,SAAS,EAAE;CACb,EAAE;CAEF,OAAO;EAAE,SAAS,IAAI;EAAO;EAAa;CAAO;AACnD;AAIA,eAAsB,iBAAiB,OAAoC;CACzE,MAAM,OAAO,MAAM,MAAM,SAAS;CAClC,MAAM,YAAoC,CAAC;CAC3C,MAAM,aAAqC,CAAC;CAC5C,IAAI,sBAAsB;CAC1B,IAAI,uBAAuB;CAC3B,IAAI,eAAe;CACnB,IAAI,aAAa;CACjB,IAAI,aAAa;CACjB,KAAK,MAAM,KAAK,MAAM;EACpB,IAAI,EAAE,SAAS,SAAS,MAAM;OACzB,IAAI,EAAE,SAAS,SAAS,OAAO;EAEpC,MAAM,MAAM,aAAa,MADP,SAAS,OAAO,EAAE,KAAK,CACb;EAC5B,uBAAuB,IAAI;EAC3B,wBAAwB,IAAI;EAC5B,gBAAgB,IAAI;EACpB,MAAM,QAAQ,MAAM,MAAM,MAAM;GAAE,OAAO,EAAE;GAAO,MAAM;EAAO,CAAC;EAChE,KAAK,MAAM,KAAK,OAAO;GACrB,IAAI,EAAE,SAAS,QAAQ;GACvB,UAAU,EAAE,aAAa,UAAU,EAAE,aAAa,KAAK;GACvD,IAAI,EAAE,WAAW,SAAS,WAAW,EAAE,aAAa,WAAW,EAAE,aAAa,KAAK;EACrF;CACF;CAEA,MAAM,QAAkB,CAAC;CACzB,MAAM,KAAK,6DAA6D;CACxE,MAAM,KAAK,sCAAsC;CACjD,MAAM,KAAK,yBAAyB,KAAK,QAAQ;CACjD,MAAM,KAAK,wEAAwE;CACnF,MAAM,KAAK,6CAA6C;CACxD,MAAM,KAAK,gCAAgC,YAAY;CACvD,MAAM,KAAK,yEAAyE;CACpF,MAAM,KAAK,6CAA6C;CACxD,MAAM,KAAK,gCAAgC,YAAY;CACvD,MAAM,KAAK,qEAAqE;CAChF,MAAM,KAAK,kDAAkD;CAC7D,MAAM,KAAK,qCAAqC,qBAAqB;CACrE,MAAM,KAAK,uEAAuE;CAClF,MAAM,KAAK,mDAAmD;CAC9D,MAAM,KAAK,sCAAsC,sBAAsB;CACvE,MAAM,KAAK,4DAA4D;CACvE,MAAM,KAAK,0CAA0C;CACrD,MAAM,KAAK,6BAA6B,cAAc;CACtD,MAAM,KAAK,4DAA4D;CACvE,MAAM,KAAK,4CAA4C;CACvD,KAAK,MAAM,CAAC,MAAM,MAAM,OAAO,QAAQ,SAAS,GAC9C,MAAM,KAAK,qCAAqC,YAAY,IAAI,EAAE,KAAK,GAAG;CAE5E,MAAM,KAAK,8DAA8D;CACzE,MAAM,KAAK,6CAA6C;CACxD,KAAK,MAAM,CAAC,MAAM,MAAM,OAAO,QAAQ,UAAU,GAC/C,MAAM,KAAK,sCAAsC,YAAY,IAAI,EAAE,KAAK,GAAG;CAE7E,OAAO,GAAG,MAAM,KAAK,IAAI,EAAE;AAC7B;AAEA,SAAS,YAAY,GAAmB;CACtC,OAAO,EAAE,QAAQ,OAAO,MAAM,CAAC,CAAC,QAAQ,MAAM,MAAK,CAAC,CAAC,QAAQ,OAAO,KAAK;AAC3E;;;;;;AAiBA,eAAsB,wBACpB,OACA,OACA,OAK8B;CAE9B,IAAI,CAAC,MADa,MAAM,OAAO,KAAK,GAC1B,MAAM,IAAI,cAAc,OAAO,MAAM,WAAW;CAC1D,MAAM,OAAO,MAAM,SAAS,OAAO,KAAK;CACxC,MAAM,UAAU,IAAI,aAAa,OAAO,EAAE,MAAM,CAAC;CACjD,MAAM,UAA+B,CAAC;CACtC,KAAK,MAAM,QAAQ,MAAM;EACvB,MAAM,EAAE,OAAO,WAAW,aAAa,MAAM,MAAM,MAAM,IAAI;EAC7D,MAAM,UAAU,MAAM,QAAQ,YAAY;GACxC,SAAS,MAAM;GACf,cAAc,KAAK;GACnB,WAAW,MAAM;GACjB;GACA;GACA;GACA,MAAM,GAAG,MAAM,GAAG,GAAG,MAAM;EAC7B,CAAC;EACD,QAAQ,KAAK;GACX,QAAQ,QAAQ;GAChB,cAAc,KAAK;GACnB,WAAW,MAAM;GACjB;GACA;EACF,CAAC;CACH;CACA,OAAO;AACT;;;ACtLA,eAAsB,qBACpB,QACA,UACA,SACA,UAA6B,CAAC,GACH;CAC3B,MAAM,OAAO,QAAQ,QAAQ;CAC7B,MAAM,gBAAgB,MAAM,QAAQ,MAAM;CAC1C,MAAM,gBAAmD,CAAC;CAC1D,MAAM,MAAgB,CAAC,aAAa;CACpC,KAAK,MAAM,EAAE,IAAI,QAAQ,UAAU;EACjC,MAAM,UAAU,GAAG,QAAQ,IAAI;EAC/B,MAAM,QAAQ,MAAM,QAAQ,OAAO;EACnC,cAAc,KAAK;GAAE,SAAS;GAAI;GAAO;EAAQ,CAAC;EAClD,IAAI,KAAK,KAAK;CAChB;CACA,MAAM,OAAO,IAAI,QAAQ,GAAG,MAAM,IAAI,GAAG,CAAC,IAAI,IAAI;CAClD,MAAM,WAAW,IAAI,QAAQ,GAAG,MAAM,KAAK,IAAI,SAAS,GAAG,CAAC,IAAI,IAAI;CACpE,MAAM,SAAS,KAAK,KAAK,QAAQ;CAGjC,OAAO;EAAE;EAAe;EAAe,WAAW;EAAM;EAAQ,YAD7C,KAAK,IAAI,GAAG,IAAI,UADvB,KAAK,IAAI,IAAI,IAAI,OAAO,KAAK,IAAI,IAAI,IAAI,EAEoB;CAAE;AAC7E;;AAKA,MAAa,oBAA6B,MAAM,EAAE,YAAY;;AAG9D,MAAa,0BAAmC,GAAG,SAAS;CAC1D,MAAM,YAAY,EAAE,MAAM,eAAe,CAAC,CAAC,OAAO,OAAO;CACzD,IAAI,UAAU,UAAU,GAAG,OAAO;CAClC,MAAM,WAAW,CAAC,GAAG,SAAS;CAC9B,IAAI,IAAI,SAAS;CACjB,KAAK,IAAI,IAAI,SAAS,SAAS,GAAG,IAAI,GAAG,KAAK;EAC5C,IAAK,IAAI,aAAa,UAAW;EACjC,MAAM,IAAI,KAAK,IAAI;EAClB,CAAC,SAAS,IAAI,SAAS,MAAM,CAAC,SAAS,IAAK,SAAS,EAAG;CAC3D;CACA,OAAO,SAAS,KAAK,GAAG;AAC1B;;AAGA,MAAa,eAAwB,GAAG,SAAS;CAC/C,IAAI,EAAE,SAAS,GAAG,OAAO;CACzB,MAAM,QAAQ,EAAE,MAAM,EAAE;CACxB,IAAI,IAAI,SAAS;CACjB,MAAM,QAAQ,KAAK,IAAI,GAAG,KAAK,MAAM,MAAM,SAAS,EAAE,CAAC;CACvD,KAAK,IAAI,IAAI,GAAG,IAAI,OAAO,KACzB,KAAK,IAAI,UAAU,GAAG,UAAU,IAAI,WAAW;EAC7C,IAAK,IAAI,aAAa,UAAW;EACjC,MAAM,MAAM,KAAK,MAAM,SAAS;EAChC,MAAM,IAAI,MAAM;EAChB,MAAM,IAAI,MAAM,MAAM;EACtB,IAAI,MAAM,KAAK,WAAW,KAAK,CAAC,KAAK,WAAW,KAAK,CAAC,GAAG;GACvD,MAAM,OAAO;GACb,MAAM,MAAM,KAAK;GACjB;EACF;CACF;CAEF,OAAO,MAAM,KAAK,EAAE;AACtB;;AAGA,MAAa,2BAAoC,MAAM,oCAAoC;;AAG3F,MAAa,6BAAsC,MAAM,EAAE,QAAQ,QAAQ,GAAG,CAAC,CAAC,KAAK;AAErF,MAAa,mBAAuD;CAClE;EAAE,IAAI;EAAa,IAAI;CAAiB;CACxC;EAAE,IAAI;EAAoB,IAAI;CAAuB;CACrD;EAAE,IAAI;EAAQ,IAAI;CAAY;CAC9B;EAAE,IAAI;EAAqB,IAAI;CAAwB;CACvD;EAAE,IAAI;EAAuB,IAAI;CAA0B;AAC7D;;;;;;;;;;;;;;;;;;;AAyDA,eAAsB,8BACpB,MAC6C;CAC7C,MAAM,OAAO,KAAK,IAAI,GAAG,KAAK,QAAQ,CAAC;CACvC,MAAM,eAAe,KAAK,SAAS,KAAK,MAAM,EAAE,IAAI;CAEpD,MAAM,cAAiE,CAAC;CAExE,KAAK,MAAM,YAAY,KAAK,WAAW;EAKrC,MAAM,iBAAgB,MAJC,KAAK,YAAY;GACtC,IAAI,SAAS;GACb,WAAW,SAAS;EACtB,CAAC,EAAA,CAC8B;EAE/B,MAAM,SAAiC,CAAC;EACxC,MAAM,iBAA2B,CAAC;EAElC,KAAK,MAAM,KAAK,KAAK,UAAU;GAC7B,MAAM,SAAmB,CAAC;GAC1B,KAAK,IAAI,IAAI,GAAG,IAAI,MAAM,KAAK;IAC7B,MAAM,eAAe,SAAS,UAAU,KAAK,MAAM,EAAE,QAAQ,CAAC,CAAC;IAC/D,MAAM,MAAM,MAAM,KAAK,YAAY;KACjC,IAAI,SAAS;KACb,WAAW;IACb,CAAC;IACD,OAAO,KAAK,IAAI,KAAK;GACvB;GACA,MAAM,OAAO,OAAO,QAAQ,GAAG,MAAM,IAAI,GAAG,CAAC,IAAI,OAAO;GACxD,OAAO,EAAE,QAAQ,OAAO;GACxB,eAAe,KAAK,GAAG,MAAM;EAC/B;EAEA,MAAM,kBACJ,eAAe,WAAW,IACtB,gBACA,eAAe,QAAQ,GAAG,MAAM,IAAI,GAAG,CAAC,IAAI,eAAe;EAEjE,YAAY,KAAK;GAAE,IAAI,SAAS;GAAI;GAAe;GAAiB;EAAO,CAAC;CAC9E;CAEA,MAAM,eACJ,YAAY,WAAW,IACnB,IACA,YAAY,QAAQ,GAAG,MAAM,IAAI,EAAE,eAAe,CAAC,IAAI,YAAY;CACzE,MAAM,kBACJ,YAAY,WAAW,IACnB,IACA,YAAY,QAAQ,GAAG,MAAM,IAAI,EAAE,iBAAiB,CAAC,IAAI,YAAY;CAE3E,MAAM,QAAQ,gBAAgB,IAAI,IAAI,kBAAkB;CAGxD,OAAO;EAAE,OAFK,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,KAAK,CAE9B;EAAG;EAAa,UAAU;CAAa;AACtD;;;;;;;;;;;;AChLA,SAAgB,WACd,GACA,GACA,UAA6B,CAAC,GACZ;CAClB,IAAI,EAAE,UAAU,EAAE,SAAS,EAAE,WAAW,EAAE,QACxC,MAAM,IAAI,gBACR,kCAAkC,EAAE,MAAM,GAAG,EAAE,OAAO,MAAM,EAAE,MAAM,GAAG,EAAE,OAAO,EAClF;CAEF,IAAI,EAAE,KAAK,WAAW,EAAE,KAAK,QAC3B,MAAM,IAAI,gBAAgB,wCAAwC;CAEpE,MAAM,YAAY,QAAQ,aAAa;CACvC,MAAM,cAAc,EAAE,QAAQ,EAAE;CAChC,IAAI,YAAY;CAChB,IAAI,WAAW;CACf,KAAK,IAAI,IAAI,GAAG,IAAI,EAAE,KAAK,QAAQ,KAAK,GAAG;EACzC,MAAM,KAAK,KAAK,IAAI,EAAE,KAAK,KAAM,EAAE,KAAK,EAAG;EAC3C,MAAM,KAAK,KAAK,IAAI,EAAE,KAAK,IAAI,KAAM,EAAE,KAAK,IAAI,EAAG;EACnD,MAAM,KAAK,KAAK,IAAI,EAAE,KAAK,IAAI,KAAM,EAAE,KAAK,IAAI,EAAG;EACnD,MAAM,KAAK,KAAK,IAAI,EAAE,KAAK,IAAI,KAAM,EAAE,KAAK,IAAI,EAAG;EACnD,MAAM,QAAQ,KAAK,IAAI,IAAI,IAAI,IAAI,EAAE;EACrC,IAAI,QAAQ,UAAU,WAAW;EACjC,IAAI,QAAQ,WAAW;CACzB;CACA,MAAM,YAAY,cAAc,IAAI,YAAY,cAAc;CAE9D,OAAO;EAAE;EAAW,iBAAiB;EAAW;EAAa,iBAAiB;EAAU,QADzE,YAAY,OAAQ,cAAc,YAAY,MAAO,qBAAqB;CACM;AACjG;;AAGA,SAAgB,gBACd,GACA,GACA,OACA,QACA,YAAY,GACJ;CACR,OAAO,WAAW;EAAE;EAAO;EAAQ,MAAM;CAAE,GAAG;EAAE;EAAO;EAAQ,MAAM;CAAE,GAAG,EAAE,UAAU,CAAC,CAAC,CAAC;AAC3F;;;AC3BA,eAAsB,OAAU,SAAqD;CACnF,MAAM,SAAS,QAAQ,YAAY,GAAG,MAAM,OAAO,GAAG,GAAG,CAAC;CAC1D,MAAM,UAAU,QAAQ,iBAAiB;CACzC,MAAM,OAAwB,CAAC;CAE/B,MAAM,cAAc,MAAM,QAAQ,QAAQ,QAAQ,IAAI;CACtD,KAAK,KAAK;EAAE,OAAO,QAAQ;EAAM,GAAG;CAAY,CAAC;CACjD,MAAM,aAAa,MAAM,QAAQ,QAAQ,QAAQ,GAAG;CACpD,KAAK,KAAK;EAAE,OAAO,QAAQ;EAAK,GAAG;CAAW,CAAC;CAE/C,IAAI,CAAC,YAAY,MACf,OAAO;EAAE,SAAS,QAAQ;EAAM;EAAM,WAAW;EAAO,mBAAmB;CAAK;CAElF,IAAI,WAAW,MACb,OAAO;EAAE,SAAS,QAAQ;EAAK;EAAM,WAAW;EAAO,mBAAmB;CAAK;CAGjF,IAAI,OAAO,QAAQ;CACnB,IAAI,MAAM,QAAQ;CAClB,KAAK,IAAI,IAAI,GAAG,IAAI,SAAS,KAAK;EAChC,MAAM,MAAM,QAAQ,QAAQ,MAAM,GAAG;EACrC,IAAI,QAAQ,QAAQ,OAAO,KAAK,IAAI,KAAK,OAAO,KAAK,GAAG,GACtD,OAAO;GAAE,SAAS;GAAK;GAAM,WAAW;GAAM,mBAAmB;EAAM;EAEzE,MAAM,IAAI,MAAM,QAAQ,QAAQ,GAAG;EACnC,KAAK,KAAK;GAAE,OAAO;GAAK,GAAG;EAAE,CAAC;EAC9B,IAAI,EAAE,MAAM,OAAO;OACd,MAAM;CACb;CACA,OAAO;EAAE,SAAS;EAAK;EAAM,WAAW;EAAO,mBAAmB;CAAM;AAC1E;;;;;AAMA,eAAsB,aAAa,SAMD;CAChC,MAAM,EAAE,YAAY;CACpB,MAAM,UAAU,QAAQ,QAAQ,QAAQ,IAAI;CAC5C,MAAM,SAAS,QAAQ,QAAQ,QAAQ,GAAG;CAC1C,IAAI,UAAU,KAAK,SAAS,GAC1B,MAAM,IAAI,MACR,0DAA0D,QAAQ,KAAK,QAAQ,QAAQ,IAAI,EAC7F;CAEF,IAAI,WAAW,QACb,MAAM,IAAI,MAAM,wDAAwD;CAE1E,OAAO,OAAe;EACpB,MAAM,QAAQ;EACd,KAAK,QAAQ;EACb,SAAS,QAAQ;EACjB,eAAe,QAAQ;EACvB,UAAU,GAAG,MAAM;GACjB,MAAM,KAAK,QAAQ,QAAQ,CAAC;GAC5B,MAAM,KAAK,QAAQ,QAAQ,CAAC;GAC5B,IAAI,KAAK,MAAM,GAAG,OAAO;GACzB,OAAO,QAAQ,KAAK,OAAO,KAAK,MAAM,CAAC,MAAM;EAC/C;CACF,CAAC;AACH;;;;;;;;AASA,eAAsB,aAAa,SAMsC;CACvE,MAAM,QAAQ,QAAQ,uBAAuB,MAAc,EAAE,MAAM,SAAS;CAC5E,MAAM,QAAQ,eAAyB,WAAW,KAAK,MAAM;CAC7D,MAAM,YAAY,MAAM,QAAQ,IAAI;CACpC,MAAM,WAAW,MAAM,QAAQ,GAAG;CAClC,IAAI,UAAU,WAAW,SAAS,QAChC,MAAM,IAAI,MACR,2CAA2C,UAAU,OAAO,MAAM,SAAS,OAAO,EACpF;CAEF,IAAI,UAAU,SAAS,GACrB,MAAM,IAAI,MAAM,oDAAoD;CAItE,MAAM,IAAI,UAAU;CACpB,MAAM,WAAW,IAAI,OAAO,CAAC;CAC7B,MAAM,UAAU,IAAI,OAAO,CAAC;CAE5B,SAAS,cAAc,MAAwB;EAC7C,OAAO,KAAK,MAAM,EAAE,CAAC,CAAC,KAAK,GAAG,MAAO,MAAM,MAAM,SAAS,KAAM,UAAU,EAAI;CAChF;CAEA,MAAM,SAAS,MAAM,OAAe;EAClC,MAAM;EACN,KAAK;EACL,UAAU,SAAS,QAAQ,QAAQ,KAAK,cAAc,IAAI,CAAC,CAAC;EAC5D,eAAe,QAAQ,iBAAiB,IAAI;EAC5C,UAAU,GAAG,MAAM;GAEjB,KAAK,IAAI,IAAI,GAAG,IAAI,EAAE,QAAQ,KAC5B,IAAI,EAAE,OAAO,EAAE,IAAI;IAEjB,MAAM,YAAsB,CAAC;IAC7B,KAAK,IAAI,IAAI,GAAG,IAAI,EAAE,QAAQ,KAAK,IAAI,EAAE,OAAO,EAAE,IAAI,UAAU,KAAK,CAAC;IACtE,IAAI,UAAU,WAAW,GAAG,OAAO;IACnC,IAAI,UAAU,WAAW,GAAG,OAAO;IAEnC,MAAM,OAAO,UAAU,MAAM,GAAG,KAAK,KAAK,UAAU,SAAS,CAAC,CAAC;IAC/D,MAAM,QAAQ,EAAE,MAAM,EAAE;IACxB,KAAK,MAAM,KAAK,MAAM,MAAM,KAAK,EAAE;IACnC,OAAO,MAAM,KAAK,EAAE;GACtB;GAEF,OAAO;EACT;EACA,SAAS,GAAG,MAAM,MAAM;CAC1B,CAAC;CAID,IAAI;CACJ,MAAM,WAAW,OAAO,KAAK,QAAQ,MAAM,EAAE,IAAI,CAAC,CAAC,IAAI;CACvD,MAAM,UAAU,OAAO;CACvB,IAAI,UACG;OAAA,IAAI,IAAI,GAAG,IAAI,GAAG,KACrB,IAAI,SAAS,MAAM,OAAO,QAAQ,IAAI;GACpC,0BAA0B;GAC1B;EACF;;CAKJ,MAAM,mBAAyC,OAAO,KAAK,KAAK,OAAO;EACrE,OAAO,KAAK,cAAc,EAAE,KAAK,CAAC;EAClC,OAAO,EAAE;EACT,MAAM,EAAE;CACV,EAAE;CAEF,OAAO;EACL,SAAS,KAAK,cAAc,OAAO,CAAC;EACpC,MAAM;EACN,WAAW,OAAO;EAClB,mBAAmB,OAAO;EAC1B;CACF;AACF;;;ACzJA,eAAsB,eACpB,OACA,MACA,MACA,UAAiC,CAAC,GACT;CACzB,MAAM,CAAC,GAAG,KAAK,MAAM,QAAQ,IAAI,CAAC,gBAAgB,OAAO,IAAI,GAAG,gBAAgB,OAAO,IAAI,CAAC,CAAC;CAC7F,MAAM,KAAK,QAAQ,cAAc;CACjC,MAAM,YAAY,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE;CAE5C,MAAM,CAAC,SAAS,WAAW,MAAM,QAAQ,IAAI,CAC3C,MAAM,MAAM;EAAE,OAAO;EAAM,MAAM;CAAQ,CAAC,CAAC,CAAC,MAAM,MAAM,EAAE,OAAO,WAAW,CAAC,GAC7E,MAAM,MAAM;EAAE,OAAO;EAAM,MAAM;CAAQ,CAAC,CAAC,CAAC,MAAM,MAAM,EAAE,OAAO,WAAW,CAAC,CAC/E,CAAC;CACD,MAAM,eAAe,iBAAiB,OAAO;CAC7C,MAAM,eAAe,iBAAiB,OAAO;CAE7C,MAAM,eAAkC,UAAU,KAAK,OACrD,cAAc,IAAI,cAAc,YAAY,CAC9C;CACA,MAAM,cAAc,aAAa,QAAQ,KAAK,OAAO,OAAO,GAAG,YAAY,IAAI,CAAC;CAEhF,MAAM,CAAC,SAAS,WAAW,MAAM,QAAQ,IAAI,CAAC,MAAM,OAAO,IAAI,GAAG,MAAM,OAAO,IAAI,CAAC,CAAC;CAMrF,OAAO;EAAE;EAAM;EAAM;EAAW;EAAc,iBAJ5C,SAAS,SAAS,UAAU,KAAA,KAAa,SAAS,SAAS,UAAU,KAAA,IACjE,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QACxC;EAEyD;CAAY;AAC7E;AAIA,SAAS,MACP,GACA,GACA,IACe;CACf,MAAM,KAAiB,MAAM,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,IAAI,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;CACjG,KAAK,IAAI,IAAI,GAAG,KAAK,EAAE,QAAQ,KAC7B,KAAK,IAAI,IAAI,GAAG,KAAK,EAAE,QAAQ,KAC7B,IAAI,GAAG,EAAE,IAAI,IAAK,EAAE,IAAI,EAAG,GAAG,GAAG,EAAE,CAAE,KAAK,GAAG,IAAI,EAAE,CAAE,IAAI,KAAM;MAC1D,GAAG,EAAE,CAAE,KAAK,KAAK,IAAI,GAAG,IAAI,EAAE,CAAE,IAAK,GAAG,EAAE,CAAE,IAAI,EAAG;CAI5D,MAAM,MAAqB,CAAC;CAC5B,IAAI,IAAI,EAAE;CACV,IAAI,IAAI,EAAE;CACV,OAAO,IAAI,KAAK,IAAI,GAClB,IAAI,IAAI,KAAK,IAAI,KAAK,GAAG,EAAE,IAAI,IAAK,EAAE,IAAI,EAAG,GAAG;EAC9C,IAAI,KAAK;GAAE,IAAI;GAAS,GAAG,EAAE,IAAI;GAAK,GAAG,EAAE,IAAI;EAAI,CAAC;EACpD;EACA;CACF,OAAO,IAAI,IAAI,KAAK,IAAI,KAAK,GAAG,IAAI,EAAE,CAAE,OAAQ,GAAG,EAAE,CAAE,IAAI,IAEzD,IAAI,EAAE,IAAI,EAAE,CAAE,KAAK,SAAS,EAAE,IAAI,EAAE,CAAE,KAAK,MAAM;EAC/C,IAAI,KAAK;GAAE,IAAI;GAAW,GAAG,EAAE,IAAI;GAAK,GAAG,EAAE,IAAI;EAAI,CAAC;EACtD;EACA;CACF,OAAO,IAAI,GAAG,IAAI,EAAE,CAAE,MAAO,GAAG,EAAE,CAAE,IAAI,IAAK;EAC3C,IAAI,KAAK;GAAE,IAAI;GAAU,GAAG,EAAE,IAAI;EAAI,CAAC;EACvC;CACF,OAAO;EACL,IAAI,KAAK;GAAE,IAAI;GAAU,GAAG,EAAE,IAAI;EAAI,CAAC;EACvC;CACF;MACK,IAAI,IAAI,MAAM,MAAM,KAAK,GAAG,IAAI,EAAE,CAAE,MAAO,GAAG,EAAE,CAAE,IAAI,KAAM;EACjE,IAAI,KAAK;GAAE,IAAI;GAAU,GAAG,EAAE,IAAI;EAAI,CAAC;EACvC;CACF,OAAO;EACL,IAAI,KAAK;GAAE,IAAI;GAAU,GAAG,EAAE,IAAI;EAAI,CAAC;EACvC;CACF;CAEF,OAAO,IAAI,QAAQ;AACrB;AAEA,SAAS,kBAAkB,GAAmB,GAA4B;CACxE,IAAI,EAAE,KAAK,SAAS,EAAE,KAAK,MAAM,OAAO;CACxC,IAAI,EAAE,KAAK,SAAS,UAAU,EAAE,KAAK,SAAS,QAAQ,OAAO,EAAE,KAAK,aAAa,EAAE,KAAK;CACxF,IAAI,EAAE,KAAK,SAAS,SAAS,EAAE,KAAK,SAAS,OAAO,OAAO,EAAE,KAAK,UAAU,EAAE,KAAK;CACnF,OAAO,EAAE,KAAK,SAAS,EAAE,KAAK;AAChC;AAIA,SAAS,iBAAiB,QAA0C;CAClE,MAAM,sBAAM,IAAI,IAAoB;CACpC,KAAK,MAAM,KAAK,QAAQ;EACtB,MAAM,QAAQ,IAAI,IAAI,EAAE,YAAY,KAAK;EACzC,IAAI,IAAI,EAAE,cAAc,QAAQ,EAAE,KAAK;CACzC;CACA,OAAO;AACT;AAEA,SAAS,YAAY,GAAwB;CAC3C,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,UAAU,EAAE,YAAY;AAC9D;AAEA,SAAS,WAAW,GAAwB;CAC1C,IAAI,EAAE,SAAS,OAAO,OAAO;CAC7B,QAAQ,EAAE,eAAe,MAAM,EAAE,gBAAgB;AACnD;AAEA,SAAS,cACP,IACA,MACA,MACiB;CACjB,IAAI,GAAG,OAAO,SAAS;EACrB,MAAM,KAAK,KAAK,IAAI,GAAG,EAAE,KAAK,MAAM;EACpC,MAAM,KAAK,KAAK,IAAI,GAAG,EAAE,KAAK,MAAM;EACpC,MAAM,WAAW,OAAO,KAAA,KAAa,OAAO,KAAA,IAAY,KAAK,KAAK;EAClE,MAAM,KAAK,YAAY,GAAG,EAAE,IAAI;EAChC,MAAM,KAAK,YAAY,GAAG,EAAE,IAAI;EAChC,MAAM,KAAK,WAAW,GAAG,EAAE,IAAI;EAC/B,MAAM,KAAK,WAAW,GAAG,EAAE,IAAI;EAC/B,OAAO;GACL;GACA;GACA,gBAAgB,OAAO,QAAQ,OAAO,OAAO,KAAK,KAAK;GACvD,YAAY,OAAO,QAAQ,OAAO,OAAO,KAAK,KAAK;GACnD,MACE,aAAa,OAAO,kCAAkC;EAC1D;CACF;CACA,IAAI,GAAG,OAAO,WAAW;EACvB,MAAM,KAAK,KAAK,IAAI,GAAG,EAAE,KAAK,MAAM,KAAK;EAEzC,OAAO;GACL;GACA,WAHS,KAAK,IAAI,GAAG,EAAE,KAAK,MAAM,KAAK,KAGxB;GACf,gBAAgB;GAChB,YAAY;GACZ,MAAM,YAAY,GAAG,EAAE,KAAK,KAAK,GAAG,GAAG,EAAE,KAAK,KAAK,KAAK,GAAG,EAAE,KAAK,KAAK,GAAG,GAAG,EAAE,KAAK;EACtF;CACF;CACA,IAAI,GAAG,OAAO,UAEZ,OAAO;EACL;EACA,UAHS,KAAK,IAAI,GAAG,EAAE,KAAK,MAAM,KAAK;EAIvC,gBAAgB;EAChB,YAAY;EACZ,MAAM,uBAAuB,GAAG,EAAE,KAAK,KAAK,GAAG,GAAG,EAAE,KAAK,KAAK;CAChE;CAIF,OAAO;EACL;EACA,UAAU,EAHD,KAAK,IAAI,GAAG,EAAE,KAAK,MAAM,KAAK;EAIvC,gBAAgB;EAChB,YAAY;EACZ,MAAM,wBAAwB,GAAG,EAAE,KAAK,KAAK,GAAG,GAAG,EAAE,KAAK,KAAK;CACjE;AACF;;;AC/JA,eAAsB,wBACpB,SACA,YACA,UAAiC,CAAC,GACN;CAC5B,MAAM,aAAa,QAAQ,cAAc;CACzC,MAAM,oBAAoB,QAAQ,qBAAqB;CACvD,MAAM,OAAO,QAAQ,QAAQ;CAC7B,MAAM,YAAY,QAAQ,IAAI;CAE9B,MAAM,UAA6B,CAAC;CAIpC,KAAK,MAAM,QAAQ;EADkC;EAAQ;EAAU;EAAQ;CACxD,GAAG;EACxB,MAAM,QAAQ,UAAU,QAAQ,MAAM,EAAE,eAAe,IAAI,CAAC,CAAC;EAC7D,IAAI,QAAQ,YAAY;GACtB,MAAM,YAAY,UAAU,QAAQ,MAAM,EAAE,eAAe,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC;GAC3E,QAAQ,KAAK;IACX,QAAQ;IACR,aAAa,eAAe,KAAK,QAAQ,MAAM,+BAA+B;IAC9E,WAAW,CAAC,GAAG,SAAS;IACxB,WAAW,gBAAgB,KAAK;IAChC,UAAU,KAAK,IAAI,GAAG,IAAI,QAAQ,UAAU;GAC9C,CAAC;EACH;CACF;CAGA,MAAM,OAAO,MAAM,WAAW,SAAS;CACvC,MAAM,qCAAqB,IAAI,IAAoB;CACnD,KAAK,MAAM,KAAK,MACd,mBAAmB,IAAI,EAAE,aAAa,mBAAmB,IAAI,EAAE,UAAU,KAAK,KAAK,CAAC;CAEtF,MAAM,YAAY,CAAC,GAAG,mBAAmB,OAAO,CAAC;CACjD,MAAM,MAAM,UAAU,SAAS,IAAI,SAAS,WAAW,GAAI,IAAI;CAC/D,KAAK,MAAM,KAAK,WAAW;EACzB,MAAM,QAAQ,mBAAmB,IAAI,EAAE,EAAE,KAAK;EAC9C,IAAI,SAAS,OAAO,QAAQ,GAC1B,QAAQ,KAAK;GACX,QAAQ;GACR,aAAa,aAAa,EAAE,GAAG,aAAa,MAAM;GAClD,WAAW,CAAC,CAAC;GACb,WAAW,8BAA8B,EAAE,GAAG;GAC9C,UAAU,KAAK,IAAI,GAAG,IAAI,QAAQ,CAAC,IAAI;EACzC,CAAC;CAEL;CAGA,KAAK,MAAM,KAAK,WAAW;EAEzB,MAAM,SADQ,KAAK,QAAQ,MAAM,EAAE,eAAe,EAAE,EACjC,CAAC,CACjB,KAAK,MAAM,EAAE,SAAS,KAAK,CAAC,CAC5B,QAAQ,MAAmB,OAAO,MAAM,QAAQ;EACnD,IAAI,OAAO,SAAS,GAAG;EACvB,MAAM,OAAO,OAAO,QAAQ,GAAG,MAAM,IAAI,GAAG,CAAC,IAAI,OAAO;EACxD,MAAM,WAAW,OAAO,QAAQ,GAAG,MAAM,KAAK,IAAI,SAAS,GAAG,CAAC,IAAI,OAAO;EAC1E,IAAI,WAAW,mBACb,QAAQ,KAAK;GACX,QAAQ;GACR,aAAa,aAAa,EAAE,GAAG,mCAAmC,SAAS,QAAQ,CAAC,EAAE;GACtF,WAAW,CAAC,CAAC;GACb,WAAW;GACX,UAAU,KAAK,IAAI,GAAG,WAAW,CAAC;EACpC,CAAC;CAEL;CAGA,MAAM,iCAAiB,IAAI,IAAmB;CAC9C,KAAK,MAAM,OAAO,MAAM;EACtB,IAAI,IAAI,SAAS,SAAS,MAAM;EAGhC,MAAM,EAAE,iBAAiB,gBAAgB;GAAE;GAAK,OAAA,MAF5B,WAAW,MAAM,EAAE,OAAO,IAAI,MAAM,CAAC;GAEF,QAAA,MADlC,WAAW,OAAO,EAAE,OAAO,IAAI,MAAM,CAAC;EACG,CAAC;EAC/D,IAAI,iBAAiB,aAAa,iBAAiB,WAAW;EAC9D,MAAM,MAAM,eAAe,IAAI,YAAY,KAAK,CAAC;EACjD,IAAI,KAAK,GAAG;EACZ,eAAe,IAAI,cAAc,GAAG;CACtC;CACA,KAAK,MAAM,CAAC,KAAK,SAAS,gBAAgB;EACxC,IAAI,KAAK,SAAS,GAAG;EACrB,MAAM,oBAAoB,CAAC,GAAG,IAAI,IAAI,KAAK,KAAK,MAAM,EAAE,UAAU,CAAC,CAAC;EACpE,MAAM,YAAY,UAAU,QAAQ,MAAM,kBAAkB,SAAS,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC;EACtF,QAAQ,KAAK;GACX,QAAQ;GACR,aAAa,kBAAkB,IAAI,aAAa,KAAK,OAAO,WAAW,kBAAkB,OAAO;GAChG;GACA,WAAW,mCAAmC,IAAI;GAClD,UAAU,KAAK,IAAI,GAAG,KAAK,SAAS,EAAE;EACxC,CAAC;CACH;CAEA,OAAO,QAAQ,MAAM,GAAG,MAAM,EAAE,WAAW,EAAE,QAAQ,CAAC,CAAC,MAAM,GAAG,IAAI;AACtE;AAEA,SAAS,SAAS,IAAc,GAAmB;CACjD,MAAM,SAAS,CAAC,GAAG,EAAE,CAAC,CAAC,MAAM,GAAG,MAAM,IAAI,CAAC;CAC3C,MAAM,MAAM,KAAK,OAAO,SAAS;CACjC,MAAM,KAAK,KAAK,MAAM,GAAG;CACzB,MAAM,KAAK,KAAK,KAAK,GAAG;CACxB,OAAO,OAAO,OAAQ,OAAO,MAAO,OAAO,QAAS,MAAM;AAC5D;;;ACzGA,SAAgB,kBAAkB,OAAiD;CACjF,IAAI,MAAM,SAAS,GAAG,MAAM,IAAI,MAAM,uDAAuD;CAC7F,MAAM,UAAU,OAAO,KAAK,MAAM,EAAE,CAAE,MAAM;CAC5C,IAAI,QAAQ,SAAS,GAAG,MAAM,IAAI,MAAM,qCAAqC;CAE7E,MAAM,YAAY,MAAM,KAAK,MAAM,EAAE,KAAK;CAC1C,MAAM,YAAY,UAAU,QAAQ,GAAG,MAAM,IAAI,GAAG,CAAC,IAAI,UAAU;CACnE,MAAM,gBACJ,UAAU,QAAQ,KAAK,MAAM,OAAO,IAAI,cAAc,GAAG,CAAC,IAAI,UAAU;CAC1E,IAAI,kBAAkB,GACpB,OAAO;EACL,eAAe;EACf,aAAa,QAAQ,KAAK,OAAO;GAAE,QAAQ;GAAG,iBAAiB;GAAG,OAAO;EAAE,EAAE;EAC7E,cAAc,CAAC;EACf,eAAe;EACf,WAAW;CACb;CAIF,MAAM,cAAoC,QAAQ,KAAK,MAAM;EAC3D,MAAM,UAAUC,UAAQ,QAAQ,MAAM,EAAE,OAAO,MAAM,EAAE;EACvD,MAAM,QAAkB,CAAC;EACzB,KAAK,MAAM,OAAO,QAAQ,OAAO,GAC/B,MAAM,KAAK,IAAI,QAAQ,GAAG,MAAM,IAAI,EAAE,OAAO,CAAC,IAAI,IAAI,MAAM;EAG9D,OAAO;GACL,QAAQ;GACR,iBAHmB,MAAM,QAAQ,KAAK,MAAM,OAAO,IAAI,cAAc,GAAG,CAAC,IAAI,MAAM,SAGnD;GAChC,OAAO,KAAK,IAAI,GAAG,KAAK,IAAI,KAAK,IAAI,GAAG,KAAK;EAC/C;CACF,CAAC;CAGD,MAAM,eAA0C,CAAC;CACjD,KAAK,IAAI,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAClC,KAAK,IAAI,IAAI,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;EAC3C,MAAM,KAAK,QAAQ;EACnB,MAAM,KAAK,QAAQ;EACnB,MAAM,SAASA,UAAQ,QAAQ,MAAM,GAAG,EAAE,OAAO,IAAI,GAAG,EAAE,OAAO,KAAK;EACtE,MAAM,YAAsB,CAAC;EAC7B,KAAK,MAAM,OAAO,OAAO,OAAO,GAC9B,UAAU,KAAK,IAAI,QAAQ,GAAG,MAAM,IAAI,EAAE,OAAO,CAAC,IAAI,IAAI,MAAM;EAElE,MAAM,eACJ,UAAU,QAAQ,KAAK,MAAM,OAAO,IAAI,cAAc,GAAG,CAAC,IAAI,UAAU;EAC1E,MAAM,QAAQ,YAAY,EAAE,CAAE,kBAAkB;EAChD,MAAM,QAAQ,YAAY,EAAE,CAAE,kBAAkB;EAChD,MAAM,sBAAsB,KAAK,IAAI,GAAG,eAAe,QAAQ,KAAK;EACpE,aAAa,KAAK;GAChB,SAAS,CAAC,IAAI,EAAE;GAChB,iBAAiB,sBAAsB;EACzC,CAAC;CACH;CAGF,MAAM,UAAU,YAAY,QAAQ,GAAG,MAAM,IAAI,EAAE,iBAAiB,CAAC;CACrE,MAAM,iBAAiB,aAAa,QAAQ,GAAG,MAAM,IAAI,EAAE,iBAAiB,CAAC;CAC7E,MAAM,gBAAgB,KAAK,IAAI,GAAG,IAAI,UAAU,cAAc;CAE9D,OAAO;EAAE;EAAe;EAAa;EAAc;EAAe,WADhD,UAAU,iBAAiB;CAC+B;AAC9E;AAEA,SAASA,UAAW,OAAY,KAAyC;CACvE,MAAM,oBAAI,IAAI,IAAiB;CAC/B,KAAK,MAAM,QAAQ,OAAO;EACxB,MAAM,IAAI,IAAI,IAAI;EAClB,MAAM,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC;EACzB,IAAI,KAAK,IAAI;EACb,EAAE,IAAI,GAAG,GAAG;CACd;CACA,OAAO;AACT;;;AC1FA,eAAsB,mBACpB,OACA,QACA,UAAsC,CAAC,GACT;CAC9B,MAAM,SAAS,QAAQ,iBAAiB;CACxC,MAAM,MAA2B,CAAC;CAClC,KAAK,MAAM,KAAK,QAAQ;EACtB,MAAM,aAAa,MAAM,gBAAgB,OAAO,EAAE,KAAK;EACvD,MAAM,WAAW,IAAI,IAAI,WAAW,MAAM,KAAK,MAAM,CAAC,EAAE,KAAK,QAAQ,CAAC,CAAC,CAAC;EACxE,KAAK,MAAM,MAAM,EAAE,OAAO;GACxB,MAAM,OAAO,SAAS,IAAI,GAAG,MAAM;GACnC,IAAI,CAAC,MAAM;GACX,MAAM,MAAM,WAAW,MAAM,QAAQ,IAAI;GACzC,MAAM,aAAa,WAAW,MAAM,MAAM,KAAK,IAAI,GAAG,MAAM,MAAM,GAAG,GAAG,CAAC,CAAC,KAAK,MAAM,EAAE,IAAI;GAC3F,IAAI,KAAK;IACP,OAAO,EAAE;IACT,QAAQ,GAAG;IACX,UAAU,GAAG;IACb,OAAO,GAAG;IACV,SAAS;KACP,YAAY,WACT,IAAI,UAAU,CAAC,CACf,QAAQ,MAA8C,MAAM,IAAI;KACnE,MAAM;MAAE,MAAM,KAAK,KAAK;MAAM,MAAM,WAAW,KAAK,IAAI;KAAE;IAC5D;IACA,WAAW,GAAG;IACd,UAAU,GAAG;GACf,CAAC;EACH;CACF;CACA,OAAO;AACT;;AAGA,SAAgB,SAAS,SAAsC;CAC7D,OAAO,GAAG,QAAQ,KAAK,MAAM,KAAK,UAAU,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE;AAC7D;AAEA,SAAS,WAAW,MAAsD;CACxE,IAAI,UAAU,IAAI,GAEhB,OAAO;EAAE,MAAM;EAAa,SADf,KAAK,UAAU,KAAK,SAAS,KAAK,MAAM,GAAG,EAAE,KAAK,IAAI,EAAE,SAAS,CAAC,CAAC,KAAK,IAAI;CAC/C;CAE5C,IAAI,WAAW,IAAI,GACjB,OAAO;EACL,MAAM;EACN,SAAS,GAAG,KAAK,SAAS,GAAG,cAAc,KAAK,IAAI,EAAE,MAAM,cAAc,KAAK,MAAM;CACvF;CAEF,OAAO;AACT;AAEA,SAAS,WAAW,MAAoB;CACtC,IAAI,UAAU,IAAI,GAAG,OAAQ,KAAiB,UAAU;CACxD,IAAI,WAAW,IAAI,GACjB,OAAO,GAAG,KAAK,SAAS,GAAG,cAAc,KAAK,IAAI,EAAE,MAAM,cAAc,KAAK,MAAM;CACrF,OAAO,KAAK;AACd;AAEA,SAAS,cAAc,GAAoB;CACzC,IAAI,MAAM,QAAQ,MAAM,KAAA,GAAW,OAAO;CAC1C,IAAI,OAAO,MAAM,UAAU,OAAO;CAClC,IAAI;EACF,OAAO,KAAK,UAAU,CAAC;CACzB,QAAQ;EACN,OAAO,OAAO,CAAC;CACjB;AACF;;;AC/DA,eAAsB,kBACpB,OACA,QACA,QAC8B;CAC9B,MAAM,SAAS,MAAM,QAAQ,IAAI,OAAO,KAAK,OAAO,OAAO,MAAM,OAAO,EAAE,CAAC,CAAC;CAC5E,MAAM,UAAU,MAAM,mBAAmB,OAAO,MAAM;CACtD,MAAM,UAAU,CAAC,GAAG,IAAI,IAAI,QAAQ,KAAK,MAAM,EAAE,QAAQ,CAAC,CAAC;CAC3D,MAAM,aACJ,QAAQ,SAAS,IAAI,QAAQ,QAAQ,GAAG,MAAM,IAAI,EAAE,OAAO,CAAC,IAAI,QAAQ,SAAS;CACnF,OAAO;EACL,SAAS;EACT,UAAU;GACR,SAAS,OAAO;GAChB,UAAU,QAAQ;GAClB;GACA,6BAAY,IAAI,KAAK,EAAA,CAAE,YAAY;GACnC;EACF;EACA,gBAAgB,SAAS,OAAO;CAClC;AACF;AAaA,SAAgB,qBAAqB,QAAoC;CACvE,OAAO;EACL,MAAM,MAAM,YAAY,OAAO;GAE7B,QAAO,MADc,OAAO,MAAM,OAAO,WAAW,KAAK,EAAA,CAC3C;EAChB;EACA,UAAU;GACR,SAAS,CAAC,eAAe;GACzB,eAAe;EACjB;CACF;AACF;;;;;;;AAQA,eAAsB,uBACpB,OACA,QACA,QAC+E;CAC/E,OAAO,QAAQ,IACb,OAAO,IAAI,OAAO,UAAU;EAC1B,MAAM,CAAC,YAAY,OAAO,MAAM,QAAQ,IAAI,CAC1C,gBAAgB,OAAO,KAAK,GAC5B,MAAM,OAAO,KAAK,CACpB,CAAC;EACD,OAAO;GACL;GACA,OAAO,MAAM,OAAO,MAAM,YAAY,KAAK;GAC3C,cAAc,KAAK,SAAS,SAAS;EACvC;CACF,CAAC,CACH;AACF;;;;;;;;;;;;;;;;;;;;;AC1CA,eAAsB,YACpB,UACA,QACA,SACA,UAA2B,CAAC,GAC6B;CACzD,IAAI,QAAQ,SAAS,GACnB,MAAM,IAAI,MAAM,yEAAyE;CAC3F,MAAM,YAAY,QAAQ,aAAa;CACvC,MAAM,QAAQ,QAAQ,oBAAoB;CAC1C,MAAM,eAAe,QAAQ,gBAAgB;CAC7C,MAAM,cAAc,QAAQ,UAAU;CAEtC,MAAM,YAA8B,CAAC;CACrC,IAAI,iBAAsC,CAAC;CAC3C,MAAM,mBAAsC,CAAC;CAE7C,KAAK,IAAI,IAAI,GAAG,IAAI,aAAa,KAAK;EACpC,MAAM,WAAW,MAAM,SAAS,QAAQ,GAAG,cAAc;EACzD,MAAM,SAA4C,CAAC;EACnD,MAAM,WAAuC,CAAC;EAC9C,MAAM,YAAiC,CAAC;EACxC,KAAK,MAAM,aAAa,UAAU;GAChC,MAAM,SAAS,MAAM,OAAO,eAAe,WAAW,OAAO;GAC7D,IAAI,OAAO,SAAS,GAAG;IACrB,SAAS,KAAK;KAAE;KAAW,QAAQ;IAA6B,CAAC;IACjE;GACF;GACA,MAAM,SAAS,OAAO,KAAK,MAAM,EAAE,KAAK;GACxC,MAAM,SAAS,KAAK,IAAI,GAAG,MAAM,IAAI,KAAK,IAAI,GAAG,MAAM;GACvD,MAAM,WAAW,KAAK,IAAI,GAAG,MAAM;GACnC,OAAO,KAAK;IAAE;IAAW;IAAQ;GAAO,CAAC;GACzC,IAAI,WAAW,OAAO;IACpB,SAAS,KAAK;KACZ;KACA,QAAQ,iCAAiC,SAAS,QAAQ,CAAC,EAAE,KAAK,MAAM;IAC1E,CAAC;IACD;GACF;GACA,IAAI,SAAS,WAAW;IACtB,SAAS,KAAK;KACZ;KACA,QAAQ,2BAA2B,OAAO,QAAQ,CAAC,EAAE,KAAK,UAAU;IACtE,CAAC;IACD;GACF;GACA,UAAU,KAAK,SAAS;EAC1B;EAGA,UAAU,MAAM,GAAG,MAAM;GACvB,MAAM,KAAK,OAAO,MAAM,MAAM,EAAE,UAAU,OAAO,EAAE,EAAE,CAAC,EAAE,UAAU;GAElE,QADW,OAAO,MAAM,MAAM,EAAE,UAAU,OAAO,EAAE,EAAE,CAAC,EAAE,UAAU,KACtD;EACd,CAAC;EACD,MAAM,SAAS,UAAU,MAAM,GAAG,YAAY;EAE9C,KAAK,MAAM,KAAK,QACd,iBAAiB,KAAK;GACpB,IAAI,EAAE;GACN,SAAS,EAAE;GACX,OAAO;GACP,MAAM;IAAE,GAAG,EAAE;IAAM,gBAAgB,OAAO,CAAC;IAAG,QAAQ;GAAY;EACpE,CAAC;EAGH,UAAU,KAAK;GAAE,OAAO;GAAG;GAAU,UAAU;GAAQ;GAAU,iBAAiB;EAAO,CAAC;EAC1F,iBAAiB;CACnB;CAYA,OAAO;EAAE,QAAQ;EAAW,SAAA,IAVR,QAAQ;GAC1B,MAAM;GACN,YAAY;IACV,SAAS;IACT,4BAAW,IAAI,KAAK,EAAA,CAAE,YAAY;IAClC,aAAa;IACb,aAAa,kBAAkB,YAAY,aAAa,UAAU,QAAQ,GAAG,MAAM,IAAI,EAAE,SAAS,QAAQ,CAAC,EAAE;GAC/G;GACA,WAAW;EACb,CACkC;CAAE;AACtC;;;;;;;;;;;;;;;;;;;;;;;;;;;ACtDA,MAAa,qBAAoC;CAC/C,MAAM;CACN,MAAM,IAAI,OAAmD;EAC3D,MAAM,QAAQ,KAAK,IAAI;EACvB,MAAM,MAAM,UAAU,MAAM,KAAK,MAAM,MAAM;GAC3C,KAAK,MAAM;GACX,UAAU;GACV,SAAS,MAAM;GACf,KAAK;IAAE,GAAG,QAAQ;IAAK,IAAI;IAAK,GAAI,MAAM,OAAO,CAAC;GAAG;GACrD,OAAO,MAAM;EACf,CAAC;EACD,MAAM,aAAa,KAAK,IAAI,IAAI;EAChC,MAAM,WAAW,CAAC,EAChB,IAAI,SACJ,UAAU,IAAI,SACb,IAAI,MAAgC,SAAS;EAEhD,OAAO;GACL,QAAQ,IAAI,UAAU;GACtB,SAAS,IAAI,UAAU,GAAA,CAAI,SAAS;GACpC,SAAS,IAAI,UAAU,GAAA,CAAI,SAAS;GACpC;GACA;GACA,aAAa,IAAI,SAAS,CAAC,WAAW,OAAO,IAAI,MAAM,WAAW,IAAI,KAAK,IAAI,KAAA;EACjF;CACF;CACA,MAAM,OAAO,MAAgC;EAC3C,OAAO,iBAAiB,IAAI,MAAM;CACpC;CACA,MAAM,WAAW,MAAgC;EAC/C,OAAO,WAAW,IAAI;CACxB;CACA,MAAM,SAAS,MAAsC;EACnD,IAAI;GACF,OAAO,aAAa,MAAM,MAAM;EAClC,SAAS,KAAK;GAKZ,IAAI,YAAY,KAAK,QAAQ,GAAG,OAAO;GACvC,MAAM;EACR;CACF;CACA,MAAM,QAAQ,MAAmC;EAC/C,IAAI;EACJ,IAAI;GACF,UAAU,YAAY,IAAI;EAC5B,SAAS,KAAK;GAIZ,IAAI,YAAY,KAAK,QAAQ,GAAG,OAAO,CAAC;GACxC,MAAM;EACR;EACA,MAAM,MAAkB,CAAC;EACzB,KAAK,MAAM,QAAQ,SACjB,IAAI;GACF,MAAM,KAAK,SAAS,KAAK,MAAM,IAAI,CAAC;GACpC,IAAI,KAAK;IACP;IACA,aAAa,GAAG,YAAY;IAC5B,QAAQ,GAAG,OAAO;IAClB,WAAW,GAAG,OAAO,IAAI,GAAG,OAAO;GACrC,CAAC;EACH,SAAS,KAAK;GAGZ,IAAI,YAAY,KAAK,QAAQ,GAAG;GAChC,MAAM;EACR;EAEF,OAAO;CACT;AACF;AAEA,SAAS,YAAY,KAAc,MAA8C;CAC/E,OAAO,OAAO,QAAQ,YAAY,QAAQ,QAAS,IAA8B,SAAS;AAC5F;;;;;;;;;;AAWA,SAAS,iBAAiB,MAA6B;CAErD,IAAI,KAAK,SAAS,GAAG,KAAK,KAAK,SAAS,IAAI,GAC1C,OAAO,aAAa,IAAI,IAAI,OAAO;CAGrC,MAAM,QADU,QAAQ,IAAI,QAAQ,GAAA,CACf,MAAM,SAAS,CAAC,CAAC,QAAQ,MAAM,EAAE,SAAS,CAAC;CAChE,MAAM,OACJ,QAAQ,aAAa,WAChB,QAAQ,IAAI,WAAW,sBAAA,CAAuB,MAAM,GAAG,CAAC,CAAC,QAAQ,MAAM,EAAE,SAAS,CAAC,IACpF,CAAC,EAAE;CACT,KAAK,MAAM,OAAO,MAChB,KAAK,MAAM,OAAO,MAAM;EACtB,MAAM,YAAY,KAAK,KAAK,OAAO,GAAG;EACtC,IAAI,aAAa,SAAS,GAAG,OAAO;CACtC;CAEF,OAAO;AACT;AAEA,SAAS,aAAa,MAAuB;CAC3C,IAAI;EAGF,WAAW,MAAM,QAAQ,aAAa,UAAUC,UAAY,OAAOA,UAAY,IAAI;EACnF,OAAO;CACT,SAAS,KAAK;EAIZ,IAAI,YAAY,KAAK,QAAQ,KAAK,YAAY,KAAK,QAAQ,KAAK,YAAY,KAAK,SAAS,GACxF,OAAO;EAET,MAAM;CACR;AACF;;;;;;;;;;;ACnJA,SAAgB,gBAA+B,OAAyC;CACtF,MAAM,kBAAkB,MAAM,mBAAmB;CACjD,OAAO;EACL,MAAM,MAAM,QAAQ;EACpB,WAAW,MAAM,aAAa,CAAC,OAAO;EACtC,QAAQ,MAAM,UAAU;EACxB,OAAO,MAAM,SAAS;EACtB,KAAK,OAAO,QAAQ;GAClB,MAAM,QAAQ,KAAK,IAAI;GACvB,IAAI;GACJ,IAAI;IACF,SAAS,MAAM,MAAM,OAAO;GAC9B,SAAS,KAAK;IACZ,OAAO;KACL,OAAO,MAAM,QAAQ;KACrB,QAAQ;KACR,YAAY,KAAK,IAAI,IAAI;KACzB,UAAU,CACR;MACE,UAAU;MACV,SAAS,kCAAkC,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;KAC5F,CACF;KACA,QAAQ;IACV;GACF;GACA,IAAI;GACJ,IAAI;IACF,SAAS,MAAM,OAAO,IAAI;GAC5B,SAAS,KAAK;IACZ,OAAO;KACL,OAAO,MAAM,QAAQ;KACrB,QAAQ;KACR,YAAY,KAAK,IAAI,IAAI;KACzB,UAAU,CACR;MACE,UAAU;MACV,SAAS,yBAAyB,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;KACnF,CACF;KACA,QAAQ;IACV;GACF;GACA,IAAI,IAAI,OAAO,SACb,OAAO;IACL,OAAO,MAAM,QAAQ;IACrB,QAAQ;IACR,YAAY,KAAK,IAAI,IAAI;IACzB,UAAU,CAAC;IACX,QAAQ;GACV;GAGF,MAAM,aAAa,CAAC,mBAAmB,OAAO,kBAAkB;GAChE,MAAM,OAAO,OAAO,MAAM;GAC1B,MAAM,WAAoC,CAAC;GAC3C,IAAI,CAAC,OAAO,IACV,SAAS,KAAK;IACZ,UAAU;IACV,SAAS;IACT,WAAW,OAAO,UAAU,GAAA,CAAI,MAAM,KAAK;GAC7C,CAAC;GAEH,IAAI,OAAO,MAAM,mBAAmB,CAAC,OAAO,eAC1C,SAAS,KAAK;IACZ,UAAU;IACV,SAAS,uCAAuC,OAAO,eAAe,YAAY;GACpF,CAAC;GAEH,OAAO;IACL,OAAO,MAAM,QAAQ;IACrB,QAAQ,OAAO,SAAS;IACxB,OAAO,OAAO,IAAI;IAClB,YAAY,KAAK,IAAI,IAAI;IACzB;IACA,QAAQ,OACJ,kBAAkB,MAAM,SAAS,KAAK,MAAM,OAAO,KAAK,KAAK,OAAO,cAAc,MAAM,OAAO,gBAAgB,OAC/G,CAAC,OAAO,KACN,yBACA;IACN,aAAa;KACX,eAAe,OAAO,KAAK,IAAI;KAC/B,kBAAkB,OAAO,kBAAkB,OAAO,IAAI;KACtD,eAAe,OAAO,cAAc;IACtC;GACF;EACF;CACF;AACF;;;;;;AAmCA,SAAgB,iBAAiB,OAA4C;CAC3E,OAAO,EACL,KAAK,YAAY;EACf,MAAM,QAAQ,KAAK,IAAI;EACvB,MAAM,MAAM,MAAM,gBAAgB;EAClC,MAAM,cAAc,MAAM,eAAe;EACzC,MAAM,gBAAgB,MAAM,iBAAiB;EAC7C,MAAM,YAAY,MAAM,aAAa;EACrC,MAAM,SAAS,MAAM,MAAM,KAAK,KAAK;GAAE,KAAK,MAAM;GAAS;EAAU,CAAC;EACtE,MAAM,KAAK,OAAO,aAAa;EAC/B,IAAI,gBAAgB;EACpB,IAAI;GACF,MAAM,cAAc,MAAM,MAAM,OAAO,GAAG,YAAY,GAAG,eAAe;GACxE,gBAAgB,MAAM,QAAQ,WAAW;EAC3C,QAAQ;GACN,gBAAgB;EAClB;EAEA,OAAO;GACL;GACA,UAHa,OAAO,UAAU,OAAO,WAAW,GAAA,CAAI,MAAM,KAG/C;GACX,YAAY,KAAK,IAAI,IAAI;GACzB;GACA;EACF;CACF,EACF;AACF;;;;;;;;;;;AA6BA,SAAgB,qBAAqB,OAAgD;CACnF,OAAO,EACL,KAAK,YAAY;EACf,MAAM,QAAQ,KAAK,IAAI;EACvB,MAAM,WAAW,MAAM,gBAAgB;EACvC,MAAM,SAAS,MAAM,iBAAiB;EACtC,MAAM,YAAY,MAAM,aAAa;EAErC,MAAM,UAAU,MAAM,MAAM,OAAO,eAAe;EAClD,MAAM,WAAW,UAAU,QAAQ,MAAM,MAAM,OAAO,gBAAgB;EACtE,IAAI,CAAC,WAAW,CAAC,UACf,OAAO;GACL,IAAI;GACJ,QAAQ;GACR,YAAY,KAAK,IAAI,IAAI;GACzB,aAAa;GACb,eAAe;EACjB;EAGF,MAAM,QAAQ,MAAM,MAAM,KAAK,UAAU;GAAE,KAAK,MAAM;GAAS;EAAU,CAAC;EAC1E,IAAI,MAAM,aAAa,GAErB,OAAO;GACL,IAAI;GACJ,QAAQ,mBAHK,MAAM,UAAU,MAAM,WAAW,GAAA,CAAI,MAAM,KAG5B;GAC5B,YAAY,KAAK,IAAI,IAAI;GACzB,aAAa;GACb,eAAe;EACjB;EAGF,MAAM,MAAM,MAAM,MAAM,KAAK,QAAQ;GAAE,KAAK,MAAM;GAAS;EAAU,CAAC;EACtE,IAAI,IAAI,aAAa,GAEnB,OAAO;GACL,IAAI;GACJ,QAAQ,8BAHK,IAAI,UAAU,IAAI,WAAW,GAAA,CAAI,MAAM,KAGb;GACvC,YAAY,KAAK,IAAI,IAAI;GACzB,aAAa;GACb,eAAe;EACjB;EAIF,OAAO;GACL,IAAI;GACJ,UAHa,IAAI,UAAU,IAAI,WAAW,GAAA,CAAI,MAAM,KAGzC;GACX,YAAY,KAAK,IAAI,IAAI;GACzB,aAAa;GACb,eAAe;EACjB;CACF,EACF;AACF;;;ACrRA,MAAa,uBAA4C;CACvD;EAEE,MAAM;EACN,OAAO;CACT;CACA;EAEE,MAAM;EACN,OAAO;CACT;CACA;EAEE,MAAM;EACN,OAAO;CACT;CACA;EAEE,MAAM;EACN,OAAO;CACT;CACA;EAEE,MAAM;EACN,OAAO;CACT;CACA;EAIE,MAAM;EACN,OAAO;EACP,YAAY,MAAM,OAAO,EAAE,MAAM,CAAC;CACpC;AACF;;;;;;;;AAyBA,SAAgB,kBAAkB,MAAc,OAAuB,CAAC,GAAkB;CACxF,IAAI,CAAC,MAAM,OAAO;EAAE,OAAO;EAAM,SAAS;EAAM,SAAS,CAAC;CAAE;CAE5D,MAAM,WAAW,CAAC,GAAI,KAAK,SAAS,CAAC,GAAI,GAAG,oBAAoB,CAAC,CAAC,QAC/D,MAAM,CAAC,KAAK,QAAQ,KAAK,KAAK,SAAS,EAAE,IAAI,CAChD;CAEA,KAAK,MAAM,KAAK,UAAU;EACxB,MAAM,UAAU,MAAM,KAAK,KAAK,SAAS,EAAE,KAAK,CAAC;EACjD,IAAI,QAAQ,WAAW,GAAG;EAM1B,OAAO;GACL,OALY,EAAE,YACZ,QAAQ,QAAQ,KAAK,MAAM,MAAM,EAAE,UAAW,CAAC,GAAG,CAAC,IACnD,QAAQ;GAIV,SAAS,EAAE;GACX,SAAS,QAAQ,MAAM,GAAG,CAAC,CAAC,CAAC,KAAK,MAAM,EAAE,EAAE;EAC9C;CACF;CAEA,OAAO;EAAE,OAAO;EAAM,SAAS;EAAM,SAAS,CAAC;CAAE;AACnD;;;;;;;;;;ACCA,SAAgB,UACd,OACY;CACZ,OAAO;EACL,MAAM,MAAM,QAAQ;EACpB,WAAW,MAAM,aAAa,CAAC,OAAO;EACtC,QAAQ,MAAM,UAAU;EACxB,OAAO,MAAM,SAAS;EACtB,KAAK,OAAO,QAAQ;GAClB,MAAM,QAAQ,KAAK,IAAI;GACvB,MAAM,OAAO,IAAI,KAAK,YAAY,MAAM;GACxC,IAAI,CAAC,MACH,OAAO;IACL,OAAO,MAAM,QAAQ;IACrB,QAAQ;IACR,YAAY;IACZ,UAAU,CAAC;IACX,QAAQ;GACV;GAGF,IAAI;GACJ,IAAI;IACF,SAAS,MAAM,MAAM,OAAO;GAC9B,SAAS,KAAK;IACZ,OAAO;KACL,OAAO,MAAM,QAAQ;KACrB,QAAQ;KACR,YAAY,KAAK,IAAI,IAAI;KACzB,UAAU,CACR;MACE,UAAU;MACV,SAAS,gCAAgC,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;KAC1F,CACF;KACA,QAAQ;IACV;GACF;GAEA,MAAM,WAAoC,CAAC;GAC3C,MAAM,cAAsF,CAAC;GAC7F,IAAI,SAAS;GACb,IAAI;IACF,MAAM,SAAS,MAAM,OAAO,KAAK,KAAK,GAAG;IACzC,SAAS,OAAO;IAChB,IAAI,CAAC,OAAO,IACV,SAAS,KAAK;KACZ,UAAU;KACV,SAAS,aAAa,KAAK,IAAI,UAAU,OAAO,WAAW,KAAK,OAAO,aAAa;IACtF,CAAC;IAEH,IAAI,UAAU,KAAK,gBACjB,KAAK,IAAI,IAAI,GAAG,IAAI,KAAK,MAAM,QAAQ,KAAK;KAC1C,MAAM,OAAO,KAAK,MAAM;KACxB,IAAI,IAAI,OAAO,SAAS;KACxB,MAAM,YAAY,KAAK,IAAI;KAC3B,IAAI;KACJ,IAAI;MACF,SAAS,MAAM,OAAO,KAAK,IAAI;KACjC,SAAS,KAAK;MACZ,SAAS;OACP,IAAI;OACJ,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;OACzD,YAAY,KAAK,IAAI,IAAI;MAC3B;KACF;KACA,YAAY,KAAK;MAAE;MAAM;MAAQ,OAAO;KAAE,CAAC;KAC3C,IAAI,CAAC,OAAO,IAAI;MACd,SAAS,KAAK;OACZ,UAAU,KAAK,YAAY;OAC3B,SAAS,QAAQ,EAAE,IAAI,KAAK,SAAS,KAAK,SAAS,IAAI,KAAK,OAAO,KAAK,GAAG,SAAS,OAAO,WAAW,KAAK,OAAO,aAAa;MACjI,CAAC;MACD,IAAI,CAAC,KAAK,gBAAgB;KAC5B;IACF;GAEJ,UAAU;IACR,IAAI;KACF,MAAM,OAAO,MAAM;IACrB,QAAQ,CAER;GACF;GAEA,MAAM,aAAa,KAAK,MAAM;GAC9B,MAAM,WAAW,YAAY;GAC7B,MAAM,cAAc,YAAY,QAAQ,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC;GAC3D,MAAM,SAAgC,CAAC,SACnC,SACA,gBAAgB,aACd,SACA;GAKN,MAAM,cAAc,IAAI;GACxB,MAAM,aAAa,SAAS,IAAI,KAAK;GACrC,MAAM,QAAQ,cAAc,IAAI,QAAQ,YAAY,YAAA,CAAa,QAAQ,CAAC,CAAC,IAAI;GAE/E,OAAO;IACL,OAAO,MAAM,QAAQ;IACrB;IACA;IACA,YAAY,KAAK,IAAI,IAAI;IACzB;IACA,QACE,WAAW,SACP,GAAG,WAAW,GAAG,WAAW,iBAC5B,GAAG,YAAY,GAAG,WAAW,eAAe,WAAW,aAAa,qBAAqB,SAAS,KAAK;IAC7G,aAAa;KACX,YAAY,SAAS,IAAI;KACzB,gBAAgB;KAChB,iBAAiB;KACjB,cAAc;IAChB;GACF;EACF;CACF;AACF;;;;;;;;;;;;;;;;;;;;;;;;;;;AChMA,MAAa,6BAA6B;AAyC1C,MAAM,gBAAgB;AACtB,MAAM,kBAAkB;AACxB,MAAM,qBAAqB;AAC3B,MAAM,qBAAqB;AAC3B,MAAM,uBAAuB;AAC7B,MAAM,mBAAmB;AAEzB,MAAM,gBAAgB;CACpB,MAAM;CACN,sBAAsB;CACtB,UAAU,CAAC,SAAS,UAAU;CAC9B,YAAY;EACV,OAAO;GAAE,MAAM;GAAU,SAAS;GAAG,SAAS;EAAE;EAChD,UAAU;GAAE,MAAM;GAAU,WAAW;GAAI,WAAW;EAAI;CAC5D;AACF;AAEA,SAAS,SAAS,MAAc,KAAa,OAAuB;CAClE,IAAI,KAAK,UAAU,KAAK,OAAO;CAC/B,OAAO,GAAG,KAAK,MAAM,GAAG,GAAG,EAAE,iBAAiB,KAAK,SAAS,IAAI,YAAY,MAAM;AACpF;AAEA,SAAS,YAAY,OAAyB,MAA4C;CACxF,MAAM,aAAa,MAAM,YACtB,QAAQ,MAAM,EAAE,QAAQ,UAAU,KAAK,eAAe,CAAC,CACvD,KAAK,MAAM,aAAa,EAAE,KAAK,QAAQ,EAAE,SAAS,CAAC,CACnD,KAAK,MAAM;CACd,MAAM,OAAO,MAAM,cAAc;CAEjC,OAAO;;;;;;;;EAQP,MAAM,YAAY;;EAElB,MAAM,gBAAgB,+BAA+B,MAAM,cAAc,mBAAmB,MAAM,uBAAuB,GAAG,QAAQ,KAAK,OAAO,4CAA4C,SAAS,MAAM,KAAK,cAAc,MAAM,EAAE,QAAQ,GAAG;EACjP,SAAS,YAAY,KAAK,gBAAgB,QAAQ,EAAE;;;;;;;;;;;;;;;;;;;;;;;;AAwBtD;;;;AAKA,eAAsB,oBACpB,OACA,UAA8B,CAAC,GACH;CAC5B,MAAM,QAAQ,KAAK,IAAI;CACvB,MAAM,OAAqC;EACzC,OAAO,QAAQ,SAAS;EACxB,WAAW,QAAQ,aAAa;EAChC,WAAW,QAAQ,aAAa;EAChC,gBAAgB,QAAQ,kBAAkB;EAC1C,iBAAiB,QAAQ,mBAAmB;EAC5C,cAAc,QAAQ,gBAAgB;EACtC,KAAK,QAAQ,OAAO,CAAC;EACrB,YAAY,QAAQ,cAAc,IAAI,WAAW;EACjD,WAAW,QAAQ,aAAa;EAChC,UAAU,QAAQ,YAAY,CAAC;EAC/B,QAAQ,QAAQ,UAAU,IAAI,gBAAgB,CAAC,CAAC;CAClD;CAEA,IAAI,MAAM,YAAY,WAAW,KAAK,CAAC,MAAM,YAC3C,OAAO;EACL,MAAM;EACN,SAAS;EACT,OAAO;EACP,UAAU;EACV,YAAY;EACZ,SAAS;EACT,WAAW;EACX,OAAO;CACT;CAGF,IAAI;CACJ,IAAI;EACF,MAAM,UAAU;GACd,OAAO,KAAK;GACZ,UAAU,CACR;IACE,MAAM;IACN,SACE;GACJ,GACA;IAAE,MAAM;IAAiB,SAAS,YAAY,OAAO,IAAI;GAAE,CAC7D;GACA,YAAY;IAAE,MAAM;IAAsB,QAAQ;GAAc;GAChE,aAAa;GACb,WAAW,KAAK;GAChB,WAAW,KAAK;EAClB;EACA,MAAM,OAAO,MAAM,KAAK,WAAW,YAAY;GAC7C,SAAS;GACT,OAAO,KAAK;GACZ,OAAO;GACP,OAAO,KAAK;GACZ,GAAI,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,SAAS,IAAI,EAAE,MAAM,KAAK,SAAS,IAAI,CAAC;GACvE,eAAe,2BAA2B,SAAS,KAAK,GAAG;GAC3D,QAAQ,KAAK;GACb,UAAU,QAAQ,WAChB,YAAiD,SAAS;IACxD,GAAG,KAAK;IACR;IACA,gBAAgB;GAClB,CAAC;GACH,UAAU,EAAE,aAAa,mBAAmB,MAAM;GAClD,kBAAkB;EACpB,CAAC;EACD,UAAU,KAAK;EACf,IAAI,CAAC,KAAK,WAAW,MAAM,KAAK;EAChC,MAAM,EAAE,UAAU,KAAK;EAEvB,MAAM,QAAQ,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,OAAO,OAAO,SAAS,CAAC,CAAC,CAAC;EAChE,OAAO;GACL,MAAM;GACN,SAAS;GACT,OAAO,OAAO,MAAM,QAAQ,CAAC,CAAC;GAC9B,UAAU,OAAO,OAAO,YAAY,EAAE,CAAC,CAAC,MAAM,GAAG,GAAG;GACpD,YAAY,KAAK,IAAI,IAAI;GACzB,SAAS,KAAK,QAAQ,cAAc,OAAO,KAAK,QAAQ;GACxD,WAAW;EACb;CACF,SAAS,KAAK;EACZ,OAAO;GACL,MAAM;GACN,SAAS;GACT,OAAO;GACP,UAAU;GACV,YAAY,KAAK,IAAI,IAAI;GACzB,SAAS,WAAW,CAAC,QAAQ,cAAc,QAAQ,UAAU;GAC7D,WAAW;GACX,OAAO,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;EACxD;CACF;AACF;;;;AAKA,SAAgB,uBACd,UAA8B,CAAC,GAC0B;CACzD,QAAQ,UAAU,oBAAoB,OAAO,OAAO;AACtD;;;;;;;;AC1KA,SAAgB,oBAAoB,MAAc,UAAkC;CAClF,MAAM,UAAU,qBAAqB,KAAK,QAAQ;CAClD,IAAI,SAEF,OAAO,IADQ,OAAO,IAAI,QAAQ,GAAG,MAAM,GACnC,CAAC,CAAC,KAAK,IAAI;CAErB,MAAM,YAAY,4DAA4D,KAAK,QAAQ;CAC3F,IAAI,WAAW;EACb,MAAM,GAAG,KAAK,MAAM,SAAS;EAK7B,OAAO,IAJQ,OACb,IAAI,IAAI,aAAa,KAAK,eAAe,MAAO,QAAQ,uBAAuB,MAAM,EAAE,OACvF,GAEM,CAAC,CAAC,KAAK,IAAI;CACrB;CACA,MAAM,kBAAkB,iCAAiC,KAAK,QAAQ;CACtE,IAAI,iBAAiB;EACnB,MAAM,GAAG,KAAK,QAAQ;EAEtB,OAAO,IADQ,OAAO,IAAI,IAAI,aAAa,KAAK,MAAM,GAC9C,CAAC,CAAC,KAAK,IAAI;CACrB;CACA,OAAO;AACT;;;;;;;AAUA,SAAgB,iBAAiB,MAAc,SAA2B;CACxE,MAAM,uBAAO,IAAI,IAAY;CAG7B,KAAK,MAAM,MAAM,CAAC,qDAAQ,oDAAQ,GAAG;EACnC,IAAI,QAAgC,GAAG,KAAK,IAAI;EAChD,OAAO,UAAU,MAAM;GACrB,MAAM,MAAM,MAAM;GAClB,IAAI;IACF,KAAK,IAAI,IAAI,IAAI,KAAK,OAAO,CAAC,CAAC,SAAS,CAAC;GAC3C,QAAQ,CAER;GACA,QAAQ,GAAG,KAAK,IAAI;EACtB;CACF;CACA,OAAO,MAAM,KAAK,IAAI;AACxB;;;;;;;AAUA,SAAgB,wBACd,MACA,kBACA,SAAgC,CAAC,GACV;CACvB,MAAM,QAAQ,KAAK,IAAI;CACvB,IAAI,iBAAiB,WAAW,GAC9B,OAAO;EACL,OAAO;EACP,cAAc;EACd,YAAY;EACZ,UAAU,CAAC;EACX,YAAY;EACZ,qBAAqB;CACvB;CAEF,MAAM,WAAW,GAAG,KAAK,IAAI,OAAO,KAAK,IAAI,IAAI,YAAY;CAC7D,MAAM,WAAqC,iBAAiB,KAAK,YAAY;EAC3E,MAAM,kBAA4B,CAAC;EACnC,KAAK,MAAM,MAAM,QAAQ,UACvB,IAAI,SAAS,SAAS,GAAG,YAAY,CAAC,GAAG,gBAAgB,KAAK,EAAE;EAElE,MAAM,yBAAyB,QAAQ,kBACnC,oBAAoB,MAAM,QAAQ,eAAe,IACjD;EACJ,MAAM,oBAAoB,2BAA2B,QAAQ,2BAA2B;EACxF,MAAM,QAAQ,gBAAgB,SAAS,KAAK;EAC5C,OAAO;GAAE,SAAS,QAAQ;GAAM;GAAO;GAAiB;EAAuB;CACjF,CAAC;CACD,MAAM,eAAe,SAAS,QAAQ,MAAM,EAAE,KAAK,CAAC,CAAC;CACrD,OAAO;EACL,OAAO,eAAe,iBAAiB;EACvC;EACA,YAAY,iBAAiB;EAC7B;EACA,YAAY,KAAK,IAAI,IAAI;EACzB,qBAAqB,SAAS;CAChC;AACF;;;;;;AAOA,eAAsB,2BACpB,YACA,kBACA,UAAkC,CAAC,GACH;CAChC,MAAM,QAAQ,KAAK,IAAI;CACvB,MAAM,UAAU,QAAQ,SAAS,WAAW;CAC5C,MAAM,cAAc,QAAQ,iBAAiB;CAC7C,MAAM,eAAe,QAAQ,kBAAkB;CAE/C,IAAI,iBAAiB,WAAW,GAC9B,OAAO;EACL,OAAO;EACP,cAAc;EACd,YAAY;EACZ,UAAU,CAAC;EACX,YAAY;EACZ,qBAAqB;CACvB;CAGF,IAAI,OAAO;CACX,IAAI;EACF,MAAM,OAAO,MAAM,QAAQ,YAAY;GACrC,UAAU;GACV,QAAQ,YAAY,QAAQ,WAAW;EACzC,CAAC;EACD,IAAI,CAAC,KAAK,IACR,OAAO,SAAS,kBAAkB,OAAO,gBAAgB,KAAK,QAAQ;EAExE,OAAO,MAAM,KAAK,KAAK;CACzB,SAAS,KAAK;EACZ,OAAO,SAAS,kBAAkB,OAAO,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;CAC3F;CAEA,MAAM,YAAY,iBAAiB,MAAM,UAAU;CACnD,MAAM,cAAc,MAAM,QAAQ,IAChC,UAAU,IAAI,OAAO,MAAM;EACzB,IAAI;GACF,MAAM,IAAI,MAAM,QAAQ,GAAG;IACzB,UAAU;IACV,QAAQ,YAAY,QAAQ,YAAY;GAC1C,CAAC;GACD,IAAI,CAAC,EAAE,IAAI,OAAO;GAClB,OAAO,MAAM,EAAE,KAAK;EACtB,QAAQ;GACN,OAAO;EACT;CACF,CAAC,CACH;CAEA,OAAO,wBAAwB,MAAM,kBAAkB,WAAW;AACpE;AAEA,SAAS,SACP,kBACA,OACA,OACuB;CACvB,OAAO;EACL,OAAO;EACP,cAAc;EACd,YAAY,iBAAiB;EAC7B,UAAU,iBAAiB,KAAK,OAAO;GACrC,SAAS,EAAE;GACX,OAAO;GACP,iBAAiB,CAAC;GAClB,wBAAwB;EAC1B,EAAE;EACF,YAAY,KAAK,IAAI,IAAI;EACzB,qBAAqB;EACrB;CACF;AACF;;;;;;;;;;;;;;ACpGA,SAAgB,oBAAoB,OAKpB;CACd,IAAI,CAAC,MAAM,WAAW,OAAO;CAC7B,MAAM,YAAY,MAAM,aAAa;CACrC,MAAM,eAAe,MAAM,SAAS,QACjC,MAAM,EAAE,aAAa,eAAe,EAAE,YAAY,UAAU,EAAE,SAAS,KAAK,EAC/E;CACA,OAAO,MAAM,SAAS,aAAa,aAAa,WAAW,IAAI,SAAS;AAC1E;;;;AAOA,IAAa,qBAAb,MAA+C;CAChB;CAA7B,YAAY,QAAuC;EAAtB,KAAA,SAAA;EAC3B,MAAM,uBAAO,IAAI,IAAY;EAC7B,KAAK,MAAM,KAAK,QAAQ;GACtB,IAAI,KAAK,IAAI,EAAE,IAAI,GAAG,MAAM,IAAI,MAAM,6CAA6C,EAAE,KAAK,EAAE;GAC5F,KAAK,IAAI,EAAE,IAAI;EACjB;EACA,KAAK,MAAM,KAAK,QACd,KAAK,MAAM,OAAO,EAAE,aAAa,CAAC,GAChC,IAAI,CAAC,KAAK,IAAI,GAAG,GACf,MAAM,IAAI,MACR,8BAA8B,EAAE,KAAK,gBAAgB,IAAI,0BAC3D;CAIR;CAEA,MAAM,IAAI,MAAuD;EAC/D,MAAM,cAAc,KAAK,IAAI;EAC7B,MAAM,YAAY,IAAI,KAAK,WAAW,CAAC,CAAC,YAAY;EACpD,MAAM,aAAa,IAAI,gBAAgB;EACvC,MAAM,aAAa,KAAK;EACxB,MAAM,eACJ,cAAc,OACV,iBAAiB,WAAW,sBAAM,IAAI,MAAM,sBAAsB,CAAC,GAAG,UAAU,IAChF;EAEN,MAAM,UAAyB,CAAC;EAChC,MAAM,SAAsC,CAAC;EAE7C,IAAI;GACF,KAAK,MAAM,SAAS,KAAK,QAAQ;IAE/B,MAAM,SAAS,MAAM,aAAa,CAAC,EAAA,CAAG,QAAQ,MAAM,OAAO,EAAE,EAAE,WAAW,MAAM;IAChF,IAAI,MAAM,SAAS,GAAG;KACpB,MAAM,UAAuB;MAC3B,OAAO,MAAM;MACb,QAAQ;MACR,YAAY;MACZ,UAAU,CAAC;MACX,QAAQ,mCAAmC,MAAM,KAAK,IAAI;KAC5D;KACA,QAAQ,KAAK,OAAO;KACpB,OAAO,MAAM,QAAQ;KACrB,KAAK,UAAU,OAAO;KACtB;IACF;IAGA,MAAM,qBAAqB,IAAI,gBAAgB;IAC/C,MAAM,eAAe,aAAa,WAAW,QAAQ,mBAAmB,MAAM;IAC9E,MAAM,aACJ,MAAM,SAAS,OACX,iBACQ,mBAAmB,sBAAM,IAAI,MAAM,SAAS,MAAM,KAAK,KAAK,CAAC,GACnE,MAAM,KACR,IACA;IAEN,MAAM,aAAa,KAAK,IAAI;IAC5B,IAAI;IACJ,IAAI;IACJ,MAAM,eAAe,IAAI,SAAgB,UAAU,WAAW;KAC5D,MAAM,yBAA+B;MACnC,MAAM,SAAS,aAAa;MAC5B,OAAO,kBAAkB,QAAQ,SAAS,IAAI,MAAM,OAAO,UAAU,SAAS,CAAC,CAAC;KAClF;KACA,IAAI,aAAa,SAAS;MACxB,iBAAiB;MACjB;KACF;KACA,aAAa,iBAAiB,SAAS,kBAAkB,EAAE,MAAM,KAAK,CAAC;KACvE,sBAAsB,aAAa,oBAAoB,SAAS,gBAAgB;IAClF,CAAC;IACD,IAAI;KACF,SAAS,MAAM,QAAQ,KAAK,CAC1B,QAAQ,QACN,MAAM,IAAI;MAAE,KAAK,KAAK;MAAK,OAAO,EAAE,GAAG,OAAO;MAAG,QAAQ;KAAa,CAAC,CACzE,GACA,YACF,CAAC;IACH,SAAS,KAAK;KACZ,MAAM,UAAU,aAAa;KAC7B,SAAS;MACP,OAAO,MAAM;MACb,QAAQ,UAAU,YAAY;MAC9B,aAAa,MAAM,eAAe;MAClC,YAAY,KAAK,IAAI,IAAI;MACzB,UAAU,CACR;OACE,UAAU;OACV,SAAS,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;OACxD,OAAO,MAAM;MACf,CACF;MACA,QAAQ,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;KACzD;IACF,UAAU;KACR,gBAAgB;KAChB,IAAI,YAAY,aAAa,UAAU;IACzC;IAEA,IAAI,OAAO,WAAW,WAAW,OAAO,WAAW,WACjD,OAAO,gBAAgB,MAAM,eAAe;IAI9C,OAAO,WAAW,OAAO,SAAS,KAAK,OAAO;KAAE,GAAG;KAAG,OAAO,EAAE,SAAS,MAAM;IAAK,EAAE;IACrF,QAAQ,KAAK,MAAM;IACnB,OAAO,MAAM,QAAQ;IACrB,KAAK,UAAU,MAAM;IAErB,IAAI,WAAW,OAAO,SAAS;GACjC;GAGA,OADe,UAAU,KAAK,QAAQ,SAAS,WAAW,WAC9C;EACd,UAAU;GACR,IAAI,cAAc,aAAa,YAAY;EAC7C;CACF;AACF;AAEA,SAAS,UACP,QACA,SACA,WACA,aACoB;CACpB,MAAM,+BAAe,IAAI,IAAoB;CAC7C,MAAM,oCAAoB,IAAI,IAAqB;CACnD,KAAK,MAAM,KAAK,QAAQ;EACtB,aAAa,IAAI,EAAE,MAAM,EAAE,UAAU,CAAC;EACtC,kBAAkB,IAAI,EAAE,MAAM,EAAE,0BAA0B,KAAK;CACjE;CAEA,IAAI,YAAY;CAChB,IAAI,YAAY;CAChB,IAAI,eAAe;CACnB,IAAI,aAAa;CACjB,IAAI,kBAAkB;CACtB,IAAI,sBAAsB;CAE1B,KAAK,MAAM,KAAK,SAAS;EACvB,MAAM,SAAS,aAAa,IAAI,EAAE,KAAK,KAAK;EAC5C,MAAM,cAAc,kBAAkB,IAAI,EAAE,KAAK,KAAK;EACtD,IAAI,EAAE,WAAW,QAAQ;OACpB,IAAI,EAAE,WAAW,QAAQ;OACzB,IAAI,EAAE,WAAW,WAAW;OAC5B;EAEL,IAAI,uBAAuB,CAAC,KAAK,SAAS,GACpC;OAAA,EAAE,WAAW,QAAQ;IACvB,mBAAmB;IACnB,uBAAuB,SAAS,EAAE;GACpC,OAAO,IAAI,EAAE,WAAW,QAClB;QAAA,aAAa;KACf,mBAAmB;KACnB,uBAAuB,SAAS,EAAE;IACpC;;;CAIN;CAEA,MAAM,eAAe,KAAK,IAAI;CAC9B,MAAM,eAAe,kBAAkB,IAAI,sBAAsB,kBAAkB;CACnF,MAAM,eAAe,IAAI,IAAI,QAAQ,KAAK,WAAW,CAAC,OAAO,OAAO,MAAM,CAAC,CAAC;CAiB5E,MAAM,YAfJ,kBAAkB,KAClB,QAAQ,WAAW,OAAO,UAC1B,OAAO,OAAO,UAAU;EACtB,MAAM,SAAS,aAAa,IAAI,MAAM,IAAI;EAC1C,IAAI,CAAC,QAAQ,OAAO;EACpB,KAAK,MAAM,UAAU,MAAM,GAAG,OAAO;EACrC,IAAI,OAAO,WAAW,QACpB,OAAO,OAAO,UAAU,KAAA,KAAa,uBAAuB,MAAM;EAEpE,OACE,OAAO,WAAW,UAClB,MAAM,2BAA2B,QACjC,uBAAuB,MAAM;CAEjC,CAAC,KAE0B,kBAAkB,KAAK,OAAO,SAAS,YAAY,IAC1E,eACA,KAAA;CACN,MAAM,UACJ,cAAc,KAAA,KACd,QAAQ,WAAW,OAAO,UAC1B,cAAc,KACd,iBAAiB,KACjB,eAAe;CACjB,OAAO;EACL,QAAQ;EACR;EACA;EACA;EACA;EACA;EACA;EACA,GAAI,cAAc,KAAA,IAAY,CAAC,IAAI,EAAE,UAAU;EAC/C,OAAO;EACP,OAAO,aAAa;EACpB,YAAY,eAAe;EAC3B;EACA,YAAY,IAAI,KAAK,YAAY,CAAC,CAAC,YAAY;CACjD;AACF;AAEA,SAAS,uBACP,QACoE;CACpE,QACG,OAAO,WAAW,UAAU,OAAO,WAAW,WAC/C,OAAO,OAAO,UAAU,YACxB,OAAO,SAAS,OAAO,KAAK,KAC5B,OAAO,SAAS,KAChB,OAAO,SAAS;AAEpB;AAEA,SAAS,aAAa,GAAgB,GAA6B;CACjE,IAAI,EAAE,SAAS,OAAO;CACtB,IAAI,EAAE,SAAS,OAAO;CACtB,MAAM,IAAI,IAAI,gBAAgB;CAC9B,MAAM,WAAW,iBAA8B,EAAE,MAAM,OAAO,MAAM;CACpE,EAAE,iBAAiB,SAAS,QAAQ,CAAC,GAAG,EAAE,MAAM,KAAK,CAAC;CACtD,EAAE,iBAAiB,SAAS,QAAQ,CAAC,GAAG,EAAE,MAAM,KAAK,CAAC;CACtD,OAAO,EAAE;AACX;;;ACzXA,MAAM,cAA2C;CAC/C,MAAM;CACN,SAAS;CACT,MAAM;CACN,SAAS;CACT,OAAO;AACT;AAEA,SAAS,MAAM,GAAgB,GAA6B;CAC1D,QAAQ,YAAY,MAAM,OAAO,YAAY,MAAM,KAAK,IAAI;AAC9D;AAEA,MAAM,gBAA0C;CAC9C,MAAM;CACN,OAAO;CACP,OAAO;CACP,UAAU;AACZ;AAEA,SAAS,YAAY,UAA2D;CAC9E,IAAI,OAAiB;CACrB,KAAK,MAAM,KAAK,UACd,IAAI,cAAc,EAAE,YAAY,cAAc,OAAO,OAAO,EAAE;CAEhE,OAAO;AACT;;;;;;;;;;;AAyCA,SAAgB,kBACd,MACA,YACA,UAAwB,CAAC,GACZ;CACb,MAAM,gBAAgB,QAAQ,iBAAiB;CAC/C,MAAM,mBAAmB,QAAQ,oBAAoB;CACrD,MAAM,SAAS,QAAQ;CAEvB,IAAI,WAAW,WAAW,GACxB,OAAO;EACL,OAAO;EACP,QAAQ;EACR,YAAY;EACZ,UAAU,CAAC;EACX,QAAQ;CACV;CAEF,IAAI,WAAW,WAAW,GAAG;EAC3B,MAAM,OAAO,WAAW;EACxB,OAAO;GACL,GAAG,KAAK;GACR,OAAO;GACP,UAAU,KAAK,OAAO,SAAS,KAAK,OAAO;IACzC,GAAG;IACH,OAAO;IACP,SAAS,SAAS,GAAG,OAAO,KAAK,OAAO,EAAE,GAAG,EAAE,YAAY,EAAE;IAC7D,QAAQ;KAAE,GAAI,EAAE,UAAU,CAAC;KAAI,SAAS,KAAK;IAAQ;GACvD,EAAE;GACF,QAAQ,KAAK,OAAO,UAAU,GAAG,KAAK,QAAQ,IAAI,KAAK,OAAO;EAChE;CACF;CAEA,IAAI,SAAsB;CAC1B,IAAI,mBAAmB;CACvB,IAAI,cAAc;CAClB,MAAM,WAAoC,CAAC;CAC3C,IAAI,aAAa;CACjB,MAAM,cAAwB,CAAC;CAC/B,MAAM,cAA6C,CAAC;CAEpD,KAAK,MAAM,EAAE,SAAS,YAAY,YAAY;EAC5C,SAAS,MAAM,QAAQ,OAAO,MAAM;EACpC,IAAI,OAAO,OAAO,UAAU,UAAU;GACpC,oBAAoB,OAAO;GAC3B,eAAe;EACjB;EACA,aACE,kBAAkB,QACd,aAAa,OAAO,aACpB,KAAK,IAAI,YAAY,OAAO,UAAU;EAC5C,YAAY,KAAK,GAAG,QAAQ,IAAI,OAAO,QAAQ;EAC/C,KAAK,MAAM,KAAK,OAAO,UACrB,SAAS,KAAK;GACZ,GAAG;GACH,OAAO;GACP,SAAS,SAAS,GAAG,OAAO,OAAO,EAAE,GAAG,EAAE,YAAY,EAAE;GACxD,QAAQ;IAAE,GAAI,EAAE,UAAU,CAAC;IAAI;GAAQ;EACzC,CAAC;EAEH,KAAK,MAAM,CAAC,GAAG,MAAM,OAAO,QAAQ,OAAO,eAAe,CAAC,CAAC,GAAG;GAC7D,IAAI,OAAO,MAAM,YAAY,CAAC,OAAO,SAAS,CAAC,GAAG;GAClD,MAAM,OAAO,YAAY;GACzB,IAAI,QAAQ,MAAM,YAAY,KAAK;QAC9B,YAAY,KAAK,qBAAqB,QAAQ,OAAO,IAAI,KAAK,IAAI,MAAM,CAAC;EAChF;CACF;CAEA,OAAO;EACL,OAAO;EACP;EACA,OAAO,cAAc,IAAI,mBAAmB,cAAc,KAAA;EAC1D;EACA;EACA,QAAQ,YAAY,KAAK,KAAK;EAC9B,aAAa,OAAO,KAAK,WAAW,CAAC,CAAC,SAAS,IAAI,cAAc,KAAA;EACjE,QAAQ;GACN,UAAU,WAAW,KAAK,EAAE,SAAS,cAAc;IACjD;IACA,QAAQ,OAAO;IACf,OAAO,OAAO,SAAS;GACzB,EAAE;GACF,eAAe,YAAY,QAAQ;EACrC;CACF;AACF;;;;;;;;AA8BA,SAAgB,oBACd,QACY;CACZ,MAAM,cAAc,KAAK,IAAI,GAAG,OAAO,eAAe,CAAC;CACvD,OAAO;EACL,MAAM,OAAO;EACb,WAAW,OAAO;EAClB,QAAQ,OAAO;EACf,wBAAwB,OAAO;EAC/B,OAAO,OAAO;EACd,MAAM,IAAI,KAAK;GACb,IAAI,OAAO,SAAS,WAAW,GAC7B,OAAO;IACL,OAAO,OAAO;IACd,QAAQ;IACR,YAAY;IACZ,UAAU,CAAC;IACX,QAAQ;GACV;GAGF,MAAM,SAAS,OAAO,YAA0C;IAC9D,MAAM,cAAc,OAAO,YAAY,OAAO;IAC9C,IAAI;KAEF,OAAO;MAAE,SAAS;MAAa,QAAQ,MADvB,OAAO,IAAI,SAAS,GAAG;KACE;IAC3C,SAAS,KAAK;KACZ,OAAO;MACL,SAAS;MACT,QAAQ;OACN,OAAO,OAAO;OACd,QAAQ;OACR,YAAY;OACZ,UAAU,CACR;QACE,UAAU;QACV,OAAO,OAAO;QACd,SAAS,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;QACxD,QAAQ,EAAE,SAAS,YAAY;OACjC,CACF;OACA,QAAQ,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;MACzD;KACF;IACF;GACF;GAGA,MAAM,UAAwB,CAAC;GAC/B,KAAK,IAAI,IAAI,GAAG,IAAI,OAAO,SAAS,QAAQ,KAAK,aAAa;IAC5D,MAAM,QAAQ,OAAO,SAAS,MAAM,GAAG,IAAI,WAAW;IACtD,MAAM,eAAe,MAAM,QAAQ,IAAI,MAAM,IAAI,MAAM,CAAC;IACxD,QAAQ,KAAK,GAAG,YAAY;GAC9B;GACA,OAAO,kBAAkB,OAAO,MAAM,OAAO;EAC/C;CACF;AACF;;;;;;;;;;;ACzDA,MAAM,0BAA0B;AAChC,MAAM,aAAqC;CAAC;CAAS;CAAO;CAAQ;AAAS;AAE7E,eAAsB,mBACpB,OACA,SACoC;CACpC,MAAM,MAAM,QAAQ,OAAO,KAAK;CAChC,MAAM,YAAY,IAAI;CACtB,MAAM,QAAQ,QAAQ,SAAS,GAAG,QAAQ,aAAa,mBAAmB,GAAG;CAC7E,MAAM,gBAAgB,IAAI,IAAI,QAAQ,UAAU,UAAU;CAC1D,MAAM,WAA4C,CAAC;CAEnD,KAAK,MAAM,CAAC,WAAW,eAAe,MAAM,QAAQ,GAAG;EACrD,MAAM,QAAQ,WAAW,SAAS;EAClC,IAAI,UAAU,aAAa,CAAC,QAAQ,gBAAgB;EACpD,IAAI,CAAC,cAAc,IAAI,KAAK,GAAG;EAE/B,MAAM,YAAY,IAAI;EACtB,MAAM,oBAA6D;GACjE,IAAI,WAAW;GACf;GACA,OAAO,WAAW;GAClB,GAAI,WAAW,aAAa,KAAA,IAAY,EAAE,UAAU,WAAW,SAAS,IAAI,CAAC;EAC/E;EAEA,IAAI,aAAyC,CAAC;EAC9C,IAAI;EACJ,IAAI;GACF,eAAe,QAAQ,WAAW;GAClC,aAAa,MAAM,WAAW,QAAQ,SAAS,mBAAmB;IAChE;IACA;IACA,aAAa,QAAQ;GACvB,CAAC;GACD,eAAe,QAAQ,WAAW;EACpC,SAAS,OAAO;GACd,IAAI,QAAQ,aAAa,SAAS,MAAM;GACxC,IAAI,CAAC,QAAQ,iBAAiB,MAAM;GACpC,QAAQ,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;EAC/D;EAEA,MAAM,WAAoC;GACxC,IAAI,WAAW;GACf;GACA,YAAY,WAAW;GACvB;GACA,GAAI,WAAW,aAAa,KAAA,IAAY,EAAE,UAAU,WAAW,SAAS,IAAI,CAAC;EAC/E;EACA,MAAM,eAA4C;GAChD,SAAS,QAAQ;GACjB,gBAAgB,QAAQ;GACxB,eAAe,QAAQ;GACvB,gBAAgB;EAClB;EACA,MAAM,gBAAgB,qBAAqB,CAAC,QAAQ,GAAG,YAAY,CAAC,CAAC,UAAU;EAC/E,SAAS,KAAK;GACZ,QAAQ,WAAW;GACnB;GACA,OAAO,WAAW;GAClB,YAAY,WAAW;GACvB;GACA,OAAO;GACP,YAAY,KAAK,IAAI,GAAG,IAAI,IAAI,SAAS;GACzC,GAAI,WAAW,aAAa,KAAA,IAAY,EAAE,UAAU,WAAW,SAAS,IAAI,CAAC;GAC7E,GAAI,UAAU,KAAA,IAAY,EAAE,MAAM,IAAI,CAAC;EACzC,CAAC;CACH;CAEA,MAAM,cAAc,IAAI;CACxB,MAAM,eAA4C;EAChD,SAAS,QAAQ;EACjB,gBAAgB,QAAQ;EACxB,eAAe,QAAQ;EACvB,gBAAgB;CAClB;CACA,MAAM,MAAiC;EACrC,IAAI;EACJ;EACA;EACA,YAAY,KAAK,IAAI,GAAG,cAAc,SAAS;EAC/C,OAAO;EACP,OAAO,qBACL,SAAS,KAAK,aAAa;GACzB,IAAI,QAAQ;GACZ,OAAO,QAAQ;GACf,YAAY,QAAQ;GACpB,YAAY,QAAQ;GACpB,GAAI,QAAQ,aAAa,KAAA,IAAY,EAAE,UAAU,QAAQ,SAAS,IAAI,CAAC;EACzE,EAAE,GACF,YACF;EACA,GAAI,QAAQ,cAAc,KAAA,IAAY,EAAE,WAAW,QAAQ,UAAU,IAAI,CAAC;EAC1E,GAAI,QAAQ,aAAa,KAAA,IAAY,EAAE,UAAU,QAAQ,SAAS,IAAI,CAAC;CACzE;CAEA,MAAM,QAAQ,OAAO,KAAK,GAAG;CAC7B,OAAO;AACT;AAEA,SAAgB,kCACd,UACA,WACA,SAAyC,CAAC,GACR;CAClC,OAAO,+BAA+B,SAAS,OAAO,UAAU,OAAO,MAAM;AAC/E;AAEA,SAAgB,6BACd,UAAuC,CAAC,GACR;CAChC,MAAM,OAAO,CAAC,GAAG,OAAO;CACxB,OAAO;EACL,MAAM,KAAK,KAAK;GACd,KAAK,KAAK,GAAG;EACf;EACA,MAAM,OAAO;GACX,OAAO,CAAC,GAAG,IAAI;EACjB;CACF;AACF;AAQA,MAAM,kCAAkB,IAAI,IAAmB;AAC/C,SAAS,kBAAkB,MAAqB;CAC9C,IAAI,IAAI,gBAAgB,IAAI,IAAI;CAChC,IAAI,CAAC,GAAG;EACN,IAAI,IAAI,MAAM;EACd,gBAAgB,IAAI,MAAM,CAAC;CAC7B;CACA,OAAO;AACT;AAEA,SAAgB,0BACd,MACgC;CAChC,MAAM,OAAO,kBAAkB,IAAI;CACnC,OAAO;EACL,MAAM,KAAK,KAAK;GACd,MAAM,KAAK,mBAAmB;IAC5B,UAAU,QAAQ,IAAI,GAAG,EAAE,WAAW,KAAK,CAAC;IAC5C,eAAe,MAAM,GAAG,KAAK,UAAU,GAAG,EAAE,GAAG;GACjD,CAAC;EACH;EACA,MAAM,OAAO;GACX,OAAO,KAAK,mBAAmB;IAC7B,IAAI,CAAC,WAAW,IAAI,GAAG,OAAO,CAAC;IAC/B,OAAO,UAAU,IAAI;GACvB,CAAC;EACH;CACF;AACF;AAEA,SAAgB,qBACd,WACA,UAAuC,CAAC,GAClB;CACtB,MAAM,UAAU,QAAQ,WAAW;CACnC,MAAM,YAAY,QAAQ,kBAAkB;CAC5C,MAAM,gBAAgB,QAAQ,iBAAiB;CAC/C,MAAM,gBAAgB,IAAI,IAAI,QAAQ,UAAU,UAAU;CAC1D,MAAM,SAAS,UACZ,QAAQ,aAAa;EACpB,MAAM,QAAQ,SAAS,SAAS;EAChC,IAAI,UAAU,aAAa,CAAC,QAAQ,gBAAgB,OAAO;EAC3D,OAAO,cAAc,IAAI,KAAK;CAChC,CAAC,CAAC,CACD,KAAK,aAAa,cAAc,UAAU,SAAS,WAAW,aAAa,CAAC;CAE/E,OAAO;EACL,WAAW;EACX,WAAW,wBAAwB,MAAM;EACzC,SAAS,iBAAiB,MAAM;CAClC;AACF;AAEA,SAAgB,uBACd,UACA,WACkC;CAKlC,OAAO,CAAC,mBAAG,IAJQ,IAA0B,CAC3C,GAAI,OAAO,KAAK,SAAS,OAAO,GAChC,GAAI,OAAO,KAAK,UAAU,OAAO,CACnC,CACgB,CAAC,CAAC,CAAC,KAAK,YAAY,CAAC,CAAC,KAAK,UAAU;EACnD,MAAM,SAAS,SAAS,QAAQ,UAAU,eAAe;EACzD,MAAM,QAAQ,UAAU,QAAQ,UAAU,eAAe;EACzD,OAAO;GACL;GACA,YAAY,OAAO;GACnB,aAAa,MAAM;GACnB,SAAS,MAAM,KAAK,OAAO;GAC3B,gBAAgB,OAAO;GACvB,iBAAiB,MAAM;GACvB,aAAa,MAAM,SAAS,OAAO;EACrC;CACF,CAAC;AACH;AAEA,SAAgB,+BACd,UACA,WACA,SAAyC,CAAC,GACR;CAClC,MAAM,iBAAiB,OAAO,kBAAkB,CAAC,OAAO,MAAM;CAC9D,MAAM,aAAa,OAAO,cAAc;CACxC,MAAM,gBAAgB,OAAO,iBAAiB;CAC9C,MAAM,iBAAiB,OAAO,+BAA+B;CAC7D,MAAM,cAAc,uBAAuB,UAAU,SAAS;CAC9D,MAAM,wBAAwB,eAAe,QAC1C,UAAU,CAAC,SAAS,UAAU,KAAK,KAAK,CAAC,SAAS,WAAW,KAAK,CACrE;CACA,MAAM,WAAW,YAAY,QAAQ,SAAS,eAAe,SAAS,KAAK,KAAK,CAAC;CACjF,MAAM,cAAc,YAAY,QAAQ,SAAS,KAAK,UAAU,CAAC,aAAa;CAC9E,MAAM,iBAAiB,UAAU,UAAU,KAAK,SAAS,UAAU;CACnE,MAAM,mBAAmB,wBAAwB,UAAU,SAAS;CAEpE,IAAI,sBAAsB,SAAS,GACjC,OAAO;EACL,SAAS;EACT,QAAQ,sDAAsD,sBAAsB,KAAK,IAAI;EAC7F;EACA;EACA;CACF;CAGF,IAAI,SAAS,WAAW,GACtB,OAAO;EACL,SAAS;EACT,QAAQ,mCAAmC,eAAe,KAAK,IAAI;EACnE;EACA;EACA;CACF;CAGF,IAAI,YAAY,SAAS,GACvB,OAAO;EACL,SAAS;EACT,QAAQ,iBAAiB,YAAY,KAAK,MAAM,EAAE,KAAK,CAAC,CAAC,KAAK,IAAI;EAClE;EACA;EACA;CACF;CAGF,IAAI,mBAAmB,CAAC,SAAS,UAAU,SAAS,KAAK,CAAC,SAAS,WAAW,SAAS,IACrF,OAAO;EACL,SAAS;EACT,QAAQ;EACR;EACA;EACA;CACF;CAGF,IAAI,iBAAiB,iBAAiB,SAAS,KAAK,iBAAiB,gBAAgB,SAAS,GAAG;EAC/F,MAAM,OAAO,CACX,iBAAiB,iBAAiB,SAAS,IACvC,qBAAqB,kBAAkB,iBAAiB,gBAAgB,MACxE,MACJ,iBAAiB,gBAAgB,SAAS,IACtC,oBAAoB,kBAAkB,iBAAiB,eAAe,MACtE,IACN,CAAC,CAAC,QAAQ,SAAyB,SAAS,IAAI;EAChD,OAAO;GACL,SAAS;GACT,QACE,uCAAuC,SAAS,UAAU,OAAO,cACpD,UAAU,UAAU,OAAO,IAAI,KAAK,KAAK,IAAI;GAC5D;GACA;GACA;EACF;CACF;CAEA,MAAM,oBAAoB,KAAK,SAAS,KAAK,SAAS,KAAK,OAAO,CAAC;CACnE,IAAI,oBAAoB,YACtB,OAAO;EACL,SAAS;EACT,QAAQ,2BAA2B,UAAU,iBAAiB,EAAE,SAAS,UAAU,UAAU;EAC7F;EACA;EACA;CACF;CAGF,OAAO;EACL,SAAS;EACT,QAAQ,+BAA+B,UAAU,iBAAiB,EAAE;EACpE;EACA;EACA;CACF;AACF;AAOA,SAAS,wBACP,UACA,WAC0B;CAC1B,MAAM,iBAAiB,uBAAuB,QAAQ;CACtD,MAAM,kBAAkB,uBAAuB,SAAS;CACxD,OAAO;EACL,kBAAkB,gBAAgB,gBAAgB,eAAe;EACjE,iBAAiB,gBAAgB,iBAAiB,cAAc;CAClE;AACF;AAEA,SAAS,uBAAuB,OAAkD;CAChF,MAAM,yBAAS,IAAI,IAAoB;CACvC,KAAK,MAAM,YAAY,MAAM,WAAW;EACtC,MAAM,WAAW,GAAG,SAAS,MAAM,GAAG,SAAS;EAC/C,OAAO,IAAI,WAAW,OAAO,IAAI,QAAQ,KAAK,KAAK,CAAC;CACtD;CACA,OAAO;AACT;AAEA,SAAS,gBAAgB,UAA+B,QAAuC;CAC7F,MAAM,UAAoB,CAAC;CAC3B,KAAK,MAAM,CAAC,UAAU,UAAU,UAAU;EACxC,MAAM,aAAa,SAAS,OAAO,IAAI,QAAQ,KAAK;EACpD,KAAK,IAAI,QAAQ,GAAG,QAAQ,YAAY,SAAS,QAAQ,KAAK,QAAQ;CACxE;CACA,OAAO,QAAQ,KAAK;AACtB;AAEA,SAAS,kBAAkB,KAAuB;CAChD,MAAM,QAAQ,IAAI,MAAM,GAAG,CAAC;CAC5B,MAAM,YAAY,IAAI,SAAS,MAAM;CACrC,OAAO,YAAY,IAAI,GAAG,MAAM,KAAK,IAAI,EAAE,KAAK,UAAU,SAAS,MAAM,KAAK,IAAI;AACpF;AAEA,SAAgB,8BACd,WACA,WACsB;CAGtB,MAAM,YAAY,aAAa,GAFN,UAAU,MAAM,GAAG,UAAU,eAAe,MAEvB,GADrB,UAAU,MAAM,GAAG,UAAU,eAAe,IACV;CAC3D,MAAM,gBACJ,UAAU,YAAY,UAAU,WAC5B,UAAU,UAAU,QAAQ,MAAM,UAAU,UAAU,QAAQ,IAC5D,KACA,OACF;CACN,MAAM,WAAW,WAAW,UAAU,MAAM,UAAU,IAAI,IAAI;CAE9D,OAAO;EACL,OAFYC,UAAQ,YAAY,MAAO,WAAW,aAE9C;EACJ,QAAQ,SAAS,UAAU,QAAQ,CAAC,EAAE,QAAQ,SAAS,QAAQ,CAAC,EAAE,YAAY,cAAc,QAAQ,CAAC;CACvG;AACF;AAEA,SAAS,cACP,UACA,SACA,WACA,eAC8B;CAC9B,OAAO,kBAAkB,kBACrB,0BAA0B,UAAU,SAAS,SAAS,IACtD,4BAA4B,UAAU,SAAS,SAAS;AAC9D;AAEA,SAAS,4BACP,UACA,SACA,WAC8B;CAC9B,MAAM,iBAAiB,SAAS,WAAW,KAAK,WAAW,WAAW;EAAE;EAAW;CAAM,EAAE;CAC3F,MAAM,UAAkC,CAAC;CAEzC,KAAK,MAAM,aAAa,SAAS,YAAY;EAC3C,IAAI,OAKO;EACX,KAAK,MAAM,QAAQ,gBAAgB;GACjC,MAAM,SAAS,UAAU,UAAU,SAAS,WAAW,KAAK,SAAS;GACrE,IAAI,CAAC,QAAQ,OAAO,QAAQ,KAAK,OAC/B,OAAO;IAAE,GAAG;IAAM,GAAG;GAAO;EAEhC;EAEA,MAAM,SAAS,UAAU,UAAU;EACnC,IAAI,QAAQ,KAAK,SAAS,WAAW;GACnC,MAAM,aAAa,eAAe,WAAW,SAAS,KAAK,UAAU,KAAK,KAAK;GAC/E,IAAI,cAAc,GAAG,eAAe,OAAO,YAAY,CAAC;GACxD,QAAQ,KAAK;IACX,YAAY,SAAS;IACrB,aAAa,UAAU;IACvB,aAAa,KAAK,UAAU;IAC5B,OAAO,KAAK;IACZ,SAAS;IACT;IACA,QAAQ,KAAK;GACf,CAAC;EACH,OACE,QAAQ,KAAK;GACX,YAAY,SAAS;GACrB,aAAa,UAAU;GACvB,aAAa,MAAM,UAAU,MAAM;GACnC,OAAO,MAAM,SAAS;GACtB,SAAS;GACT;GACA,QAAQ,MAAM,UAAU;EAC1B,CAAC;CAEL;CAEA,OAAO,mBAAmB,UAAU,SAAS,eAAe,MAAM;AACpE;AAWA,SAAS,0BACP,UACA,SACA,WAC8B;CAC9B,MAAM,QAAkC,CAAC;CACzC,KAAK,MAAM,CAAC,gBAAgB,cAAc,SAAS,WAAW,QAAQ,GACpE,KAAK,MAAM,CAAC,gBAAgB,cAAc,SAAS,WAAW,QAAQ,GACpE,MAAM,KAAK;EACT;EACA;EACA;EACA;EACA,GAAG,UAAU,UAAU,SAAS,WAAW,SAAS;CACtD,CAAC;CAIL,MAAM,MACH,GAAG,MACF,EAAE,QAAQ,EAAE,SACZ,EAAE,iBAAiB,EAAE,kBACrB,EAAE,iBAAiB,EAAE,cACzB;CAEA,MAAM,sCAAsB,IAAI,IAAoC;CACpE,MAAM,qCAAqB,IAAI,IAAY;CAC3C,KAAK,MAAM,QAAQ,OAAO;EACxB,IAAI,KAAK,QAAQ,WAAW;EAC5B,IAAI,oBAAoB,IAAI,KAAK,cAAc,KAAK,mBAAmB,IAAI,KAAK,cAAc,GAC5F;EACF,oBAAoB,IAAI,KAAK,gBAAgB,IAAI;EACjD,mBAAmB,IAAI,KAAK,cAAc;CAC5C;CA6BA,OAAO,mBAAmB,UA3BV,SAAS,WAAW,KAAK,WAAW,mBAAmB;EACrE,MAAM,SAAS,UAAU,UAAU;EACnC,MAAM,WAAW,oBAAoB,IAAI,cAAc;EACvD,IAAI,UACF,OAAO;GACL,YAAY,SAAS;GACrB,aAAa,UAAU;GACvB,aAAa,SAAS,UAAU;GAChC,OAAO,SAAS;GAChB,SAAS;GACT;GACA,QAAQ,SAAS;EACnB;EAGF,MAAM,eAAe,MAAM,MAAM,SAAS,KAAK,mBAAmB,cAAc;EAChF,OAAO;GACL,YAAY,SAAS;GACrB,aAAa,UAAU;GACvB,aAAa,cAAc,UAAU,MAAM;GAC3C,OAAO,cAAc,SAAS;GAC9B,SAAS;GACT;GACA,QAAQ,cAAc,UAAU;EAClC;CACF,CAE0C,GAAG,SAAS,WAAW,SAAS,mBAAmB,IAAI;AACnG;AAEA,SAAS,UACP,UACA,SACA,WACA,WACmC;CACnC,MAAM,SAAS,QAAQ,WAAW,WAAW,QAAQ;CACrD,IAAI,CAAC,OAAO,SAAS,OAAO,KAAK,GAC/B,MAAM,IAAI,MACR,0DAA0D,SAAS,GAAG,GAAG,UAAU,GAAG,GAAG,UAAU,IACrG;CAEF,OAAO;EAAE,OAAOA,UAAQ,OAAO,KAAK;EAAG,QAAQ,OAAO,UAAU;CAAG;AACrE;AAEA,SAAS,mBACP,UACA,SACA,gBAC8B;CAC9B,MAAM,UAAU,QAAQ,QAAQ,UAAU,MAAM,OAAO,CAAC,CAAC;CACzD,MAAM,QAAQ,SAAS,WAAW;CAClC,MAAM,gBAAgB,QACnB,QAAQ,UAAU,MAAM,OAAO,CAAC,CAChC,QAAQ,KAAK,UAAU,MAAM,MAAM,QAAQ,CAAC;CAC/C,MAAM,cAAc,QAAQ,QAAQ,KAAK,UAAU,MAAM,MAAM,QAAQ,CAAC;CACxE,MAAM,YAAY,MAAM,SAAS,UAAU,cAAc;CACzD,MAAM,SAAS,MAAM,SAAS,KAAK;CACnC,OAAO;EACL,YAAY,SAAS;EACrB,OAAO,SAAS,SAAS;EACzB;EACA;EACA;EACA;EACA;EACA;EACA;EACA,IAAI,GAAG,WAAW,MAAM;EACxB;CACF;AACF;AAEA,SAAS,iBACP,QACiE;CACjE,MAAM,MAAuE,CAAC;CAC9E,KAAK,MAAM,SAAS,YAAY;EAC9B,MAAM,SAAS,OAAO,QAAQ,UAAU,MAAM,UAAU,KAAK;EAC7D,IAAI,OAAO,SAAS,GAAG,IAAI,SAAS,wBAAwB,MAAM;CACpE;CACA,OAAO;AACT;AAEA,SAAS,wBAAwB,QAAkE;CACjG,MAAM,UAAUC,MAAI,OAAO,KAAK,UAAU,MAAM,OAAO,CAAC;CACxD,MAAM,QAAQA,MAAI,OAAO,KAAK,UAAU,MAAM,KAAK,CAAC;CACpD,MAAM,iBAAiBA,MAAI,OAAO,KAAK,UAAU,MAAM,cAAc,CAAC;CACtE,MAAM,gBAAgBA,MAAI,OAAO,KAAK,UAAU,MAAM,aAAa,CAAC;CACpE,MAAM,cAAcA,MAAI,OAAO,KAAK,UAAU,MAAM,WAAW,CAAC;CAChE,MAAM,YAAY,MAAM,SAAS,UAAU,cAAc;CACzD,MAAM,SAAS,MAAM,SAAS,KAAK;CACnC,OAAO;EACL;EACA;EACA;EACA;EACA;EACA;EACA;EACA,IAAI,GAAG,WAAW,MAAM;EACxB,gBAAgB,MAAM,eAAe,WAAW;CAClD;AACF;AAEA,SAAS,iBAA2C;CAClD,OAAO;EACL,SAAS;EACT,OAAO;EACP,gBAAgB;EAChB,eAAe;EACf,aAAa;EACb,WAAW;EACX,QAAQ;EACR,IAAI;EACJ,gBAAgB;CAClB;AACF;AAEA,SAAS,SAAS,OAA6B,OAAsC;CACnF,OAAO,MAAM,QAAQ,WAAW,KAAA;AAClC;AAEA,SAAS,GAAG,WAAmB,QAAwB;CACrD,OAAO,YAAY,WAAW,IAAI,IAAK,IAAI,YAAY,UAAW,YAAY;AAChF;AAEA,SAAS,MAAM,WAAmB,aAA6B;CAC7D,OAAO,cAAc,IAAI,YAAY,cAAc;AACrD;AAEA,SAAS,aAAa,GAAW,GAAmB;CAClD,MAAM,OAAO,IAAI,IAAI,OAAO,CAAC,CAAC;CAC9B,MAAM,QAAQ,IAAI,IAAI,OAAO,CAAC,CAAC;CAC/B,IAAI,KAAK,SAAS,KAAK,MAAM,SAAS,GAAG,OAAO;CAChD,IAAI,eAAe;CACnB,KAAK,MAAM,SAAS,MAClB,IAAI,MAAM,IAAI,KAAK,GAAG;CAExB,OAAO,gBAAgB,KAAK,OAAO,MAAM,OAAO;AAClD;AAEA,SAAS,WAAW,GAAyB,GAAiC;CAC5E,IAAI,CAAC,GAAG,UAAU,CAAC,GAAG,QAAQ,OAAO;CACrC,MAAM,OAAO,IAAI,IAAI,EAAE,IAAI,SAAS,CAAC;CACrC,MAAM,QAAQ,IAAI,IAAI,EAAE,IAAI,SAAS,CAAC;CACtC,IAAI,eAAe;CACnB,KAAK,MAAM,OAAO,MAChB,IAAI,MAAM,IAAI,GAAG,GAAG;CAEtB,OAAO,eAAe,KAAK,IAAI,KAAK,MAAM,MAAM,IAAI;AACtD;AAEA,SAAS,OAAO,MAAwB;CACtC,OAAO,UAAU,IAAI,CAAC,CACnB,MAAM,KAAK,CAAC,CACZ,QAAQ,UAAU,MAAM,UAAU,KAAK,CAAC,WAAW,IAAI,KAAK,CAAC;AAClE;AAEA,SAAS,UAAU,MAAsB;CACvC,OAAO,KACJ,YAAY,CAAC,CACb,QAAQ,eAAe,GAAG,CAAC,CAC3B,KAAK;AACV;AAEA,SAASD,UAAQ,OAAuB;CACtC,IAAI,CAAC,OAAO,SAAS,KAAK,GAAG,OAAO;CACpC,OAAO,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,KAAK,CAAC;AACvC;AAEA,SAASC,MAAI,QAA0B;CACrC,OAAO,OAAO,QAAQ,KAAK,UAAU,MAAM,OAAO,CAAC;AACrD;AAEA,SAAS,KAAK,QAA0B;CACtC,OAAO,OAAO,SAASA,MAAI,MAAM,IAAI,OAAO,SAAS;AACvD;AAEA,SAAS,UAAU,OAAuB;CACxC,OAAO,IAAI,QAAQ,IAAA,CAAK,QAAQ,CAAC,EAAE;AACrC;AAEA,SAAS,aAAa,GAAyB,GAAiC;CAC9E,OAAO,WAAW,QAAQ,CAAC,IAAI,WAAW,QAAQ,CAAC;AACrD;AAEA,SAAS,WACP,SACA,UACA,SACqC;CACrC,OAAO,OAAO,YAAY,aAAa,QAAQ,UAAU,OAAO,IAAI,QAAQ,IAAI,UAAU,OAAO;AACnG;AAEA,SAAS,eAAe,QAAuC;CAC7D,IAAI,CAAC,QAAQ,SAAS;CACtB,IAAI,OAAO,kBAAkB,OAAO,MAAM,OAAO;CACjD,MAAM,IAAI,MAAM,OAAO,SAAS,OAAO,OAAO,MAAM,IAAI,0BAA0B;AACpF;AAEA,SAAS,UAAiB,MAA2C;CACnE,MAAM,MAAM,aAAa,MAAM,MAAM;CACrC,MAAM,MAAmC,CAAC;CAC1C,KAAK,MAAM,QAAQ,IAAI,MAAM,IAAI,GAAG;EAClC,MAAM,UAAU,KAAK,KAAK;EAC1B,IAAI,CAAC,SAAS;EACd,IAAI,KAAK,KAAK,MAAM,OAAO,CAA8B;CAC3D;CACA,OAAO;AACT;AAEA,MAAM,6BAAa,IAAI,IAAI;CACzB;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF,CAAC;;;;;;;;;;;;;;;;;;;ACjxBD,MAAM,kBAAkB;CACtB,MAAM;CACN,sBAAsB;CACtB,UAAU;EAAC;EAAgB;EAAa;EAAuB;EAAkB;CAAY;CAC7F,YAAY;EACV,cAAc;GAAE,MAAM;GAAU,WAAW;GAAI,WAAW;EAAK;EAC/D,WAAW;GAAE,MAAM;GAAU,WAAW;GAAI,WAAW;EAAK;EAC5D,qBAAqB;GAAE,MAAM;GAAU,WAAW;GAAI,WAAW;EAAK;EACtE,gBAAgB,EAAE,MAAM,UAAU;EAClC,YAAY;GAAE,MAAM;GAAU,SAAS;GAAG,SAAS;EAAE;CACvD;AACF;AAIA,SAAS,gBAAgB,QAAuC;CAC9D,IAAI,OAAO,WAAW,GAAG,OAAO;CAChC,OAAO,OACJ,KAAK,MAAM;EAOV,OAAO;GAAC,QANe,EAAE,KAAK,iBAAiB,EAAE,cAAc,EAAA,CAAG,QAAQ,CAAC,EAAE,kBAAkB,EAAE,kBAAkB;GACvG,EAAE,eAAe,mBAAmB,EAAE,aAAa,MAAM,GAAG,GAAG,MAAM;GACpE,EAAE,YAAY,gBAAgB,EAAE,UAAU,MAAM,GAAG,GAAG,MAAM;GAC3D,EAAE,sBACZ,wBAAwB,EAAE,oBAAoB,MAAM,GAAG,GAAG,MAC1D;EAC4B,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC,KAAK,IAAI;CAC7D,CAAC,CAAC,CACD,KAAK,MAAM;AAChB;;;;;;AAOA,SAAgB,oBAAoB,OAA8D;CAChG,MAAM,SACJ;CAIF,MAAM,qBACJ,MAAM,aAAa,iBAAiB,MAAM,aAAa,cAAc,SAAS,IAC1E,mBAAmB,MAAM,aAAa,cAAc,KAAK,IAAI,MAC7D;CAmCN,OAAO;EAAE;EAAQ,MAAA;OAhCZ,MAAM,KAAK;;;EAGhB,MAAM,YAAY;;yBAEK,MAAM,KAAK;EAClC,MAAM,aAAa;EACnB,MAAM,eAAe,4BAA4B,MAAM,aAAa,MAAM,GAAG;yBACtD,MAAM,KAAK;gBACpB,MAAM,aAAa,aAAa,QAAQ,CAAC,EAAE;WAChD,MAAM,aAAa,QAAQ;aACzB,MAAM,aAAa,UAAU;EACxC,mBAAmB;;;EAGnB,gBAAgB,MAAM,MAAM,EAAE;EAC9B,MAAM,kBAAkB,+BAA+B,MAAM,gBAAgB,MAAM,GAAG;;;;;;;;;;;;;;;CAgBhE;AACxB;AAIA,MAAM,oBAAwD;CAC5D,cAAc;CACd,WAAW;CACX,qBACE;CAEF,gBAAgB;CAChB,YAAY;AACd;;;;;;;AAQA,SAAgB,sBACd,SACyD;CACzD,MAAM,WAA+C;EACnD,GAAG;EACH,GAAI,QAAQ,oBAAoB,CAAC;CACnC;CACA,MAAM,gBAAgB,QAAQ,iBAAiB;CAC/C,MAAM,YAAY,QAAQ,aAAa;CACvC,MAAM,YAAY,QAAQ,aAAa;CACvC,MAAM,aAAa,QAAQ,cAAc,IAAI,WAAW;CAExD,OAAO,OAAO,UAAU;EACtB,MAAM,QAAQ,KAAK,IAAI;EACvB,MAAM,EAAE,QAAQ,SAAS,cAAc,KAAK;EAC5C,IAAI;EACJ,IAAI;GACF,MAAM,UAAU;IACd,OAAO,QAAQ;IACf,UAAU,CACR;KAAE,MAAM;KAAmB,SAAS;IAAO,GAC3C;KAAE,MAAM;KAAiB,SAAS;IAAK,CACzC;IACA,YAAY;KAAE,MAAM;KAAmB,QAAQ;IAAgB;IAC/D,aAAa;IACb;IACA;GACF;GACA,MAAM,OAAO,MAAM,WAAW,YAAY;IACxC,SAAS;IACT,OAAO,QAAQ,aAAa;IAC5B,OAAO;IACP,OAAO,QAAQ;IACf,eAAe,2BAA2B,SAAS,QAAQ,GAAG;IAC9D,QAAQ,QAAQ;IAChB,UAAU,QAAQ,WAChB,YAMG,SAAS;KACV,GAAG,QAAQ;KACX;KACA,gBAAgB;IAClB,CAAC;IACH,UAAU,EAAE,aAAa,mBAAmB,MAAM;IAClD,kBAAkB;GACpB,CAAC;GACD,UAAU,KAAK;GACf,IAAI,CAAC,KAAK,WAAW,MAAM,KAAK;GAChC,MAAM,EAAE,UAAU,KAAK;GAEvB,OAAO;IACL,MAAM,MAAM;IACZ,cAAc,OAAO,MAAM,gBAAgB,SAAS,YAAY;IAChE,WAAW,OAAO,MAAM,aAAa,SAAS,SAAS;IACvD,qBAAqB,OAAO,MAAM,uBAAuB,SAAS,mBAAmB;IACrF,gBAAgB,QAAQ,MAAM,cAAc;IAC5C,YAAY,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,OAAO,MAAM,cAAc,SAAS,UAAU,CAAC,CAAC;IACpF,SAAS,KAAK,QAAQ,cAAc,OAAO,KAAK,QAAQ;IACxD,YAAY,KAAK,IAAI,IAAI;IACzB,WAAW;GACb;EACF,SAAS,KAAK;GACZ,OAAO;IACL,MAAM,MAAM;IACZ,cAAc,SAAS;IACvB,WAAW,SAAS;IACpB,qBAAqB,SAAS;IAC9B,gBAAgB,SAAS;IACzB,YAAY,SAAS;IACrB,SAAS,WAAW,CAAC,QAAQ,cAAc,QAAQ,UAAU;IAC7D,YAAY,KAAK,IAAI,IAAI;IACzB,WAAW;IACX,OAAO,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;GACxD;EACF;CACF;AACF;;;;ACxMA,SAASC,WAAS,KAAoC;CAKpD,OAAO,aAAa,GAAG;AACzB;;AAGA,SAAS,QAAQ,KAAwB;CACvC,OAAO,IAAI;AACb;;AAQA,SAAS,iBAAiB,MAAkC;CAC1D,MAAM,wBAAQ,IAAI,IAAY;CAC9B,MAAM,sBAAM,IAAI,IAAwC;CACxD,KAAK,MAAM,OAAO,MAAM;EACtB,MAAM,MAAM,QAAQ,GAAG;EACvB,MAAM,IAAI,GAAG;EACb,MAAM,IAAIA,WAAS,GAAG;EACtB,IAAI,MAAM,KAAA,GAAW;EACrB,MAAM,MAAM,IAAI,IAAI,GAAG,KAAK;GAAE,KAAK;GAAG,GAAG;EAAE;EAC3C,IAAI,OAAO;EACX,IAAI,KAAK;EACT,IAAI,IAAI,KAAK,GAAG;CAClB;CACA,OAAO;EACL;EACA,UAAU,IAAI,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC,KAAK,CAAC,KAAK,WAAW,CAAC,KAAK,MAAM,MAAM,MAAM,CAAC,CAAC,CAAC;CAC9E;AACF;;;;AAKA,SAAgB,qBAAqB,SAAyB;CAC5D,OAAO,SAAS,OAAO,KAAK,SAAS,MAAM,CAAC,CAAC,CAAC,aAAa;AAC7D;;;AAIA,SAAgB,oBACd,aACA,MACA,YACQ;CACR,IAAI,OAAO;CACX,KAAK,MAAM,OAAO,MAAM;EACtB,MAAM,IAAI,YAAY,IAAI,GAAG;EAC7B,IAAI,MAAM,KAAA,GACR,MAAM,IAAI,gBAAgB,2CAA2C,IAAI,EAAE;EAE7E,QAAQ,CAAC,KAAK,KAAK,KAAK,IAAI,GAAG,UAAU,CAAC;CAC5C;CACA,OAAO;AACT;AAEA,IAAa,wBAAb,MAAmC;CACjC;CACA;CACA;CACA;CACA;CAEA,YAAY,QAAiC;EAC3C,IAAI,CAAC,OAAO,aAAa,MAAM,IAAI,MAAM,gDAAgD;EACzF,KAAK,cAAc,OAAO;EAC1B,KAAK,SAAS,OAAO,UAAU;EAC/B,KAAK,aAAa,OAAO,cAAc;EACvC,KAAK,aAAa,OAAO,cAAc,KAAK;EAC5C,KAAK,WAAW,OAAO,YAAY;EACnC,IAAI,EAAE,KAAK,UAAU,IAAI,MAAM,IAAI,MAAM,2CAA2C;EACpF,IAAI,EAAE,KAAK,aAAa,KAAK,KAAK,aAAa,IAC7C,MAAM,IAAI,MAAM,oDAAoD;CACxE;;;;CAKA,SACE,WACA,UAC2B;EAC3B,MAAM,cAAcC,mBAAiB,UAAU,MAAM,KAAK,WAAW;EACrE,MAAM,iBAAiB,iBAAiB,UAAU,IAAI;EACtD,MAAM,gBAAgB,iBAAiB,SAAS,IAAI;EACpD,MAAM,aAAa,eAAe;EAClC,MAAM,aAAa,cAAc;EACjC,MAAM,QAAQ,CAAC,mBAAG,IAAI,IAAI,CAAC,GAAG,eAAe,OAAO,GAAG,cAAc,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK;EACnF,MAAM,SAAS,MAAM,QAAQ,QAAQ,WAAW,IAAI,GAAG,KAAK,WAAW,IAAI,GAAG,CAAC;EAC/E,MAAM,mBAAmB,MAAM,QAAQ,QAAQ,CAAC,WAAW,IAAI,GAAG,CAAC;EACnE,MAAM,kBAAkB,MAAM,QAAQ,QAAQ,CAAC,WAAW,IAAI,GAAG,CAAC;EAElE,MAAM,YAAY;GAChB,WAAW,KAAK,SAAS,qBAAqB,UAAU,OAAO;GAC/D,UAAU,KAAK,SAAS,qBAAqB,SAAS,OAAO;EAC/D;EACA,MAAM,WAAW;GACf,WAAW,oBAAoB,YAAY,QAAQ,KAAK,UAAU;GAClE,UAAU,oBAAoB,YAAY,QAAQ,KAAK,UAAU;EACnE;EACA,MAAM,YAAY;GAChB,WAAW,UAAU,YAAY,SAAS;GAC1C,UAAU,UAAU,WAAW,SAAS;EAC1C;EACA,MAAM,WAAsC;GAC1C,OAAO,OAAO;GACd;GACA;GACA;GACA,WAAW,UAAU,YAAY,UAAU;GAC3C,gBAAgB,UAAU,YAAY,UAAU;GAChD,eAAe,SAAS,YAAY,SAAS;EAC/C;EACA,MAAM,OAAO;GAAE;GAAa,YAAY,KAAK;GAAa;EAAS;EACnE,MAAM,OAAO,MAAc,EAAE,QAAQ,CAAC;EAEtC,IAAI,OAAO,SAAS,KAAK,UACvB,OAAO;GACL,GAAG;GACH,SAAS;GACT,QAAQ,cAAc,OAAO,OAAO,wBAAwB,KAAK;GACjE,eAAe;EACjB;EAEF,IAAI,iBAAiB,SAAS,KAAK,gBAAgB,SAAS,GAAG;GAC7D,MAAM,UAAU,CACd,iBAAiB,SAAS,IACtB,sBAAsB,WAAW,KAAK,GAAG,MAAM,OAAO,IAAI,iBAAiB,OAAO,YAAY,cAAc,gBAAgB,MAC5H,MACJ,gBAAgB,SAAS,IACrB,qBAAqB,WAAW,KAAK,GAAG,MAAM,OAAO,IAAI,gBAAgB,OAAO,YAAY,cAAc,eAAe,MACzH,IACN,CAAC,CAAC,QAAQ,SAAyB,SAAS,IAAI;GAChD,OAAO;IACL,GAAG;IACH,SAAS;IACT,QACE,wBAAwB,QAAQ,KAAK,IAAI,EAAE,qCACP,OAAO,OAAO;IACpD,eAAe;GACjB;EACF;EACA,IAAI,EAAE,SAAS,YAAY,CAAC,KAAK,aAAa;GAG5C,MAAM,OACJ,SAAS,gBAAgB,IAAI,gBAAgB;GAC/C,MAAM,MACJ,SAAS,gBACL,cAAc,IAAI,SAAS,cAAc,EAAE,qBAAqB,IAAI,CAAC,SAAS,aAAa,EAAE,kBAC7F,oCAAoC,IAAI,SAAS,aAAa,EAAE;GACtE,OAAO;IACL,GAAG;IACH,SAAS;IACT,QAAQ,GAAG,KAAK,YAAY,IAAI,SAAS,SAAS,EAAE,2BAA2B,IAAI,KAAK,UAAU,EAAE,gBAAgB;IACpH,eAAe;GACjB;EACF;EACA,OAAO;GACL,GAAG;GACH,SAAS;GACT,QAAQ,oBAAoB,IAAI,SAAS,SAAS,EAAE,iBAAiB,IAAI,SAAS,cAAc,EAAE,WAAW,IAAI,SAAS,aAAa,EAAE,SAAS,OAAO,OAAO;GAChK,eAAe;EACjB;CACF;AACF;AAEA,SAAS,cAAc,KAAuB;CAC5C,MAAM,QAAQ,IAAI,MAAM,GAAG,CAAC;CAC5B,MAAM,YAAY,IAAI,SAAS,MAAM;CACrC,OAAO,YAAY,IAAI,GAAG,MAAM,KAAK,IAAI,EAAE,KAAK,UAAU,SAAS,MAAM,KAAK,IAAI;AACpF;AAEA,SAASA,mBAAiB,MAAmB,aAA6B;CACxE,KAAK,MAAM,OAAO,MAChB,IAAI,IAAI,eAAe,IAAI,gBAAgB,aAAa,OAAO,IAAI;CACrE,OAAO,KAAK,EAAE,EAAE,eAAe;AACjC;;;;;;;;;ACzPA,MAAM,kBAAkB;AAExB,eAAsB,iBACpB,KACA,OAAgC,CAAC,GACH;CAC9B,MAAM,UAAU,KAAK,WAAW;CAChC,MAAM,UAAU,IAAI,IAAI,KAAK,WAAW,CAAC,CAAC;CAC1C,MAAM,UAAU,KAAK;CAErB,eAAe,KAAK,GAAyC;EAC3D,IAAI;EACJ,IAAI;GAEF,WAAU,MADQC,SAAG,QAAQ,GAAG,EAAE,eAAe,KAAK,CAAC,EAAA,CACzC,KAAK,OAAO;IAAE,MAAM,EAAE;IAAM,OAAO,EAAE,YAAY;GAAE,EAAE;EACrE,SAAS,KAAK;GAEZ,IADc,IAA8B,SAC/B,UAAU,OAAO,CAAC;GAC/B,MAAM;EACR;EACA,MAAM,MAA2B,CAAC;EAClC,KAAK,MAAM,SAAS,SAAS;GAC3B,MAAM,OAAO,KAAK,GAAG,MAAM,IAAI;GAC/B,IAAI,MAAM,OAAO;IACf,IAAI,KAAK,WAAW,IAAI,KAAK,GAAI,MAAM,KAAK,IAAI,CAAE;IAClD;GACF;GACA,IAAI,CAAC,QAAQ,KAAK,MAAM,IAAI,GAAG;GAC/B,IAAI,QAAQ,IAAI,MAAM,IAAI,KAAK,QAAQ,IAAI,SAAS,MAAM,MAAM,QAAQ,MAAM,IAAI,CAAC,CAAC,GAClF;GACF,IAAI,WAAW,QAAQ,SAAS,GAAG;IACjC,MAAM,KAAK,SAAS,MAAM,MAAM,QAAQ,MAAM,IAAI,CAAC;IAEnD,IAAI,CADY,QAAQ,MAAM,WAAW,MAAM,KAAK,SAAS,MAAM,KAAK,GAAG,SAAS,MAAM,CAC/E,GAAG;GAChB;GACA,IAAI,KAAK;IACP,MAAM;IACN,UAAU,MAAM;IAChB,IAAI,SAAS,MAAM,MAAM,QAAQ,MAAM,IAAI,CAAC;GAC9C,CAAC;EACH;EACA,OAAO;CACT;CAEA,MAAM,UAAU,MAAM,KAAK,GAAG;CAC9B,QAAQ,MAAM,GAAG,MAAM,EAAE,SAAS,cAAc,EAAE,QAAQ,CAAC;CAC3D,OAAO;AACT;;;;;;;;AClCA,SAAgB,aACd,SACA,YACA,UAMI,CAAC,GACQ;CACb,MAAM,UAAU,QAAQ,QAAQ;CAChC,MAAM,YAAY,WAAW,KAAK,MAAM,QAAQ,CAAC,CAAC,CAAC,YAAY,CAAC;CAChE,MAAM,UAAU,QAAQ,KAAK,WAAW,cAAc,QAAQ,SAAS,CAAC;CACxE,OAAO;EACL;EACA,MAAM,QAAQ,OAAO,OAAO,CAAC,CAAC;EAC9B,OAAO,QAAQ;CACjB;AACF;AAEA,SAAS,eAAe,WAA4B;CAClD,IAAI,OAAO,cAAc,UAAU,OAAO;CAC1C,IAAI,aAAa,OAAO,cAAc,UAAU;EAC9C,MAAM,QAAkB,CAAC;EACzB,KAAK,MAAM,KAAK,OAAO,OAAO,SAAoC,GAChE,IAAI,OAAO,MAAM,UAAU,MAAM,KAAK,CAAC;EAEzC,OAAO,MAAM,KAAK,GAAG;CACvB;CACA,OAAO,OAAO,aAAa,EAAE;AAC/B;AAEA,SAAS,cAAc,QAAoB,WAA8B;CACvE,KAAK,MAAM,UAAU,OAAO,KAAK;EAC/B,MAAM,SAAS,OAAO,YAAY,CAAC,CAAC,KAAK;EACzC,IAAI,CAAC,QAAQ;EACb,IAAI,UAAU,MAAM,MAAM,EAAE,SAAS,MAAM,CAAC,GAAG,OAAO;CACxD;CACA,KAAK,MAAM,WAAW,OAAO,YAAY,CAAC,GAAG;EAC3C,IAAI;EACJ,IAAI;GACF,KAAK,IAAI,OAAO,SAAS,GAAG;EAC9B,QAAQ;GACN;EACF;EACA,IAAI,UAAU,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,GAAG,OAAO;CAChD;CACA,OAAO;AACT;;AAGA,MAAa,2BAA2D;CACtE,UAAU;CACV,OAAO;CACP,OAAO;AACT;;AAGA,SAAgB,eACd,SACA,QACA,UAA0C,0BAClC;CACR,IAAI,QAAQ,WAAW,GAAG,OAAO;CACjC,MAAM,QAAQ,QAAQ,QAAQ,GAAG,MAAM,KAAK,QAAQ,EAAE,aAAa,IAAI,CAAC;CACxE,IAAI,UAAU,GAAG,OAAO;CAKxB,OAJY,QAAQ,QACjB,GAAG,GAAG,MAAM,KAAK,OAAO,QAAQ,KAAM,QAAQ,EAAE,aAAa,IAAK,IACnE,CAEO,IAAI;AACf;;;;;;;;;AAUA,SAAgB,UACd,SACA,YACA,UAA+C,CAAC,GACxC;CACR,IAAI,WAAW,WAAW,GAAG,OAAO;CACpC,MAAM,UAAU,QAAQ,QAAQ;CAChC,IAAI,UAAU;CACd,KAAK,MAAM,QAAQ,YAAY;EAC7B,MAAM,WAAW,QAAQ,IAAI,CAAC,CAAC,YAAY;EAY3C,IAXmB,QAAQ,MACxB,MACC,EAAE,IAAI,MAAM,WAAW,OAAO,SAAS,KAAK,SAAS,SAAS,OAAO,YAAY,CAAC,CAAC,MAClF,EAAE,YAAY,CAAC,EAAA,CAAG,MAAM,QAAQ;GAC/B,IAAI;IACF,OAAO,IAAI,OAAO,KAAK,GAAG,CAAC,CAAC,KAAK,QAAQ;GAC3C,QAAQ;IACN,OAAO;GACT;EACF,CAAC,CAEQ,GAAG;CAClB;CACA,OAAO,UAAU,WAAW;AAC9B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC8LA,IAAa,cAAb,MAAyB;CACvB;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CAEA,YAAY,QAA2B;EACrC,IAAI,CAAC,OAAO,aACV,MAAM,IAAI,MAAM,sCAAsC;EAExD,IACE,OAAO,gBAAgB,KAAA,KACvB,EAAE,OAAO,SAAS,OAAO,WAAW,KAAK,OAAO,eAAe,KAAK,OAAO,eAAe,IAE1F,MAAM,IAAI,MACR,qEAAqE,OAAO,aAC9E;EAEF,KAAK,cAAc,OAAO,eAAe;EACzC,KAAK,aAAa,OAAO,cAAc;EACvC,KAAK,oBAAoB,KAAK,IAC5B,OAAO,qBAAqB,GAC5B,+BAA+B,KAAK,UAAU,CAChD;EACA,KAAK,uBAAuB,OAAO,wBAAwB;EAC3D,KAAK,sBAAsB,OAAO,uBAAuB;EACzD,KAAK,cAAc,OAAO;EAC1B,KAAK,YAAY,OAAO,sBAAsB;EAC9C,KAAK,OAAO,OAAO;EACnB,KAAK,iBAAiB,OAAO,kBAAkB;EAC/C,IACE,OAAO,uBAAuB,KAAA,KAC9B,EAAE,OAAO,SAAS,OAAO,kBAAkB,KAAK,OAAO,qBAAqB,IAE5E,MAAM,IAAI,MAAM,kEAAkE;EAEpF,KAAK,qBAAqB,OAAO;CACnC;;;;CAKA,SAAS,WAAwB,UAAqC;EACpE,MAAM,cAAc,iBAAiB,WAAW,KAAK,WAAW;EAChE,MAAM,aAAa,KAAK;EACxB,yBAAyB,CAAC,GAAG,WAAW,GAAG,QAAQ,CAAC;EAMpD,MAAM,oBAAoB,CAAC,GAAG,WAAW,GAAG,QAAQ,CAAC,CAAC,OAAO,eAAe,CAAC,CAAC;EAC9E,MAAM,kBAAkB,UAAU,QAAQ,QAAQ,CAAC,gBAAgB,GAAG,CAAC;EACvE,MAAM,iBAAiB,SAAS,QAAQ,QAAQ,CAAC,gBAAgB,GAAG,CAAC;EAErE,MAAM,kBAAkB,WAAW,iBAAiB,QAAQ;EAC5D,MAAM,iBAAiB,WAAW,gBAAgB,QAAQ;EAC1D,MAAM,mBAAmB,WAAW,iBAAiB,SAAS;EAC9D,MAAM,kBAAkB,WAAW,gBAAgB,SAAS;EAC5D,MAAM,gBAAgB,eAAe,gBAAgB,eAAe;EACpE,MAAM,iBAAiB,eAAe,iBAAiB,gBAAgB;EAMvE,MAAM,iBAAiB,cAAc,gBAAgB,iBAAiB,QAAQ;EAC9E,MAAM,kBAAkB,cAAc,gBAAgB,iBAAiB,SAAS;EAGhF,MAAM,gBAAgB,KAAgB,UACpC,mBAAmB,KAAK,KAAK;EAC/B,MAAM,eAAe,cAAc,MAAM,KAAK,SAAS,aAAa,KAAK,UAAU,QAAQ,CAAC;EAC5F,MAAM,cAAc,cAAc,MAAM,KAAK,SAAS,aAAa,KAAK,WAAW,QAAQ,CAAC;EAC5F,MAAM,gBAAgB,eAAe,MAAM,KAAK,SAAS,aAAa,KAAK,UAAU,SAAS,CAAC;EAC/F,MAAM,eAAe,eAAe,MAAM,KAAK,SAAS,aAAa,KAAK,WAAW,SAAS,CAAC;EAE/F,MAAM,iBAAiB,cAAc;EAErC,MAAM,sBAAsB,WAAW,WAAW;EAClD,MAAM,uBAAuB,WAAW,YAAY;EACpD,MAAM,qBAAqB,WAAW,YAAY;EAClD,MAAM,sBAAsB,WAAW,aAAa;EAEpD,MAAM,aAAa,WAAW,qBAAqB,oBAAoB;EACvE,MAAM,qBAAqB,WAAW,oBAAoB,mBAAmB;EAc7E,MAAM,sBAAsB,mBAAmB,CAC7C,GAAG,cAAc,MAAM,KAAK,SAAS,KAAK,SAAS,GACnD,GAAG,eAAe,MAAM,KAAK,SAAS,KAAK,SAAS,CACtD,CAAC;EACD,MAAM,qBAAqB,mBAAmB,CAC5C,GAAG,cAAc,MAAM,KAAK,SAAS,KAAK,QAAQ,GAClD,GAAG,eAAe,MAAM,KAAK,SAAS,KAAK,QAAQ,CACrD,CAAC;EACD,MAAM,iBAAiB;GACrB;GACA,uBAAuB,eAAe,kBAAkB;GACxD,sBAAsB,eAAe,iBAAiB;GACtD,aAAa;GACb,cAAc;GACd;GACA;GACA;GACA;GACA;GACA;GACA;EACF;;;;EAIA,MAAM,aAAa,KAAK,YAAY,eAAe,YAAY;EAC/D,MAAM,eAAe;GACnB,GAAG;GACH,mBAAmB,iBAAiB,IAAI,YAAY,eAAe,YAAY,IAAI;GACnF,gBAAgB,WAAW;GAC3B,eAAe;GACf,UAAU;GACV,cAAc;GACd,SAAS;GACT,aAAa,WAAW;GACxB,aAAa,WAAW;EAC1B;EAEA,MAAM,qBAAqB;GACzB,gBAAgB,WAAW,IAAI,qBAAqB;GACpD,iBAAiB,WAAW,IAAI,sBAAsB;GACtD,eAAe,WAAW,IAAI,oBAAoB;GAClD,gBAAgB,WAAW,IAAI,qBAAqB;EACtD,CAAC,CAAC,QAAQ,UAA2B,UAAU,IAAI;EACnD,IAAI,mBAAmB,SAAS,GAC9B,OAAO;GACL,SAAS;GACT;GACA;GACA,UAAU;GACV,QAAQ,yBAAyB,mBAAmB,KAAK,IAAI,EAAE;GAC/D,eAAe;EACjB;EAUF,MAAM,aACJ,CACE,CAAC,WAAW,eAAe,GAC3B,CAAC,UAAU,cAAc,CAC3B,CAAC,CACD,QAAQ,GAAG,SAAS,IAAI,WAAW,KAAK,WAAW;EACrD,IAAI,WAAW,SAAS,GACtB,OAAO;GACL,SAAS;GACT;GACA;GACA,UAAU;GACV,QACE,wBAAwB,WAAW,KAAK,CAAC,OAAO,SAAS,iBAAiB,OAAO,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI,EAAA,cACjF,IAAI,KAAK,WAAW,EAAE;GAEvC,eAAe;EACjB;EAGF,IAAI,iBAAiB,KAAK,mBACxB,OAAO;GACL,SAAS;GACT;GACA;GACA,UAAU;GACV,QAAQ,aAAa,eAAe,uCAAuC,KAAK;GAChF,eAAe;EACjB;EAEF,IAAI,eAAe,QAAQ,uBAAuB,MAChD,MAAM,IAAI,MAAM,iEAAiE;EAQnF,MAAM,WAAW,sBAAsB,eAAe,cAAc;GAClE,WAAW,KAAK;GAChB,YAAY,KAAK;GACjB,WAAW,KAAK;GAChB,MAAM,KAAK;GACX,UAAU,KAAK;GACf,WAAW,KAAK,mBAAmB,WAAW,WAAW;EAC3D,CAAC;EACD,MAAM,gBAAgB,YAAY,eAAe,YAAY;EAC7D,MAAM,WAAW,mBAAmB,eAAe,YAAY;EAC/D,MAAM,EAAE,OAAO,eAAe,KAAK,MAAM,OAAO,eAAe;EAE/D,MAAM,WAAyB;GAC7B,GAAG;GACH,mBAAmB;GACnB,gBAAgB,SAAS;GACzB;GACA,UAAU;IAAE;IAAK;GAAK;GACtB,cAAc,SAAS;GACvB,SAAS,SAAS;GAClB,aAAa,SAAS;GACtB,aAAa,SAAS;EACxB;EAYA,IAAI,SAAS,eACX,OAAO;GACL,SAAS;GACT;GACA;GACA;GACA,QACE,wBAAwB,SAAS,mBAAmB,iCAChD,IAAI,GAAG,EAAE,IAAI,IAAI,IAAI,EAAE,yDACE,IAAI,KAAK,oBAAoB,EAAE;GAC9D,eAAe;EACjB;EAYF,MAAM,kBAAkB,SAAS;EAGjC,IAAI,CAAC,SAAS,mBAAmB,iBAAiB;GAChD,MAAM,SAAS,kBACX,oBAAoB,SAAS,SAAS,OAAO,cAAc,CAAC,EAAE,wBAAwB,IAAI,IAAI,KAAK,UAAU,EAAE,KAC/G,SAAS;GACb,OAAO;IACL,SAAS;IACT;IACA;IACA;IACA,QACE,kCAAkC,WAAW,KAAK,IAAI,aAAa,EAAE,OAC9D,IAAI,GAAG,EAAE,IAAI,IAAI,IAAI,EAAE,6BAA6B,IAAI,KAAK,oBAAoB,EAAE,GAAG;IAC/F,eAAe;GACjB;EACF;EAIA,IAAI,aAAa,qBAAqB,KAAK,qBACzC,OAAO;GACL,SAAS;GACT;GACA;GACA;GACA,QACE,8BAA8B,IAAI,UAAU,EAAE,wBAAwB,IAAI,kBAAkB,EAAE,gBAC9E,IAAI,KAAK,mBAAmB;GAC9C,eAAe;EACjB;EAMF,IAAI,KAAK,uBAAuB,KAAA,KAAa,wBAAwB,MACnE,OAAO;GACL,SAAS;GACT;GACA;GACA;GACA,QAAQ;GACR,eAAe;EACjB;EAEF,IACE,KAAK,uBAAuB,KAAA,KAC5B,wBAAwB,QACxB,sBAAsB,KAAK,oBAE3B,OAAO;GACL,SAAS;GACT;GACA;GACA;GACA,QACE,wCAAwC,IAAI,mBAAmB,EAAE,oBAC7C,IAAI,KAAK,kBAAkB,EAAE,cAAc,IAAI,kBAAkB,EAAE;GACzF,eAAe;EACjB;EAGF,OAAO;GACL,SAAS;GACT;GACA;GACA;GACA,QACE,2BAA2B,WAAW,KAAK,IAAI,aAAa,EAAE,OACvD,IAAI,GAAG,EAAE,IAAI,IAAI,IAAI,EAAE,SAAS,eAAe,gCAC7B,IAAI,UAAU,EAAE,eAAe,IAAI,kBAAkB,EAAE,2BACtD,IAAI,mBAAmB,EAAE,gBAAgB,IAAI,kBAAkB;GAC3F,eAAe;EACjB;CACF;;;;;;;CAQA,YAAoB,QAAkB,OAAsC;EAC1E,OAAO,oBAAoB,QAAQ,OAAO,KAAK,mBAAmB,WAAW,WAAW,MAAM;CAChG;AACF;AAIA,SAAS,iBAAiB,WAAwB,aAA6B;CAC7E,KAAK,MAAM,OAAO,WAChB,IAAI,IAAI,eAAe,IAAI,gBAAgB,aAAa,OAAO,IAAI;CAIrE,OAAO,UAAU,EAAE,EAAE,eAAe;AACtC;AAEA,SAAS,yBAAyB,MAAyB;CACzD,KAAK,MAAM,OAAO,MAChB,IAAI,OAAO,IAAI,eAAe,YAAY,IAAI,WAAW,KAAK,MAAM,IAClE,MAAM,IAAI,MAAM,oBAAoB,IAAI,MAAM,uBAAuB;AAG3E;;;;;;;AAQA,SAAS,WAAW,MAAmB,OAAqC;CAC1E,OAAO,KAAK,QAAQ,QAAQ;EAC1B,IAAI,IAAI,aAAa,OAAO,OAAO;EACnC,MAAM,IAAI,mBAAmB,KAAK,KAAK;EACvC,OAAO,OAAO,MAAM,YAAY,OAAO,SAAS,CAAC;CACnD,CAAC;AACH;;;AAIA,SAAS,UAAU,MAAmB,OAAqC;CACzE,OAAO,KAAK,QAAQ,QAAQ,IAAI,aAAa,KAAK;AACpD;AAEA,SAAS,eAAe,KAAgB,OAAiC;CACvE,MAAM,IAAI,mBAAmB,KAAK,KAAK;CACvC,OAAO,OAAO,MAAM,YAAY,OAAO,SAAS,CAAC;AACnD;;;;;;;;;;;AAYA,SAAS,cACP,UACA,WACA,OACe;CACf,MAAM,UAAU,eAAe,UAAU,UAAU,KAAK,GAAG,UAAU,WAAW,KAAK,CAAC;CACtF,IAAI,WAAW;CACf,KAAK,MAAM,QAAQ,QAAQ,OACzB,IAAI,eAAe,KAAK,UAAU,KAAK,KAAK,eAAe,KAAK,WAAW,KAAK,GAAG,YAAY;CAEjG,MAAM,gBAAgB,QAAQ,MAAM,SAAS;CAC7C,MAAM,gBAAgB,QAAQ,kBAAkB;CAChD,MAAM,eAAe,QAAQ,iBAAiB;CAC9C,MAAM,QAAQ,QAAQ,MAAM,SAAS,gBAAgB;CACrD,OAAO;EACL;EACA;EACA;EACA;EACA;EACA,UAAU,UAAU,IAAI,IAAI,WAAW;CACzC;AACF;AAEA,SAAS,iBAAiB,OAAe,KAA4B;CACnE,MAAM,OAAO;EACX,IAAI,gBAAgB,IAAI,GAAG,IAAI,cAAc,2CAA2C;EACxF,IAAI,eAAe,IAAI,GAAG,IAAI,aAAa,yCAAyC;EACpF,IAAI,gBAAgB,IAAI,GAAG,IAAI,cAAc,0CAA0C;CACzF,CAAC,CAAC,QAAQ,SAAyB,SAAS,IAAI;CAChD,OACE,GAAG,MAAM,UAAU,IAAI,SAAS,MAAM,IAAI,MAAM,yBAAyB,IAAI,IAAI,QAAQ,EAAE,MAC1F,KAAK,SAAS,IAAI,MAAM,KAAK,KAAK,IAAI,MAAM;AAEjD;AAEA,SAAS,WAAW,IAA6B;CAC/C,IAAI,GAAG,WAAW,GAAG,OAAO;CAC5B,OAAO,GAAG,QAAQ,GAAG,MAAM,IAAI,GAAG,CAAC,IAAI,GAAG;AAC5C;AAEA,SAAS,WAAW,GAAkB,GAAiC;CACrE,IAAI,MAAM,QAAQ,MAAM,MAAM,OAAO;CACrC,OAAO,IAAI;AACb;AAEA,SAAS,YAAY,QAAkB,OAAyB;CAC9D,MAAM,KAAK,OAAO,KAAK,GAAG,MAAM,MAAM,KAAM,CAAC,CAAC,CAAC,MAAM,GAAG,MAAM,IAAI,CAAC;CACnE,IAAI,GAAG,WAAW,GAAG,MAAM,IAAI,MAAM,sDAAsD;CAC3F,MAAM,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC;CACpC,OAAO,GAAG,SAAS,MAAM,KAAK,GAAG,MAAM,KAAM,GAAG,QAAS,IAAI,GAAG;AAClE;AAEA,SAAS,aAAa,IAA6B;CACjD,MAAM,KAAK,GAAG,QAAQ,MAAM,OAAO,SAAS,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,MAAM,IAAI,CAAC;CACpE,IAAI,GAAG,WAAW,GAAG,OAAO;CAC5B,MAAM,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC;CACpC,OAAO,GAAG,SAAS,MAAM,KAAK,GAAG,MAAM,KAAM,GAAG,QAAS,IAAI,GAAG;AAClE;AAEA,SAAS,mBAAmB,MAAkC;CAC5D,IAAI,KAAK,WAAW,GAAG,OAAO;CAC9B,MAAM,QAAkB,CAAC;CACzB,KAAK,MAAM,OAAO,MAAM;EACtB,MAAM,aAAa,IAAI;EACvB,IAAI,WAAW,SAAS,cAAc,OAAO;EAC7C,MAAM,KAAK,WAAW,GAAG;CAC3B;CACA,OAAO,aAAa,KAAK;AAC3B;AAEA,SAAS,IAAI,GAA0B;CACrC,IAAI,MAAM,MAAM,OAAO;CACvB,OAAO,EAAE,QAAQ,CAAC;AACpB;;;AC1xBA,SAAgB,kBAAqB,OAAmD;CACtF,MAAM,SAAS,MAAM;CACrB,IAAI,OAAO,SAAS,GAClB,OAAO;EAAE,eAAe;EAAG,WAAW,OAAO;EAAQ,cAAc,CAAC;CAAE;CAExE,MAAM,SAAS,MAAM,QAAQ;CAC7B,MAAM,SAAS,MAAM,kBAAkB;CACvC,MAAM,UAAU,OAAO,KAAK,MAAM,WAAW,EAAE,UAAU,QAAQ,MAAM,CAAC;CACxE,MAAM,OAAiB,CAAC;CACxB,KAAK,IAAI,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAClC,KAAK,IAAI,IAAI,IAAI,GAAG,IAAI,QAAQ,QAAQ,KACtC,KAAK,KAAK,iBAAiB,QAAQ,IAAK,QAAQ,EAAG,CAAC;CAGxD,MAAM,OAAO,KAAK,WAAW,IAAI,IAAI,KAAK,QAAQ,GAAG,MAAM,IAAI,GAAG,CAAC,IAAI,KAAK;CAC5E,OAAO;EACL,eAAe,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,IAAI,IAAI,CAAC;EAChD,WAAW,OAAO;EAClB,cAAc;CAChB;AACF;AAEA,SAAS,cAAc,MAAuB;CAC5C,IAAI,OAAO,SAAS,UAAU,OAAO;CACrC,IAAI,QAAQ,OAAO,SAAS,UAAU;EACpC,MAAM,QAAkB,CAAC;EACzB,KAAK,MAAM,KAAK,OAAO,OAAO,IAA+B,GAC3D,IAAI,OAAO,MAAM,UAAU,MAAM,KAAK,CAAC;EAEzC,OAAO,MAAM,KAAK,GAAG;CACvB;CACA,OAAO,OAAO,QAAQ,EAAE;AAC1B;AAEA,SAAS,WACP,OACA,QACA,QACqB;CACrB,MAAM,sBAAM,IAAI,IAAoB;CACpC,KAAK,MAAM,QAAQ,OAAO;EACxB,MAAM,OAAO,OAAO,IAAI,CAAC,CAAC,YAAY;EACtC,KAAK,MAAM,OAAO,KAAK,MAAM,YAAY,CAAC,CAAC,QAAQ,MAAM,EAAE,UAAU,MAAM,GACzE,IAAI,IAAI,MAAM,IAAI,IAAI,GAAG,KAAK,KAAK,CAAC;CAExC;CACA,OAAO;AACT;AAEA,SAAS,iBAAiB,GAAwB,GAAgC;CAChF,IAAI,MAAM;CACV,IAAI,OAAO;CACX,IAAI,OAAO;CACX,KAAK,MAAM,GAAG,MAAM,GAAG,QAAQ,IAAI;CACnC,KAAK,MAAM,GAAG,MAAM,GAAG,QAAQ,IAAI;CACnC,KAAK,MAAM,CAAC,GAAG,MAAM,GAAG;EACtB,MAAM,KAAK,EAAE,IAAI,CAAC;EAClB,IAAI,IAAI,OAAO,IAAI;CACrB;CACA,IAAI,SAAS,KAAK,SAAS,GAAG,OAAO;CACrC,OAAO,OAAO,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,IAAI;AAChD;;;AC9EA,SAAgB,kCACd,MACA,UAAqD,CAAC,GAC3B;CAC3B,MAAM,OAAkC,CAAC;CACzC,KAAK,MAAM,OAAO,MAAM;EACtB,MAAM,YAAY,IAAI,aAAa,IAAI;EACvC,MAAM,SAAS,QAAQ,eAAe,GAAG,KAAK;GAC5C,IAAI;GACJ,UAAU,IAAI;EAChB;EAEA,KAAK,MAAM,WAAW,IAAI,OACxB,KAAK,KAAK;GACR;GACA,YAAY,QAAQ;GACpB;GACA,OACE,QAAQ,eAAe,SAAS,GAAG,KACnC,kCAAkC,QAAQ,OAAO,QAAQ,UAAU;GACrE,UAAU;IACR,OAAO,IAAI;IACX,OAAO,QAAQ;IACf,MAAM,QAAQ,UAAU,QAAQ,QAAQ,UAAU,QAAQ,QAAQ;IAClE,gBAAgB,QAAQ,WAAW;IACnC,gBAAgB,QAAQ,WAAW;IACnC,SAAS,QAAQ,MAAM;IACvB,OAAO,QAAQ,MAAM;IACrB,gBAAgB,QAAQ,MAAM;IAC9B,WAAW,QAAQ,MAAM;IACzB,QAAQ,QAAQ,MAAM;IACtB,IAAI,QAAQ,MAAM;IAClB,OAAO,QAAQ;IACf,GAAI,QAAQ,YAAY,CAAC;GAC3B;EACF,CAAC;CAEL;CACA,OAAO;AACT;AAEA,SAAgB,kCACd,eACA,aAAa,GACH;CACV,MAAM,UAAU,cAAc;CAC9B,MAAM,SAAS,cAAc;CAC7B,MAAM,YAAY,cAAc;CAChC,MAAM,SAAS,cAAc,QAAQ,KAAK,cAAc,YAAY;CAEpE,OAAO;EACL;EACA,cAAc;EACd,kBAAkB;EAClB,cAAc,IAAI;EAClB,gBAAgB;EAChB,cAAc;EACd,aAAa,cAAc,QAAQ,IAAI,IAAI;EAC3C,WAAW;EACX,kBAAkB,SAAS,IAAI;EAC/B,SAAS;EACT,aAAa,KAAK,IAAI,GAAG,aAAa,GAAI;EAC1C,OAAO,CACL,4BAA4B,cAAc,QAAQ,GAAG,cAAc,SACnE,aAAa,UAAU,QAAQ,CAAC,EAAE,UAAU,OAAO,QAAQ,CAAC,EAAE,MAAM,QAAQ,QAAQ,CAAC,GACvF;CACF;AACF;;;;;;;ACmCA,IAAa,qBAAb,MAAsD;CACvB;CAA7B,YAAY,WAAuD;EAAtC,KAAA,YAAA;CAAuC;CAEpE,gBAAgB,MAA2C;EACzD,OAAO,KAAK,UAAU,gBAAgB,IAAI;CAC5C;CAEA,cAAc,UAAoD;EAChE,OAAO,KAAK,UAAU,cAAc,QAAQ;CAC9C;CAEA,YAAY,SAA2B,UAAmD;EACxF,OAAO,KAAK,UAAU,YAAY,SAAS,QAAQ;CACrD;CAEA,eAAe,MAAiD;EAC9D,OAAO,KAAK,UAAU,eAAe,IAAI;CAC3C;AACF;;;;;;;;AASA,IAAa,iBAAb,MAAkD;CAChD;CAEA,YAAY,OAAO,2CAA2C;EAC5D,KAAK,OAAO;CACd;CAEA,MAAM,gBAAgB,OAA4C;EAChE,MAAM,IAAI,MAAM,GAAG,KAAK,KAAK,mCAAmC;CAClE;CAEA,MAAM,cAAc,WAAqD;EACvE,MAAM,IAAI,MAAM,GAAG,KAAK,KAAK,iCAAiC;CAChE;CAEA,MAAM,YACJ,UACA,WACyB;EACzB,MAAM,IAAI,MAAM,GAAG,KAAK,KAAK,+BAA+B;CAC9D;CAEA,MAAM,eAAe,OAAkD;EACrE,MAAM,IAAI,MAAM,GAAG,KAAK,KAAK,kCAAkC;CACjE;AACF;;;;;;;;;;;;;;;;;;;;;;;AC9FA,SAAgB,kBAAqB,MAAgD;CACnF,IAAI,KAAK,OAAO,GAAG,MAAM,IAAI,MAAM,uCAAuC,KAAK,KAAK,EAAE;CAEtF,MAAM,QAAwB,CAAC;CAK/B,MAAM,UAAoB,CAAC;CAC3B,MAAM,QAAQ,IAAI,MAAM;CACxB,IAAI,aAAa;CAMjB,IAAI,YAAY;CAChB,IAAI,iBAAiB;CACrB,IAAI,SAAS;CACb,IAAI,UAAU;CACd,MAAM,YAAY,KAAK,IAAI;;;;;;;CAQ3B,eAAe,cAAqC;EAClD,IAAI;EACJ,MAAM,QAAQ,MAAM,MAAM,aAAa,YAAY;GACjD,MAAM,OAAO,MAAM,MAAM,MAAM,CAAC,EAAE,IAAI;GACtC,IAAI,MAAM;IACR,KAAK,OAAO;IACZ,OAAO;GACT;GACA,IAAI,MAAM,SAAS,YAAY,KAAK,MAAM;IAGxC,SAAS,QAAQ;IACjB;IACA,OAAO;GACT;GACA,OAAO;EACT,CAAC;EACD,IAAI,OAAO,OAAO;EAClB,IAAI,WAAW,KAAA,GAAW;GACxB,IAAI;GACJ,IAAI;IACF,WAAW,MAAM,KAAK,QAAQ,OAAO,MAAM;GAC7C,SAAS,KAAK;IAGZ,MAAM,MAAM,mBAAmB;KAC7B;IACF,CAAC;IACD,IAAI,CAAC,SAAS,iBAAiB;IAC/B,MAAM;GACR;GACA,MAAM,QAAsB;IAC1B,MAAM;KAAE,IAAI;KAAQ;IAAS;IAC7B,MAAM;GACR;GACA,MAAM,MAAM,mBAAmB;IAC7B,MAAM,KAAK,KAAK;IAChB;GACF,CAAC;GACD,OAAO;EACT;EAEA,OAAO,IAAI,SAAuB,SAAS,WAAW;GACpD,QAAQ,KAAK;IAAE;IAAS;GAAO,CAAC;EAClC,CAAC;CACH;;;;;;CAOA,SAAS,iBAAiB,OAA2B;EACnD,MAAM,OAAO,QAAQ,MAAM;EAC3B,IAAI,MAAM;GACR,MAAM,OAAO;GACb,KAAK,QAAQ,KAAK;EACpB;CACF;;;;;;;CAQA,SAAS,mBAAyB;EAChC,MAAM,OAAO,QAAQ,MAAM;EAC3B,IAAI,CAAC,MAAM;EACX,YAAY,CAAC,CAAC,KAAK,KAAK,SAAS,KAAK,MAAM;CAC9C;;;;;;;;;;CAWA,SAAS,YAAY,OAA2B;EAC9C,CAAM,YAAY;GAChB,IAAI;IACF,IAAI,KAAK,QAAQ,OACf,MAAM,KAAK,QAAQ,MAAM,MAAM,IAAI;IAErC,MAAM,OAAO;IACb,IAAI,CAAC,SAAS,iBAAiB,KAAK;GACtC,SAAS,UAAU;IAGjB,MAAM,MAAM,mBAAmB;KAC7B,MAAM,IAAI,MAAM,QAAQ,KAAK;KAC7B,IAAI,MAAM,IAAI,MAAM,OAAO,GAAG,CAAC;IACjC,CAAC;IACD,IAAI;KACF,MAAM,KAAK,QAAQ,QAAQ,MAAM,IAAI;IACvC,SAAS,YAAY;KACnB,QAAQ,KACN,wCAAwC,MAAM,KAAK,GAAG,6BACtD,UACF;IACF;IACA,QAAQ,KACN,wCAAwC,MAAM,KAAK,GAAG,mCACtD,QACF;IACA,IAAI,CAAC,SAAS,iBAAiB;GACjC;EACF,EAAA,CAAG,CAAC,CAAC,OAAO,QAAQ;GAGlB,QAAQ,KAAK,kCAAkC,MAAM,KAAK,GAAG,YAAY,GAAG;EAC9E,CAAC;CACH;CAEA,eAAe,WAAgE;EAC7E,MAAM,QAAQ,MAAM,YAAY;EAChC,MAAM,gBAAgB,KAAK,IAAI;EAC/B;EACA,OAAO;GACL,MAAM,MAAM;GACZ,eAAe;IACb,UAAU,KAAK,IAAI,IAAI;IACvB,YAAY,KAAK;GACnB;EACF;CACF;CAEA,eAAe,SAAY,IAAmD;EAC5E,MAAM,EAAE,MAAM,YAAY,MAAM,SAAS;EACzC,IAAI;GACF,OAAO,MAAM,GAAG,IAAI;EACtB,UAAU;GACR,QAAQ;EACV;CACF;CAEA,eAAe,QAAuB;EACpC,UAAU;EAGV,MAAM,EAAE,UAAU,YAAY,MAAM,MAAM,mBAAmB;GAG3D,OAAO;IAAE,UAFK,MAAM,OAAO,GAAG,MAAM,MAEb;IAAG,SADX,QAAQ,OAAO,GAAG,QAAQ,MACD;GAAE;EAC5C,CAAC;EAID,KAAK,MAAM,KAAK,SACd,EAAE,uBAAO,IAAI,MAAM,mDAAmD,CAAC;EAEzE,MAAM,QAAQ,WAAW,SAAS,KAAK,MAAM,KAAK,QAAQ,QAAQ,EAAE,IAAI,CAAC,CAAC;CAC5E;CAEA,SAAS,cAAc;EACrB,OAAO;GACL;GACA,SAAS,KAAK,IAAI,IAAI;GACtB,WAAW;EACb;CACF;CAEA,OAAO;EACL;EACA;EACA;EACA,gBAAgB,MAAM;EACtB,uBAAuB,MAAM,QAAQ,MAAM,EAAE,IAAI,CAAC,CAAC;EACnD;CACF;AACF;;;;;;;;;;;;;;ACzPA,SAAgB,iBAAiB,MAAgD;CAU/E,MAAM,WAAW,mBAAmB;EARlC,GAAG,MAAM;EACT,oBAAoB;GAClB,GAAI,MAAM,eAAe,EAAE,iBAAiB,KAAK,aAAa,IAAI,CAAC;GACnE,GAAI,MAAM,aAAa,EAAE,eAAe,KAAK,WAAW,IAAI,CAAC;GAC7D,GAAG,MAAM,YAAY;EACvB;CAGuC,CAAC;CAE1C,OAAO;EACL;EACA,MAAM,WAAW;GACf,IAAI,UAAU,MAAM,SAAS,SAAS;EACxC;CACF;AACF;;;;AAKA,SAAgB,mBAA4B;CAC1C,OAAO,CAAC,EAAE,OAAO,YAAY,eAAe,QAAQ,IAAI;AAC1D;;;;;;;;;;;;;;;;;;;;;;;;;;AC9BA,MAAa,eAAuB;CAClC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF,CAAC,CAAC,KAAK,IAAI;;;AAIX,MAAa,iBAAyB;CACpC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF,CAAC,CAAC,KAAK,IAAI;;AAGX,MAAa,iBAAyB;CACpC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF,CAAC,CAAC,KAAK,IAAI;;AAGX,MAAa,iBAAiB;CAC5B,UAAU;CACV,YAAY;CACZ,YAAY;AACd;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACLA,SAAS,YAAY,OAA6B;CAChD,MAAM,QAAQ,CAAC,OAAO,MAAM,QAAQ,MAAM,WAAW;CACrD,IAAI,MAAM,SAAS,SAAS,GAC1B,MAAM,KAAK,aAAa,MAAM,SAAS,KAAK,IAAI,GAAG;CAErD,IAAI,MAAM,eAAe,KAAA,GACvB,MAAM,KAAK,YAAY,MAAM,YAAY;CAE3C,OAAO,MAAM,KAAK,IAAI;AACxB;;;;;;;;AASA,SAAgB,cAAc,GAA0B;CActD,OAAO;EAZL,EAAE,KAAK,KAAK;EACZ,qBAAqB,EAAE,YAAY,KAAK;EACxC,0BAA0B,EAAE,gBAAgB,KAAK;EACjD,gBACE,EAAE,OAAO,SAAS,IAAI,EAAE,OAAO,IAAI,WAAW,CAAC,CAAC,KAAK,MAAM,IAAI;EAEjE,yBACE,EAAE,OAAO,SAAS,IACd,EAAE,OAAO,KAAK,MAAM,OAAO,EAAE,MAAM,MAAM,EAAE,KAAK,KAAK,GAAG,CAAC,CAAC,KAAK,MAAM,IACrE;CAGG,CAAC,CAAC,KAAK,MAAM;AAC1B;;;AAIA,SAAgB,iBAAiB,GAA0B;CACzD,OAAO,cAAc,CAAC;AACxB;AAEA,MAAM,eAA+B,CACnC;CACE,MAAM;CACN,aACE;CACF,UAAU,CACR,qCACA,qDACF;AACF,GACA;CACE,MAAM;CACN,aACE;CACF,UAAU,CAAC,yCAAyC,qCAAqC;AAC3F,CACF;AAEA,MAAM,uBACJ;AAMF,MAAM,4BACJ;;;;;;AASF,SAAgB,gBAAgB,MAKd;CAChB,OAAO;EACL,MAAM,KAAK;EACX,aAAa,KAAK,eAAe;EACjC,iBAAiB,KAAK,mBAAmB;EACzC,QAAQ,KAAK,UAAU;EACvB,QAAQ,CAAC;CACX;AACF;;;;;;;;AASA,SAAgB,wBACd,MACA,OAAoF,CAAC,GACtE;CACf,OAAO,gBAAgB;EAAE,MAAM,eAAe;EAAO,GAAG;CAAK,CAAC;AAChE;;;;;AAMA,SAAgB,YACd,UACA,SACe;CACf,OAAO;EAAE,GAAG;EAAU,QAAQ,CAAC,GAAG,SAAS,QAAQ,GAAG,OAAO;CAAE;AACjE;;;;;;;;AASA,SAAgB,iBACd,GACA,WACA,SACe;CACf,MAAM,MAAM,EAAE,OAAO,WAAW,MAAM,EAAE,OAAO,SAAS;CACxD,IAAI,QAAQ,IACV,MAAM,IAAI,MACR,wCAAwC,UAAU,WAChD,EAAE,OAAO,KAAK,MAAM,EAAE,EAAE,CAAC,CAAC,KAAK,IAAI,KAAK,SACzC,EACH;CAEF,MAAM,SAAS,EAAE,OAAO;CACxB,IAAI,WAAW,KAAA,GACb,MAAM,IAAI,MAAM,qCAAqC,UAAU,wBAAwB;CAEzF,IAAI,CAAC,OAAO,WACV,MAAM,IAAI,MAAM,qCAAqC,UAAU,mBAAmB;CAEpF,MAAM,OAAO,CAAC,GAAG,EAAE,MAAM;CACzB,KAAK,OAAO;EAAE,GAAG;EAAQ,MAAM;CAAQ;CACvC,OAAO;EAAE,GAAG;EAAG,QAAQ;CAAK;AAC9B;;;;;;;;;;AAWA,SAAgB,YAAY,SAAsC;CAChE,OAAO,mBAAmB,KAAK,UAAU;EAAE,OAAO,QAAQ;EAAO,MAAM,QAAQ;CAAK,CAAC,CAAC;AACxF;;;;AC7MA,eAAsB,oBACpB,OACA,SACA,cAC8B;CAC9B,MAAM,aAAa,MAAM,aAAa,QAAQ,KAAK;EACjD,MAAM;EACN,MAAM;EACN,cAAc,aAAa;EAC3B,YAAY;GACV,kBAAkB,QAAQ,OAAO;GACjC,2BAA2B,MAAM,SAAS;GAC1C,0BAA0B,QAAQ,QAAQ,iBAAiB;GAC3D,yBAAyB,QAAQ,QAAQ,eAAe;GACxD,cAAc;EAChB;CACF,CAAC;CAED,IAAI;EACF,MAAM,SAAS,MAAM,cAAc,OAAO,OAAO;EACjD,KAAK,MAAM,CAAC,OAAO,SAAS,OAAO,WAAW,QAAQ,GAAG;GACvD,MAAM,UAAU,KAAK,UAAU,IAAI;GAWnC,OAAM,MAViB,aAAa,QAAQ,KAAK;IAC/C,MAAM;IACN,MAAM,gBAAgB,QAAQ;IAC9B,cAAc,WAAW,KAAK;IAC9B,YAAY;KACV,gBAAgB,QAAQ;KACxB,sBAAsB,OAAO,WAAW,OAAO;KAC/C,cAAc;IAChB;GACF,CAAC,EAAA,CACc,IAAI;EACrB;EACA,MAAM,WAAW,IAAI,EACnB,YAAY;GACV,kBAAkB,QAAQ,OAAO;GACjC,uBAAuB,OAAO;GAC9B,sBAAsB,OAAO;GAC7B,sBAAsB,OAAO,WAAW;GACxC,yBAAyB,OAAO,SAAS;GACzC,yBAAyB,OAAO,OAAO;GACvC,cAAc;EAChB,EACF,CAA4B;EAC5B,OAAO;CACT,SAAS,OAAO;EACd,MAAM,WAAW,KAAK,iBAAiB,QAAQ,QAAQ,OAAO,KAAK,CAAC;EACpE,MAAM;CACR;AACF;;;;;;ACxCA,SAAgB,WAAW,OAAgB,WAAmB,MAAmC;CAC/F,OAAO,OAAO,MAAkB,UAA6C;EAC3E,MAAM,OAAO,MAAM,KAAK,QAAQ,KAAK;GACnC,MAAM;GACN,MAAM,SAAS;GACf,cAAc,KAAK;GACnB,YAAY;IACV,cAAc;IACd,cAAc;GAChB;EACF,CAAC;EACD,IAAI;GACF,MAAM,SAAS,MAAM,MAAM,MAAM,KAAK;GACtC,MAAM,YACJ,OAAO,SAAS,IAAI,OAAO,QAAQ,KAAK,MAAM,MAAM,EAAE,OAAO,CAAC,IAAI,OAAO,SAAS;GACpF,MAAM,KAAK,IAAI,EACb,YAAY;IACV,cAAc;IACd,yBAAyB;IACzB,yBAAyB,OAAO;IAChC,cAAc;GAChB,EACF,CAA4B;GAC5B,OAAO;EACT,SAAS,KAAK;GACZ,MAAM,KAAK,KAAK,eAAe,QAAQ,MAAM,OAAO,GAAG,CAAC;GACxD,MAAM;EACR;CACF;AACF;;;;;;AAOA,SAAgB,mBACd,QACA,YACA,MACS;CACT,OAAO,OAAO,MAAkB,UAAsB;EACpD,MAAM,eAAe,MAAM,KAAK,QAAQ,KAAK;GAC3C,MAAM;GACN,MAAM;GACN,cAAc,KAAK;GACnB,YAAY;IACV,uBAAuB,OAAO;IAC9B,cAAc;GAChB;EACF,CAAC;EACD,IAAI;GACF,MAAM,YAA0B,CAAC;GACjC,IAAI,eAAe;GACnB,KAAK,IAAI,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK;IACtC,MAAM,QAAQ,OAAO;IAErB,MAAM,WAAW,WAAW,OADf,WAAW,MAAM,SAAS,KACE;KACvC,SAAS,KAAK;KACd,cAAc,aAAa,KAAK;IAClC,CAAC;IACD,IAAI;KACF,MAAM,SAAS,MAAM,SAAS,MAAM,KAAK;KACzC,UAAU,KAAK,GAAG,MAAM;IAC1B,SAAS,KAAK;KAKZ,IAAI,EAAE,eAAe,kBAAkB,MAAM;KAC7C;IACF;GACF;GACA,MAAM,YACJ,UAAU,SAAS,IAAI,UAAU,QAAQ,KAAK,MAAM,MAAM,EAAE,OAAO,CAAC,IAAI,UAAU,SAAS;GAC7F,MAAM,aAAa,IAAI,EACrB,YAAY;IACV,uBAAuB,OAAO;IAC9B,yBAAyB;IACzB,0BAA0B,UAAU;IACpC,uBAAuB;IACvB,cAAc;GAChB,EACF,CAA4B;GAC5B,OAAO;EACT,SAAS,KAAK;GACZ,MAAM,aAAa,KAAK,eAAe,QAAQ,MAAM,OAAO,GAAG,CAAC;GAChE,MAAM;EACR;CACF;AACF;;;;AC7EA,SAAgB,WAAW,QAAsC;CAC/D,MAAM,UAAU,OAAO,QAAQ;CAC/B,MAAM,2BAAW,IAAI,IAA6B;CAClD,KAAK,MAAM,SAAS,OAAO,KAAK,GAAG;EACjC,MAAM,OAAO,SAAS,IAAI,MAAM,KAAK,KAAK;GACxC,OAAO,MAAM;GACb,KAAK;GACL,SAAS;GACT,UAAU;EACZ;EACA,KAAK,OAAO,MAAM;EAClB,KAAK,WAAW;EAChB,IAAI,MAAM,aAAa,KAAK,WAAW;EACvC,SAAS,IAAI,MAAM,OAAO,IAAI;CAChC;CACA,OAAO;EACL,YAAY,QAAQ;EACpB,OAAO;GACL,KAAK,QAAQ;GACb,gBAAgB,QAAQ,UAAU,QAAQ,KAAK,MAAM,MAAM,EAAE,eAAe,CAAC;EAC/E;EACA,UAAU,CAAC,GAAG,SAAS,OAAO,CAAC,CAAC,CAAC,MAAM,GAAG,MAAM,EAAE,MAAM,cAAc,EAAE,KAAK,CAAC;CAChF;AACF;;;;;;;AAQA,SAAgB,mBACd,QACA,QAC0B;CAC1B,IAAI,UAAU,QACZ,MAAM,IAAI,gBACR,+FACF;CAEF,OAAO;EAAE,GAAG;EAAQ,MAAM,WAAW,MAAM;CAAE;AAC/C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACVA,MAAa,cAA0D;CACrE,SAAS;EACP,QAAQ;EACR,QAAQ;GAAC;GAAmB;GAAe;EAAyB;EACpE,SAAS;EACT,YAAY;EACZ,UAAU;CACZ;CACA,UAAU,CAAC;AACb;;AAGA,IAAa,iBAAb,cAAoC,YAAY;CAClB;CAA5B,YAAY,MAAgC;EAC1C,MACE,qBAAqB,KAAK,yHAE5B;EAJ0B,KAAA,OAAA;CAK5B;AACF;AAgBA,SAAgB,YACd,OACA,MACA,UACmB;CACnB,MAAM,QAAQ,MAAM;CACpB,IAAI,SAAS,UAAU;EACrB,IAAI,UAAU,KAAA,KAAa,CAAC,MAAM,QAAQ,KAAK,GAC7C,MAAM,IAAI,gBAAgB,qDAAqD,OAAO,OAAO;EAE/F,MAAM,SAAS,MAAM,QAAQ,KAAK,IAAI,QAAQ,CAAC;EAC/C,IAAI,OAAO,SAAS,GAAG;GACrB,MAAM,QAAQ,OAAO,WAAW,MAAM,OAAO,MAAM,YAAY,EAAE,KAAK,MAAM,EAAE;GAC9E,IAAI,SAAS,GACX,MAAM,IAAI,gBACR,sBAAsB,MAAM,sDAC9B;GAEF,OAAO,CAAC,GAAG,MAAM;EACnB;CACF,OAAO;EACL,IAAI,UAAU,KAAA,KAAa,OAAO,UAAU,UAC1C,MAAM,IAAI,gBAAgB,qBAAqB,KAAK,0BAA0B,OAAO,OAAO;EAE9F,IAAI,OAAO,UAAU,YAAY,MAAM,KAAK,MAAM,IAAI,OAAO;CAC/D;CACA,IAAI,aAAa,KAAA,GAAW;EAC1B,IAAI,SAAS,KAAK,MAAM,IACtB,MAAM,IAAI,gBAAgB,kCAAkC,KAAK,WAAW;EAE9E,OAAO,SAAS,WAAW,CAAC,QAAQ,IAAI;CAC1C;CACA,MAAM,IAAI,eAAe,IAAI;AAC/B;;;;;;;;;;;;;;;;;;;;;;;ACjHA,MAAa,wBAAwB;;;;;;;AAsCrC,SAAgB,OAAO,QAAiB,YAAmD;CACzF,OAAO;EACL,YAAY,YAAY,MAAM;EAC9B;EACA,WAAW;CACb;AACF;;;;;;;AAQA,SAAgB,kBACd,QACA,UACyB;CACzB,IAAI,SAAS,cAAA,yBACX,OAAO;EACL,OAAO;EACP,QAAQ,sBAAsB,SAAS,UAAU,iCAAiC,sBAAsB;CAC1G;CAEF,IAAI;CACJ,IAAI;EACF,aAAa,YAAY,MAAM;CACjC,SAAS,KAAK;EACZ,OAAO;GACL,OAAO;GACP,QAAQ,kCAAkC,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;EAC3F;CACF;CACA,IAAI,eAAe,SAAS,YAC1B,OAAO;EACL,OAAO;EACP,QAAQ,kCAAkC,SAAS,WAAW,eAAe;CAC/E;CAEF,OAAO,EAAE,OAAO,KAAK;AACvB;;;;;;;;;;;;;;;;;;;;;;ACnEA,MAAa,kCAAkC;CAC7C;CACA;CACA;CACA;CACA;CACA;AACF;AAwEA,SAAS,OAAO,OAAuB;CACrC,OAAO,UAAU,WAAW,QAAQ,CAAC,CAAC,OAAO,KAAK,CAAC,CAAC,OAAO,KAAK;AAClE;AAEA,SAAS,aAAa,OAAuB;CAC3C,OACE,MACG,QAAQ,qBAAqB,GAAG,CAAC,CACjC,QAAQ,YAAY,EAAE,CAAC,CACvB,MAAM,GAAG,EAAE,KAAK;AAEvB;AAEA,SAAS,IAAI,MAAyB,UAA0B;CAC9D,MAAM,MAAM,UAAU,OAAO,MAAM;EAAE,KAAK,QAAQ,IAAI;EAAG,UAAU;CAAO,CAAC;CAC3E,MAAM,QAAQ,IAAI,WAAW,IAAI,IAAI,OAAO,KAAK,IAAI;CACrD,OAAO,MAAM,SAAS,IAAI,QAAQ;AACpC;AAEA,SAAS,SAAS,MAAkC;CAClD,MAAM,QAAQ,QAAQ,IAAI,KAAK,EAAE,KAAK;CACtC,OAAO,SAAS,UAAU,YAAY,QAAQ,KAAA;AAChD;AAEA,SAAS,eAAmC;CAC1C,MAAM,SACJ,SAAS,iBAAiB,KAAK,SAAS,iBAAiB,KAAK,SAAS,uBAAuB;CAChG,IAAI,QAAQ,OAAO;CACnB,MAAM,MAAM,SAAS,YAAY;CACjC,OAAO,KAAK,WAAW,aAAa,IAAI,IAAI,MAAM,EAAoB,IAAI,KAAA;AAC5E;AAEA,SAAS,aAAqB;CAC5B,MAAM,KAAK,aAAa;CACxB,IAAI,IAAI,OAAO;CACf,MAAM,SAAS,IAAI,CAAC,UAAU,gBAAgB,GAAG,EAAE;CACnD,IAAI,QAAQ,OAAO;CACnB,MAAM,OAAO,IAAI;EAAC;EAAY;EAAe;EAAoB;CAAM,GAAG,EAAE;CAC5E,IAAI,QAAQ,SAAS,aAAa,OAAO;CACzC,OAAO,YAAY,IAAI;EAAC;EAAa;EAAW;CAAM,GAAG,SAAS;AACpE;;AAGA,SAAgB,+BAAiE;CAC/E,OAAO;EACL,KAAK,IAAI;GAAC;GAAU;GAAS;EAAmB,GAAG,SAAS;EAC5D,QAAQ,IAAI,CAAC,aAAa,MAAM,GAAG,SAAS;EAC5C,QAAQ,WAAW;CACrB;AACF;;;;;AAMA,SAAS,eAAe,MAAsB;CAC5C,MAAM,MAAM,KAAK,MAAM,aAAa,QAAQ,cAAc,GAAG,MAAM,CAAC;CAMpE,IAAI,IAAI,SAAS,QAAQ,IAAI,SAAS,OAAO,IAAI;CACjD,MAAM,WAAW,IAAI,eAAe,SAAS,IAAI,kBAAkB;CACnE,IAAI,UAAU,OAAO;CACrB,MAAM,YAAY,QAAQ,gBAAgB,MAAM,cAAc;CAC9D,IAAI,WAAW,SAAS,GAAG;EACzB,MAAM,eAAe,KAAK,MAAM,aAAa,WAAW,MAAM,CAAC;EAC/D,IAAI,aAAa,SAAS,OAAO,aAAa;CAChD;CACA,OAAO;AACT;AAIA,SAAS,eAAe,MAA2B;CAKjD,OAJc,aAAa,MAAM,MAAM,CAAC,CACrC,MAAM,IAAI,CAAC,CACX,KAAK,SAAS,KAAK,KAAK,CAAC,CAAC,CAC1B,OAAO,OACC,CAAC,CAAC,KAAK,MAAM,UAAU;EAChC,IAAI;EACJ,IAAI;GACF,SAAS,KAAK,MAAM,IAAI;EAC1B,SAAS,KAAK;GACZ,MAAM,IAAI,gBACR,GAAG,KAAK,GAAG,QAAQ,EAAE,IAAI,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,KACxE,EAAE,OAAO,IAAI,CACf;EACF;EACA,OAAO,qBAAqB,QAAQ,GAAG,KAAK,GAAG,QAAQ,GAAG;CAC5D,CAAC;AACH;AAEA,SAAS,qBAAqB,OAAgB,MAAyB;CACrE,IAAI,CAAC,SAAS,OAAO,UAAU,YAAY,MAAM,QAAQ,KAAK,GAC5D,MAAM,IAAI,gBAAgB,GAAG,KAAK,+BAA+B;CAEnE,MAAM,MAAM;CACZ,KAAK,MAAM,OAAO,CAAC,SAAS,OAAO,GACjC,IAAI,OAAO,IAAI,SAAS,YAAY,IAAI,IAAI,CAAC,WAAW,GACtD,MAAM,IAAI,gBAAgB,GAAG,KAAK,eAAe,IAAI,4BAA4B;CAGrF,KAAK,MAAM,OAAO,CAAC,WAAW,QAAQ,GACpC,IAAI,OAAO,IAAI,SAAS,YAAY,CAAC,OAAO,SAAS,IAAI,IAAI,GAC3D,MAAM,IAAI,gBAAgB,GAAG,KAAK,eAAe,IAAI,yBAAyB;CAGlF,MAAM,aAAa,IAAI;CACvB,IACE,CAAC,cACD,OAAO,WAAW,UAAU,YAC5B,OAAO,WAAW,WAAW,UAE7B,MAAM,IAAI,gBAAgB,GAAG,KAAK,qDAAqD;CAEzF,MAAM,UAAU,IAAI;CACpB,IAAI,CAAC,SAAS,OAAO,OAAO,QAAQ,QAAQ,UAC1C,MAAM,IAAI,gBAAgB,GAAG,KAAK,2CAA2C;CAE/E,OAAO;AACT;AAIA,SAASC,UAAQ,OAAuB;CACtC,OAAO,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,KAAK,CAAC;AACvC;AAEA,SAAS,QAAQ,QAAmB,MAAoD;CACtF,MAAM,SAAS,KAAK,gBAAgB,MAAM;CAC1C,IAAI,QAAQ,OAAO;CACnB,IAAK,OAAO,QAAQ,IAA+B,WAAW,GAAG,OAAO;CACxE,IAAI,OAAO,aAAa,WAAW,OAAO;CAC1C,IAAI,OAAO,aAAa,OAAO,OAAO;CACtC,OAAO;AACT;;;;;;AAOA,SAAS,QAAQ,QAA2B;CAC1C,MAAM,QAAQ,aAAa,MAAM;CACjC,IAAI,UAAU,KAAA,GAAW,OAAOA,UAAQ,KAAK;CAC7C,KACG,OAAO,QAAQ,aAAa,cAAc,UAAU,KAAK,MACzD,OAAO,QAAQ,IAAI,qBAAqB,KAAK,GAE9C,MAAM,IAAI,gBACR,OAAO,OAAO,MAAM,qFACtB;CAEF,MAAM,IAAI,gBACR,OAAO,OAAO,MAAM,qEACtB;AACF;AAEA,SAAS,UAAU,QAAmC;CACpD,MAAM,UAAW,OAAO,QAAQ,IAAgC;CAChE,IAAI,OAAO,YAAY,WAAW,OAAO;CACzC,IAAI,OAAO,YAAY,YAAY,OAAO,SAAS,OAAO,GAAG,OAAO,WAAW;CAC/E,OAAO;AACT;AAEA,SAAS,OAAO,QAAmB,OAAe,WAA4B;CAC5E,MAAM,UAAU,UAAU,MAAM;CAChC,MAAM,iBAAiB,OAAO,iBAAiB,KAAA,KAAa,OAAO,iBAAiB;CACpF,IAAI,YAAY,MAAM,OAAO,WAAW,CAAC;CACzC,OAAO,SAAS,aAAa,CAAC;AAChC;AAEA,SAAS,UACP,QACA,OACA,WAC2E;CAC3E,IAAI,OAAO,iBAAiB,KAAA,KAAa,OAAO,iBAAiB,WAC/D,OAAO;EACL,cAAc,OAAO;EACrB,eAAe,OAAO,eAAe;CACvC;CAEF,MAAM,iBAAiB,4BAA4B,KAAK,MAAM,QAAQ,GAAG,EAAE,MAAM,KAAK,MAAM,YAAY,GAAG,EAAE;CAC7G,IAAI,UAAU,MAAM,MAAM,OACxB,OAAO;EACL,cAAc;EACd,eAAe,QAAQ,YAAY,iBAAiB;CACtD;CAEF,IAAI,OAAO,QAAQ,OAAO,SAAS,GACjC,OAAO;EAAE,cAAc;EAAM,eAAe;CAAK;CAEnD,OAAO;EAAE,cAAc;EAAW,eAAe;CAAe;AAClE;AAEA,SAAS,kBAAkB,QAA2C;CACpE,MAAM,aAAqC,CAAC;CAC5C,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,OAAO,QAAQ,OAAO,CAAC,CAAC,GAChE,IAAI,OAAO,UAAU,YAAY,OAAO,SAAS,KAAK,GAAG,WAAW,OAAO;CAE7E,IAAI,OAAO,KAAK,UAAU,CAAC,CAAC,WAAW,GAAG,WAAW,QAAQ,QAAQ,MAAM;CAC3E,OAAO;AACT;AAEA,SAAS,QAAQ,QAA2B;CAC1C,IAAI,OAAO,aAAa,OAAO,OAAO;CACtC,MAAM,UAAU,OAAO,cAAc,YAAY;CACjD,IAAI,OAAO,YAAY,YAAY,QAAQ,SAAS,GAAG,OAAO;CAC9D,MAAM,YAAY,OAAO,cAAc,YAAY;CACnD,IAAI,OAAO,cAAc,YAAY,UAAU,SAAS,GAAG,OAAO;CAClE,OAAO;AACT;AAEA,SAAS,UAAU,QAA2B;CAC5C,MAAM,UAAU,OAAO,cAAc,YAAY;CACjD,OAAO,OAAO,YAAY,YAAY,QAAQ,SAAS,IAAI,UAAU;AACvE;AAEA,SAAS,cAAc,QAA2B;CAChD,MAAM,UAAU,UAAU,MAAM;CAChC,IAAI,YAAY,cAAc,OAAO;CACrC,IAAI,YAAY,WAAW,OAAO;CAClC,IAAI,OAAO,MAAM,WAAW,SAAS,GAAG,OAAO;CAC/C,OAAO,YAAY,YAAY,WAAW;AAC5C;AAEA,SAAS,kBAAkB,QAAmB,MAAgD;CAC5F,MAAM,kBAAkB,OAAO,cAAc,YAAY;CACzD,OAAO;EACL,OAAO,OAAO,cAAc,SAAS,OAAO;EAC5C,SAAS,OAAO,cAAc,SAAS,MAAM,GAAG,KAAK,UAAU;EAC/D,SAAS,UAAU,MAAM;EACzB,GAAI,OAAO,oBAAoB,YAAY,gBAAgB,SAAS,IAChE,EAAE,gBAAgB,IAClB,CAAC;CACP;AACF;AAEA,SAAS,kBAAkB,QAA2B;CACpD,OACE,OAAO,cAAc,eAAe,QACpC,OAAO,cAAc,UACrB,OACE,KAAK,UAAU;EACb,aAAa,OAAO;EACpB,YAAY,OAAO;EACnB,YAAY,OAAO;CACrB,CAAC,CACH;AAEJ;AAEA,SAAS,wBAAwB,QAAmB,SAAoC;CACtF,OAAO,OACL,KAAK,UAAU;EAAE,mBAAmB,kBAAkB,MAAM;EAAG,OAAO,QAAQ;CAAM,CAAC,CACvF;AACF;AAEA,SAAS,YACP,QACA,OACA,SACA,MACQ;CACR,MAAM,OAAO,OAAO,cAAc,aAAa,KAAK,qBAAqB;CAEzE,OAAO,GADS,KAAK,SAAS,IAAI,OAAO,IAAI,OAAO,GAAG,KAAK,GAAG,QAC7C,GAAG,QAAQ;AAC/B;AAEA,SAAS,YAAY,QAAmB,QAAgB,MAAqC;CAC3F,MAAM,MAAM,OAAO,QAAQ;CAC3B,MAAM,UAAU,OAAO,IAAI,mBAAmB,IAAI,cAAc,IAAI,aAAa,CAAC;CAClF,IAAI,OAAO,SAAS,OAAO,KAAK,UAAU,GAAG,OAAO;CACpD,MAAM,WAAW,KAAK,mBAAmB,QAAQ,MAAM;CACvD,IAAI,aAAa,KAAA,KAAa,OAAO,SAAS,QAAQ,KAAK,WAAW,GAAG,OAAO;CAChF,OAAO,OAAO,SAAS,OAAO,IAAI,UAAU;AAC9C;AAIA,MAAM,mBAAmB;CAAC;CAAgB;CAAU;CAAS;AAAa;AAC1E,MAAM,iBAAiB,CAAC,cAAc,YAAY;AAClD,MAAM,mBAAmB,CAAC,eAAe,eAAe;AAExD,SAAS,cAAc,QAAgB,YAAuC;CAC5E,OAAO,WAAW,MAAM,cAAc,WAAW,KAAK,QAAQ,SAAS,CAAC,CAAC,KAAK,WAAW;AAC3F;AAEA,SAAS,kBAAkB,QAAqD;CAC9E,OAAO;EACL,SAAS;EACT,QAAQ,cAAc,QAAQ,gBAAgB;EAC9C,MAAM,cAAc,QAAQ,cAAc;EAC1C,QAAQ,cAAc,QAAQ,gBAAgB;EAC9C,WAAW,WAAW,KAAK,QAAQ,WAAW,CAAC,IAAI,cAAc;CACnE;AACF;AAEA,SAAS,kBAAkB,QAAqD;CAC9E,MAAM,MAAM,kBAAkB,MAAM;CACpC,OAAO;EACL,SAAS,QAAQ,QAAQ,IAAI,OAAO;EACpC,QAAQ,QAAQ,QAAQ,IAAI,MAAM;EAClC,MAAM,QAAQ,QAAQ,IAAI,IAAI;EAC9B,QAAQ,QAAQ,QAAQ,IAAI,MAAM;EAClC,WAAW,QAAQ,QAAQ,IAAI,SAAS;CAC1C;AACF;AAEA,SAAS,wBACP,QACA,QACA,OACqC;CACrC,IAAI,QAAQ,MAAM,MAAM,QAAQ,MAAM,GAAG,OAAO,kBAAkB,MAAM;CACxE,MAAM,MAAM,SAAS,QAAQ,MAAM;CACnC,IAAI,OAAO,CAAC,IAAI,WAAW,IAAI,KAAK,CAAC,WAAW,GAAG,GACjD,MAAM,IAAI,gBAAgB,4CAA4C,QAAQ;CAGhF,MAAM,UAAU,KAAK,eAAe,GADtB,OAAO,QAAQ,CAAC,CAAC,CAAC,SAAS,GAAG,GAAG,EAAE,GAAG,aAAa,SAAS,MAAM,CAAC,EAAE,GAAG,OAAO,MAAM,CAAC,CAAC,MAAM,GAAG,EAAE,GAC1E;CACtC,MAAM,UAAU,KAAK,QAAQ,OAAO;CACpC,UAAU,QAAQ,OAAO,GAAG,EAAE,WAAW,KAAK,CAAC;CAC/C,OAAO,QAAQ,SAAS;EAAE,WAAW;EAAM,OAAO;CAAK,CAAC;CACxD,MAAM,SAAS,kBAAkB,MAAM;CACvC,OAAO;EACL,SAAS,KAAK,SAAS,OAAO,OAAO;EACrC,QAAQ,KAAK,SAAS,OAAO,MAAM;EACnC,MAAM,KAAK,SAAS,OAAO,IAAI;EAC/B,QAAQ,KAAK,SAAS,OAAO,MAAM;EACnC,WAAW,OAAO,cAAc,MAAM,UAAU,KAAK,SAAS,OAAO,SAAS;CAChF;AACF;AAEA,SAAS,eAAe,cAAsB,OAAwB;CACpE,OAAO,WAAW,QAAQ,cAAc,KAAK,CAAC;AAChD;;AAKA,SAAgB,kCACd,QACA,QACA,cACA,WACA,SACwB;CACxB,MAAM,OAAO,eAAe,OAAO;CACnC,MAAM,UAAU,kBAAkB,QAAQ,IAAI;CAC9C,MAAM,QAAQ,QAAQ,MAAM;CAC5B,MAAM,UAAU,UAAU,QAAQ,OAAO,KAAK,aAAa;CAC3D,MAAM,QAAQ,QAAQ,MAAM;CAC5B,MAAM,cAAc,OAAO,WAAW;CACtC,MAAM,eAAe,OAAO,WAAW;CACvC,MAAM,gBAAgB,YAAY,QAAQ,QAAQ,IAAI;CACtD,MAAM,aAAa,kBAAkB,MAAM;CAC3C,IAAI,OAAO,YAAY,MACrB,MAAM,IAAI,gBACR,QAAQ,OAAO,MAAM,iEACvB;CAEF,MAAM,UAAU,OAAO;CACvB,IAAI,EAAE,gBAAgB,aAAa,WAAW,aAAa;CA2C3D,OAAO,+BAA+B;EAzCpC,eAAe;EACf,WAAW,KAAK;EAChB,aAAa,KAAK;EAClB,OAAO,OAAO;EACd,YAAY,OAAO;EACnB,OAAO,QAAQ,QAAQ,IAAI;EAC3B;EACA,KAAK,OAAO,OAAO,QAAQ,CAAC,IAAI;EAChC,cAAc;GACZ,IAAI,YAAY,QAAQ,OAAO,SAAS,IAAI;GAC5C,MAAM,wBAAwB,QAAQ,OAAO;GAC7C,MAAM,KAAK;GACX,UAAU;GACV,UAAU;EACZ;EACA,OAAO;GAAE,UAAU,cAAc,MAAM;GAAG,IAAI,OAAO;EAAM;EAC3D,SAAS;GAAE,MAAM,UAAU,MAAM;GAAG,SAAS,KAAK;EAAe;EACjE,SAAS;GACP,MAAM,OAAO,QAAQ,OAAO,KAAK,aAAa;GAC9C;GACA;GACA,GAAG;EACL;EACA,OAAO;GACL;GACA;GACA;GAEA,QAAQ,KAAK,MAAM,OAAO,MAAM;GAChC,WAAW;EACb;EACA,WAAW;GACT,aAAa,cAAc,eAAe;GAC1C,YAAY,eAAe,cAAc,UAAU,IAAI;GACvD,cAAc,eAAe,cAAc,UAAU,MAAM;GAC3D,YAAY,cAAc,eAAe;GACzC,QAAQ,UAAU;GAClB,qBAAqB,QAAQ,OAAO,cAAc,MAAM;EAC1D;EACA;CAE0C,CAAC;AAC/C;;;;;AAMA,SAAS,iBAAiB,SAAsE;CAC9F,MAAM,wBAAQ,IAAI,IAAoC;CACtD,KAAK,MAAM,UAAU,SAAS;EAC5B,MAAM,QAAQ,MAAM,IAAI,OAAO,KAAK;EACpC,IAAI,CAAC,OAAO;GACV,MAAM,IAAI,OAAO,OAAO,MAAM;GAC9B;EACF;EACA,MAAM,SAAS;GACb;IAAC;IAAa,MAAM,aAAa;IAAI,OAAO,aAAa;GAAE;GAC3D;IAAC;IAAS,MAAM,aAAa,SAAS;IAAO,OAAO,aAAa,SAAS;GAAK;GAC/E;IAAC;IAAW,MAAM,aAAa,SAAS;IAAS,OAAO,aAAa,SAAS;GAAO;GACrF;IAAC;IAAW,MAAM,aAAa,SAAS;IAAS,OAAO,aAAa,SAAS;GAAO;GACrF;IACE;IACA,MAAM,aAAa,SAAS;IAC5B,OAAO,aAAa,SAAS;GAC/B;EACF;EACA,KAAK,MAAM,CAAC,MAAM,GAAG,MAAM,QACzB,IAAI,MAAM,GACR,MAAM,IAAI,gBACR,oBAAoB,OAAO,MAAM,gBAAgB,KAAK,IAAI,OAAO,CAAC,EAAE,MAAM,OAAO,CAAC,EAAE,sCACtF;CAGN;CACA,OAAO,CAAC,GAAG,MAAM,OAAO,CAAC;AAC3B;;;;AAKA,SAAS,sBACP,SAC0B;CAC1B,MAAM,6BAAa,IAAI,IAAoC;CAC3D,KAAK,MAAM,UAAU,SAAS;EAC5B,MAAM,QAAQ,WAAW,IAAI,OAAO,UAAU;EAC9C,IAAI,CAAC,OAAO;GACV,WAAW,IAAI,OAAO,YAAY,MAAM;GACxC;EACF;EACA,IAAI,MAAM,UAAU,OAAO,OACzB,MAAM,IAAI,gBACR,yBAAyB,OAAO,WAAW,uBAAuB,MAAM,MAAM,MAAM,OAAO,MAAM,EACnG;CAEJ;CACA,OAAO,CAAC,GAAG,WAAW,OAAO,CAAC;AAChC;;AAGA,SAAgB,8BACd,SACA,SAI0B;CAC1B,IAAI,QAAQ,WAAW,GACrB,MAAM,IAAI,gBAAgB,6DAA6D;CAEzF,MAAM,oBAAoB,QAAQ,qBAAqB,yBAAyB,QAAQ,SAAS;CACjG,MAAM,kBAAkB,QAAQ,mBAAmB;CACnD,MAAM,4BAAY,IAAI,IAA0D;CAChF,KAAK,MAAM,UAAU,SACnB,UAAU,IAAI,OAAO,aAAa,IAAI;EACpC,IAAI,OAAO,aAAa;EACxB,aAAa,OAAO,aAAa;EACjC,kBAAkB,OAAO,aAAa;CACxC,CAAC;CA0CH,OAAO,iCAAiC;EAvCtC,eAAe;EACf,WAAW,QAAQ;EACnB,aAAa,QAAQ;EACrB,MAAM,6BAA6B;EACnC,WAAW;GACT,WAAW,eAAe,4BAA4B;GACtD,cAAc,eAAe,+BAA+B;GAC5D,gBAAgB,eAAe,iCAAiC;GAChE,SAAS,eAAe,yBAAyB;GACjD,GAAG,QAAQ;EACb;EACA,UAAU,CAAC,GAAG,UAAU,OAAO,CAAC;EAChC,MAAM,iBAAiB,OAAO,CAAC,CAAC,KAAK,YAAY;GAC/C,IAAI,OAAO;GACX,WAAW,OAAO,aAAa;GAC/B,iBAAiB,CAAC,GAAG,eAAe;GACpC,YAAY;IACV,SAAS,OAAO,MAAM,SAAS,QAAQ,IAAI,kBAAkB;IAC7D,OAAO,OAAO,aAAa,SAAS;IACpC,SAAS,OAAO,aAAa,SAAS;IACtC,SAAS,OAAO,aAAa,SAAS;IACtC,GAAI,OAAO,aAAa,SAAS,oBAAoB,KAAA,IACjD,EAAE,iBAAiB,OAAO,aAAa,SAAS,gBAAgB,IAChE,CAAC;GACP;EACF,EAAE;EACF,WAAW,sBAAsB,OAAO,CAAC,CAAC,KAAK,YAAY;GACzD,IAAI,OAAO;GACX,OAAO,OAAO;GACd,MAAM;IAAC;IAAmB,QAAQ;IAAa,OAAO;GAAK;GAC3D,2BAA2B;EAC7B,EAAE;EACF,SAAS;GACP,QAAQ,QAAQ,QAAQ,KAAK,WAAW,MAAM,OAAO,MAAM,SAAS,CAAC;GACrE,UAAU,QAAQ;GAClB,WAAW,QAAQ,QAAQ,KAAK,WAAW,MAAM,OAAO,MAAM,QAAQ,CAAC;EACzE;EACA,qBAAqB,QAAQ,QAAQ,MAAM;CAEE,CAAC;AAClD;;AAKA,SAAgB,uBACd,SAC8B;CAC9B,MAAM,EAAE,QAAQ,GAAG,SAAS;CAC5B,OAAO,2BAA2B;EAAE,GAAG;EAAM,SAAS,CAAC,MAAM;CAAE,CAAC;AAClE;;;;;;AAOA,SAAgB,2BACd,SAC8B;CAC9B,MAAM,OAAO,eAAe,OAAO;CACnC,MAAM,SAAS,QAAQ,QAAQ,MAAM;CACrC,MAAM,UAAU,QAAQ,QAAQ,KAAK,WAAW,QAAQ,MAAM,CAAC;CAC/D,IAAI,QAAQ,WAAW,GAAG,MAAM,IAAI,gBAAgB,4CAA4C;CAChG,MAAM,cAAc,QAAQ,0BAA0B;CACtD,MAAM,OAAO,QAAQ,SAAS,WAAW;EACvC,MAAM,oBAAoB,KAAK,QAAQ,eAAe;EACtD,IAAI,CAAC,WAAW,iBAAiB,GAAG,MAAM,IAAI,gBAAgB,WAAW,mBAAmB;EAC5F,MAAM,UAAU,eAAe,iBAAiB;EAChD,IAAI,QAAQ,WAAW,GAAG,MAAM,IAAI,gBAAgB,GAAG,kBAAkB,UAAU;EACnF,OAAO,QAAQ,KAAK,YAAY;GAAE;GAAQ;EAAO,EAAE;CACrD,CAAC;CACD,UAAU,QAAQ,EAAE,WAAW,KAAK,CAAC;CACrC,MAAM,oCAAoB,IAAI,IAAiD;CAC/E,KAAK,MAAM,CAAC,OAAO,WAAW,QAAQ,QAAQ,GAC5C,kBAAkB,IAChB,QACA,cAAc,wBAAwB,QAAQ,QAAQ,KAAK,IAAI,kBAAkB,MAAM,CACzF;CAEF,MAAM,eAAe,cAAc,SAAS;CAC5C,MAAM,aAAa,KAAK,KAAK,EAAE,QAAQ,aACrC,kCACE,QACA,QACA,cACA,kBAAkB,IAAI,MAAM,GAC5B;EAAE,GAAG;EAAS;EAAS,gBAAgB,KAAK;CAAe,CAC7D,CACF;CACA,MAAM,WAAW,8BAA8B,YAAY;EACzD;EACA,WAAW,KAAK;EAChB,aAAa,KAAK;EAClB,mBAAmB,KAAK;EACxB,iBAAiB,KAAK;EACtB,GAAI,QAAQ,cAAc,KAAA,IAAY,EAAE,WAAW,QAAQ,UAAU,IAAI,CAAC;CAC5E,CAAC;CACD,MAAM,eAAe,KAAK,QAAQ,iCAAiC;CACnE,MAAM,cAAc,KAAK,QAAQ,iCAAiC;CAClE,cAAc,cAAc,GAAG,KAAK,UAAU,UAAU,MAAM,CAAC,EAAE,GAAG;CACpE,cAAc,aAAa,GAAG,WAAW,KAAK,WAAW,KAAK,UAAU,MAAM,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,GAAG;CAC/F,OAAO;EAAE;EAAc;EAAa,SAAS,WAAW;CAAO;AACjE;AAEA,SAAS,yBAAyB,WAA2B;CAC3D,OAAO,UAAU,QAAQ,WAAW,EAAE,KAAK;AAC7C;AAEA,SAAS,eACP,SACuB;CACvB,OAAO;EACL,WAAW,QAAQ;EACnB,aAAa,QAAQ;EACrB,kBAAkB,QAAQ;EAC1B,eAAe,QAAQ,iBAAiB;EACxC,mBAAmB,QAAQ,qBAAqB,yBAAyB,QAAQ,SAAS;EAC1F,GAAI,QAAQ,sBAAsB,KAAA,IAC9B,EAAE,mBAAmB,QAAQ,kBAAkB,IAC/C,CAAC;EACL,iBAAiB,QAAQ,mBAAmB;EAC5C,GAAI,QAAQ,kBAAkB,KAAA,IAAY,EAAE,eAAe,QAAQ,cAAc,IAAI,CAAC;EACtF,GAAI,QAAQ,qBAAqB,KAAA,IAC7B,EAAE,kBAAkB,QAAQ,iBAAiB,IAC7C,CAAC;EACL,gBAAgB,QAAQ,kBAAkB,eAAe,yBAAyB;CACpF;AACF;;;ACttBA,MAAa,yBAAyB;CAAC;CAAY;CAAO;CAAW;CAAU;AAAU;AA4JzF,SAAS,SAAS,OAAkD;CAClE,OAAO,QAAQ,KAAK,KAAK,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,KAAK;AAC5E;AAEA,SAAS,KAAK,MAAc,SAAwB;CAClD,MAAM,IAAI,gBAAgB,GAAG,KAAK,IAAI,SAAS;AACjD;AAEA,SAAS,oBAAoB,MAAc,KAAqB;CAC9D,IAAI,eAAe,iBACjB,MAAM,IAAI,gBAAgB,GAAG,KAAK,IAAI,IAAI,WAAW,EAAE,OAAO,IAAI,CAAC;CAErE,MAAM,IAAI,gBAAgB,GAAG,KAAK,IAAI,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,KAAK,EACxF,OAAO,IACT,CAAC;AACH;AAEA,SAAS,aAAa,OAAgB,MAAuC;CAC3E,IAAI,CAAC,SAAS,KAAK,GAAG,KAAK,MAAM,mBAAmB;CACpD,OAAO;AACT;AAEA,SAAS,aAAa,OAAgB,MAAsB;CAC1D,IAAI,OAAO,UAAU,YAAY,MAAM,KAAK,CAAC,CAAC,WAAW,GACvD,KAAK,MAAM,4BAA4B;CACzC,OAAO;AACT;AAEA,SAAS,mBAAmB,OAAgB,MAAgD;CAC1F,MAAM,SAAS,aAAa,OAAO,IAAI;CACvC,IAAI,WAAW,aAAa,CAAC,gBAAgB,SAAS,MAAsB,GAC1E,KAAK,MAAM,iDAAiD,KAAK,UAAU,MAAM,GAAG;CAEtF,OAAO;AACT;AAEA,SAAS,cAAc,OAAgB,MAAuB;CAC5D,IAAI,OAAO,UAAU,WAAW,KAAK,MAAM,mBAAmB;CAC9D,OAAO;AACT;AAEA,SAAS,aACP,OACA,MACA,OAAqF,CAAC,GAC9E;CACR,IAAI,OAAO,UAAU,YAAY,CAAC,OAAO,SAAS,KAAK,GAAG,KAAK,MAAM,yBAAyB;CAC9F,IAAI,KAAK,WAAW,CAAC,OAAO,UAAU,KAAK,GAAG,KAAK,MAAM,oBAAoB;CAC7E,IAAI,KAAK,QAAQ,KAAA,KAAa,QAAQ,KAAK,KAAK,KAAK,MAAM,cAAc,KAAK,KAAK;CACnF,IAAI,KAAK,QAAQ,KAAA,KAAa,QAAQ,KAAK,KAAK,KAAK,MAAM,cAAc,KAAK,KAAK;CACnF,OAAO;AACT;AAEA,SAAS,kBAAkB,OAAgB,MAAwB;CACjE,IAAI,CAAC,MAAM,QAAQ,KAAK,GAAG,KAAK,MAAM,kBAAkB;CACxD,OAAO,MAAM,KAAK,OAAO,UAAU,aAAa,OAAO,GAAG,KAAK,GAAG,MAAM,EAAE,CAAC;AAC7E;AAEA,SAAS,kBAAkB,OAAgB,MAAyC;CAClF,IAAI,CAAC,MAAM,QAAQ,KAAK,GAAG,KAAK,MAAM,kBAAkB;CACxD,OAAO,MAAM,KAAK,OAAO,UAAU,aAAa,OAAO,GAAG,KAAK,GAAG,MAAM,EAAE,CAAC;AAC7E;AAEA,SAAS,YAAY,OAAgB,MAAqC;CACxE,MAAM,QAAQ,aAAa,OAAO,IAAI;CACtC,IAAI,CAAC,uBAAuB,SAAS,KAA8B,GACjE,KAAK,MAAM,kBAAkB,uBAAuB,KAAK,IAAI,GAAG;CAElE,OAAO;AACT;AAEA,SAAS,eAAe,OAAgB,MAAkC;CACxE,IAAI,UAAU,KAAA,GAAW,OAAO,KAAA;CAChC,OAAO,aAAa,OAAO,IAAI;AACjC;AAEA,SAAS,iBAAiB,OAAgB,MAAsC;CAC9E,MAAM,MAAM,aAAa,OAAO,IAAI;CACpC,MAAM,MAA8B,CAAC;CACrC,KAAK,MAAM,CAAC,KAAK,QAAQ,OAAO,QAAQ,GAAG,GAAG,IAAI,OAAO,aAAa,KAAK,GAAG,KAAK,GAAG,KAAK;CAC3F,OAAO;AACT;AAEA,SAAS,wBAAwB,OAAgB,MAAiC;CAChF,MAAM,MAAM,aAAa,OAAO,IAAI;CACpC,OAAO;EACL,OAAO,aAAa,IAAI,OAAO,GAAG,KAAK,OAAO;EAC9C,SAAS,aAAa,IAAI,SAAS,GAAG,KAAK,SAAS;EACpD,SAAS,aAAa,IAAI,SAAS,GAAG,KAAK,SAAS;EACpD,GAAI,IAAI,oBAAoB,KAAA,IACxB,EAAE,iBAAiB,eAAe,IAAI,iBAAiB,GAAG,KAAK,iBAAiB,EAAE,IAClF,CAAC;CACP;AACF;AAEA,SAAgB,iCAAiC,OAA0C;CACzF,MAAM,MAAM,aAAa,OAAO,UAAU;CAC1C,IAAI,IAAI,kBAAkB,GAAG,KAAK,0BAA0B,WAAW;CACvE,MAAM,OAAO,aAAa,IAAI,MAAM,eAAe;CACnD,MAAM,YAAY,aAAa,IAAI,WAAW,oBAAoB;CAClE,MAAM,WAAW,kBAAkB,IAAI,UAAU,mBAAmB,CAAC,CAAC,KAAK,SAAS,WAAW;EAC7F,IAAI,aAAa,QAAQ,IAAI,qBAAqB,MAAM,KAAK;EAC7D,aAAa,aAAa,QAAQ,aAAa,qBAAqB,MAAM,cAAc;EACxF,kBAAkB,aAChB,QAAQ,kBACR,qBAAqB,MAAM,mBAC7B;CACF,EAAE;CACF,MAAM,OAAO,kBAAkB,IAAI,MAAM,eAAe,CAAC,CAAC,KAAK,KAAK,WAAW;EAC7E,IAAI,aAAa,IAAI,IAAI,iBAAiB,MAAM,KAAK;EACrD,WAAW,aAAa,IAAI,WAAW,iBAAiB,MAAM,YAAY;EAC1E,iBAAiB,kBACf,IAAI,iBACJ,iBAAiB,MAAM,kBACzB;EACA,YAAY,aAAa,IAAI,YAAY,iBAAiB,MAAM,aAAa;CAC/E,EAAE;CACF,MAAM,YAAY,kBAAkB,IAAI,WAAW,oBAAoB,CAAC,CAAC,KACtE,UAAU,WAAW;EACpB,IAAI,aAAa,SAAS,IAAI,sBAAsB,MAAM,KAAK;EAC/D,OAAO,YAAY,SAAS,OAAO,sBAAsB,MAAM,QAAQ;EACvE,MAAM,kBAAkB,SAAS,MAAM,sBAAsB,MAAM,OAAO;EAC1E,2BAA2B,cACzB,SAAS,2BACT,sBAAsB,MAAM,4BAC9B;CACF,EACF;CACA,MAAM,UAAU,aAAa,IAAI,SAAS,kBAAkB;CAC5D,IAAI,SAAS,WAAW,GAAG,KAAK,qBAAqB,mCAAmC;CACxF,IAAI,KAAK,WAAW,GAAG,KAAK,iBAAiB,+BAA+B;CAC5E,IAAI,UAAU,WAAW,GAAG,KAAK,sBAAsB,oCAAoC;CAC3F,aACE,SAAS,KAAK,YAAY,QAAQ,EAAE,GACpC,sBACF;CACA,aACE,KAAK,KAAK,QAAQ,IAAI,EAAE,GACxB,kBACF;CACA,aACE,UAAU,KAAK,aAAa,SAAS,EAAE,GACvC,uBACF;CACA,MAAM,aAAa,IAAI,IAAI,SAAS,KAAK,YAAY,QAAQ,EAAE,CAAC;CAChE,KAAK,MAAM,OAAO,MAChB,IAAI,CAAC,WAAW,IAAI,IAAI,SAAS,GAC/B,KAAK,iBAAiB,IAAI,GAAG,aAAa,mBAAmB,IAAI,WAAW;CAEhF,OAAO;EACL,eAAe;EACf,WAAW,aAAa,IAAI,WAAW,oBAAoB;EAC3D,aAAa,aAAa,IAAI,aAAa,sBAAsB;EACjE,MAAM;GACJ,KAAK,aAAa,KAAK,KAAK,mBAAmB;GAC/C,QAAQ,aAAa,KAAK,QAAQ,sBAAsB;GACxD,QAAQ,aAAa,KAAK,QAAQ,sBAAsB;EAC1D;EACA,WAAW;GACT,WAAW,aAAa,UAAU,WAAW,8BAA8B;GAC3E,cAAc,aAAa,UAAU,cAAc,iCAAiC;GACpF,gBAAgB,aAAa,UAAU,gBAAgB,mCAAmC;GAC1F,SAAS,aAAa,UAAU,SAAS,4BAA4B;GACrE,GAAI,UAAU,eAAe,KAAA,IACzB,EAAE,YAAY,aAAa,UAAU,YAAY,+BAA+B,EAAE,IAClF,CAAC;EACP;EACA;EACA;EACA;EACA,SAAS;GACP,QAAQ,aAAa,QAAQ,QAAQ,2BAA2B,EAAE,KAAK,EAAE,CAAC;GAC1E,UAAU,aAAa,QAAQ,UAAU,6BAA6B;IACpE,KAAK;IACL,SAAS;GACX,CAAC;GACD,WAAW,aAAa,QAAQ,WAAW,8BAA8B;IACvE,KAAK;IACL,SAAS;GACX,CAAC;EACH;EACA,qBAAqB,aAAa,IAAI,qBAAqB,8BAA8B;CAC3F;AACF;AAEA,SAAgB,+BAA+B,OAAwC;CACrF,MAAM,MAAM,aAAa,OAAO,QAAQ;CACxC,IAAI,IAAI,kBAAkB,GAAG,KAAK,wBAAwB,WAAW;CACrE,MAAM,eAAe,aAAa,IAAI,cAAc,qBAAqB;CACzE,MAAM,QAAQ,aAAa,IAAI,OAAO,cAAc;CACpD,MAAM,UAAU,aAAa,IAAI,SAAS,gBAAgB;CAC1D,MAAM,UAAU,aAAa,IAAI,SAAS,gBAAgB;CAC1D,MAAM,QAAQ,aAAa,IAAI,OAAO,cAAc;CACpD,MAAM,YAAY,aAAa,IAAI,WAAW,kBAAkB;CAChE,MAAM,YAAY,aAAa,IAAI,WAAW,kBAAkB;CAChE,MAAM,cAAc,cAAc,QAAQ,MAAM,qBAAqB;CACrE,MAAM,eACJ,QAAQ,iBAAiB,OACrB,OACA,mBAAmB,QAAQ,cAAc,6BAA6B;CAC5E,MAAM,gBACJ,QAAQ,kBAAkB,OACtB,OACA,aAAa,QAAQ,eAAe,8BAA8B;CACxE,IAAI,gBAAgB,iBAAiB,QAAQ,kBAAkB,OAC7D,KAAK,kBAAkB,6CAA6C;CAEtE,IAAI,CAAC,eAAe,iBAAiB,MACnC,KAAK,+BAA+B,uCAAuC;CAE7E,IAAI,iBAAiB,QAAQ,kBAAkB,MAC7C,KAAK,gCAAgC,yCAAyC;CAEhF,MAAM,SAAiC;EACrC,eAAe;EACf,WAAW,aAAa,IAAI,WAAW,kBAAkB;EACzD,aAAa,aAAa,IAAI,aAAa,oBAAoB;EAC/D,OAAO,aAAa,IAAI,OAAO,cAAc;EAC7C,YAAY,aAAa,IAAI,YAAY,mBAAmB;EAC5D,OAAO,YAAY,IAAI,OAAO,cAAc;EAC5C,OAAO,aAAa,IAAI,OAAO,cAAc;EAC7C,KAAK,aAAa,IAAI,KAAK,cAAc;GAAE,KAAK;GAAG,SAAS;EAAK,CAAC;EAClE,cAAc;GACZ,IAAI,aAAa,aAAa,IAAI,wBAAwB;GAC1D,MAAM,aAAa,aAAa,MAAM,0BAA0B;GAChE,MAAM,aAAa,aAAa,MAAM,0BAA0B;GAChE,UAAU,wBAAwB,aAAa,UAAU,8BAA8B;GACvF,UAAU,wBAAwB,aAAa,UAAU,8BAA8B;EACzF;EACA,OAAO;GACL,UAAU,aAAa,MAAM,UAAU,uBAAuB;GAC9D,IAAI,aAAa,MAAM,IAAI,iBAAiB;EAC9C;EACA,SAAS;GACP,MAAM,aAAa,QAAQ,MAAM,qBAAqB;GACtD,SAAS,aAAa,QAAQ,SAAS,wBAAwB;EACjE;EACA,SAAS;GACP,MAAM;GACN,OAAO,aAAa,QAAQ,OAAO,wBAAwB;IAAE,KAAK;IAAG,KAAK;GAAE,CAAC;GAC7E,YAAY,iBAAiB,QAAQ,YAAY,2BAA2B;GAC5E;GACA;EACF;EACA,OAAO;GACL,aAAa,aAAa,MAAM,aAAa,4BAA4B;IACvE,KAAK;IACL,SAAS;GACX,CAAC;GACD,cAAc,aAAa,MAAM,cAAc,6BAA6B;IAC1E,KAAK;IACL,SAAS;GACX,CAAC;GACD,SAAS,aAAa,MAAM,SAAS,wBAAwB,EAAE,KAAK,EAAE,CAAC;GACvE,QAAQ,aAAa,MAAM,QAAQ,uBAAuB;IAAE,KAAK;IAAG,SAAS;GAAK,CAAC;GACnF,WAAW,aAAa,MAAM,WAAW,0BAA0B;IAAE,KAAK;IAAG,SAAS;GAAK,CAAC;EAC9F;EACA,WAAW;GACT,aAAa,cAAc,UAAU,aAAa,8BAA8B;GAChF,YAAY,cAAc,UAAU,YAAY,6BAA6B;GAC7E,cAAc,cAAc,UAAU,cAAc,+BAA+B;GACnF,YAAY,cAAc,UAAU,YAAY,6BAA6B;GAC7E,QAAQ,cAAc,UAAU,QAAQ,yBAAyB;GACjE,qBAAqB,cACnB,UAAU,qBACV,sCACF;EACF;EACA,WAAW;GACT,SAAS,aAAa,UAAU,SAAS,0BAA0B;GACnE,QAAQ,aAAa,UAAU,QAAQ,yBAAyB;GAChE,MAAM,aAAa,UAAU,MAAM,uBAAuB;GAC1D,QAAQ,aAAa,UAAU,QAAQ,yBAAyB;GAChE,WAAW,aAAa,UAAU,WAAW,4BAA4B;EAC3E;CACF;CACA,IAAI,OAAO,UAAU,eAAe,OAAO,MAAM,cAAc,OAAO,MAAM,iBAAiB,GAC3F,KAAK,gBAAgB,kDAAkD;CAEzE,OAAO;AACT;AAEA,SAAgB,kCAAkC,QAA0C;CAC1F,MAAM,WAAqB,CAAC;CAC5B,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,OAAO,SAAS,GACxD,IAAI,CAAC,OAAO,SAAS,KAAK,GAAG,OAAO,MAAM,GAAG,IAAI,OAAO;CAE1D,OAAO;AACT;AAEA,SAAgB,4BAA4B,MAAwC;CAClF,MAAM,QAAQ,aAAa,MAAM,MAAM,CAAC,CACrC,MAAM,IAAI,CAAC,CACX,KAAK,SAAS,KAAK,KAAK,CAAC,CAAC,CAC1B,OAAO,OAAO;CACjB,MAAM,UAAoC,CAAC;CAC3C,KAAK,MAAM,CAAC,OAAO,SAAS,MAAM,QAAQ,GACxC,IAAI;EACF,QAAQ,KAAK,+BAA+B,KAAK,MAAM,IAAI,CAAC,CAAC;CAC/D,SAAS,KAAK;EACZ,oBAAoB,GAAG,KAAK,GAAG,QAAQ,KAAK,GAAG;CACjD;CAEF,OAAO;AACT;AAEA,SAAgB,6BAA6B,MAAwC;CACnF,IAAI;EACF,OAAO,iCAAiC,KAAK,MAAM,aAAa,MAAM,MAAM,CAAC,CAAC;CAChF,SAAS,KAAK;EACZ,oBAAoB,MAAM,GAAG;CAC/B;AACF;AAEA,SAAgB,4BACd,OACkC;CAClC,MAAM,WAAW,6BAA6B,MAAM,YAAY;CAChE,MAAM,UAAU,4BAA4B,MAAM,WAAW;CAC7D,MAAM,uBAAuB,GAAG,SAAS,UAAU,GAAG,SAAS;CAC/D,MAAM,oBAAoB,QAAQ,QAAQ,iCAAiC;CAC3E,MAAM,mBACJ,MAAM,mBAAmB,QACrB,CAAC,IACD,QAAQ,SAAS,WACf,0BAA0B,QAAQ,MAAM,gBAAgB,QAAQ,MAAM,WAAW,CAAC,CACpF;CACN,KAAK,MAAM,CAAC,OAAO,WAAW,QAAQ,QAAQ,GAAG;EAC/C,MAAM,qBAAqB,GAAG,OAAO,UAAU,GAAG,OAAO;EACzD,IAAI,uBAAuB,sBACzB,KACE,WAAW,MAAM,IACjB,qBAAqB,mBAAmB,2BAA2B,sBACrE;EAEF,IAAI,CAAC,SAAS,KAAK,MAAM,QAAQ,IAAI,OAAO,OAAO,KAAK,GACtD,KAAK,WAAW,MAAM,UAAU,eAAe,OAAO,OAAO;EAC/D,IAAI,CAAC,SAAS,UAAU,MAAM,aAAa,SAAS,OAAO,OAAO,UAAU,GAC1E,KAAK,WAAW,MAAM,eAAe,oBAAoB,OAAO,YAAY;CAEhF;CACA,MAAM,eAAgB;EAAC;EAAO;EAAU;CAAQ,CAAC,CAC9C,QAAQ,QAAQ,SAAS,KAAK,IAAI,CAAC,KAAK,CAAC,CAAC,WAAW,KAAK,SAAS,KAAK,SAAS,SAAS,CAAC,CAC3F,KAAK,QAAQ,iBAAiB,KAAK;CACtC,MAAM,oBAAqB;EAAC;EAAa;EAAgB;EAAkB;CAAS,CAAC,CAClF,QACE,QAAQ,SAAS,UAAU,IAAI,CAAC,KAAK,CAAC,CAAC,WAAW,KAAK,SAAS,UAAU,SAAS,SACtF,CAAC,CACA,KAAK,QAAQ,sBAAsB,KAAK;CAC3C,OAAO;EACL,cAAc,MAAM;EACpB,aAAa,MAAM;EACnB,SAAS,QAAQ;EACjB;EACA;EACA,UAAU,aAAa,QAAQ,KAAK,WAAW,OAAO,SAAS,CAAC;EAChE,YAAY,aAAa,QAAQ,KAAK,WAAW,OAAO,WAAW,CAAC;EACpE,MAAM,aAAa,QAAQ,KAAK,WAAW,OAAO,KAAK,CAAC;EACxD,WAAW,aAAa,QAAQ,KAAK,WAAW,OAAO,UAAU,CAAC;EAClE,QAAQ,QAAQ,QAAQ,WAAW,OAAO,QAAQ,IAAI,CAAC,CAAC;EACxD,QAAQ,QAAQ,QAAQ,WAAW,CAAC,OAAO,QAAQ,IAAI,CAAC,CAAC;EACzD,aAAa,IAAI,UAAU,WAAW,OAAO,MAAM,WAAW;EAC9D,cAAc,IAAI,UAAU,WAAW,OAAO,MAAM,YAAY;EAChE,SAAS,IAAI,UAAU,WAAW,OAAO,MAAM,OAAO;EACtD,QAAQ,IAAI,UAAU,WAAW,OAAO,MAAM,MAAM;EACpD;EACA;CACF;AACF;AAEA,SAAS,0BAA0B,QAAgC,cAAgC;CACjG,MAAM,UAAoB,CAAC;CAC3B,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,OAAO,SAAS,GAExD,IAAI,CAAC,WADQ,oBAAoB,OAAO,YACrB,CAAC,GAAG,QAAQ,KAAK,GAAG,OAAO,MAAM,GAAG,IAAI,GAAG,OAAO;CAEvE,OAAO;AACT;AAEA,SAAS,oBAAoB,OAAe,cAA8B;CACxE,OAAO,MAAM,WAAW,GAAG,IAAI,QAAQ,KAAK,cAAc,KAAK;AACjE;AAEA,SAAS,aAAa,QAA2B,MAAoB;CACnE,MAAM,uBAAO,IAAI,IAAY;CAC7B,KAAK,MAAM,SAAS,QAAQ;EAC1B,IAAI,KAAK,IAAI,KAAK,GAAG,KAAK,MAAM,aAAa,OAAO;EACpD,KAAK,IAAI,KAAK;CAChB;AACF;AAEA,SAAS,aAAa,QAAqC;CACzD,OAAO,CAAC,GAAG,IAAI,IAAI,MAAM,CAAC,CAAC,CAAC,KAAK;AACnC;AAEA,SAAS,IAAO,OAAqB,IAAiC;CACpE,OAAO,MAAM,QAAQ,OAAO,SAAS,QAAQ,GAAG,IAAI,GAAG,CAAC;AAC1D;AAEA,SAAgB,8BACd,QACsC;CACtC,MAAM,eAAe,KAAK,QAAQ,iCAAiC;CACnE,MAAM,cAAc,KAAK,QAAQ,iCAAiC;CAClE,IACE,WAAW,YAAY,KACvB,SAAS,YAAY,CAAC,CAAC,OAAO,KAC9B,WAAW,WAAW,KACtB,SAAS,WAAW,CAAC,CAAC,OAAO,GAE7B,OAAO;EAAE;EAAc;CAAY;CAErC,OAAO;AACT;;;;;;AAOA,SAAgB,0BAA0B,QAAkD;CAC1F,MAAM,YAAY,8BAA8B,MAAM;CACtD,IAAI,CAAC,WACH,KAAK,QAAQ,4EAA4E;CAE3F,MAAM,SAAS,4BAA4B;EAAE,GAAG;EAAW,cAAc;CAAO,CAAC;CACjF,MAAM,WAAW;EACf,GAAG,OAAO;EACV,GAAG,OAAO;EACV,GAAG,OAAO;EACV,GAAG,OAAO;CACZ;CACA,IAAI,SAAS,SAAS,GACpB,KAAK,QAAQ,yCAAyC,SAAS,KAAK,IAAI,GAAG;CAE7E,OAAO;AACT"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["packageVersion","fsConstants","fs","DEFAULT_FALLBACK_INSTRUCTION","clamp01","clamp01","isObject","stripSlash","packageVersion","packageVersion"],"sources":["../src/profile/baselines.ts","../src/profile/index.ts","../src/verification-strategy.ts","../src/budget-guard.ts","../src/feedback-trajectory.ts","../src/scorecard.ts","../src/trace-contracts.ts","../src/active-learning.ts","../src/deprecation.ts","../src/client.ts","../src/command-runner.ts","../src/detectors/index.ts","../src/control-runtime.ts","../src/discover-personas.ts","../src/driver.ts","../src/propose-review.ts","../src/propose-review-control.ts","../src/capability-headroom.ts","../src/cost-tracker.ts","../src/error-count-extractor.ts","../src/knowledge/readiness.ts","../src/leaderboard.ts","../src/partition-held-out.ts","../src/product-benchmark/export.ts","../src/product-benchmark/index.ts","../src/runtime-trajectory.ts","../src/action-policy.ts","../src/deploy-gate-layer.ts","../src/held-out-gate.ts","../src/hidden-criteria-grading.ts","../src/integrity/single-backend.ts","../src/intent-match-judge.ts","../src/judge-ensemble.ts","../src/judge-retry.ts","../src/judge-panel.ts","../src/keyword-coverage-judge.ts","../src/multi-layer-verifier.ts","../src/oracle.ts","../src/treatment-gate.ts","../src/anti-slop.ts","../src/eval-trace-store.ts","../src/integrity/preflight.ts","../src/model-seats.ts","../src/prompt-registry.ts","../src/steering-optimizer.ts"],"sourcesContent":["/**\n * Strong, generically-useful baseline ROLES — the top zone of an `AgentProfile`\n * before any domain layer. A product composes one of these with its own\n * environment description (its sandbox) and its domain guidance, which lives in\n * the product repo (not here): a profile is `<baseline role> + <environment> +\n * <domain sections>`. Domain strength is NOT generalized into the substrate —\n * it is lifted here only once ≥2 products genuinely reuse it.\n *\n * Three roles cover the common shapes:\n * - `engineerRole` — builds + verifies real artifacts in a sandbox. Distilled\n * from agent-runtime's `coderProfile` doctrine (minimal\n * correct change, run the checks, fix the root cause,\n * never weaken a test or hide an error).\n * - `researcherRole` — gathers from real sources and grounds every claim\n * (cite or mark inferred; never fabricate).\n * - `generalistRole` — a strong default: helpful, grounded, verify-before-assert.\n *\n * All three are verification-first and domain-agnostic. They describe HOW a\n * capable IC operates, not WHAT domain it works in.\n */\n\n/** Senior-IC engineer operating in a sandbox — produces real artifacts and\n * verifies them before declaring done. The shared operator foundation for any\n * file-producing, tool-using product agent. */\nexport const engineerRole: string = [\n 'You are a senior principal engineer — a 10x individual contributor — operating inside an isolated sandbox workspace with real tools (shell, filesystem, editors, test runners).',\n 'You do not behave like a chatbot that describes work. You DO the work: you produce the actual artifact in the workspace, then you verify it.',\n '',\n 'How you operate:',\n '- Deliver the smallest correct change that fully satisfies the goal. Bias to the real artifact (the file, the patch, the document), never a description of it.',\n '- Before declaring done, run the available checks (tests, typecheck, validators, a re-read of what you produced). If a check fails, fix the ROOT CAUSE — never weaken the check, never hide the error, never fake success.',\n '- External-boundary calls (shell, network, filesystem) can fail. Inspect the outcome before relying on it; surface failures loudly rather than proceeding on a bad value.',\n '- State outcomes faithfully: what you verified, what you skipped, what is still failing. \"Done\" means produced AND verified.',\n].join('\\n')\n\n/** Researcher who grounds every claim in real sources — gathers, cites, and\n * distinguishes verified fact from inference. */\nexport const researcherRole: string = [\n 'You are a principal research analyst operating inside a workspace with tools to read sources, search, and record findings.',\n 'Your output is only as good as its grounding. You gather from the real sources in front of you and you ground every material claim.',\n '',\n 'How you operate:',\n '- Read the actual sources before concluding. Do not answer from memory when a source is available to check.',\n '- Cite the source for every material claim; explicitly mark anything you infer rather than verify. Never fabricate a source, a quote, a number, or a citation.',\n '- Distinguish what the sources establish from what you are extrapolating, and say which is which.',\n '- When the sources are insufficient or contradictory, say so plainly rather than papering over the gap.',\n].join('\\n')\n\n/** Strong general-purpose default — helpful, grounded, verifies before asserting. */\nexport const generalistRole: string = [\n 'You are a capable, senior generalist assistant operating inside a workspace with real tools.',\n 'You are direct and grounded: you verify before you assert, and you produce real output rather than describing it.',\n '',\n 'How you operate:',\n '- Prefer doing over describing — when the workspace lets you produce the artifact, produce it.',\n '- Ground claims in what you can check; when you cannot check something, say so instead of guessing confidently.',\n '- Verify your output before declaring done, and report what you verified vs. what remains uncertain.',\n '- Ask the user only when a choice is genuinely theirs and you cannot resolve it from the task, the workspace, or sensible defaults.',\n].join('\\n')\n\n/** The named baseline roles, for selection by key (e.g. from a product config). */\nexport const BASELINE_ROLES = {\n engineer: engineerRole,\n researcher: researcherRole,\n generalist: generalistRole,\n} as const\n\nexport type BaselineRoleKey = keyof typeof BASELINE_ROLES\n","/**\n * Structured prompt profile — the system prompt as named, addressable sections\n * instead of one opaque blob. The self-improvement loop targets ONE evolvable\n * `domain` section at a time (via `applyDomainPatch`); the role, environment,\n * tool conventions, and skill roster stay fixed so a candidate diff is\n * attributable to a single section rather than a whole-prompt rewrite.\n *\n * `renderProfile` emits the prompt in a fixed five-zone order — role,\n * Environment, Tool conventions, Skills, Domain guidance — mirroring the layout\n * of Harvey LAB's `harness/system_prompt.md` (workspace root, read-only\n * documents, output dir, skills dir). `profileToSurface` is the bridge to the\n * loop's string `MutableSurface`: a profile renders to exactly the text a\n * candidate is scored on.\n *\n * Distinct from the canonical `AgentProfile` exported by\n * `@tangle-network/agent-interface`. This helper builds prompt content that can\n * be rendered into an agent-interface profile's `prompt.systemPrompt`.\n */\n\nimport { surfaceContentHash } from '../campaign/surface-identity'\nimport { BASELINE_ROLES, type BaselineRoleKey } from './baselines'\n\nexport {\n BASELINE_ROLES,\n type BaselineRoleKey,\n engineerRole,\n generalistRole,\n researcherRole,\n} from './baselines'\n\n/** A named, addressable region of the system prompt. `evolvable` marks whether\n * the self-improvement loop is allowed to patch its body; fixed scaffolding\n * (e.g. a compliance preamble) sets `evolvable: false`. */\nexport interface AgentProfileSection {\n id: string\n title: string\n body: string\n evolvable: boolean\n}\n\n/** A skill the agent can invoke. `triggers` are the phrases/conditions that\n * should activate it; `scriptsDir` points at its executable scripts when the\n * skill ships code (mirrors Harvey's `skills/<name>/scripts/`). */\nexport interface ProfileSkill {\n name: string\n description: string\n triggers: string[]\n scriptsDir?: string\n}\n\n/** The structured system prompt. The first four fields are fixed scaffolding;\n * `domain` is the evolvable surface the loop optimizes. */\nexport interface PromptProfile {\n role: string\n environment: string\n toolConventions: string\n skills: ProfileSkill[]\n domain: AgentProfileSection[]\n}\n\nfunction renderSkill(skill: ProfileSkill): string {\n const lines = [`### ${skill.name}`, skill.description]\n if (skill.triggers.length > 0) {\n lines.push(`Triggers: ${skill.triggers.join(', ')}`)\n }\n if (skill.scriptsDir !== undefined) {\n lines.push(`Scripts: ${skill.scriptsDir}`)\n }\n return lines.join('\\n')\n}\n\n/**\n * Emit the sectioned system prompt in fixed order: role text, then\n * `## Environment`, `## Tool conventions`, `## Skills` (each skill as\n * `### <name>` + description + triggers), `## Domain guidance` (each section as\n * `### <title>` + body). The order is load-bearing — the loop diffs rendered\n * text, and reordering would make every candidate look like a full rewrite.\n */\nexport function renderProfile(p: PromptProfile): string {\n const zones: string[] = [\n p.role.trim(),\n `## Environment\\n\\n${p.environment.trim()}`,\n `## Tool conventions\\n\\n${p.toolConventions.trim()}`,\n `## Skills\\n\\n${\n p.skills.length > 0 ? p.skills.map(renderSkill).join('\\n\\n') : '_No skills configured._'\n }`,\n `## Domain guidance\\n\\n${\n p.domain.length > 0\n ? p.domain.map((s) => `### ${s.title}\\n\\n${s.body.trim()}`).join('\\n\\n')\n : '_No domain guidance yet._'\n }`,\n ]\n return zones.join('\\n\\n')\n}\n\n/** The string `MutableSurface` the self-improvement loop scores — a profile\n * renders to exactly the text a candidate is graded on. */\nexport function profileToSurface(p: PromptProfile): string {\n return renderProfile(p)\n}\n\nconst STOCK_SKILLS: ProfileSkill[] = [\n {\n name: 'read-documents',\n description:\n 'Read every source document under the read-only documents directory before drafting.',\n triggers: [\n 'task references a source document',\n 'instructions cite an exhibit, filing, or input file',\n ],\n },\n {\n name: 'write-deliverable',\n description:\n 'Write deliverables to the output directory; use markdown for notes and the file-type skills for binary artifacts.',\n triggers: ['the task asks for a produced artifact', 'a deliverable is named in the brief'],\n },\n]\n\nconst ENVIRONMENT_PREAMBLE =\n 'You are an AI agent executing a task within a single workspace root.\\n\\n' +\n '- Workspace root: bash starts here. Use it for notes, scratch files, and intermediate work.\\n' +\n '- Documents directory: task source documents live here and are read-only — never write to them.\\n' +\n '- Output directory: write every deliverable here; relative write/edit paths route here automatically.\\n' +\n '- Skills directory: skill scripts live at <workspace>/skills/<name>/scripts/.'\n\nconst TOOL_CONVENTIONS_PREAMBLE =\n 'Use read to consume input files. Use write only for plain markdown (typically a response summary). ' +\n 'Use edit for incremental refinement of a file you already created. ' +\n 'External-boundary calls return typed outcomes — inspect success before using a value.'\n\n/**\n * The fixed-scaffolding baseline: a `role`/`environment`/`toolConventions`\n * profile with the stock skill roster and NO domain guidance. The\n * production profile is this plus shipped domain sections.\n */\nexport function baselineProfile(args: {\n role: string\n environment?: string\n toolConventions?: string\n skills?: ProfileSkill[]\n}): PromptProfile {\n return {\n role: args.role,\n environment: args.environment ?? ENVIRONMENT_PREAMBLE,\n toolConventions: args.toolConventions ?? TOOL_CONVENTIONS_PREAMBLE,\n skills: args.skills ?? STOCK_SKILLS,\n domain: [],\n }\n}\n\n/**\n * Baseline from one of the strong generic roles (`'engineer' | 'researcher' |\n * 'generalist'`) — the common case: pick a role foundation, optionally override\n * the environment to describe THIS product's sandbox, then layer domain via\n * `prodProfile`. Domain guidance stays in the product repo; this only supplies\n * the generically-useful role + stock scaffolding.\n */\nexport function baselineProfileFromRole(\n role: BaselineRoleKey,\n args: { environment?: string; toolConventions?: string; skills?: ProfileSkill[] } = {},\n): PromptProfile {\n return baselineProfile({ role: BASELINE_ROLES[role], ...args })\n}\n\n/** The production profile: the baseline scaffolding plus the domain sections\n * shipped after self-improvement. Differs from the baseline ONLY in `domain`\n * (and any skills the caller layered into the baseline) — the role,\n * environment, and tool conventions are carried through unchanged. */\nexport function prodProfile(\n baseline: PromptProfile,\n shipped: AgentProfileSection[],\n): PromptProfile {\n return { ...baseline, domain: [...baseline.domain, ...shipped] }\n}\n\n/**\n * Section-scoped edit — replace the body of ONE domain section by id, leaving\n * every other section byte-identical. This is how the loop targets a single\n * evolvable surface. Throws on an unknown section id (a patch that hits no\n * section is a silent no-op otherwise — fail loud). Throws when the targeted\n * section is `evolvable: false`.\n */\nexport function applyDomainPatch(\n p: PromptProfile,\n sectionId: string,\n newBody: string,\n): PromptProfile {\n const idx = p.domain.findIndex((s) => s.id === sectionId)\n if (idx === -1) {\n throw new Error(\n `applyDomainPatch: no domain section \"${sectionId}\" (have: ${\n p.domain.map((s) => s.id).join(', ') || '<none>'\n })`,\n )\n }\n const target = p.domain[idx]\n if (target === undefined) {\n throw new Error(`applyDomainPatch: domain section \"${sectionId}\" resolved to undefined`)\n }\n if (!target.evolvable) {\n throw new Error(`applyDomainPatch: domain section \"${sectionId}\" is not evolvable`)\n }\n const next = [...p.domain]\n next[idx] = { ...target, body: newBody }\n return { ...p, domain: next }\n}\n\n/**\n * Content hash of a single section — its loop identity. Delegates to the\n * campaign provenance `surfaceContentHash` (the same helper the loop's\n * provenance record uses for full surfaces), so a section hash is byte-for-byte\n * comparable with the `sha256:`-prefixed content hashes that record carries.\n * Two sections that render identically (same title + body) share a hash; the\n * `id` and `evolvable` flag are excluded — they are routing metadata, not\n * content.\n */\nexport function sectionHash(section: AgentProfileSection): string {\n return surfaceContentHash(JSON.stringify({ title: section.title, body: section.body }))\n}\n","/**\n * Verification-strategy family — the shared vocabulary for \"what certified\n * this result\", covering tasks with an answer key and tasks without one.\n *\n * Charter Wave 5 (docs/charter.md): an unsolved problem has no held-out\n * suite by definition, so the held-out suite must be ONE member of a\n * strategy family, not the family itself. This module carries the taxonomy,\n * the port shape, and the one protocol built directly on that port: the\n * blind two-arm statement-equivalence check. A checker is an injected\n * executable boundary that returns a typed outcome, so a consumer binds its\n * own kernel (a Lean toolchain, a metamorphic harness, a replication\n * runner) and this package never chooses one. Instruments, never methods.\n *\n * Full family doc, per-member failure modes in prose, and the BCWW pilot\n * worked example: docs/verification-strategies.md. How every executed\n * verdict lands in `DefaultVerdict` with a certification: docs/verdicts.md.\n *\n * Leaf module: no imports from this package. `src/verdict.ts` and\n * `src/rl/verifiable-reward.ts` both build on these types.\n */\n\n/**\n * One member of the verification-strategy family.\n *\n * Every member has a documented failure mode — the specific way it can\n * certify a wrong result. A consumer that reads a certification must weigh\n * the member's failure mode, not treat \"certified\" as one bit.\n *\n * - `'compile'` — typecheck / build / lint passed. Deterministic.\n * Failure mode: code that compiles is not code that is correct; the\n * weakest deterministic member.\n * - `'test'` — unit / integration / held-out suite pass-rate. Deterministic.\n * Failure mode: assumes an answer key exists; certifies nothing outside\n * the suite's coverage, and a stubbed integration reports green.\n * - `'schema'` — structured output validates. Deterministic.\n * Failure mode: shape is not meaning; a well-formed wrong answer passes.\n * - `'sandbox'` — sandbox execution exit code. Deterministic.\n * Failure mode: an exit code compresses the whole run to one bit; a\n * faked success exits 0.\n * - `'judge'` — LLM judge score. Probabilistic.\n * Failure mode: drifts across model versions and is Goodhart-gameable by\n * the graded policy.\n * - `'composite'` — weighted blend across members. Determinism inherited\n * from its members.\n * Failure mode: scalar collapse — the blend hides which member carried\n * the score and which failed.\n * - `'proof-kernel'` — a proof assistant's kernel accepted a formal proof.\n * Deterministic.\n * Failure mode: the formalization gap. The kernel certifies the formal\n * statement, never that the formal statement matches the informal claim;\n * a proved theorem about the wrong statement is a wrong result with a\n * valid certificate. Discharge it with the blind statement-equivalence\n * protocol (`runEquivalenceCheck` in this module).\n * - `'invariant'` — invariant / metamorphic properties held on the result.\n * Deterministic.\n * Failure mode: weak invariants pass everything. An invariant set earns\n * weight only through seeded-bug calibration — a mutation the set\n * provably rejects; an uncalibrated set is a rubber stamp.\n * - `'replication'` — an independent re-execution reproduced the result\n * from pinned inputs. Deterministic given the pins.\n * Failure mode: replication re-runs the method, so it catches\n * nondeterminism and environment drift, never a methodological error the\n * method itself carries.\n * - `'agreement'` — independently-derived results agree. Probabilistic.\n * Failure mode: the shared blind spot. Derivers that share training\n * corpora, priors, or the same misread of the source agree for the same\n * wrong reason; the blindness provenance of each arm is what the\n * certificate rests on.\n */\nexport type VerificationStrategySource =\n | 'compile'\n | 'test'\n | 'schema'\n | 'sandbox'\n | 'judge'\n | 'composite'\n | 'proof-kernel'\n | 'invariant'\n | 'replication'\n | 'agreement'\n\n/**\n * What a strategy member can honestly claim about its outcomes.\n *\n * `determinism: 'inherited'` exists only for `'composite'`: a blend takes\n * the class of its members. The reward axis stays binary\n * (`VerifiableReward.determinism`); this registry describes the family,\n * it never scores a run.\n */\nexport interface VerificationStrategyProfile {\n /** Determinism class a well-formed checker of this member can claim. */\n determinism: 'deterministic' | 'probabilistic' | 'inherited'\n /** The documented way this member certifies a wrong result. */\n failureMode: string\n}\n\n/**\n * The family registry. `Record` over the union keeps it exhaustive: adding\n * a member to `VerificationStrategySource` without a profile here fails to\n * compile. The failure mode travels with the taxonomy so a reader of a\n * certification can surface it without this package's docs at hand.\n */\nexport const VERIFICATION_STRATEGIES: Record<\n VerificationStrategySource,\n VerificationStrategyProfile\n> = {\n compile: {\n determinism: 'deterministic',\n failureMode: 'code that compiles is not code that is correct',\n },\n test: {\n determinism: 'deterministic',\n failureMode:\n 'assumes an answer key; certifies nothing outside suite coverage, and a stubbed integration reports green',\n },\n schema: {\n determinism: 'deterministic',\n failureMode: 'shape is not meaning; a well-formed wrong answer passes',\n },\n sandbox: {\n determinism: 'deterministic',\n failureMode: 'an exit code compresses the run to one bit; a faked success exits 0',\n },\n judge: {\n determinism: 'probabilistic',\n failureMode: 'drifts across model versions and is Goodhart-gameable by the graded policy',\n },\n composite: {\n determinism: 'inherited',\n failureMode: 'scalar collapse: the blend hides which member carried the score',\n },\n 'proof-kernel': {\n determinism: 'deterministic',\n failureMode:\n 'the formalization gap: the kernel certifies the formal statement, never that it matches the informal claim',\n },\n invariant: {\n determinism: 'deterministic',\n failureMode:\n 'weak invariants pass everything; a set uncalibrated by seeded bugs is a rubber stamp',\n },\n replication: {\n determinism: 'deterministic',\n failureMode:\n 're-runs the method, so it catches drift and nondeterminism, never an error the method itself carries',\n },\n agreement: {\n determinism: 'probabilistic',\n failureMode:\n 'the shared blind spot: derivers with common corpora or priors agree for the same wrong reason',\n },\n}\n\n/** Every family member, derived from the registry so it cannot drift. */\nexport const VERIFICATION_STRATEGY_SOURCES = Object.keys(\n VERIFICATION_STRATEGIES,\n) as readonly VerificationStrategySource[]\n\n/**\n * Exact identity of the thing that checked. \"lean4 4.33.0 with Mathlib\n * db584cd6d46c\" and \"lean4, some version\" are different certificates: the\n * first is re-runnable, the second is a story.\n */\nexport interface CheckerIdentity {\n /** Toolchain or model name, e.g. `'lean4'` or a judge model id. */\n name: string\n /** Exact version or snapshot, e.g. `'4.33.0'` or a model snapshot id. */\n version: string\n /**\n * Content pins the version alone does not capture, e.g.\n * `{ mathlib: 'db584cd6d46c' }`. Keyed by dependency name.\n */\n pins?: Record<string, string>\n}\n\n/**\n * Typed outcome of an external checker call. Callers MUST inspect\n * `succeeded` before touching `value`; a failed check keeps its full error\n * text instead of collapsing to null.\n */\nexport type CheckerOutcome<Result> =\n | { succeeded: true; value: Result }\n | { succeeded: false; error: string }\n\n/**\n * The port shape every strategy binds through: an injected executable\n * boundary. This package defines the port and refuses to ship any\n * implementation behind it — the consumer binds its own kernel, invariant\n * harness, replication runner, or judge, and the binding carries its own\n * identity and determinism claim.\n *\n * A checker that ran but could not decide returns\n * `{ succeeded: false, error }` with the reason; `succeeded: true` is\n * reserved for a discharged check.\n */\nexport interface StrategyChecker<Input, Result> {\n /** Which family member this checker discharges obligations for. */\n strategy: VerificationStrategySource\n identity: CheckerIdentity\n /** Determinism class this checker claims for its outcomes. */\n determinism: 'deterministic' | 'probabilistic'\n check(input: Input): Promise<CheckerOutcome<Result>>\n}\n\n// ── Blind statement-equivalence protocol ─────────────────────────────\n\n/**\n * Statement-equivalence protocol — the blind two-arm design as a typed\n * primitive.\n *\n * The problem it closes is the proof-kernel failure mode (the\n * formalization gap): a kernel certifies a formal statement, never that\n * the formal statement matches the informal claim. The protocol makes the\n * gap measurable: two arms derive the formal statement independently and\n * blind to each other, then a checker discharges the obligation that the\n * two statements are equivalent. A statement mismatch is a successful\n * outcome — it is the formalization gap made visible with a separating\n * witness in hand.\n *\n * The protocol is pure contract + record types + the asymmetry refusals.\n * Execution binds through the same `StrategyChecker` port as every other\n * strategy: the consumer injects its own kernel. The pilot record this\n * shape reproduces was assembled by hand for the BCWW (4.6) inequality;\n * docs/verification-strategies.md carries the worked example with artifact\n * paths. `equivalenceVerdict` (src/verdict.ts) lands a finished record in\n * the shared verdict spine.\n *\n * The refusals are the design. An arm that saw the other arm's statement,\n * or the outcome it feeds, did not independently derive anything — the\n * check is invalid, and this module throws rather than record it.\n */\n\n/**\n * The two-arm blind design. `arms: 2` and `blind: true` are literal types\n * on purpose: a wider design is a different protocol, not a parameter.\n */\nexport interface EquivalenceCheckSpec {\n /**\n * The strategy member whose obligation the check discharges — the pilot\n * used `'proof-kernel'`: the Lean kernel proved the two statements\n * equivalent. The bound checker must declare the same member.\n */\n source: VerificationStrategySource\n /**\n * Stable identity of the claim under verification: a path, digest, or\n * citation. Pilot: arXiv:1507.05650 inequality (4.6) plus the\n * five-atom counterexample record.\n */\n artifact: string\n /** Exactly two independent arms. An N-arm design is not this protocol. */\n arms: 2\n /**\n * Blind derivation is the point: a non-blind run is not a weaker check,\n * it is no check. `false` is unrepresentable here and refused at runtime\n * for untyped callers.\n */\n blind: true\n}\n\n/** A validated, frozen spec. Produced only by `defineEquivalenceCheck`. */\nexport interface EquivalenceCheckDefinition {\n readonly spec: Readonly<EquivalenceCheckSpec>\n}\n\n/** One arm's committed statement plus the provenance the record rests on. */\nexport interface EquivalenceArm {\n armId: string\n /** The committed formal statement text (pilot: the arm's `Statement.lean` source). */\n statement: string\n /**\n * What this arm derived the statement from. Pilot arm A: the paper's\n * LaTeX source; pilot arm B: the campaign's artifacts. The two arms\n * SHOULD derive from different renderings of the claim — that is what\n * makes agreement informative.\n */\n derivedFrom: string\n /**\n * The blindness declaration. Both flags must be `true`; a `false` value\n * is refused loudly, because recording a non-blind arm would launder an\n * invalid check into a valid-looking record.\n */\n blindness: {\n /** This arm never saw any other arm's statement before committing its own. */\n toOtherArms: boolean\n /** This arm never saw the verification outcome before committing. */\n toOutcome: boolean\n }\n}\n\nexport type EquivalenceObligationStatus =\n | 'proved'\n | 'refuted-with-separating-witness'\n | 'unresolved'\n\n/**\n * The discharged (or undischarged) equivalence obligation.\n *\n * Field presence is status-dependent and enforced by\n * `buildEquivalenceRecord`:\n * - `'proved'` requires `evidenceDigest` and forbids `separatingWitness`.\n * - `'refuted-with-separating-witness'` requires both the witness and\n * `evidenceDigest`.\n * - `'unresolved'` requires `unresolvedReason` and forbids the witness —\n * an undischarged obligation keeps its diagnostic instead of faking\n * either verdict.\n */\nexport interface EquivalenceObligation {\n status: EquivalenceObligationStatus\n /** The input on which the two statements provably disagree. */\n separatingWitness?: string\n /** Why the obligation could not be discharged (checker error text, coverage limit). */\n unresolvedReason?: string\n /** The checker that ran (or failed to run) the obligation. */\n checker: CheckerIdentity\n /** Digest of the checker's evidence artifact (pilot: the kernel-checked `Check.lean` run). */\n evidenceDigest?: string\n}\n\n/** The record the protocol produces — the by-hand pilot record, typed. */\nexport interface EquivalenceRecord {\n spec: Readonly<EquivalenceCheckSpec>\n arms: readonly [EquivalenceArm, EquivalenceArm]\n obligation: EquivalenceObligation\n}\n\n/** Input the bound checker receives: the artifact identity and both committed statements. */\nexport interface EquivalenceCheckerInput {\n artifact: string\n statements: readonly [string, string]\n}\n\n/**\n * What a checker that RAN must return. `'unresolved'` is deliberately not\n * a checker result: a checker that could not decide returns\n * `{ succeeded: false, error }` through the port, and the protocol records\n * the unresolved obligation with that reason.\n */\nexport interface EquivalenceCheckerResult {\n status: 'proved' | 'refuted-with-separating-witness'\n /** Required when `status` is refuted. */\n separatingWitness?: string\n evidenceDigest: string\n}\n\n/** An equivalence checker is a `StrategyChecker` — same port as every strategy. */\nexport type EquivalenceChecker = StrategyChecker<EquivalenceCheckerInput, EquivalenceCheckerResult>\n\n/** A refused equivalence check. `code` names the exact refusal for programmatic handling. */\nexport class EquivalenceProtocolError extends Error {\n readonly code:\n | 'arm-count'\n | 'not-blind'\n | 'arm-saw-other'\n | 'arm-saw-outcome'\n | 'duplicate-arm-id'\n | 'empty-field'\n | 'unknown-source'\n | 'witness-missing'\n | 'witness-on-proved'\n | 'witness-on-unresolved'\n | 'reason-missing'\n | 'evidence-missing'\n | 'checker-strategy-mismatch'\n\n constructor(code: EquivalenceProtocolError['code'], message: string) {\n super(message)\n this.name = 'EquivalenceProtocolError'\n this.code = code\n }\n}\n\n/**\n * Validate and freeze a two-arm blind equivalence check spec.\n *\n * The literal types already refuse a wide design at compile time; the\n * runtime checks hold the same line for untyped callers. There is no\n * escape hatch: `arms: 3` or `blind: false` throws, never downgrades.\n */\nexport function defineEquivalenceCheck(spec: EquivalenceCheckSpec): EquivalenceCheckDefinition {\n if (spec.arms !== 2) {\n throw new EquivalenceProtocolError(\n 'arm-count',\n `equivalence check requires exactly 2 arms, received ${String(spec.arms)}`,\n )\n }\n if (spec.blind !== true) {\n throw new EquivalenceProtocolError(\n 'not-blind',\n 'equivalence check requires blind: true — a non-blind run is not a weaker check, it is no check',\n )\n }\n if (typeof spec.artifact !== 'string' || spec.artifact.trim() === '') {\n throw new EquivalenceProtocolError(\n 'empty-field',\n 'spec.artifact must identify the claim under verification',\n )\n }\n if (!VERIFICATION_STRATEGY_SOURCES.includes(spec.source)) {\n throw new EquivalenceProtocolError(\n 'unknown-source',\n `spec.source '${String(spec.source)}' is not a verification-strategy member`,\n )\n }\n return Object.freeze({ spec: Object.freeze({ ...spec }) })\n}\n\n/**\n * Assemble the equivalence record, refusing every asymmetry.\n *\n * Refusals (each throws `EquivalenceProtocolError`):\n * - an arm whose `blindness.toOtherArms` is false — it saw the other\n * statement, so nothing was independently derived;\n * - an arm whose `blindness.toOutcome` is false — it could steer its\n * statement toward (or away from) the known result;\n * - duplicate arm ids, empty statements, empty derivations;\n * - an obligation whose fields contradict its status (see\n * `EquivalenceObligation`).\n */\nexport function buildEquivalenceRecord(\n definition: EquivalenceCheckDefinition,\n arms: readonly [EquivalenceArm, EquivalenceArm],\n obligation: EquivalenceObligation,\n): EquivalenceRecord {\n assertArms(arms)\n assertObligation(obligation)\n return Object.freeze({\n spec: definition.spec,\n arms: Object.freeze([Object.freeze({ ...arms[0] }), Object.freeze({ ...arms[1] })] as const),\n obligation: Object.freeze({ ...obligation }),\n })\n}\n\n/**\n * Discharge the obligation through an injected checker and return the\n * record.\n *\n * Order matters: every arm refusal fires BEFORE the checker runs — an\n * invalid check must not spend. A checker whose `strategy` differs from\n * `spec.source` is refused for the same reason: a judge cannot silently\n * discharge a proof-kernel obligation.\n *\n * A checker failure (`succeeded: false`) is not thrown: it becomes an\n * `'unresolved'` obligation carrying the full error text, which is the\n * honest record of an undischarged check.\n */\nexport async function runEquivalenceCheck(\n definition: EquivalenceCheckDefinition,\n arms: readonly [EquivalenceArm, EquivalenceArm],\n checker: EquivalenceChecker,\n): Promise<EquivalenceRecord> {\n assertArms(arms)\n if (checker.strategy !== definition.spec.source) {\n throw new EquivalenceProtocolError(\n 'checker-strategy-mismatch',\n `spec.source is '${definition.spec.source}' but the bound checker declares '${checker.strategy}'`,\n )\n }\n const outcome = await checker.check({\n artifact: definition.spec.artifact,\n statements: [arms[0].statement, arms[1].statement],\n })\n if (!outcome.succeeded) {\n return buildEquivalenceRecord(definition, arms, {\n status: 'unresolved',\n unresolvedReason: outcome.error,\n checker: checker.identity,\n })\n }\n const { status, separatingWitness, evidenceDigest } = outcome.value\n return buildEquivalenceRecord(definition, arms, {\n status,\n ...(separatingWitness === undefined ? {} : { separatingWitness }),\n checker: checker.identity,\n evidenceDigest,\n })\n}\n\nfunction assertArms(arms: readonly [EquivalenceArm, EquivalenceArm]): void {\n if (arms.length !== 2) {\n throw new EquivalenceProtocolError(\n 'arm-count',\n `equivalence record requires exactly 2 arms, received ${arms.length}`,\n )\n }\n if (arms[0].armId === arms[1].armId) {\n throw new EquivalenceProtocolError(\n 'duplicate-arm-id',\n `both arms declare armId '${arms[0].armId}' — two labels for one derivation is one arm`,\n )\n }\n for (const arm of arms) {\n if (arm.statement.trim() === '') {\n throw new EquivalenceProtocolError(\n 'empty-field',\n `arm '${arm.armId}' committed an empty statement`,\n )\n }\n if (arm.derivedFrom.trim() === '') {\n throw new EquivalenceProtocolError(\n 'empty-field',\n `arm '${arm.armId}' declares no derivation provenance`,\n )\n }\n if (arm.blindness.toOtherArms !== true) {\n throw new EquivalenceProtocolError(\n 'arm-saw-other',\n `arm '${arm.armId}' saw another arm's statement — the derivation is not independent and the check is invalid`,\n )\n }\n if (arm.blindness.toOutcome !== true) {\n throw new EquivalenceProtocolError(\n 'arm-saw-outcome',\n `arm '${arm.armId}' saw the outcome before committing — the check is invalid`,\n )\n }\n }\n}\n\nfunction assertObligation(obligation: EquivalenceObligation): void {\n const { status, separatingWitness, unresolvedReason, evidenceDigest } = obligation\n if (status === 'refuted-with-separating-witness') {\n if (typeof separatingWitness !== 'string' || separatingWitness.trim() === '') {\n throw new EquivalenceProtocolError(\n 'witness-missing',\n 'a refuted equivalence must carry the separating witness — a refutation without one is an assertion',\n )\n }\n if (typeof evidenceDigest !== 'string' || evidenceDigest.trim() === '') {\n throw new EquivalenceProtocolError(\n 'evidence-missing',\n 'a refuted equivalence must carry its evidence digest',\n )\n }\n return\n }\n if (status === 'proved') {\n if (separatingWitness !== undefined) {\n throw new EquivalenceProtocolError(\n 'witness-on-proved',\n 'a proved equivalence cannot carry a separating witness — the two claims contradict',\n )\n }\n if (typeof evidenceDigest !== 'string' || evidenceDigest.trim() === '') {\n throw new EquivalenceProtocolError(\n 'evidence-missing',\n 'a proved equivalence must carry its evidence digest',\n )\n }\n return\n }\n // status === 'unresolved'\n if (separatingWitness !== undefined) {\n throw new EquivalenceProtocolError(\n 'witness-on-unresolved',\n 'an unresolved obligation cannot carry a separating witness — a witness in hand is a refutation',\n )\n }\n if (typeof unresolvedReason !== 'string' || unresolvedReason.trim() === '') {\n throw new EquivalenceProtocolError(\n 'reason-missing',\n \"an unresolved obligation must say why — 'unresolved' with no reason erases the diagnostic\",\n )\n }\n}\n","/**\n * BudgetGuard — enforces token / wall-clock / call / $ caps, records\n * a ledger entry on every decrement, emits `budget_breach` + throws\n * `BudgetBreachError` when a cap is hit.\n *\n * Wraps a TraceEmitter. The emitter persists ledger entries + breach\n * events so the classifier, pipelines, and reports can all read\n * budget state from the trace corpus — no separate accounting.\n */\n\nimport { AgentEvalError } from './errors'\nimport type { TraceEmitter } from './trace/emitter'\nimport type { BudgetSpec } from './trace/schema'\n\nexport class BudgetBreachError extends AgentEvalError {\n constructor(\n public dimension: keyof BudgetSpec,\n public limit: number,\n public attempted: number,\n ) {\n super('verification', `budget breach on ${dimension}: attempted ${attempted} vs limit ${limit}`)\n }\n}\n\nexport class BudgetGuard {\n private consumed: Record<keyof BudgetSpec, number> = { tokens: 0, wallMs: 0, calls: 0, usd: 0 }\n private emitter: TraceEmitter\n private budget: BudgetSpec\n private startedAt: number\n\n constructor(emitter: TraceEmitter, budget: BudgetSpec, now: () => number = () => Date.now()) {\n this.emitter = emitter\n this.budget = budget\n this.startedAt = now()\n }\n\n /** Record consumption. Throws `BudgetBreachError` if any dimension exceeds its cap. */\n async charge(delta: Partial<Record<keyof BudgetSpec, number>>, spanId?: string): Promise<void> {\n for (const [dim, value] of Object.entries(delta) as Array<[keyof BudgetSpec, number]>) {\n if (!Number.isFinite(value) || value < 0) {\n throw new Error(`BudgetGuard.charge: non-finite or negative ${dim}=${value}`)\n }\n this.consumed[dim] += value\n const limit = this.budget[dim]\n const consumed = this.consumed[dim]\n const remaining = limit === undefined ? Infinity : limit - consumed\n const breached = limit !== undefined && consumed > limit\n if (limit !== undefined) {\n await this.emitter.recordBudget({\n dimension: dim,\n limit,\n consumed,\n remaining,\n breached,\n spanId,\n })\n }\n if (breached) {\n throw new BudgetBreachError(dim, limit!, consumed)\n }\n }\n }\n\n /** Convenience: advance wall-clock budget based on elapsed wall time. */\n async tickWall(nowMs: number, spanId?: string): Promise<void> {\n const elapsed = nowMs - this.startedAt\n const already = this.consumed.wallMs\n const delta = Math.max(0, elapsed - already)\n if (delta > 0) await this.charge({ wallMs: delta }, spanId)\n }\n\n get state(): Record<keyof BudgetSpec, number> {\n return { ...this.consumed }\n }\n}\n","import type { AnalystFinding, AnalystRunResult } from './analyst/types'\nimport type { ControlEvalResult, ControlRunResult, ControlStep } from './control-runtime'\nimport type { DatasetScenario, DatasetSplit } from './dataset'\nimport {\n type AnalystReviewDecision,\n analystFindingDigest,\n analystRunDigest,\n assertUniqueFindingIds,\n completedAnalystReviewQuality,\n readAnalystReview,\n snapshotAnalystRun,\n validateAnalystReviewDecisions,\n} from './feedback-trajectory-review'\n\nexport type {\n AnalystFindingDigest,\n AnalystMissedIssue,\n AnalystReviewCounts,\n AnalystReviewDecision,\n AnalystReviewQuality,\n AnalystReviewSource,\n AnalystRunDigest,\n} from './feedback-trajectory-review'\nexport { analystFindingDigest, analystRunDigest } from './feedback-trajectory-review'\n\nexport type FeedbackArtifactType =\n | 'text'\n | 'code'\n | 'plan'\n | 'research'\n | 'action'\n | 'ui'\n | 'decision'\n | 'data'\n | 'other'\n\nexport type FeedbackLabelSource = 'user' | 'judge' | 'environment' | 'metric' | 'policy' | 'system'\n\nexport type FeedbackLabelKind =\n | 'approve'\n | 'reject'\n | 'select'\n | 'edit'\n | 'rank'\n | 'rate'\n | 'comment'\n | 'metric_outcome'\n | 'policy_block'\n | 'revision_request'\n\nexport type FeedbackSeverity = 'info' | 'warning' | 'error' | 'critical'\n\nexport interface FeedbackTask {\n intent: string\n context?: unknown\n}\n\nexport interface ProposedSideEffect {\n type: string\n risk?: 'low' | 'medium' | 'high'\n costUsd?: number\n externalSideEffect?: boolean\n requiresApproval?: boolean\n metadata?: Record<string, unknown>\n}\n\nexport interface FeedbackLabel {\n id?: string\n source: FeedbackLabelSource\n kind: FeedbackLabelKind\n value: unknown\n reason?: string\n severity?: FeedbackSeverity\n createdAt: string\n metadata?: Record<string, unknown>\n}\n\nexport interface FeedbackAttempt {\n id: string\n stepIndex: number\n artifactType: FeedbackArtifactType\n artifact: unknown\n options?: unknown[]\n proposedAction?: ProposedSideEffect\n evals?: ControlEvalResult[]\n feedback?: FeedbackLabel[]\n createdAt: string\n metadata?: Record<string, unknown>\n}\n\nexport interface FeedbackOutcome {\n success?: boolean\n score?: number\n metrics?: Record<string, number>\n costUsd?: number\n detail?: string\n observedAt?: string\n metadata?: Record<string, unknown>\n}\n\nexport interface FeedbackTrajectory {\n id: string\n projectId?: string\n scenarioId?: string\n task: FeedbackTask\n attempts: FeedbackAttempt[]\n labels: FeedbackLabel[]\n outcome?: FeedbackOutcome\n split?: DatasetSplit\n tags?: Record<string, string>\n createdAt: string\n updatedAt?: string\n metadata?: Record<string, unknown>\n}\n\nexport interface FeedbackTrajectoryStore {\n save(trajectory: FeedbackTrajectory): Promise<void>\n get(id: string): Promise<FeedbackTrajectory | null>\n list(filter?: FeedbackTrajectoryFilter): Promise<FeedbackTrajectory[]>\n appendAttempt(id: string, attempt: FeedbackAttempt): Promise<FeedbackTrajectory>\n appendLabel(id: string, label: FeedbackLabel, attemptId?: string): Promise<FeedbackTrajectory>\n}\n\nexport interface FeedbackTrajectoryFilter {\n projectId?: string\n scenarioId?: string\n split?: DatasetSplit\n tag?: [string, string]\n}\n\nexport interface FeedbackSplitPolicy {\n trainPct?: number\n devPct?: number\n testPct?: number\n holdoutPct?: number\n}\n\nexport interface PreferenceMemoryEntry {\n instruction: string\n rationale: string\n weight: number\n sourceTrajectoryId: string\n sourceLabelId?: string\n category?: string\n}\n\nexport interface FeedbackOptimizerRow {\n scenarioId: string\n trajectoryId: string\n labelKinds: FeedbackLabelKind[]\n score?: number\n metadata?: Record<string, unknown>\n}\n\nexport interface FeedbackReplayResult {\n trajectoryId: string\n pass: boolean\n score?: number\n labels: FeedbackLabel[]\n outcome?: FeedbackOutcome\n metadata?: Record<string, unknown>\n}\n\nexport interface FeedbackReplayAdapter {\n replay(\n trajectory: FeedbackTrajectory,\n ):\n | Promise<Omit<FeedbackReplayResult, 'trajectoryId'>>\n | Omit<FeedbackReplayResult, 'trajectoryId'>\n}\n\nexport interface AnalystFeedbackTrajectoryOptions {\n task: FeedbackTask\n labels?: readonly FeedbackLabel[]\n reviewRequests?: readonly AnalystReviewRequest[]\n reviewDecisions?: readonly AnalystReviewDecision[]\n outcome?: FeedbackOutcome\n id?: string\n projectId?: string\n scenarioId?: string\n split?: DatasetSplit\n tags?: Record<string, string>\n createdAt?: string\n trace?: {\n source?: string\n traceIds?: readonly string[]\n artifactUri?: string\n }\n metadata?: Record<string, unknown>\n}\n\nexport interface AnalystReviewRequest {\n id: string\n runId: string\n runDigest: `sha256:${string}`\n findingId: string\n findingDigest: `sha256:${string}`\n analystId: string\n area: string\n claim: string\n evidence: AnalystFinding['evidence_refs']\n recommendedAction?: string\n validationPlan?: string\n severity: FeedbackSeverity\n confidence: number\n createdAt: string\n}\n\nconst DEFAULT_SPLIT_POLICY: Required<FeedbackSplitPolicy> = {\n trainPct: 70,\n devPct: 15,\n testPct: 10,\n holdoutPct: 5,\n}\n\nexport class InMemoryFeedbackTrajectoryStore implements FeedbackTrajectoryStore {\n private readonly trajectories = new Map<string, FeedbackTrajectory>()\n\n async save(trajectory: FeedbackTrajectory): Promise<void> {\n this.trajectories.set(trajectory.id, cloneTrajectory(trajectory))\n }\n\n async get(id: string): Promise<FeedbackTrajectory | null> {\n const trajectory = this.trajectories.get(id)\n return trajectory ? cloneTrajectory(trajectory) : null\n }\n\n async list(filter: FeedbackTrajectoryFilter = {}): Promise<FeedbackTrajectory[]> {\n return [...this.trajectories.values()]\n .filter((trajectory) => matchesFilter(trajectory, filter))\n .map(cloneTrajectory)\n }\n\n async appendAttempt(id: string, attempt: FeedbackAttempt): Promise<FeedbackTrajectory> {\n const trajectory = this.trajectories.get(id)\n if (!trajectory)\n throw new Error(`FeedbackTrajectoryStore.appendAttempt: unknown trajectory \"${id}\"`)\n const next = cloneTrajectory({\n ...trajectory,\n attempts: [...trajectory.attempts, attempt],\n updatedAt: attempt.createdAt,\n })\n this.trajectories.set(id, next)\n return cloneTrajectory(next)\n }\n\n async appendLabel(\n id: string,\n label: FeedbackLabel,\n attemptId?: string,\n ): Promise<FeedbackTrajectory> {\n const trajectory = this.trajectories.get(id)\n if (!trajectory)\n throw new Error(`FeedbackTrajectoryStore.appendLabel: unknown trajectory \"${id}\"`)\n const attempts = attemptId\n ? trajectory.attempts.map((attempt) =>\n attempt.id === attemptId\n ? { ...attempt, feedback: [...(attempt.feedback ?? []), label] }\n : attempt,\n )\n : trajectory.attempts\n const next = cloneTrajectory({\n ...trajectory,\n attempts,\n labels: attemptId ? trajectory.labels : [...trajectory.labels, label],\n updatedAt: label.createdAt,\n })\n this.trajectories.set(id, next)\n return cloneTrajectory(next)\n }\n}\n\nexport class FileSystemFeedbackTrajectoryStore implements FeedbackTrajectoryStore {\n private readonly dir: string\n private readonly memory = new InMemoryFeedbackTrajectoryStore()\n private loaded = false\n\n constructor(options: { dir: string }) {\n this.dir = options.dir\n }\n\n async save(trajectory: FeedbackTrajectory): Promise<void> {\n await this.load()\n await this.memory.save(trajectory)\n await this.append({ op: 'save', trajectory })\n }\n\n async get(id: string): Promise<FeedbackTrajectory | null> {\n await this.load()\n return this.memory.get(id)\n }\n\n async list(filter: FeedbackTrajectoryFilter = {}): Promise<FeedbackTrajectory[]> {\n await this.load()\n return this.memory.list(filter)\n }\n\n async appendAttempt(id: string, attempt: FeedbackAttempt): Promise<FeedbackTrajectory> {\n await this.load()\n const next = await this.memory.appendAttempt(id, attempt)\n await this.append({ op: 'appendAttempt', id, attempt })\n return next\n }\n\n async appendLabel(\n id: string,\n label: FeedbackLabel,\n attemptId?: string,\n ): Promise<FeedbackTrajectory> {\n await this.load()\n const next = await this.memory.appendLabel(id, label, attemptId)\n await this.append({ op: 'appendLabel', id, label, attemptId })\n return next\n }\n\n private async append(record: unknown): Promise<void> {\n const { appendFile, mkdir } = await import('node:fs/promises')\n const { join } = await import('node:path')\n await mkdir(this.dir, { recursive: true })\n await appendFile(\n join(this.dir, 'feedback-trajectories.ndjson'),\n `${JSON.stringify(record)}\\n`,\n 'utf8',\n )\n }\n\n private async load(): Promise<void> {\n if (this.loaded) return\n const { readFile } = await import('node:fs/promises')\n const { join } = await import('node:path')\n const file = join(this.dir, 'feedback-trajectories.ndjson')\n try {\n const raw = await readFile(file, 'utf8')\n for (const line of raw.split('\\n')) {\n if (!line.trim()) continue\n try {\n const record = JSON.parse(line) as\n | { op: 'save'; trajectory: FeedbackTrajectory }\n | { op: 'appendAttempt'; id: string; attempt: FeedbackAttempt }\n | { op: 'appendLabel'; id: string; label: FeedbackLabel; attemptId?: string }\n if (record.op === 'save') await this.memory.save(record.trajectory)\n if (record.op === 'appendAttempt')\n await this.memory.appendAttempt(record.id, record.attempt)\n if (record.op === 'appendLabel')\n await this.memory.appendLabel(record.id, record.label, record.attemptId)\n } catch {\n /* corrupt records are skipped so one bad line does not discard the corpus */\n }\n }\n } catch {\n /* first run */\n }\n this.loaded = true\n }\n}\n\nexport function createFeedbackTrajectory(input: {\n id?: string\n projectId?: string\n scenarioId?: string\n task: FeedbackTask\n attempts?: FeedbackAttempt[]\n labels?: FeedbackLabel[]\n outcome?: FeedbackOutcome\n split?: DatasetSplit\n tags?: Record<string, string>\n createdAt?: string\n metadata?: Record<string, unknown>\n}): FeedbackTrajectory {\n const createdAt = input.createdAt ?? new Date().toISOString()\n const id =\n input.id ??\n `ft_${stableHash(`${input.projectId ?? ''}|${input.scenarioId ?? ''}|${input.task.intent}|${createdAt}`).toString(16)}`\n return {\n id,\n projectId: input.projectId,\n scenarioId: input.scenarioId,\n task: input.task,\n attempts: input.attempts ?? [],\n labels: input.labels ?? [],\n outcome: input.outcome,\n split: input.split,\n tags: input.tags,\n createdAt,\n metadata: input.metadata,\n }\n}\n\n/** Preserve a trace-analysis run for review, whether or not review is complete. */\nexport function analystRunToFeedbackTrajectory(\n run: AnalystRunResult,\n options: AnalystFeedbackTrajectoryOptions,\n): FeedbackTrajectory {\n const archivedRun = snapshotAnalystRun(run, `analyst run \"${run.run_id}\"`)\n const runDigest = analystRunDigest(archivedRun)\n const findings = archivedRun.findings\n const findingIds = findings.map((finding) => finding.finding_id)\n assertUniqueFindingIds(findingIds)\n const analystIds = [\n ...new Set([\n ...findings.map((finding) => finding.analyst_id),\n ...archivedRun.per_analyst.map((summary) => summary.analyst_id),\n ]),\n ]\n const reviewDecisions = validateAnalystReviewDecisions({\n runId: archivedRun.run_id,\n runDigest,\n findings,\n analystIds,\n decisions: options.reviewDecisions ?? [],\n })\n const reviewRequests =\n options.reviewRequests === undefined\n ? undefined\n : validateAnalystReviewRequests(archivedRun, options.reviewRequests)\n const createdAt = options.createdAt ?? archivedRun.started_at\n const knownCostUsd = archivedRun.total_cost_usd\n const capturedCost =\n archivedRun.total_cost_provenance?.kind === 'uncaptured'\n ? undefined\n : archivedRun.total_cost_usd\n return createFeedbackTrajectory({\n id: options.id,\n projectId: options.projectId,\n scenarioId: options.scenarioId,\n task: options.task,\n attempts: [\n {\n id: `analysis:${archivedRun.run_id}`,\n stepIndex: 0,\n artifactType: 'research',\n artifact: {\n type: 'analyst-run',\n analystRunId: archivedRun.run_id,\n runDigest,\n correlationId: archivedRun.correlation_id,\n analystIds,\n findings,\n ...('execution_plan' in archivedRun ? { executionPlan: archivedRun.execution_plan } : {}),\n ...('completion' in archivedRun ? { completion: archivedRun.completion } : {}),\n },\n createdAt,\n metadata: {\n perAnalyst: archivedRun.per_analyst,\n trace: options.trace,\n reviewRequests,\n },\n },\n ],\n labels: [...(options.labels ?? [])],\n outcome: options.outcome\n ? {\n ...options.outcome,\n costUsd: options.outcome.costUsd ?? capturedCost,\n }\n : capturedCost === undefined\n ? undefined\n : { costUsd: capturedCost, observedAt: archivedRun.ended_at },\n split: options.split,\n tags: options.tags,\n createdAt,\n metadata: {\n ...options.metadata,\n analysis: {\n kind: 'analyst-run',\n runId: archivedRun.run_id,\n runDigest,\n startedAt: archivedRun.started_at,\n endedAt: archivedRun.ended_at,\n reviewDecisions,\n costProvenance: archivedRun.total_cost_provenance,\n knownCostUsd,\n },\n },\n })\n}\n\n/** Convert one immutable analyst run into revision requests for an independent reviewer. */\nexport function analystRunToReviewRequests(\n run: AnalystRunResult,\n options: { createdAt?: string } = {},\n): AnalystReviewRequest[] {\n const archivedRun = snapshotAnalystRun(run, `analyst run \"${run.run_id}\"`)\n const runDigest = analystRunDigest(archivedRun)\n const createdAt = options.createdAt ?? new Date().toISOString()\n return archivedRun.findings.map((finding) => ({\n id: analystReviewRequestId(runDigest, finding.finding_id),\n runId: archivedRun.run_id,\n runDigest,\n findingId: finding.finding_id,\n findingDigest: analystFindingDigest(finding),\n analystId: finding.analyst_id,\n area: finding.area,\n claim: finding.claim,\n evidence: finding.evidence_refs,\n recommendedAction: finding.recommended_action,\n validationPlan: finding.validation_plan,\n severity: feedbackSeverityFromFinding(finding),\n confidence: finding.confidence,\n createdAt,\n }))\n}\n\nfunction validateAnalystReviewRequests(\n run: AnalystRunResult,\n requests: readonly AnalystReviewRequest[],\n): AnalystReviewRequest[] {\n const runDigest = analystRunDigest(run)\n const findingsById = new Map(run.findings.map((finding) => [finding.finding_id, finding]))\n const seenFindingIds = new Set<string>()\n return requests.map((request, index) => {\n if (request.runId !== run.run_id) {\n throw new TypeError(`analyst review request ${index} run id mismatch`)\n }\n if (request.runDigest !== runDigest) {\n throw new TypeError(`analyst review request ${index} run digest mismatch`)\n }\n const finding = findingsById.get(request.findingId)\n if (!finding) {\n throw new TypeError(\n `analyst review request ${index} references unknown finding id \"${request.findingId}\"`,\n )\n }\n if (seenFindingIds.has(request.findingId)) {\n throw new TypeError(`duplicate analyst review request for finding id \"${request.findingId}\"`)\n }\n seenFindingIds.add(request.findingId)\n if (request.findingDigest !== analystFindingDigest(finding)) {\n throw new TypeError(`analyst review request ${index} finding digest mismatch`)\n }\n if (request.id !== analystReviewRequestId(runDigest, request.findingId)) {\n throw new TypeError(`analyst review request ${index} id mismatch`)\n }\n return request\n })\n}\n\nfunction analystReviewRequestId(runDigest: `sha256:${string}`, findingId: string): string {\n return `analyst:${runDigest}:${findingId}`\n}\n\nexport function assignFeedbackSplit(\n trajectory: Pick<FeedbackTrajectory, 'id' | 'projectId' | 'scenarioId' | 'task'>,\n policy: FeedbackSplitPolicy = {},\n): DatasetSplit {\n const split = { ...DEFAULT_SPLIT_POLICY, ...policy }\n const total = split.trainPct + split.devPct + split.testPct + split.holdoutPct\n if (total <= 0) throw new Error('assignFeedbackSplit: split percentages must sum above zero')\n const bucket =\n stableHash(\n `${trajectory.projectId ?? ''}|${trajectory.scenarioId ?? ''}|${trajectory.id}|${trajectory.task.intent}`,\n ) % total\n if (bucket < split.trainPct) return 'train'\n if (bucket < split.trainPct + split.devPct) return 'dev'\n if (bucket < split.trainPct + split.devPct + split.testPct) return 'test'\n return 'holdout'\n}\n\nexport function withAssignedFeedbackSplit(\n trajectory: FeedbackTrajectory,\n policy?: FeedbackSplitPolicy,\n): FeedbackTrajectory {\n return {\n ...trajectory,\n split: trajectory.split ?? assignFeedbackSplit(trajectory, policy),\n }\n}\n\nexport function feedbackTrajectoryToDatasetScenario(\n trajectory: FeedbackTrajectory,\n): DatasetScenario {\n const withSplit = withAssignedFeedbackSplit(trajectory)\n return {\n id: withSplit.scenarioId ?? withSplit.id,\n split: withSplit.split,\n payload: withSplit,\n tags: {\n ...(withSplit.projectId ? { projectId: withSplit.projectId } : {}),\n ...(withSplit.tags ?? {}),\n source: 'feedback-trajectory',\n },\n }\n}\n\nexport function feedbackTrajectoriesToDatasetScenarios(\n trajectories: FeedbackTrajectory[],\n): DatasetScenario[] {\n return trajectories.map(feedbackTrajectoryToDatasetScenario)\n}\n\nexport function feedbackTrajectoryToOptimizerRow(\n trajectory: FeedbackTrajectory,\n): FeedbackOptimizerRow {\n const labels = allLabels(trajectory)\n const analystReview = readAnalystReview(trajectory)\n const analystQuality = analystReview ? completedAnalystReviewQuality(analystReview) : undefined\n const reviewLabelKinds = analystReview\n ? analystReview.reviewDecisions.map((decision): FeedbackLabelKind => {\n if (decision.verdict === 'rejected') return 'reject'\n if (decision.verdict === 'completeness_assessed' && decision.missedIssues.length > 0) {\n return 'revision_request'\n }\n return 'approve'\n })\n : []\n return {\n scenarioId: trajectory.scenarioId ?? trajectory.id,\n trajectoryId: trajectory.id,\n labelKinds: [...new Set([...labels.map((label) => label.kind), ...reviewLabelKinds])],\n score: analystQuality?.f1 ?? trajectory.outcome?.score ?? scoreFromLabels(labels),\n metadata: {\n projectId: trajectory.projectId,\n split: trajectory.split,\n intent: trajectory.task.intent,\n attempts: trajectory.attempts.length,\n outcome: trajectory.outcome,\n labels,\n ...(analystReview\n ? {\n analystReview: {\n findingIds: analystReview.findingIds,\n findingDigests: analystReview.findings.map((finding) => ({\n findingId: finding.finding_id,\n findingDigest: analystFindingDigest(finding),\n })),\n decisions: analystReview.reviewDecisions,\n precision: analystQuality?.precision,\n recall: analystQuality?.recall,\n f1: analystQuality?.f1,\n counts: analystQuality?.counts,\n },\n }\n : {}),\n },\n }\n}\n\nexport function feedbackTrajectoriesToOptimizerRows(\n trajectories: FeedbackTrajectory[],\n): FeedbackOptimizerRow[] {\n return trajectories.map(feedbackTrajectoryToOptimizerRow)\n}\n\nexport async function replayFeedbackTrajectory(\n trajectory: FeedbackTrajectory,\n adapter: FeedbackReplayAdapter,\n): Promise<FeedbackReplayResult> {\n try {\n const result = await adapter.replay(trajectory)\n return {\n trajectoryId: trajectory.id,\n ...result,\n }\n } catch (err) {\n const createdAt = new Date().toISOString()\n const message = err instanceof Error ? err.message : String(err)\n return {\n trajectoryId: trajectory.id,\n pass: false,\n labels: [\n {\n source: 'system',\n kind: 'reject',\n value: false,\n reason: message,\n severity: 'error',\n createdAt,\n },\n ],\n outcome: {\n success: false,\n score: 0,\n detail: message,\n observedAt: createdAt,\n },\n metadata: { replayError: true },\n }\n }\n}\n\nexport async function replayFeedbackTrajectories(\n trajectories: FeedbackTrajectory[],\n adapter: FeedbackReplayAdapter,\n): Promise<FeedbackReplayResult[]> {\n const results: FeedbackReplayResult[] = []\n for (const trajectory of trajectories) {\n results.push(await replayFeedbackTrajectory(trajectory, adapter))\n }\n return results\n}\n\nexport function summarizePreferenceMemory(\n trajectories: FeedbackTrajectory[],\n options: { maxEntries?: number } = {},\n): PreferenceMemoryEntry[] {\n const maxEntries = options.maxEntries ?? 20\n const entries: PreferenceMemoryEntry[] = []\n for (const trajectory of trajectories) {\n for (const label of allLabels(trajectory)) {\n const instruction = instructionFromLabel(trajectory, label)\n if (!instruction) continue\n entries.push({\n instruction,\n rationale: label.reason ?? `${label.kind} label from ${label.source}`,\n weight: weightForLabel(label),\n sourceTrajectoryId: trajectory.id,\n sourceLabelId: label.id,\n category: label.kind,\n })\n }\n }\n\n const byInstruction = new Map<string, PreferenceMemoryEntry>()\n for (const entry of entries) {\n const key = entry.instruction.toLowerCase().replace(/\\s+/g, ' ').trim()\n const existing = byInstruction.get(key)\n if (!existing || entry.weight > existing.weight) byInstruction.set(key, entry)\n }\n return [...byInstruction.values()].sort((a, b) => b.weight - a.weight).slice(0, maxEntries)\n}\n\nexport function renderPreferenceMemoryMarkdown(entries: PreferenceMemoryEntry[]): string {\n const lines = ['# Preference Memory', '']\n for (const entry of entries) {\n lines.push(`- ${entry.instruction}`)\n lines.push(` Rationale: ${entry.rationale}`)\n lines.push(` Source: ${entry.sourceTrajectoryId}`)\n lines.push('')\n }\n return `${lines.join('\\n').trim()}\\n`\n}\n\nexport function serializeFeedbackTrajectoriesJsonl(trajectories: FeedbackTrajectory[]): string {\n return `${trajectories\n .slice()\n .sort((a, b) => a.id.localeCompare(b.id))\n .map((trajectory) => JSON.stringify(canonicalize(trajectory)))\n .join('\\n')}\\n`\n}\n\nexport function parseFeedbackTrajectoriesJsonl(jsonl: string): FeedbackTrajectory[] {\n const trajectories: FeedbackTrajectory[] = []\n for (const line of jsonl.split('\\n')) {\n if (!line.trim()) continue\n trajectories.push(JSON.parse(line) as FeedbackTrajectory)\n }\n return trajectories\n}\n\nexport function controlRunToFeedbackTrajectory<TState, TAction, TActionResult>(\n run: ControlRunResult<TState, TAction, TActionResult>,\n options: {\n projectId?: string\n scenarioId?: string\n artifactType?: FeedbackArtifactType\n artifactFromStep?: (step: ControlStep<TState, TAction, TActionResult>) => unknown\n proposedActionFromStep?: (\n step: ControlStep<TState, TAction, TActionResult>,\n ) => ProposedSideEffect | undefined\n createdAt?: string\n } = {},\n): FeedbackTrajectory {\n const createdAt = options.createdAt ?? new Date().toISOString()\n const trajectoryId =\n run.runId ?? `ft_control_${stableHash(`${run.intent}|${createdAt}`).toString(16)}`\n return createFeedbackTrajectory({\n id: trajectoryId,\n projectId: options.projectId,\n scenarioId: options.scenarioId,\n task: { intent: run.intent },\n createdAt,\n attempts: run.steps.map((step) => ({\n id: `${trajectoryId}_step_${step.index}`,\n stepIndex: step.index,\n artifactType: options.artifactType ?? 'action',\n artifact: options.artifactFromStep?.(step) ?? step.actionOutcome?.result ?? step.decision,\n proposedAction: options.proposedActionFromStep?.(step),\n evals: step.evalsAfter,\n createdAt: step.startedAt,\n metadata: {\n decision: step.decision,\n actionOutcome: step.actionOutcome,\n },\n })),\n labels: [\n {\n source: 'system',\n kind: run.pass ? 'approve' : 'reject',\n value: run.pass,\n reason: run.reason,\n severity: run.pass ? 'info' : 'error',\n createdAt,\n },\n ],\n outcome: {\n success: run.pass,\n score: run.score,\n costUsd: run.spentCostUsd,\n detail: run.reason,\n observedAt: createdAt,\n metadata: {\n stoppedBy: run.stoppedBy,\n failureClass: run.failureClass,\n },\n },\n })\n}\n\nfunction allLabels(trajectory: FeedbackTrajectory): FeedbackLabel[] {\n const labels = [\n ...trajectory.labels,\n ...trajectory.attempts.flatMap((attempt) => attempt.feedback ?? []),\n ]\n const seen = new Set<string>()\n return labels.filter((label) => {\n const key =\n label.id ?? `${label.source}|${label.kind}|${label.createdAt}|${JSON.stringify(label.value)}`\n if (seen.has(key)) return false\n seen.add(key)\n return true\n })\n}\n\nfunction feedbackSeverityFromFinding(finding: AnalystFinding): FeedbackSeverity {\n switch (finding.severity) {\n case 'critical':\n return 'critical'\n case 'high':\n return 'error'\n case 'medium':\n return 'warning'\n default:\n return 'info'\n }\n}\n\nfunction scoreFromLabels(labels: FeedbackLabel[]): number | undefined {\n if (!labels.length) return undefined\n const scored = labels\n .map((label) => {\n if (label.kind === 'approve' || label.kind === 'select') return 1\n if (label.kind === 'reject' || label.kind === 'policy_block') return 0\n if (label.kind === 'rate' && typeof label.value === 'number')\n return Math.max(0, Math.min(1, label.value))\n return undefined\n })\n .filter((value): value is number => typeof value === 'number')\n if (!scored.length) return undefined\n return Math.round((scored.reduce((sum, value) => sum + value, 0) / scored.length) * 1000) / 1000\n}\n\nfunction instructionFromLabel(\n trajectory: FeedbackTrajectory,\n label: FeedbackLabel,\n): string | undefined {\n if (label.kind === 'reject' && label.reason)\n return `Avoid outputs like \"${compact(trajectory.task.intent, 80)}\" when: ${label.reason}`\n if (label.kind === 'revision_request' && label.reason)\n return `Revise similar work by applying: ${label.reason}`\n if (label.kind === 'select' && label.reason)\n return `Prefer selected options for \"${compact(trajectory.task.intent, 80)}\" because: ${label.reason}`\n if (label.kind === 'approve' && label.reason)\n return `Repeat the pattern approved for \"${compact(trajectory.task.intent, 80)}\": ${label.reason}`\n if (label.kind === 'comment' && label.reason) return label.reason\n return undefined\n}\n\nfunction weightForLabel(label: FeedbackLabel): number {\n const severity =\n label.severity === 'critical'\n ? 4\n : label.severity === 'error'\n ? 3\n : label.severity === 'warning'\n ? 2\n : 1\n const source =\n label.source === 'user'\n ? 3\n : label.source === 'metric' || label.source === 'environment'\n ? 2\n : 1\n return severity * source\n}\n\nfunction matchesFilter(trajectory: FeedbackTrajectory, filter: FeedbackTrajectoryFilter): boolean {\n if (filter.projectId && trajectory.projectId !== filter.projectId) return false\n if (filter.scenarioId && trajectory.scenarioId !== filter.scenarioId) return false\n if (filter.split && trajectory.split !== filter.split) return false\n if (filter.tag) {\n const [key, value] = filter.tag\n if (trajectory.tags?.[key] !== value) return false\n }\n return true\n}\n\nfunction cloneTrajectory(trajectory: FeedbackTrajectory): FeedbackTrajectory {\n return JSON.parse(JSON.stringify(trajectory)) as FeedbackTrajectory\n}\n\nfunction compact(value: string, max: number): string {\n const normalized = value.replace(/\\s+/g, ' ').trim()\n return normalized.length > max ? `${normalized.slice(0, max).trim()}...` : normalized\n}\n\nfunction stableHash(input: string): number {\n let hash = 2166136261\n for (let i = 0; i < input.length; i += 1) {\n hash ^= input.charCodeAt(i)\n hash = Math.imul(hash, 16777619)\n }\n return hash >>> 0\n}\n\nfunction canonicalize(value: unknown): unknown {\n if (value === null || typeof value !== 'object') return value\n if (Array.isArray(value)) return value.map(canonicalize)\n const out: Record<string, unknown> = {}\n for (const key of Object.keys(value as Record<string, unknown>).sort()) {\n out[key] = canonicalize((value as Record<string, unknown>)[key])\n }\n return out\n}\n","/**\n * @stable\n *\n * Eval scorecard — the persistent (persona × profile) score timeline.\n *\n * Every benchmark run folds into per-cell entries; a cell is\n * `(scenarioId, profileHash)` and its timeline carries one entry per commit.\n * The scorecard answers the question a single run cannot: did THIS change\n * regress persona P on profile F, even while the aggregate improved?\n *\n * Storage is an append-only JSONL log — one line per (cell, commit). Appends\n * never read-modify-write, so concurrent campaign runs cannot clobber each\n * other; `loadScorecard` folds the log into the queryable `Scorecard`, and a\n * malformed line never breaks the read. `diffScorecard` compares the latest\n * entry of each cell against its predecessor with Cohen's d + Welch's t-test.\n */\n\nimport { appendFileSync, existsSync, mkdirSync, readFileSync } from 'node:fs'\nimport { dirname } from 'node:path'\nimport type { AgentProfile } from './agent-profile'\nimport { agentProfileHash, agentProfileModelId } from './agent-profile'\nimport { welchsTTest } from './baseline'\nimport { type RunRecord, runTaskScore } from './run-record'\nimport { cohensD } from './statistics'\n\n// ── Types ────────────────────────────────────────────────────────────\n\n/** One commit's measurement of one (scenario, profile) cell. */\nexport interface ScorecardEntry {\n commitSha: string\n /** ISO timestamp the entry was recorded. */\n timestamp: string\n /** Per-seed (or per-rep) scores for this cell at this commit. */\n scores: number[]\n /** Median of `scores` — the cell's headline score for the commit. */\n composite: number\n /** Per-dimension means, when the runs carried a judge breakdown. */\n perDimension?: Record<string, number>\n /** RunRecord ids folded into this entry — provenance. */\n runIds: string[]\n}\n\n/** A (scenario, profile) cell and its commit-ordered score timeline. */\nexport interface ScorecardCell {\n scenarioId: string\n profileHash: string\n /** Model id — denormalised from the profile for readable filtering. */\n model: string\n timeline: ScorecardEntry[]\n}\n\n/** The folded scorecard: every cell, plus the profile definitions by hash. */\nexport interface Scorecard {\n cells: ScorecardCell[]\n /** Profile definitions seen — keeps the scorecard self-describing. */\n profiles: Record<string, AgentProfile>\n}\n\n/** One append-only log line — a single cell's entry for a single commit. */\nexport interface ScorecardLogLine {\n scenarioId: string\n profileHash: string\n model: string\n profile: AgentProfile\n entry: ScorecardEntry\n}\n\n// ── Recording ────────────────────────────────────────────────────────\n\nexport interface RecordRunsOptions {\n /** The profile that produced these runs — keys the cell. */\n profile: AgentProfile\n commitSha: string\n /** Defaults to `new Date().toISOString()`. */\n timestamp?: string\n}\n\nfunction median(xs: number[]): number {\n if (xs.length === 0) return 0\n const sorted = [...xs].sort((a, b) => a - b)\n const mid = Math.floor(sorted.length / 2)\n return sorted.length % 2 === 0 ? (sorted[mid - 1]! + sorted[mid]!) / 2 : sorted[mid]!\n}\n\n// Cells rank on `runTaskScore` — RAW on purpose: a scorecard reports the\n// measurement, and hiding a gamed run's score behind a 0 would make the gaming\n// invisible in the report.\n\n/** Mean of each judge dimension across the runs that reported one. */\nfunction aggregatePerDimension(runs: RunRecord[]): Record<string, number> | undefined {\n const sums = new Map<string, { total: number; count: number }>()\n for (const run of runs) {\n const dims = run.outcome.judgeScores?.perDimMean\n if (!dims) continue\n for (const [dim, value] of Object.entries(dims)) {\n if (!Number.isFinite(value)) continue\n const acc = sums.get(dim) ?? { total: 0, count: 0 }\n acc.total += value\n acc.count += 1\n sums.set(dim, acc)\n }\n }\n if (sums.size === 0) return undefined\n const out: Record<string, number> = {}\n for (const [dim, acc] of sums) out[dim] = acc.total / acc.count\n return out\n}\n\n/**\n * Fold a benchmark's `RunRecord[]` into per-cell scorecard log lines — one\n * line per scenario the runs cover. All runs are attributed to the single\n * `profile` in `opts` (the harness ran them under it); the cell key is\n * `(scenarioId, agentProfileHash(profile))`.\n */\nexport function recordRuns(runs: RunRecord[], opts: RecordRunsOptions): ScorecardLogLine[] {\n const profileHash = agentProfileHash(opts.profile)\n const model = agentProfileModelId(opts.profile)\n const timestamp = opts.timestamp ?? new Date().toISOString()\n\n const byScenario = new Map<string, RunRecord[]>()\n for (const run of runs) {\n const scenarioId = run.scenarioId\n if (!scenarioId) continue // un-keyed run — cannot place it in a cell\n const bucket = byScenario.get(scenarioId)\n if (bucket) bucket.push(run)\n else byScenario.set(scenarioId, [run])\n }\n\n const lines: ScorecardLogLine[] = []\n for (const [scenarioId, scenarioRuns] of byScenario) {\n const scored = scenarioRuns\n .map((run) => ({ run, score: runTaskScore(run) }))\n .filter((s): s is { run: RunRecord; score: number } => s.score !== undefined)\n if (scored.length === 0) continue\n const scores = scored.map((s) => s.score)\n const entry: ScorecardEntry = {\n commitSha: opts.commitSha,\n timestamp,\n scores,\n composite: median(scores),\n runIds: scored.map((s) => s.run.runId),\n }\n const perDimension = aggregatePerDimension(scenarioRuns)\n if (perDimension) entry.perDimension = perDimension\n lines.push({\n scenarioId,\n profileHash,\n model,\n profile: opts.profile,\n entry,\n })\n }\n return lines\n}\n\n// ── Storage ──────────────────────────────────────────────────────────\n\n/** Append cell entries to the JSONL scorecard log. Creates the file/dir. */\nexport function appendScorecard(logPath: string, lines: ScorecardLogLine[]): void {\n if (lines.length === 0) return\n mkdirSync(dirname(logPath), { recursive: true })\n appendFileSync(logPath, `${lines.map((line) => JSON.stringify(line)).join('\\n')}\\n`)\n}\n\n/** Record runs and append them to the log in one call. Returns the lines. */\nexport function recordRunsToScorecard(\n logPath: string,\n runs: RunRecord[],\n opts: RecordRunsOptions,\n): ScorecardLogLine[] {\n const lines = recordRuns(runs, opts)\n appendScorecard(logPath, lines)\n return lines\n}\n\n/**\n * Fold the JSONL log into a queryable `Scorecard`. A missing file yields an\n * empty scorecard; a malformed line is skipped — a corrupt append never\n * breaks the read. Each cell's timeline is sorted chronologically.\n */\nexport function loadScorecard(logPath: string): Scorecard {\n if (!existsSync(logPath)) return { cells: [], profiles: {} }\n const cells = new Map<string, ScorecardCell>()\n const profiles: Record<string, AgentProfile> = {}\n\n for (const raw of readFileSync(logPath, 'utf8').split('\\n')) {\n const line = raw.trim()\n if (!line) continue\n let parsed: ScorecardLogLine\n try {\n parsed = JSON.parse(line) as ScorecardLogLine\n } catch {\n continue // skip a malformed line rather than failing the whole read\n }\n if (!parsed?.scenarioId || !parsed.profileHash || !parsed.entry) continue\n const key = `${parsed.scenarioId}::${parsed.profileHash}`\n let cell = cells.get(key)\n if (!cell) {\n cell = {\n scenarioId: parsed.scenarioId,\n profileHash: parsed.profileHash,\n model: parsed.model,\n timeline: [],\n }\n cells.set(key, cell)\n }\n cell.timeline.push(parsed.entry)\n if (parsed.profile) profiles[parsed.profileHash] = parsed.profile\n }\n\n for (const cell of cells.values()) {\n cell.timeline.sort((a, b) => a.timestamp.localeCompare(b.timestamp))\n }\n return { cells: [...cells.values()], profiles }\n}\n\n// ── Diff ─────────────────────────────────────────────────────────────\n\nexport type CellVerdict = 'improved' | 'regressed' | 'flat' | 'new'\n\nexport interface ScorecardCellDiff {\n scenarioId: string\n profileHash: string\n model: string\n verdict: CellVerdict\n /** Composite of the latest entry. */\n current: number\n /** Composite of the comparison entry — `null` when `verdict === 'new'`. */\n baseline: number | null\n /** `current − baseline` — `null` when new. */\n delta: number | null\n /** Cohen's d of current vs baseline samples — `null` when new or n < 2. */\n cohensD: number | null\n /** Welch's t-test p-value — `null` when new or n < 2. */\n pValue: number | null\n currentCommit: string\n baselineCommit: string | null\n}\n\nexport interface ScorecardDiff {\n cells: ScorecardCellDiff[]\n summary: { improved: number; regressed: number; flat: number; new: number }\n}\n\nexport interface DiffScorecardOptions {\n /** Compare each cell against this commit instead of its immediate predecessor. */\n baselineCommit?: string\n /** |Cohen's d| at/above which a move counts as real. Default 0.5. */\n minEffect?: number\n /** p-value at/below which a move is significant. Default 0.05. */\n maxP?: number\n /**\n * |delta| at/above which a move counts when statistics are unavailable\n * (a cell with fewer than 2 samples on either side). Default 0.05.\n */\n minDelta?: number\n}\n\n/**\n * Compare the latest entry of every cell against its predecessor (or against\n * `baselineCommit`) and classify the move. A move is `improved`/`regressed`\n * only when it clears both the effect-size and significance gates; otherwise\n * `flat`. Cells with no prior entry are `new`.\n */\nexport function diffScorecard(\n scorecard: Scorecard,\n opts: DiffScorecardOptions = {},\n): ScorecardDiff {\n const minEffect = opts.minEffect ?? 0.5\n const maxP = opts.maxP ?? 0.05\n const minDelta = opts.minDelta ?? 0.05\n\n const cells: ScorecardCellDiff[] = []\n for (const cell of scorecard.cells) {\n const timeline = cell.timeline\n if (timeline.length === 0) continue\n const current = timeline[timeline.length - 1]!\n\n const baseline = opts.baselineCommit\n ? [...timeline].reverse().find((e) => e.commitSha === opts.baselineCommit && e !== current)\n : timeline[timeline.length - 2]\n\n const base: Omit<\n ScorecardCellDiff,\n 'verdict' | 'baseline' | 'delta' | 'cohensD' | 'pValue' | 'baselineCommit'\n > = {\n scenarioId: cell.scenarioId,\n profileHash: cell.profileHash,\n model: cell.model,\n current: current.composite,\n currentCommit: current.commitSha,\n }\n\n if (!baseline) {\n cells.push({\n ...base,\n verdict: 'new',\n baseline: null,\n delta: null,\n cohensD: null,\n pValue: null,\n baselineCommit: null,\n })\n continue\n }\n\n const delta = current.composite - baseline.composite\n const canStat = baseline.scores.length >= 2 && current.scores.length >= 2\n let d: number | null = null\n let p: number | null = null\n let verdict: CellVerdict\n\n if (canStat) {\n d = cohensD(baseline.scores, current.scores)\n const t = welchsTTest(baseline.scores, current.scores)\n p = Number.isFinite(t.p) ? t.p : null\n // `canStat` guarantees ≥ 2 samples per side, so a null d means zero\n // pooled spread across a real mean gap — an unbounded standardized\n // effect, which clears any finite threshold.\n const effectClears = d === null || Math.abs(d) >= minEffect\n const significant = effectClears && p !== null && p <= maxP\n verdict = significant ? (delta > 0 ? 'improved' : 'regressed') : 'flat'\n } else {\n // Too few samples for a real test — fall back to a raw-delta threshold.\n verdict = Math.abs(delta) >= minDelta ? (delta > 0 ? 'improved' : 'regressed') : 'flat'\n }\n\n cells.push({\n ...base,\n verdict,\n baseline: baseline.composite,\n delta,\n cohensD: d,\n pValue: p,\n baselineCommit: baseline.commitSha,\n })\n }\n\n const summary = { improved: 0, regressed: 0, flat: 0, new: 0 }\n for (const cell of cells) summary[cell.verdict] += 1\n return { cells, summary }\n}\n\n/**\n * Render a scorecard diff as a human-readable report — the block a feature\n * PR prints. Regressions are listed first; flat cells are summarised, not\n * enumerated.\n */\nexport function formatScorecardDiff(diff: ScorecardDiff): string {\n const lines: string[] = []\n const { summary } = diff\n lines.push(\n `Scorecard: ${summary.regressed} regressed · ${summary.improved} improved · ` +\n `${summary.flat} flat · ${summary.new} new`,\n )\n\n const fmt = (n: number) => n.toFixed(3)\n const noteworthy = diff.cells\n .filter((c) => c.verdict === 'regressed' || c.verdict === 'improved')\n .sort((a, b) => {\n // Regressions first, then by magnitude of delta.\n if (a.verdict !== b.verdict) return a.verdict === 'regressed' ? -1 : 1\n return Math.abs(b.delta ?? 0) - Math.abs(a.delta ?? 0)\n })\n\n for (const cell of noteworthy) {\n const mark = cell.verdict === 'regressed' ? 'REGRESSED' : 'improved'\n const deltaStr =\n cell.delta !== null ? (cell.delta >= 0 ? `+${fmt(cell.delta)}` : fmt(cell.delta)) : '—'\n const stat =\n cell.cohensD !== null\n ? ` (d=${cell.cohensD.toFixed(2)}${cell.pValue !== null ? `, p=${cell.pValue.toFixed(3)}` : ''})`\n : ''\n lines.push(\n ` ${mark} ${cell.scenarioId} · ${cell.model} · ${cell.profileHash.slice(0, 8)} ` +\n `${fmt(cell.baseline ?? 0)} → ${fmt(cell.current)} ${deltaStr}${stat}`,\n )\n }\n\n return lines.join('\\n')\n}\n","/**\n * Trace contracts — finite-trace temporal assertions over span sequences.\n *\n * Five LTLf operators over one ordered span sequence — `always(p)`,\n * `never(p)`, `eventually(p)`, `precedes(a, b)`, `neverUnless(p, prior)` —\n * deterministic and judge-free. No nesting: each rule is one operator over\n * flat `SpanPredicate`s; compose richer checks with multiple rules.\n *\n * A built `TraceContract` is a serializable plain object (RegExp matchers\n * are normalized to `SerializedRegex`), so ONE contract definition is\n * dual-use:\n *\n * - recorded eval traces — `evaluateTraceContract(contract, await\n * store.spans({ runId }))`.\n * - the production OTLP stream — `ExportableSpan`s flattened by\n * `trace/otel-bridge` satisfy `ContractSpan` structurally. A production\n * monitor implements `OtelExporter`, buffers `exportSpan` payloads per\n * trace, and runs `checkTraceContracts(buffer, contracts)` on flush:\n *\n * const buffer: ContractSpan[] = []\n * const monitor: OtelExporter = {\n * exportSpan: (s) => { buffer.push(s) },\n * flush: async () => {\n * const { allValid, verdicts } = checkTraceContracts(buffer, contracts)\n * if (!allValid) alert(verdicts)\n * },\n * shutdown: async () => {},\n * }\n * const store = createOtelTracingStore(inner, monitor, runId)\n *\n * `custom` predicate functions are the one non-serializable escape hatch:\n * the builder stamps `requiresCustom: true` (which DOES survive JSON) so a\n * deserialized contract that lost its function fails loud at evaluation\n * instead of silently weakening.\n *\n * Naming: the root barrel exports ci-gate's threshold-contract\n * `evaluateContract`, so the evaluators here are `evaluateTraceContract` /\n * `checkTraceContracts`.\n */\n\nimport type { JudgeConfig, JudgeDimension, Scenario } from './campaign/types'\nimport { ValidationError } from './errors'\nimport { packageVersion } from './package-version'\nimport { certificationEvidenceDigest, type DefaultVerdict } from './verdict'\n\n// ── Span surface ──────────────────────────────────────────────────────\n\n/**\n * Minimal structural span the checker reads. Both the eval-side `Span`\n * (trace/schema) and the OTLP-flattened `ExportableSpan` (trace/otel-export)\n * satisfy it; any other producer only needs these fields.\n */\nexport interface ContractSpan {\n spanId?: string\n name?: string\n kind?: string\n startedAt?: number\n status?: string\n error?: string\n /** Typed field on eval-side ToolSpans; OTLP flattenings drop it (see\n * `tool` matching order in {@link matchSpan}). */\n toolName?: string\n attributes?: Record<string, unknown>\n}\n\n/** JSON-safe RegExp form — what the builder normalizes RegExp matchers to. */\nexport interface SerializedRegex {\n $regex: string\n flags: string\n}\n\nexport type TextMatcher = string | RegExp | SerializedRegex\n\n/**\n * Proposition over one span. All specified fields must match (AND).\n * At least one field is required — an empty predicate would match every\n * span and is rejected.\n *\n * `tool` resolution order covers both span shapes: `span.toolName` (typed\n * ToolSpan) → `attributes['tool.name']` / `attributes['toolName']`\n * (OTLP-flat attribute conventions) → `span.name` when `kind === 'tool'`\n * (otel-bridge's `ExportableSpan`, which drops `toolName`).\n *\n * `attr` values match by strict equality, or regex-test when the value is a\n * RegExp/SerializedRegex and the attribute is a string. Structured attribute\n * values need `custom`.\n */\nexport interface SpanPredicate {\n name?: TextMatcher\n tool?: TextMatcher\n attr?: Record<string, unknown>\n custom?: (span: ContractSpan) => boolean\n /** Stamped by the builder when `custom` is present. Survives JSON while\n * the function does not, so evaluation of a deserialized contract throws\n * instead of silently dropping the check. */\n requiresCustom?: true\n}\n\n// ── Contract shape ────────────────────────────────────────────────────\n\nexport type ContractRuleKind = 'always' | 'never' | 'eventually' | 'precedes' | 'neverUnless'\n\nexport interface ContractRule {\n kind: ContractRuleKind\n /** Unique within the contract — keys the per-rule score. */\n label: string\n /** Subject predicate for always / never / eventually / neverUnless. */\n p?: SpanPredicate\n /** precedes: the required precondition. */\n a?: SpanPredicate\n /** precedes: the guarded match — every b-match needs an earlier a-match. */\n b?: SpanPredicate\n /** neverUnless: the authorizing earlier match. */\n prior?: SpanPredicate\n}\n\n/** Serializable plain object — `traceContract(name)....build()` output. */\nexport interface TraceContract {\n name: string\n rules: ContractRule[]\n}\n\nexport interface ContractViolation {\n rule: string\n spanId?: string\n detail: string\n}\n\nexport interface ContractVerdict extends DefaultVerdict {\n /** Contract name — keys this verdict in multi-contract reports. */\n contract: string\n valid: boolean\n /** Fraction of rules passing, in [0, 1]. */\n score: number\n /** Per-rule 0|1 keyed by rule label. */\n scores: Record<string, number>\n violations: ContractViolation[]\n}\n\nexport interface ContractCheckResult {\n verdicts: ContractVerdict[]\n allValid: boolean\n}\n\n// ── Predicate matching ────────────────────────────────────────────────\n\nfunction isSerializedRegex(v: unknown): v is SerializedRegex {\n return (\n typeof v === 'object' &&\n v !== null &&\n typeof (v as SerializedRegex).$regex === 'string' &&\n typeof (v as SerializedRegex).flags === 'string'\n )\n}\n\nfunction matchText(actual: string | undefined, matcher: TextMatcher): boolean {\n if (typeof actual !== 'string') return false\n if (typeof matcher === 'string') return actual === matcher\n if (matcher instanceof RegExp) return matcher.test(actual)\n return new RegExp(matcher.$regex, matcher.flags).test(actual)\n}\n\nfunction resolveToolName(span: ContractSpan): string | undefined {\n if (typeof span.toolName === 'string') return span.toolName\n const fromAttr = span.attributes?.['tool.name'] ?? span.attributes?.toolName\n if (typeof fromAttr === 'string') return fromAttr\n if (span.kind === 'tool' && typeof span.name === 'string') return span.name\n return undefined\n}\n\nfunction assertPredicate(value: unknown, where: string): asserts value is SpanPredicate {\n if (value === null || typeof value !== 'object') {\n throw new ValidationError(`${where}: predicate must be an object, got ${typeof value}`)\n }\n const p = value as SpanPredicate\n for (const field of ['name', 'tool'] as const) {\n const m = p[field]\n if (\n m !== undefined &&\n typeof m !== 'string' &&\n !(m instanceof RegExp) &&\n !isSerializedRegex(m)\n ) {\n throw new ValidationError(`${where}: \"${field}\" must be string | RegExp | SerializedRegex`)\n }\n }\n if (\n p.attr !== undefined &&\n (p.attr === null || typeof p.attr !== 'object' || Array.isArray(p.attr))\n ) {\n throw new ValidationError(`${where}: \"attr\" must be a plain object`)\n }\n if (p.requiresCustom && typeof p.custom !== 'function') {\n throw new ValidationError(\n `${where}: rule was built with a custom predicate function, which does not survive JSON ` +\n 'serialization — re-attach `custom` after deserializing or drop the rule',\n )\n }\n const hasAttr = p.attr !== undefined && Object.keys(p.attr).length > 0\n if (p.name === undefined && p.tool === undefined && !hasAttr && typeof p.custom !== 'function') {\n throw new ValidationError(\n `${where}: empty predicate would match every span — specify name, tool, attr, or custom`,\n )\n }\n}\n\n/** Test one span against one predicate. All specified fields must match. */\nexport function matchSpan(span: ContractSpan, predicate: SpanPredicate): boolean {\n assertPredicate(predicate, 'matchSpan')\n if (predicate.name !== undefined && !matchText(span.name, predicate.name)) return false\n if (predicate.tool !== undefined && !matchText(resolveToolName(span), predicate.tool))\n return false\n if (predicate.attr !== undefined) {\n for (const [key, expected] of Object.entries(predicate.attr)) {\n const actual = span.attributes?.[key]\n if (expected instanceof RegExp || isSerializedRegex(expected)) {\n if (!matchText(typeof actual === 'string' ? actual : undefined, expected as TextMatcher)) {\n return false\n }\n } else if (actual !== expected) {\n return false\n }\n }\n }\n if (predicate.custom !== undefined && !predicate.custom(span)) return false\n return true\n}\n\n// ── Builder ───────────────────────────────────────────────────────────\n\nfunction describeMatcher(m: TextMatcher): string {\n if (typeof m === 'string') return m\n if (m instanceof RegExp) return `/${m.source}/${m.flags}`\n return `/${m.$regex}/${m.flags}`\n}\n\nfunction describePredicate(p: SpanPredicate): string {\n const parts: string[] = []\n if (p.name !== undefined) parts.push(`name=${describeMatcher(p.name)}`)\n if (p.tool !== undefined) parts.push(`tool=${describeMatcher(p.tool)}`)\n if (p.attr !== undefined) {\n for (const [k, v] of Object.entries(p.attr)) {\n parts.push(\n `attr.${k}=${v instanceof RegExp || isSerializedRegex(v) ? describeMatcher(v as TextMatcher) : JSON.stringify(v)}`,\n )\n }\n }\n if (typeof p.custom === 'function') parts.push(`custom=${p.custom.name || 'fn'}`)\n return parts.join(',')\n}\n\nfunction normalizeMatcher(m: TextMatcher): string | SerializedRegex {\n return m instanceof RegExp ? { $regex: m.source, flags: m.flags } : m\n}\n\nfunction normalizePredicate(p: SpanPredicate, where: string): SpanPredicate {\n assertPredicate(p, where)\n const out: SpanPredicate = {}\n if (p.name !== undefined) out.name = normalizeMatcher(p.name)\n if (p.tool !== undefined) out.tool = normalizeMatcher(p.tool)\n if (p.attr !== undefined) {\n out.attr = Object.fromEntries(\n Object.entries(p.attr).map(([k, v]) => [k, v instanceof RegExp ? normalizeMatcher(v) : v]),\n )\n }\n if (typeof p.custom === 'function') {\n out.custom = p.custom\n out.requiresCustom = true\n }\n return out\n}\n\nexport class TraceContractBuilder {\n private readonly rules: ContractRule[] = []\n\n constructor(private readonly name: string) {}\n\n /** Every span in the trace must satisfy `p`. */\n always(p: SpanPredicate, label?: string): this {\n const np = normalizePredicate(p, `traceContract(\"${this.name}\").always`)\n return this.add({ kind: 'always', label: label ?? `always(${describePredicate(np)})`, p: np })\n }\n\n /** No span in the trace may satisfy `p`. */\n never(p: SpanPredicate, label?: string): this {\n const np = normalizePredicate(p, `traceContract(\"${this.name}\").never`)\n return this.add({ kind: 'never', label: label ?? `never(${describePredicate(np)})`, p: np })\n }\n\n /** At least one span in the trace must satisfy `p`. */\n eventually(p: SpanPredicate, label?: string): this {\n const np = normalizePredicate(p, `traceContract(\"${this.name}\").eventually`)\n return this.add({\n kind: 'eventually',\n label: label ?? `eventually(${describePredicate(np)})`,\n p: np,\n })\n }\n\n /** Every `b`-match must have a strictly earlier `a`-match. */\n precedes(a: SpanPredicate, b: SpanPredicate, label?: string): this {\n const na = normalizePredicate(a, `traceContract(\"${this.name}\").precedes (a)`)\n const nb = normalizePredicate(b, `traceContract(\"${this.name}\").precedes (b)`)\n return this.add({\n kind: 'precedes',\n label: label ?? `precedes(${describePredicate(na)} -> ${describePredicate(nb)})`,\n a: na,\n b: nb,\n })\n }\n\n /** Every `p`-match is a violation unless a strictly earlier `prior`-match exists. */\n neverUnless(p: SpanPredicate, prior: SpanPredicate, label?: string): this {\n const np = normalizePredicate(p, `traceContract(\"${this.name}\").neverUnless (p)`)\n const nprior = normalizePredicate(prior, `traceContract(\"${this.name}\").neverUnless (prior)`)\n return this.add({\n kind: 'neverUnless',\n label: label ?? `neverUnless(${describePredicate(np)} unless ${describePredicate(nprior)})`,\n p: np,\n prior: nprior,\n })\n }\n\n build(): TraceContract {\n if (this.rules.length === 0) {\n throw new ValidationError(\n `traceContract(\"${this.name}\").build(): no rules — an empty contract would vacuously pass`,\n )\n }\n return { name: this.name, rules: [...this.rules] }\n }\n\n private add(rule: ContractRule): this {\n // Labels key per-rule scores — auto-suffix duplicates so two identical\n // operator+predicate rules never collapse into one score entry.\n let label = rule.label\n let n = 2\n while (this.rules.some((r) => r.label === label)) {\n label = `${rule.label} #${n}`\n n += 1\n }\n this.rules.push({ ...rule, label })\n return this\n }\n}\n\nexport function traceContract(name: string): TraceContractBuilder {\n if (typeof name !== 'string' || name.length === 0) {\n throw new ValidationError('traceContract: name must be a non-empty string')\n }\n return new TraceContractBuilder(name)\n}\n\n// ── Evaluation ────────────────────────────────────────────────────────\n\nfunction assertContract(contract: TraceContract): void {\n if (typeof contract?.name !== 'string' || contract.name.length === 0) {\n throw new ValidationError('evaluateTraceContract: contract.name must be a non-empty string')\n }\n if (!Array.isArray(contract.rules) || contract.rules.length === 0) {\n throw new ValidationError(\n `evaluateTraceContract: contract \"${contract.name}\" has no rules — an empty contract would vacuously pass`,\n )\n }\n const seen = new Set<string>()\n for (const rule of contract.rules) {\n const where = `contract \"${contract.name}\" rule \"${rule?.label ?? '<unlabeled>'}\"`\n if (typeof rule?.label !== 'string' || rule.label.length === 0) {\n throw new ValidationError(`${where}: label must be a non-empty string`)\n }\n if (seen.has(rule.label)) {\n throw new ValidationError(`${where}: duplicate label would collapse per-rule scores`)\n }\n seen.add(rule.label)\n switch (rule.kind) {\n case 'always':\n case 'never':\n case 'eventually':\n assertPredicate(rule.p, `${where} (p)`)\n break\n case 'precedes':\n assertPredicate(rule.a, `${where} (a)`)\n assertPredicate(rule.b, `${where} (b)`)\n break\n case 'neverUnless':\n assertPredicate(rule.p, `${where} (p)`)\n assertPredicate(rule.prior, `${where} (prior)`)\n break\n default:\n throw new ValidationError(\n `${where}: unknown rule kind \"${String((rule as ContractRule).kind)}\"`,\n )\n }\n }\n}\n\n/**\n * Order spans for temporal evaluation: by `startedAt` when EVERY span carries\n * one (stable — ties keep array order), by array order when NONE does. Mixed\n * timestamps throw: neither time order nor array order is a trustworthy total\n * order over a partially-stamped sequence, and guessing would corrupt\n * `precedes` / `neverUnless` verdicts.\n */\nfunction orderSpans(spans: readonly ContractSpan[]): ContractSpan[] {\n const timed = spans.filter(\n (s) => typeof s.startedAt === 'number' && Number.isFinite(s.startedAt),\n ).length\n if (timed === spans.length) {\n return spans\n .map((span, i) => ({ span, i }))\n .sort((x, y) => x.span.startedAt! - y.span.startedAt! || x.i - y.i)\n .map((x) => x.span)\n }\n if (timed === 0) return [...spans]\n throw new ValidationError(\n `evaluateTraceContract: ${timed}/${spans.length} spans carry a finite startedAt — ` +\n 'mixed timestamps make ordering ambiguous; stamp every span or none',\n )\n}\n\nfunction spanRef(span: ContractSpan, index: number): string {\n return span.spanId ?? `#${index}`\n}\n\n// precedes(a, b) and neverUnless(p, prior) share one semantics: every\n// guarded-match must have a STRICTLY earlier guard-match. The guard flag\n// updates after the guarded check, so a span matching both cannot witness\n// itself.\nfunction checkGuarded(args: {\n label: string\n ordered: readonly ContractSpan[]\n guard: SpanPredicate\n guarded: SpanPredicate\n detail: (ref: string) => string\n}): ContractViolation[] {\n const out: ContractViolation[] = []\n let guardSeen = false\n for (let i = 0; i < args.ordered.length; i++) {\n const span = args.ordered[i]!\n if (!guardSeen && matchSpan(span, args.guarded)) {\n out.push({ rule: args.label, spanId: span.spanId, detail: args.detail(spanRef(span, i)) })\n }\n if (matchSpan(span, args.guard)) guardSeen = true\n }\n return out\n}\n\nfunction checkRule(rule: ContractRule, ordered: readonly ContractSpan[]): ContractViolation[] {\n switch (rule.kind) {\n case 'always': {\n const out: ContractViolation[] = []\n for (let i = 0; i < ordered.length; i++) {\n const span = ordered[i]!\n if (!matchSpan(span, rule.p!)) {\n out.push({\n rule: rule.label,\n spanId: span.spanId,\n detail: `span ${spanRef(span, i)} (\"${span.name ?? ''}\") fails always(${describePredicate(rule.p!)})`,\n })\n }\n }\n return out\n }\n case 'never': {\n const out: ContractViolation[] = []\n for (let i = 0; i < ordered.length; i++) {\n const span = ordered[i]!\n if (matchSpan(span, rule.p!)) {\n out.push({\n rule: rule.label,\n spanId: span.spanId,\n detail: `span ${spanRef(span, i)} (\"${span.name ?? ''}\") matches never(${describePredicate(rule.p!)})`,\n })\n }\n }\n return out\n }\n case 'eventually': {\n const hit = ordered.some((span) => matchSpan(span, rule.p!))\n return hit\n ? []\n : [\n {\n rule: rule.label,\n detail: `no span matches eventually(${describePredicate(rule.p!)}) over ${ordered.length} span(s)`,\n },\n ]\n }\n case 'precedes':\n return checkGuarded({\n label: rule.label,\n ordered,\n guard: rule.a!,\n guarded: rule.b!,\n detail: (ref) =>\n `span ${ref} matches ${describePredicate(rule.b!)} with no earlier ${describePredicate(rule.a!)} match`,\n })\n case 'neverUnless':\n return checkGuarded({\n label: rule.label,\n ordered,\n guard: rule.prior!,\n guarded: rule.p!,\n detail: (ref) =>\n `span ${ref} matches ${describePredicate(rule.p!)} with no earlier ${describePredicate(rule.prior!)} match`,\n })\n }\n}\n\n/**\n * Evaluate one contract over a span sequence. Pure and synchronous — works\n * on `Span[]` from a TraceStore, `ExportableSpan[]` from the otel-bridge\n * flattening, or any array satisfying `ContractSpan`.\n */\nexport function evaluateTraceContract(\n contract: TraceContract,\n spans: readonly ContractSpan[],\n): ContractVerdict {\n assertContract(contract)\n const ordered = orderSpans(spans)\n const scores: Record<string, number> = {}\n const violations: ContractViolation[] = []\n for (const rule of contract.rules) {\n const ruleViolations = checkRule(rule, ordered)\n scores[rule.label] = ruleViolations.length === 0 ? 1 : 0\n violations.push(...ruleViolations)\n }\n const ruleCount = contract.rules.length\n const passCount = Object.values(scores).filter((s) => s === 1).length\n // Steps the certificate rests on unverified: array ordering when no span\n // carries a timestamp, and any rule whose truth depends on a custom\n // predicate function that is not part of the serialized contract.\n const assumptions: string[] = []\n if (spans.length > 0 && ordered.every((s) => typeof s.startedAt !== 'number')) {\n assumptions.push('spans ordered by array position — no startedAt timestamps to order by')\n }\n for (const rule of contract.rules) {\n const predicates = [rule.p, rule.a, rule.b, rule.prior]\n if (predicates.some((p) => p !== undefined && typeof p.custom === 'function')) {\n assumptions.push(`rule '${rule.label}' rests on a custom predicate function`)\n }\n }\n return {\n contract: contract.name,\n valid: passCount === ruleCount,\n score: passCount / ruleCount,\n scores,\n violations,\n notes: `${passCount}/${ruleCount} rules passed`,\n certification: {\n strategy: 'invariant',\n checker: { name: 'agent-eval:trace-contracts', version: packageVersion() },\n assumptions,\n evidenceDigest: certificationEvidenceDigest({\n contract: contract.name,\n scores,\n violations,\n }),\n },\n }\n}\n\n/**\n * Evaluate many contracts over one span sequence. Throws on an empty\n * contract list — `allValid: true` over zero contracts is a silent pass.\n */\nexport function checkTraceContracts(\n spans: readonly ContractSpan[],\n contracts: readonly TraceContract[],\n): ContractCheckResult {\n if (contracts.length === 0) {\n throw new ValidationError(\n 'checkTraceContracts: empty contract list would vacuously pass — supply at least one contract',\n )\n }\n const verdicts = contracts.map((c) => evaluateTraceContract(c, spans))\n return { verdicts, allValid: verdicts.every((v) => v.valid) }\n}\n\n// ── Campaign judge adapter ────────────────────────────────────────────\n\nexport interface ContractJudgeOptions<TArtifact, TScenario extends Scenario = Scenario> {\n /**\n * Project the span sequence out of a cell's artifact. `JudgeConfig.score`\n * receives only `{ artifact, scenario, signal }` (src/campaign/types.ts) —\n * spans are NOT reachable generically — so the consumer supplies this\n * explicit extraction (e.g. dispatch writes spans into the artifact, or\n * closes over a per-cell TraceStore read).\n */\n spans: (input: { artifact: TArtifact; scenario: TScenario }) => readonly ContractSpan[]\n /** Judge name in campaign reports. Default 'trace-contracts'. */\n name?: string\n}\n\n/**\n * Adapt trace contracts to a campaign `JudgeConfig`. One judge dimension per\n * contract (key = contract name, value = its rule-pass fraction); composite\n * is the mean across contracts. Deterministic — no LLM call.\n */\nexport function contractJudge<TArtifact, TScenario extends Scenario = Scenario>(\n contracts: readonly TraceContract[],\n opts: ContractJudgeOptions<TArtifact, TScenario>,\n): JudgeConfig<TArtifact, TScenario> {\n if (contracts.length === 0) {\n throw new ValidationError('contractJudge: at least one contract required')\n }\n for (const c of contracts) assertContract(c)\n const names = new Set<string>()\n for (const c of contracts) {\n if (names.has(c.name)) {\n throw new ValidationError(\n `contractJudge: duplicate contract name \"${c.name}\" would collapse judge dimensions`,\n )\n }\n names.add(c.name)\n }\n if (typeof opts?.spans !== 'function') {\n throw new ValidationError('contractJudge: opts.spans extraction function is required')\n }\n const dimensions: JudgeDimension[] = contracts.map((c) => ({\n key: c.name,\n description: c.rules.map((r) => r.label).join('; '),\n }))\n return {\n name: opts.name ?? 'trace-contracts',\n dimensions,\n score({ artifact, scenario }) {\n const spans = opts.spans({ artifact, scenario })\n if (!Array.isArray(spans)) {\n throw new ValidationError(\n `contractJudge: spans() must return a span array, got ${typeof spans}`,\n )\n }\n const { verdicts } = checkTraceContracts(spans, contracts)\n const dims: Record<string, number> = {}\n const violations: ContractViolation[] = []\n for (const v of verdicts) {\n dims[v.contract] = v.score\n violations.push(...v.violations)\n }\n const composite = verdicts.reduce((acc, v) => acc + v.score, 0) / verdicts.length\n return {\n dimensions: dims,\n composite,\n notes:\n violations.length === 0\n ? 'all trace contracts satisfied'\n : violations\n .slice(0, 8)\n .map((x) => `${x.rule}: ${x.detail}`)\n .join('\\n'),\n }\n },\n }\n}\n","/**\n * Active learning — agent-as-scenario-author.\n *\n * Analyzes an existing Dataset + trace corpus for coverage gaps and\n * weak spots, returns a prioritized list of *synthesis targets*:\n * (gap description, existing-neighbor examples, suggested direction).\n *\n * Does NOT call an LLM itself — the proposer agent is caller-supplied.\n * This module's job is to identify WHERE new scenarios would compound\n * the most information, not to author them.\n *\n * Gaps we detect:\n * - dimensions with high score variance (unstable, need more data)\n * - dimensions with low coverage count (undersampled)\n * - failure classes with clusters (systematic weakness)\n * - difficulty bins with no coverage\n */\n\nimport type { Dataset, DatasetScenario } from './dataset'\nimport { classifyFailure } from './failure-taxonomy'\nimport type { Run } from './trace/schema'\nimport type { TraceStore } from './trace/store'\n\nexport type SynthesisReason =\n | 'high-variance'\n | 'undersampled'\n | 'failure-cluster'\n | 'difficulty-gap'\n\nexport interface SynthesisTarget {\n reason: SynthesisReason\n description: string\n /** Existing scenarios that are closest to the gap; caller feeds these to\n * their LLM proposer as few-shot examples. */\n neighbors: DatasetScenario[]\n /** Suggested direction — e.g. \"harder variants\", \"edge cases of X\", \"failure class Y\". */\n direction: string\n /** Priority score — higher = more information-dense gap. 0..1. */\n priority: number\n}\n\nexport interface ActiveLearningOptions {\n /** Minimum scenarios per difficulty band to count as \"covered\". */\n minPerBand?: number\n /** Variance threshold above which a scenario's dimension is \"unstable\". */\n varianceThreshold?: number\n /** Max synthesis targets returned. */\n topK?: number\n}\n\nexport async function proposeSynthesisTargets(\n dataset: Dataset,\n traceStore: TraceStore,\n options: ActiveLearningOptions = {},\n): Promise<SynthesisTarget[]> {\n const minPerBand = options.minPerBand ?? 5\n const varianceThreshold = options.varianceThreshold ?? 0.05\n const topK = options.topK ?? 10\n const scenarios = dataset.all()\n\n const targets: SynthesisTarget[] = []\n\n // 1. Difficulty coverage gaps\n const BANDS: Array<DatasetScenario['difficulty']> = ['easy', 'medium', 'hard', 'extreme']\n for (const band of BANDS) {\n const count = scenarios.filter((s) => s.difficulty === band).length\n if (count < minPerBand) {\n const neighbors = scenarios.filter((s) => s.difficulty === band).slice(0, 3)\n targets.push({\n reason: 'difficulty-gap',\n description: `difficulty=\"${band}\" has ${count} scenario(s) — below minimum ${minPerBand}`,\n neighbors: [...neighbors],\n direction: `create more \"${band}\" scenarios; reuse domain but shift complexity`,\n priority: Math.max(0, 1 - count / minPerBand),\n })\n }\n }\n\n // 2. Undersampled scenarios (few runs per scenario)\n const runs = await traceStore.listRuns()\n const runCountByScenario = new Map<string, number>()\n for (const r of runs) {\n runCountByScenario.set(r.scenarioId, (runCountByScenario.get(r.scenarioId) ?? 0) + 1)\n }\n const runCounts = [...runCountByScenario.values()]\n const p25 = runCounts.length > 0 ? quantile(runCounts, 0.25) : 0\n for (const s of scenarios) {\n const count = runCountByScenario.get(s.id) ?? 0\n if (count <= p25 && count < 3) {\n targets.push({\n reason: 'undersampled',\n description: `scenario \"${s.id}\" has only ${count} run(s)`,\n neighbors: [s],\n direction: `create near-duplicates of \"${s.id}\" to stabilize its mean`,\n priority: Math.max(0, 1 - count / 3) * 0.7,\n })\n }\n }\n\n // 3. High-variance scenarios (same scenario scored inconsistently)\n for (const s of scenarios) {\n const sRuns = runs.filter((r) => r.scenarioId === s.id)\n const scores = sRuns\n .map((r) => r.outcome?.score)\n .filter((x): x is number => typeof x === 'number')\n if (scores.length < 3) continue\n const mean = scores.reduce((a, b) => a + b, 0) / scores.length\n const variance = scores.reduce((a, b) => a + (b - mean) ** 2, 0) / scores.length\n if (variance > varianceThreshold) {\n targets.push({\n reason: 'high-variance',\n description: `scenario \"${s.id}\" has unstable scoring (variance ${variance.toFixed(3)})`,\n neighbors: [s],\n direction: `disambiguate the scenario description — current wording admits too many valid interpretations`,\n priority: Math.min(1, variance * 5),\n })\n }\n }\n\n // 4. Failure-class clusters — run classifier across the corpus\n const failureByClass = new Map<string, Run[]>()\n for (const run of runs) {\n if (run.outcome?.pass === true) continue\n const spans = await traceStore.spans({ runId: run.runId })\n const events = await traceStore.events({ runId: run.runId })\n const { failureClass } = classifyFailure({ run, spans, events })\n if (failureClass === 'success' || failureClass === 'unknown') continue\n const arr = failureByClass.get(failureClass) ?? []\n arr.push(run)\n failureByClass.set(failureClass, arr)\n }\n for (const [cls, runs] of failureByClass) {\n if (runs.length < 3) continue\n const affectedScenarios = [...new Set(runs.map((r) => r.scenarioId))]\n const neighbors = scenarios.filter((s) => affectedScenarios.includes(s.id)).slice(0, 3)\n targets.push({\n reason: 'failure-cluster',\n description: `failure class \"${cls}\" observed ${runs.length}× across ${affectedScenarios.length} scenario(s)`,\n neighbors,\n direction: `create scenarios that exercise \"${cls}\" recovery — currently a systematic weakness`,\n priority: Math.min(1, runs.length / 10),\n })\n }\n\n return targets.sort((a, b) => b.priority - a.priority).slice(0, topK)\n}\n\nfunction quantile(xs: number[], p: number): number {\n const sorted = [...xs].sort((a, b) => a - b)\n const idx = p * (sorted.length - 1)\n const lo = Math.floor(idx)\n const hi = Math.ceil(idx)\n return sorted[lo]! + (sorted[hi]! - sorted[lo]!) * (idx - lo)\n}\n","/**\n * One-shot deprecation warnings. A deprecated surface warns the FIRST time it\n * is used in a process — loud enough to be seen, quiet enough not to flood a\n * matrix run that constructs it per cell.\n */\n\nconst warned = new Set<string>()\n\n/** Emit `message` on console.warn once per process per `key`. */\nexport function warnDeprecatedOnce(key: string, message: string): void {\n if (warned.has(key)) return\n warned.add(key)\n console.warn(`[agent-eval deprecation] ${message}`)\n}\n\n/** Test seam: forget prior warnings so once-semantics can be asserted. */\nexport function resetDeprecationWarnings(): void {\n warned.clear()\n}\n","import { warnDeprecatedOnce } from './deprecation'\nimport type { CheckResult, ProductClientConfig, RouteMap, TestResult } from './types'\n\nconst DEFAULT_REQUEST_TIMEOUT_MS = 30_000\n\n/**\n * ProductClient — configurable HTTP client for exercising any agent's APIs.\n *\n * Routes are config, not hardcoded. Each agent provides its own RouteMap.\n *\n * @deprecated A one-product REST client does not belong in the generic\n * substrate. Moves to the product repo in the next major\n * (tangle-network/agent-runtime#694); vendor it if you construct it directly.\n */\nexport class ProductClient {\n private baseUrl: string\n private routes: RouteMap\n private cookies: string = ''\n private timeoutMs: number\n\n constructor(config: ProductClientConfig) {\n warnDeprecatedOnce(\n 'ProductClient',\n 'ProductClient is deprecated and moves to the product repo in the next major (tangle-network/agent-runtime#694).',\n )\n this.baseUrl = config.baseUrl.replace(/\\/+$/, '')\n this.routes = config.routes\n this.timeoutMs = config.timeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS\n }\n\n private route(name: keyof RouteMap): string {\n const path = this.routes[name]\n if (!path) throw new Error(`Route \"${name}\" not configured`)\n return path\n }\n\n /**\n * Single HTTP boundary for every JSON request. Aborts after `timeoutMs`,\n * checks `res.ok` BEFORE parsing, and throws `${method} ${path} failed:\n * HTTP ${status} — ${body}` on a non-ok response so a 4xx/5xx error body\n * can never be parsed as a success shape. Callers inspect the resolved\n * value only after a successful return.\n */\n private async request(\n method: string,\n path: string,\n body?: Record<string, unknown>,\n ): Promise<Record<string, unknown>> {\n const controller = new AbortController()\n const timeout = setTimeout(() => controller.abort(), this.timeoutMs)\n let res: Response\n try {\n res = await fetch(`${this.baseUrl}${path}`, {\n method,\n headers: {\n ...(body ? { 'Content-Type': 'application/json' } : {}),\n Origin: this.baseUrl,\n Cookie: this.cookies,\n },\n ...(body ? { body: JSON.stringify(body) } : {}),\n signal: controller.signal,\n })\n } finally {\n clearTimeout(timeout)\n }\n if (!res.ok) {\n const text = await res.text().catch(() => '')\n throw new Error(`${method} ${path} failed: HTTP ${res.status} — ${text.slice(0, 500)}`)\n }\n return res.json() as Promise<Record<string, unknown>>\n }\n\n /**\n * Read a required collection field. A missing/non-array field is a contract\n * violation (wrong route, drift, partial body) — surface it loud instead of\n * masking it as a healthy empty set. A genuinely empty `[]` passes through.\n */\n private requireArray<T>(res: Record<string, unknown>, field: string): T[] {\n const value = res[field]\n if (!Array.isArray(value)) {\n throw new Error(\n `Response missing array field \"${field}\" (got ${typeof value}: ${JSON.stringify(value)?.slice(0, 200)})`,\n )\n }\n return value as T[]\n }\n\n async signup(name: string, email: string, password: string): Promise<{ userId: string }> {\n const res = await this.post(this.route('signup'), { name, email, password })\n const user = res.user as Record<string, unknown> | undefined\n if (!user?.id) throw new Error(`Signup failed: ${JSON.stringify(res)}`)\n return { userId: user.id as string }\n }\n\n async login(email: string, password: string): Promise<void> {\n const res = await fetch(`${this.baseUrl}${this.route('login')}`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', Origin: this.baseUrl },\n body: JSON.stringify({ email, password }),\n redirect: 'manual',\n })\n const setCookie = res.headers.get('set-cookie')\n if (setCookie) {\n this.cookies = setCookie.split(';')[0] ?? ''\n }\n const body = (await res.json()) as Record<string, unknown>\n if (!body.user) throw new Error(`Login failed: ${JSON.stringify(body)}`)\n }\n\n async createWorkspace(name: string, type = 'project'): Promise<string> {\n const res = await this.post(this.route('workspaces'), { name, type })\n const ws = res.workspace as Record<string, unknown> | undefined\n if (!ws?.id) throw new Error(`Workspace creation failed: ${JSON.stringify(res)}`)\n return ws.id as string\n }\n\n async createThread(workspaceId: string): Promise<string> {\n const res = await this.post(this.route('threads'), { workspaceId })\n const thread = res.thread as Record<string, unknown> | undefined\n if (!thread?.id) throw new Error(`Thread creation failed: ${JSON.stringify(res)}`)\n return thread.id as string\n }\n\n async chat(\n workspaceId: string,\n threadId: string,\n content: string,\n _opts?: { blockPatterns?: RegExp[] },\n ): Promise<{ text: string; blocks: { type: string; title: string }[] }> {\n const res = await fetch(`${this.baseUrl}${this.route('chat')}`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Origin: this.baseUrl,\n Cookie: this.cookies,\n },\n body: JSON.stringify({ workspaceId, threadId, content }),\n })\n\n if (!res.ok || !res.body) throw new Error(`Chat failed: ${res.status}`)\n\n // Parse NDJSON stream\n const reader = res.body.getReader()\n const decoder = new TextDecoder()\n let buf = ''\n let text = ''\n const blocks: { type: string; title: string }[] = []\n\n while (true) {\n const { done, value } = await reader.read()\n if (done) break\n buf += decoder.decode(value, { stream: true })\n const lines = buf.split('\\n')\n buf = lines.pop() ?? ''\n for (const line of lines) {\n if (!line.trim()) continue\n try {\n const event = JSON.parse(line) as { type?: string; data?: { delta?: string } }\n if (event.type === 'message.part.updated' && event.data?.delta) {\n text += event.data.delta\n }\n } catch {\n /* skip non-JSON lines */\n }\n }\n }\n\n // Extract :::blocks from text\n const blockRe = /:::(\\w+)\\s*\\n([\\s\\S]*?)\\n\\s*:::/g\n let match: RegExpExecArray | null = blockRe.exec(text)\n while (match !== null) {\n const fields: Record<string, string> = {}\n for (const line of match[2]!.split('\\n')) {\n const idx = line.indexOf(':')\n if (idx > 0) fields[line.slice(0, idx).trim()] = line.slice(idx + 1).trim()\n }\n blocks.push({ type: match[1]!, title: fields.title ?? '' })\n match = blockRe.exec(text)\n }\n\n return { text, blocks }\n }\n\n async getTasks(\n workspaceId: string,\n ): Promise<{ id: string; title: string; status: string; priority: string }[]> {\n const res = await this.get(`${this.route('tasks')}?workspaceId=${workspaceId}`)\n return this.requireArray<{ id: string; title: string; status: string; priority: string }>(\n res,\n 'tasks',\n )\n }\n\n async getEvents(workspaceId: string): Promise<{ id: string; title: string; type: string }[]> {\n const res = await this.get(`${this.route('events')}?workspaceId=${workspaceId}`)\n return this.requireArray<{ id: string; title: string; type: string }>(res, 'events')\n }\n\n async getApprovals(\n workspaceId: string,\n ): Promise<{ id: string; title: string; status: string; type: string }[]> {\n const res = await this.get(`${this.route('approvals')}?workspaceId=${workspaceId}`)\n return this.requireArray<{ id: string; title: string; status: string; type: string }>(\n res,\n 'actions',\n )\n }\n\n async getVaultTree(workspaceId: string): Promise<string[]> {\n const res = await this.get(`${this.route('vault')}?workspaceId=${workspaceId}`)\n const paths: string[] = []\n function extract(nodes: unknown[]) {\n for (const n of nodes) {\n const node = n as { path?: string; type?: string; children?: unknown[] }\n if (node.type === 'file' && node.path) paths.push(node.path)\n if (node.children) extract(node.children)\n }\n }\n extract(this.requireArray<unknown>(res, 'tree'))\n return paths\n }\n\n async approveAction(workspaceId: string, id: string): Promise<void> {\n await this.patch(this.route('approvals'), { workspaceId, id, status: 'approved' })\n }\n\n async rejectAction(workspaceId: string, id: string, reason: string): Promise<void> {\n await this.patch(this.route('approvals'), { workspaceId, id, status: 'rejected', reason })\n }\n\n async getGenerations(\n workspaceId: string,\n ): Promise<{ id: string; type: string; prompt: string }[]> {\n const res = await this.get(`${this.route('generations')}?workspaceId=${workspaceId}`)\n return this.requireArray<{ id: string; type: string; prompt: string }>(res, 'generations')\n }\n\n /** Generic GET for custom routes */\n async get(path: string): Promise<Record<string, unknown>> {\n return this.request('GET', path)\n }\n\n /** Generic POST for custom routes */\n async post(path: string, body: Record<string, unknown>): Promise<Record<string, unknown>> {\n return this.request('POST', path, body)\n }\n\n /** Generic PATCH for custom routes */\n async patch(path: string, body: Record<string, unknown>): Promise<Record<string, unknown>> {\n return this.request('PATCH', path, body)\n }\n}\n\n/**\n * Run a full e2e workflow test against a live product.\n *\n * The `workflow` callback receives a ProductClient and returns CheckResults.\n * This is the generic harness — each agent defines its own workflow steps.\n */\nexport async function runE2EWorkflow(\n client: ProductClient,\n name: string,\n workflow: (client: ProductClient) => Promise<CheckResult[]>,\n): Promise<TestResult> {\n const start = Date.now()\n const checks: CheckResult[] = []\n\n try {\n const results = await workflow(client)\n checks.push(...results)\n } catch (err) {\n checks.push({\n name: 'fatal_error',\n passed: false,\n expected: 'no crash',\n actual: err instanceof Error ? err.message : String(err),\n })\n }\n\n return {\n name,\n passed: checks.every((c) => c.passed),\n duration: Date.now() - start,\n detail: `${checks.filter((c) => c.passed).length}/${checks.length} checks passed`,\n checks,\n }\n}\n","/**\n * CommandRunner — abstract subprocess execution surface.\n *\n * Layers in a {@link MultiLayerVerifier} that need to invoke external\n * tools (compilers, test runners, package managers) call out via this\n * interface rather than directly using `child_process`. Two reasons:\n *\n * 1. **Sandbox interchangeability.** A run that targets a sandbox box\n * (via SDK-specific Box.exec) and a run that targets the host both\n * satisfy this same contract. The harness doesn't care which.\n * 2. **Testability.** Tests inject a fake runner and assert on calls\n * without spawning real subprocesses.\n *\n * agent-eval ships only the local implementation (host-process). Sandbox\n * implementations live with their consumer because they depend on\n * SDK-specific Box / Sandbox types that don't belong in this package.\n */\n\nimport { spawnSync } from 'node:child_process'\nimport {\n accessSync,\n existsSync,\n constants as fsConstants,\n readdirSync,\n readFileSync,\n statSync,\n} from 'node:fs'\nimport { delimiter, join } from 'node:path'\n\n// ─── Types ──────────────────────────────────────────────────────────────\n\nexport interface RunCommandInput {\n /** Executable name, looked up via PATH unless absolute. */\n cmd: string\n /** Argument vector, NOT shell-interpolated. Each element passed to argv. */\n argv: string[]\n /** Working directory. Defaults to runner's notion of cwd if omitted. */\n cwd?: string\n /**\n * Wall-clock cap in ms. The runner SHOULD return `timedOut: true` when\n * exceeded; callers MAY treat status null + timedOut as \"killed.\"\n */\n capMs?: number\n /** Env overrides merged on top of the runner's base environment. */\n env?: Record<string, string>\n /** Optional stdin payload. */\n stdin?: string\n}\n\nexport interface RunCommandResult {\n /** Exit code, or null when the process couldn't start / was killed. */\n status: number | null\n stdout: string\n stderr: string\n durationMs: number\n timedOut: boolean\n /** Non-fatal runner-side error (binary missing, signal, etc.). */\n runnerError?: string\n}\n\nexport interface DirEntry {\n name: string\n isDirectory: boolean\n isFile: boolean\n /** File size in bytes. `null` for directories (not stat'd). */\n sizeBytes: number | null\n}\n\nexport interface CommandRunner {\n /** Identifier for telemetry + logs. Open-ended literal-union for new runners. */\n readonly name: string\n /** Execute a command in the runner's environment. */\n run(input: RunCommandInput): Promise<RunCommandResult>\n /** True iff `<name>` resolves on the runner's PATH. */\n hasBin(name: string): Promise<boolean>\n /** True iff the given path exists in the runner's filesystem. */\n fileExists(path: string): Promise<boolean>\n /** Read a file. Returns `null` if missing or unreadable. */\n readFile(path: string): Promise<string | null>\n /** List a directory. Returns `[]` if unreadable / missing. */\n readDir(path: string): Promise<DirEntry[]>\n}\n\n// ─── Local runner ───────────────────────────────────────────────────────\n\n/**\n * Host-process runner. Uses node:child_process spawnSync (synchronous\n * under the hood — wrapped in a Promise to satisfy the interface). For\n * very long-running commands consider an async-spawn variant; this\n * shape matches VB's existing behavior and is fine for build/test/lint\n * subprocesses that finish in seconds-to-minutes.\n */\nexport const localCommandRunner: CommandRunner = {\n name: 'local',\n async run(input: RunCommandInput): Promise<RunCommandResult> {\n const start = Date.now()\n const res = spawnSync(input.cmd, input.argv, {\n cwd: input.cwd,\n encoding: 'utf8',\n timeout: input.capMs,\n env: { ...process.env, CI: '1', ...(input.env ?? {}) },\n input: input.stdin,\n })\n const durationMs = Date.now() - start\n const timedOut = !!(\n res.error &&\n 'code' in res.error &&\n (res.error as NodeJS.ErrnoException).code === 'ETIMEDOUT'\n )\n return {\n status: res.status ?? null,\n stdout: (res.stdout ?? '').toString(),\n stderr: (res.stderr ?? '').toString(),\n durationMs,\n timedOut,\n runnerError: res.error && !timedOut ? String(res.error.message ?? res.error) : undefined,\n }\n },\n async hasBin(name: string): Promise<boolean> {\n return resolveBinOnPath(name) !== null\n },\n async fileExists(path: string): Promise<boolean> {\n return existsSync(path)\n },\n async readFile(path: string): Promise<string | null> {\n try {\n return readFileSync(path, 'utf8')\n } catch (err) {\n // ENOENT is the only \"legitimately absent\" signal → null. Any other\n // errno (EACCES, EISDIR, EIO, …) is a real failure that must NOT\n // masquerade as \"file not present\" — surface it so callers don't\n // treat a permission/IO error as a missing artifact.\n if (isErrnoCode(err, 'ENOENT')) return null\n throw err\n }\n },\n async readDir(path: string): Promise<DirEntry[]> {\n let entries: string[]\n try {\n entries = readdirSync(path)\n } catch (err) {\n // Same ENOENT-vs-real-error split as readFile: a missing directory\n // is legitimately empty (→ []); EACCES/ENOTDIR/EIO must surface so\n // an unreadable directory isn't silently reported as having no files.\n if (isErrnoCode(err, 'ENOENT')) return []\n throw err\n }\n const out: DirEntry[] = []\n for (const name of entries) {\n try {\n const st = statSync(join(path, name))\n out.push({\n name,\n isDirectory: st.isDirectory(),\n isFile: st.isFile(),\n sizeBytes: st.isFile() ? st.size : null,\n })\n } catch (err) {\n // An entry that vanished between readdir and stat (TOCTOU) is a\n // benign race → skip. Any other errno surfaces.\n if (isErrnoCode(err, 'ENOENT')) continue\n throw err\n }\n }\n return out\n },\n}\n\nfunction isErrnoCode(err: unknown, code: NodeJS.ErrnoException['code']): boolean {\n return typeof err === 'object' && err !== null && (err as NodeJS.ErrnoException).code === code\n}\n\n/**\n * Resolve `name` to an executable absolute path using the runner's PATH,\n * or `null` if not found. Cross-platform: does not depend on `which`\n * (absent on Windows) or a `command -v` shell (absent on minimal\n * containers). On Windows, candidate extensions come from PATHEXT.\n *\n * Throws only on a non-ENOENT/EACCES filesystem error while probing a\n * candidate — those indicate a real IO fault, not \"binary absent.\"\n */\nfunction resolveBinOnPath(name: string): string | null {\n // An explicit path component means PATH lookup doesn't apply: probe directly.\n if (name.includes('/') || name.includes('\\\\')) {\n return isExecutable(name) ? name : null\n }\n const pathEnv = process.env.PATH ?? ''\n const dirs = pathEnv.split(delimiter).filter((d) => d.length > 0)\n const exts =\n process.platform === 'win32'\n ? (process.env.PATHEXT ?? '.COM;.EXE;.BAT;.CMD').split(';').filter((e) => e.length > 0)\n : ['']\n for (const dir of dirs) {\n for (const ext of exts) {\n const candidate = join(dir, name + ext)\n if (isExecutable(candidate)) return candidate\n }\n }\n return null\n}\n\nfunction isExecutable(path: string): boolean {\n try {\n // On win32 X_OK is a no-op; presence of the file (with a PATHEXT\n // extension) is the executability signal there.\n accessSync(path, process.platform === 'win32' ? fsConstants.F_OK : fsConstants.X_OK)\n return true\n } catch (err) {\n // Not found / not executable / not permitted → \"not a usable binary\n // here,\" keep scanning. A different errno (EIO, ELOOP, …) is a real\n // fault and must surface rather than silently yield a false negative.\n if (isErrnoCode(err, 'ENOENT') || isErrnoCode(err, 'EACCES') || isErrnoCode(err, 'ENOTDIR')) {\n return false\n }\n throw err\n }\n}\n","/**\n * Streaming detectors — the canonical, online failure-mode kernel.\n *\n * A `StreamingDetector` is a pure incremental reducer: fold one normalized step, get a signal the\n * moment a threshold trips (else null). The SAME kernel runs in two places, so the logic lives once:\n * - ONLINE, over a live agent pipe (a worker's tool-call stream) → raise a finding mid-run.\n * - INSIDE the control loop (`control-runtime`) → its `stopOn*` policies fold these detectors.\n *\n * Detectors are stateful but self-contained; `streak` is exposed for telemetry and `reset` clears it.\n * Fingerprinting is the CALLER's job — the control loop hashes state/action with `stableFingerprint`,\n * a tool-call pipe hashes args with `argHash` — so a detector stays agnostic to what it's watching.\n */\n\nimport type { FailureClass } from '../trace/schema'\n\nexport type DetectorSeverity = 'info' | 'warn' | 'critical'\n\n/** A normalized step a detector folds over. Fields are optional; each detector reads only what it\n * needs (repeated-action → `actionFingerprint`; no-progress → `stateFingerprint` + `score`;\n * error-streak → `status`). */\nexport interface DetectorEvent {\n /** Fingerprint of the action/tool-call this step took (caller pre-hashes). */\n readonly actionFingerprint?: string\n /** Fingerprint of observable state AFTER this step. */\n readonly stateFingerprint?: string\n /** Score after this step (the score-flat half of no-progress). */\n readonly score?: number\n /** Whether this step errored. */\n readonly status?: 'ok' | 'error'\n /** Free-form label carried into the signal evidence (e.g. the tool name). */\n readonly label?: string\n}\n\nexport interface DetectorSignal {\n readonly detector: string\n readonly severity: DetectorSeverity\n readonly failureClass?: FailureClass\n readonly reason: string\n /** Consecutive matching steps at the moment the signal fired. */\n readonly streak: number\n readonly evidence?: Record<string, unknown>\n}\n\nexport interface StreamingDetector {\n readonly id: string\n /** Current streak (consecutive matching steps) — for telemetry/introspection between observes. */\n readonly streak: number\n /** Fold one event; return a signal when the threshold trips, else null. */\n observe(event: DetectorEvent): DetectorSignal | null\n /** Clear all state. */\n reset(): void\n}\n\nexport interface RepeatedActionOptions {\n /** Signal once the same action fingerprint repeats this many CONSECUTIVE steps (default 3).\n * `<= 0` disables the signal (the streak is still tracked, for telemetry). */\n readonly maxRepeated?: number\n readonly severity?: DetectorSeverity\n /** Failure class to stamp on the signal (default `tool_recovery_failure`). */\n readonly failureClass?: FailureClass\n}\n\n/** Same action fingerprint N consecutive steps = a stuck loop (the #1 long-horizon failure mode). */\nexport function repeatedActionDetector(opts: RepeatedActionOptions = {}): StreamingDetector {\n const max = opts.maxRepeated ?? 3\n const severity = opts.severity ?? 'warn'\n const failureClass: FailureClass = opts.failureClass ?? 'tool_recovery_failure'\n let last: string | undefined\n let streak = 0\n return {\n id: 'repeated-action',\n get streak() {\n return streak\n },\n observe(event) {\n const fp = event.actionFingerprint\n if (fp === undefined) return null\n streak = fp === last ? streak + 1 : 1\n last = fp\n if (max <= 0 || streak < max) return null\n return {\n detector: 'repeated-action',\n severity,\n failureClass,\n reason: `stuck: repeated same action for ${streak} step(s)`,\n streak,\n ...(event.label ? { evidence: { action: event.label } } : {}),\n }\n },\n reset() {\n last = undefined\n streak = 0\n },\n }\n}\n\nexport interface NoProgressOptions {\n /** Signal once state is unchanged AND score is flat for this many CONSECUTIVE steps (default 3).\n * `<= 0` disables the signal. */\n readonly maxNoProgress?: number\n /** Minimum |score change| that counts as progress (default 0.001). */\n readonly minScoreDelta?: number\n readonly severity?: DetectorSeverity\n readonly failureClass?: FailureClass\n}\n\n/** State + score unchanged across N steps = spinning wheels. Compares each step to the previous one,\n * so prime with the initial state (observe it once before the first real step) to detect on step 1. */\nexport function noProgressDetector(opts: NoProgressOptions = {}): StreamingDetector {\n const max = opts.maxNoProgress ?? 3\n const minScoreDelta = opts.minScoreDelta ?? 0.001\n const severity = opts.severity ?? 'warn'\n const failureClass: FailureClass = opts.failureClass ?? 'tool_recovery_failure'\n let lastState: string | undefined\n let lastScore: number | undefined\n let streak = 0\n return {\n id: 'no-progress',\n get streak() {\n return streak\n },\n observe(event) {\n const stateUnchanged = lastState !== undefined && lastState === event.stateFingerprint\n const scoreFlat = Math.abs((event.score ?? 0) - (lastScore ?? 0)) < minScoreDelta\n streak = stateUnchanged && scoreFlat ? streak + 1 : 0\n lastState = event.stateFingerprint\n lastScore = event.score\n if (max <= 0 || streak < max) return null\n return {\n detector: 'no-progress',\n severity,\n failureClass,\n reason: `stuck: no state/score progress for ${streak} step(s)`,\n streak,\n ...(event.label ? { evidence: { state: event.label } } : {}),\n }\n },\n reset() {\n lastState = undefined\n lastScore = undefined\n streak = 0\n },\n }\n}\n\nexport interface ErrorStreakOptions {\n /** Signal once this many CONSECUTIVE steps errored (default 3). `<= 0` disables. */\n readonly maxErrors?: number\n readonly severity?: DetectorSeverity\n readonly failureClass?: FailureClass\n}\n\n/** N consecutive tool errors = the worker is hammering a broken approach. */\nexport function errorStreakDetector(opts: ErrorStreakOptions = {}): StreamingDetector {\n const max = opts.maxErrors ?? 3\n const severity = opts.severity ?? 'warn'\n const failureClass: FailureClass = opts.failureClass ?? 'tool_recovery_failure'\n let streak = 0\n return {\n id: 'error-streak',\n get streak() {\n return streak\n },\n observe(event) {\n if (event.status === undefined) return null\n streak = event.status === 'error' ? streak + 1 : 0\n if (max <= 0 || streak < max) return null\n return {\n detector: 'error-streak',\n severity,\n failureClass,\n reason: `stuck: ${streak} consecutive errored step(s)`,\n streak,\n ...(event.label ? { evidence: { lastError: event.label } } : {}),\n }\n },\n reset() {\n streak = 0\n },\n }\n}\n\n/** Fold one event through many detectors at once; returns every signal that fired this step. The\n * natural shape for an online pipe watching with a whole panel of detectors. */\nexport function observeAll(\n detectors: ReadonlyArray<StreamingDetector>,\n event: DetectorEvent,\n): DetectorSignal[] {\n const signals: DetectorSignal[] = []\n for (const d of detectors) {\n const s = d.observe(event)\n if (s) signals.push(s)\n }\n return signals\n}\n","/**\n * Policy-based agent control runtime.\n *\n * This is the minimal reusable loop behind driver-agent patterns:\n *\n * observe state -> validate -> decide next action -> act -> observe -> ...\n *\n * It deliberately does not model named \"topologies\". Direct execution,\n * critic/revise, driver intervention, specialist calls, and human escalation\n * are all just actions chosen by the control policy.\n */\n\nimport { noProgressDetector, repeatedActionDetector } from './detectors'\nimport { type SpanHandle, TraceEmitter } from './trace/emitter'\nimport type { FailureClass } from './trace/schema'\nimport type { TraceStore } from './trace/store'\n\nexport type ControlSeverity = 'info' | 'warning' | 'error' | 'critical'\nexport type ControlActionFailureMode = 'continue' | 'stop'\n\nexport interface ControlEvalResult {\n /** Stable validator or judge id. */\n id: string\n /** Whether this check passed. */\n passed: boolean\n /** Optional normalized score. 1 = best, 0 = worst. */\n score?: number\n /** Objective validators should usually be \"error\" or \"critical\" when failed. */\n severity?: ControlSeverity\n /** Human-readable result. */\n detail?: string\n /** Small evidence string or pointer. Avoid large payloads. */\n evidence?: string\n /** True when the result came from deterministic state, not LLM judgment. */\n objective?: boolean\n /** Structured details for downstream control policies and reports. */\n metadata?: Record<string, unknown>\n}\n\nexport interface ControlBudget {\n maxSteps: number\n maxWallMs?: number\n maxCostUsd?: number\n}\n\nexport interface ControlStopPolicies<TState, TAction> {\n /**\n * Stop after N consecutive steps with no state fingerprint change and\n * less than `minScoreDelta` score movement. Disabled when omitted.\n */\n maxNoProgressSteps?: number\n /**\n * Stop after the same action fingerprint is selected N consecutive\n * times. Disabled when omitted.\n */\n maxRepeatedActions?: number\n /** Minimum score movement that counts as progress. Default 0.001. */\n minScoreDelta?: number\n /** Override the default JSON/string fingerprint for state comparisons. */\n stateFingerprint?: (state: TState) => string\n /** Override the default JSON/string fingerprint for repeated-action checks. */\n actionFingerprint?: (action: TAction) => string\n}\n\nexport interface ControlContext<\n TState,\n TAction,\n TActionResult,\n TEval extends ControlEvalResult = ControlEvalResult,\n> {\n intent: string\n state: TState\n evals: TEval[]\n history: ControlStep<TState, TAction, TActionResult, TEval>[]\n budget: ControlBudget\n stepIndex: number\n wallMs: number\n spentCostUsd: number\n remainingCostUsd?: number\n abortSignal: AbortSignal\n emitter?: TraceEmitter\n}\n\nexport type ControlDecision<TAction> =\n | {\n type: 'continue'\n action: TAction\n reason?: string\n }\n | {\n type: 'stop'\n reason: string\n pass?: boolean\n score?: number\n /** Canonical task-failure class when this stop represents a failed task. */\n failureClass?: FailureClass\n }\n\nexport interface StopDecision {\n stop: boolean\n pass: boolean\n reason: string\n score?: number\n failureClass?: FailureClass\n}\n\nexport interface ControlActionOutcome<TActionResult> {\n ok: boolean\n result?: TActionResult\n error?: string\n costUsd?: number\n durationMs: number\n}\n\nexport interface ControlRuntimeError {\n phase: 'observe' | 'validate' | 'decide' | 'act' | 'stop-policy' | 'on-step' | 'trace'\n stepIndex: number\n message: string\n}\n\nexport interface ControlStep<\n TState,\n TAction,\n TActionResult,\n TEval extends ControlEvalResult = ControlEvalResult,\n> {\n index: number\n decision: ControlDecision<TAction>\n beforeState: TState\n afterState: TState\n evalsBefore: TEval[]\n evalsAfter: TEval[]\n actionOutcome?: ControlActionOutcome<TActionResult>\n startedAt: string\n endedAt: string\n}\n\nexport interface ControlRunResult<\n TState,\n TAction,\n TActionResult,\n TEval extends ControlEvalResult = ControlEvalResult,\n> {\n intent: string\n pass: boolean\n completed: boolean\n reason: string\n score?: number\n steps: ControlStep<TState, TAction, TActionResult, TEval>[]\n finalState: TState | undefined\n finalEvals: TEval[]\n wallMs: number\n spentCostUsd: number\n /** null when the run executed without a TraceEmitter wired (no run record was persisted). */\n runId: string | null\n failureClass?: FailureClass\n runtimeErrors: ControlRuntimeError[]\n stoppedBy: 'policy' | 'stop-policy' | 'budget' | 'abort' | 'runtime-error'\n}\n\nexport interface ControlRuntimeConfig<\n TState,\n TAction,\n TActionResult,\n TEval extends ControlEvalResult = ControlEvalResult,\n> {\n intent: string\n budget?: Partial<ControlBudget>\n signal?: AbortSignal\n /** Defaults to `continue`: action failures are recorded, then the policy gets another chance. */\n actionFailure?: ControlActionFailureMode\n /**\n * Extract cost from an action result. Used for `maxCostUsd` budget\n * enforcement and trace budget ledger emission.\n */\n getActionCostUsd?: (ctx: {\n action: TAction\n result: TActionResult\n state: TState\n evals: TEval[]\n history: ControlStep<TState, TAction, TActionResult, TEval>[]\n }) => number | undefined\n\n /** Read typed task/product state. Prefer structured state over transcript-only context. */\n observe: (ctx: {\n history: ControlStep<TState, TAction, TActionResult, TEval>[]\n abortSignal: AbortSignal\n }) => Promise<TState> | TState\n\n /** Objective validators first, subjective judges only where objective state is insufficient. */\n validate: (ctx: {\n intent: string\n state: TState\n history: ControlStep<TState, TAction, TActionResult, TEval>[]\n abortSignal: AbortSignal\n }) => Promise<TEval[]> | TEval[]\n\n /** Choose the next control action. Can call a worker, ask user, run critic, inspect state, or stop. */\n decide: (\n ctx: ControlContext<TState, TAction, TActionResult, TEval>,\n ) => Promise<ControlDecision<TAction>> | ControlDecision<TAction>\n\n /** Execute the action selected by the policy. */\n act: (\n action: TAction,\n ctx: ControlContext<TState, TAction, TActionResult, TEval>,\n ) => Promise<TActionResult> | TActionResult\n\n /** Final stopping policy. Called before decide and after each action. */\n shouldStop?: (\n ctx: ControlContext<TState, TAction, TActionResult, TEval>,\n ) => Promise<StopDecision> | StopDecision\n\n /** Optional hook for tracing or live progress updates. */\n onStep?: (step: ControlStep<TState, TAction, TActionResult, TEval>) => Promise<void> | void\n\n /** Optional generic stuck-loop policies. Custom `shouldStop` still runs first. */\n stopPolicies?: ControlStopPolicies<TState, TAction>\n\n /** Optional trace sink. Emits one run plus one span per control step. */\n store?: TraceStore\n scenarioId?: string\n projectId?: string\n variantId?: string\n}\n\nconst DEFAULT_BUDGET: ControlBudget = {\n maxSteps: 8,\n maxWallMs: 5 * 60 * 1000,\n}\n\nexport async function runAgentControlLoop<\n TState,\n TAction,\n TActionResult,\n TEval extends ControlEvalResult = ControlEvalResult,\n>(\n config: ControlRuntimeConfig<TState, TAction, TActionResult, TEval>,\n): Promise<ControlRunResult<TState, TAction, TActionResult, TEval>> {\n const budget = normalizeBudget(config.budget)\n const actionFailure = config.actionFailure ?? 'continue'\n const controller = new AbortController()\n const upstreamAbort = () => controller.abort(config.signal?.reason)\n if (config.signal) {\n if (config.signal.aborted) controller.abort(config.signal.reason)\n else config.signal.addEventListener('abort', upstreamAbort, { once: true })\n }\n\n const started = Date.now()\n const wallTimer = budget.maxWallMs\n ? setTimeout(\n () => controller.abort(new Error('control runtime wall timeout')),\n budget.maxWallMs,\n )\n : undefined\n const history: ControlStep<TState, TAction, TActionResult, TEval>[] = []\n const emitter = config.store ? new TraceEmitter(config.store) : undefined\n let spentCostUsd = 0\n const runtimeErrors: ControlRuntimeError[] = []\n // The stuck-detection kernels (shared with the online detectors). Thresholds 0 = disabled; the\n // streak is still tracked for telemetry. Both stops report `tool_recovery_failure`.\n const repeatedDetector = repeatedActionDetector({\n maxRepeated: config.stopPolicies?.maxRepeatedActions ?? 0,\n })\n const progressDetector = noProgressDetector({\n maxNoProgress: config.stopPolicies?.maxNoProgressSteps ?? 0,\n minScoreDelta: config.stopPolicies?.minScoreDelta ?? 0.001,\n })\n\n try {\n if (emitter) {\n await runTrace(runtimeErrors, 0, () =>\n emitter.startRun({\n scenarioId: config.scenarioId ?? 'agent-control-loop',\n projectId: config.projectId,\n variantId: config.variantId,\n layer: 'meta',\n tags: {\n intent: config.intent.slice(0, 120),\n maxSteps: String(budget.maxSteps),\n ...(budget.maxCostUsd !== undefined ? { maxCostUsd: String(budget.maxCostUsd) } : {}),\n },\n }),\n )\n }\n\n let state: TState\n let evals: TEval[]\n try {\n state = await config.observe({ history, abortSignal: controller.signal })\n } catch (err) {\n const error = runtimeError('observe', 0, err)\n runtimeErrors.push(error)\n return finish(emitter, {\n intent: config.intent,\n pass: false,\n completed: false,\n reason: error.message,\n steps: history,\n finalState: undefined,\n finalEvals: [],\n wallMs: Date.now() - started,\n spentCostUsd,\n runId: emitter?.runId ?? null,\n failureClass: 'unknown',\n runtimeErrors,\n stoppedBy: 'runtime-error',\n })\n }\n try {\n evals = await config.validate({\n intent: config.intent,\n state,\n history,\n abortSignal: controller.signal,\n })\n await recordEvalSpans(emitter, evals, 'initial', runtimeErrors, 0)\n } catch (err) {\n const error = runtimeError('validate', 0, err)\n runtimeErrors.push(error)\n return finish(emitter, {\n intent: config.intent,\n pass: false,\n completed: false,\n reason: error.message,\n steps: history,\n finalState: state,\n finalEvals: [],\n wallMs: Date.now() - started,\n spentCostUsd,\n runId: emitter?.runId ?? null,\n failureClass: 'unknown',\n runtimeErrors,\n stoppedBy: 'runtime-error',\n })\n }\n // Prime the no-progress detector with the initial state + score so step 0 can already detect a\n // no-op (mirrors the pre-loop fingerprint baseline). The priming observe never signals (streak 0).\n progressDetector.observe({\n stateFingerprint: fingerprintState(state, config.stopPolicies),\n score: averageScore(evals),\n })\n\n for (let stepIndex = 0; stepIndex < budget.maxSteps; stepIndex++) {\n if (controller.signal.aborted) {\n return finish(emitter, {\n intent: config.intent,\n pass: false,\n completed: false,\n reason: abortReason(controller.signal),\n score: undefined,\n steps: history,\n finalState: state,\n finalEvals: evals,\n wallMs: Date.now() - started,\n spentCostUsd,\n runId: emitter?.runId ?? null,\n failureClass: 'timeout',\n runtimeErrors,\n stoppedBy: 'abort',\n })\n }\n\n const budgetStop = budgetStopDecision(budget, spentCostUsd)\n if (budgetStop.stop) {\n return finish(emitter, {\n intent: config.intent,\n pass: false,\n completed: false,\n reason: budgetStop.reason,\n score: averageScore(evals),\n steps: history,\n finalState: state,\n finalEvals: evals,\n wallMs: Date.now() - started,\n spentCostUsd,\n runId: emitter?.runId ?? null,\n failureClass: 'budget_exceeded',\n runtimeErrors,\n stoppedBy: 'budget',\n })\n }\n\n const ctx = makeContext(\n config.intent,\n state,\n evals,\n history,\n budget,\n stepIndex,\n started,\n spentCostUsd,\n controller.signal,\n emitter,\n )\n let stop: StopDecision\n try {\n stop = config.shouldStop ? await config.shouldStop(ctx) : defaultStopDecision(evals)\n } catch (err) {\n runtimeErrors.push(runtimeError('stop-policy', stepIndex, err))\n return finish(emitter, {\n intent: config.intent,\n pass: false,\n completed: false,\n reason: runtimeErrors[runtimeErrors.length - 1]!.message,\n score: averageScore(evals),\n steps: history,\n finalState: state,\n finalEvals: evals,\n wallMs: Date.now() - started,\n spentCostUsd,\n runId: emitter?.runId ?? null,\n failureClass: 'unknown',\n runtimeErrors,\n stoppedBy: 'runtime-error',\n })\n }\n if (stop.stop) {\n return finish(emitter, {\n intent: config.intent,\n pass: stop.pass,\n completed: true,\n reason: stop.reason,\n score: stop.score,\n steps: history,\n finalState: state,\n finalEvals: evals,\n wallMs: Date.now() - started,\n spentCostUsd,\n runId: emitter?.runId ?? null,\n failureClass: stop.failureClass,\n runtimeErrors,\n stoppedBy: 'stop-policy',\n })\n }\n\n let decision: ControlDecision<TAction>\n try {\n decision = await config.decide(ctx)\n } catch (err) {\n runtimeErrors.push(runtimeError('decide', stepIndex, err))\n return finish(emitter, {\n intent: config.intent,\n pass: false,\n completed: false,\n reason: runtimeErrors[runtimeErrors.length - 1]!.message,\n score: averageScore(evals),\n steps: history,\n finalState: state,\n finalEvals: evals,\n wallMs: Date.now() - started,\n spentCostUsd,\n runId: emitter?.runId ?? null,\n failureClass: 'unknown',\n runtimeErrors,\n stoppedBy: 'runtime-error',\n })\n }\n if (decision.type === 'stop') {\n const pass = decision.pass ?? false\n return finish(emitter, {\n intent: config.intent,\n pass,\n completed: true,\n reason: decision.reason,\n score: decision.score,\n steps: history,\n finalState: state,\n finalEvals: evals,\n wallMs: Date.now() - started,\n spentCostUsd,\n runId: emitter?.runId ?? null,\n failureClass: pass ? undefined : (decision.failureClass ?? 'unknown'),\n runtimeErrors,\n stoppedBy: 'policy',\n })\n }\n\n const actionFingerprint = fingerprintAction(decision.action, config.stopPolicies)\n const repeatedActionSignal = repeatedDetector.observe({ actionFingerprint })\n const repeatedActionStreak = repeatedDetector.streak\n if (repeatedActionSignal) {\n return finish(emitter, {\n intent: config.intent,\n pass: false,\n completed: true,\n reason: repeatedActionSignal.reason,\n score: averageScore(evals),\n steps: history,\n finalState: state,\n finalEvals: evals,\n wallMs: Date.now() - started,\n spentCostUsd,\n runId: emitter?.runId ?? null,\n failureClass: 'tool_recovery_failure',\n runtimeErrors,\n stoppedBy: 'stop-policy',\n })\n }\n\n const beforeState = state\n const evalsBefore = evals\n const scoreBefore = averageScore(evals)\n const actionStarted = Date.now()\n const stepHandle = emitter\n ? await runTrace(runtimeErrors, stepIndex, () =>\n emitter.tool({\n name: `control-step-${stepIndex}`,\n toolName: 'agent-control-action',\n args: decision.action,\n attributes: {\n decision: decision.reason ?? 'continue',\n repeatedActionStreak,\n },\n }),\n )\n : undefined\n let actionOutcome: ControlActionOutcome<TActionResult>\n try {\n const result = await config.act(decision.action, ctx)\n const rawCostUsd = config.getActionCostUsd?.({\n action: decision.action,\n result,\n state,\n evals,\n history,\n })\n const costUsd = normalizeActionCostUsd(rawCostUsd, runtimeErrors, stepIndex)\n if (costUsd !== undefined && Number.isFinite(costUsd) && costUsd > 0) {\n spentCostUsd += costUsd\n await recordCostBudget(\n emitter,\n budget,\n spentCostUsd,\n stepHandle,\n runtimeErrors,\n stepIndex,\n )\n }\n actionOutcome = {\n ok: true,\n result,\n ...(costUsd !== undefined ? { costUsd } : {}),\n durationMs: Date.now() - actionStarted,\n }\n } catch (err) {\n runtimeErrors.push(runtimeError('act', stepIndex, err))\n actionOutcome = {\n ok: false,\n error: runtimeErrors[runtimeErrors.length - 1]!.message,\n durationMs: Date.now() - actionStarted,\n }\n if (actionFailure === 'stop') {\n await runTrace(runtimeErrors, stepIndex, () =>\n stepHandle?.fail(actionOutcome.error ?? 'action failed'),\n )\n const step: ControlStep<TState, TAction, TActionResult, TEval> = {\n index: stepIndex,\n decision,\n beforeState,\n afterState: state,\n evalsBefore,\n evalsAfter: evals,\n actionOutcome,\n startedAt: new Date(actionStarted).toISOString(),\n endedAt: new Date().toISOString(),\n }\n history.push(step)\n await runOnStep(config.onStep, step, runtimeErrors)\n return finish(emitter, {\n intent: config.intent,\n pass: false,\n completed: false,\n reason: actionOutcome.error ?? 'action failed',\n score: averageScore(evals),\n steps: history,\n finalState: state,\n finalEvals: evals,\n wallMs: Date.now() - started,\n spentCostUsd,\n runId: emitter?.runId ?? null,\n failureClass: 'unknown',\n runtimeErrors,\n stoppedBy: 'runtime-error',\n })\n }\n }\n\n try {\n state = await config.observe({ history, abortSignal: controller.signal })\n } catch (err) {\n runtimeErrors.push(runtimeError('observe', stepIndex, err))\n const step: ControlStep<TState, TAction, TActionResult, TEval> = {\n index: stepIndex,\n decision,\n beforeState,\n afterState: beforeState,\n evalsBefore,\n evalsAfter: evals,\n actionOutcome,\n startedAt: new Date(actionStarted).toISOString(),\n endedAt: new Date().toISOString(),\n }\n history.push(step)\n await runTrace(runtimeErrors, stepIndex, () =>\n stepHandle?.fail(runtimeErrors[runtimeErrors.length - 1]!.message),\n )\n await runOnStep(config.onStep, step, runtimeErrors)\n return finish(emitter, {\n intent: config.intent,\n pass: false,\n completed: false,\n reason: runtimeErrors[runtimeErrors.length - 1]!.message,\n score: averageScore(evals),\n steps: history,\n finalState: beforeState,\n finalEvals: evals,\n wallMs: Date.now() - started,\n spentCostUsd,\n runId: emitter?.runId ?? null,\n failureClass: 'unknown',\n runtimeErrors,\n stoppedBy: 'runtime-error',\n })\n }\n try {\n evals = await config.validate({\n intent: config.intent,\n state,\n history,\n abortSignal: controller.signal,\n })\n await recordEvalSpans(\n emitter,\n evals,\n `step-${stepIndex}`,\n runtimeErrors,\n stepIndex,\n stepHandle?.span.spanId,\n )\n } catch (err) {\n runtimeErrors.push(runtimeError('validate', stepIndex, err))\n const step: ControlStep<TState, TAction, TActionResult, TEval> = {\n index: stepIndex,\n decision,\n beforeState,\n afterState: state,\n evalsBefore,\n evalsAfter: evals,\n actionOutcome,\n startedAt: new Date(actionStarted).toISOString(),\n endedAt: new Date().toISOString(),\n }\n history.push(step)\n await runTrace(runtimeErrors, stepIndex, () =>\n stepHandle?.fail(runtimeErrors[runtimeErrors.length - 1]!.message),\n )\n await runOnStep(config.onStep, step, runtimeErrors)\n return finish(emitter, {\n intent: config.intent,\n pass: false,\n completed: false,\n reason: runtimeErrors[runtimeErrors.length - 1]!.message,\n score: averageScore(evals),\n steps: history,\n finalState: state,\n finalEvals: evals,\n wallMs: Date.now() - started,\n spentCostUsd,\n runId: emitter?.runId ?? null,\n failureClass: 'unknown',\n runtimeErrors,\n stoppedBy: 'runtime-error',\n })\n }\n const scoreAfter = averageScore(evals)\n const stateFingerprint = fingerprintState(state, config.stopPolicies)\n const noProgressSignal = progressDetector.observe({ stateFingerprint, score: scoreAfter })\n const noProgressStreak = progressDetector.streak\n\n const step: ControlStep<TState, TAction, TActionResult, TEval> = {\n index: stepIndex,\n decision,\n beforeState,\n afterState: state,\n evalsBefore,\n evalsAfter: evals,\n actionOutcome,\n startedAt: new Date(actionStarted).toISOString(),\n endedAt: new Date().toISOString(),\n }\n history.push(step)\n if (actionOutcome.ok) {\n await runTrace(runtimeErrors, stepIndex, () =>\n stepHandle?.end({\n attributes: {\n actionCostUsd: actionOutcome.costUsd ?? null,\n spentCostUsd,\n scoreBefore: scoreBefore ?? null,\n scoreAfter: scoreAfter ?? null,\n noProgressStreak,\n },\n }),\n )\n } else {\n await runTrace(runtimeErrors, stepIndex, () =>\n stepHandle?.fail(actionOutcome.error ?? 'action failed', {\n attributes: {\n spentCostUsd,\n noProgressStreak,\n },\n }),\n )\n }\n await runOnStep(config.onStep, step, runtimeErrors)\n\n if (noProgressSignal) {\n return finish(emitter, {\n intent: config.intent,\n pass: false,\n completed: true,\n reason: noProgressSignal.reason,\n score: scoreAfter,\n steps: history,\n finalState: state,\n finalEvals: evals,\n wallMs: Date.now() - started,\n spentCostUsd,\n runId: emitter?.runId ?? null,\n failureClass: 'tool_recovery_failure',\n runtimeErrors,\n stoppedBy: 'stop-policy',\n })\n }\n\n const postStepBudgetStop = budgetStopDecision(budget, spentCostUsd)\n if (postStepBudgetStop.stop) {\n return finish(emitter, {\n intent: config.intent,\n pass: false,\n completed: false,\n reason: postStepBudgetStop.reason,\n score: scoreAfter,\n steps: history,\n finalState: state,\n finalEvals: evals,\n wallMs: Date.now() - started,\n spentCostUsd,\n runId: emitter?.runId ?? null,\n failureClass: 'budget_exceeded',\n runtimeErrors,\n stoppedBy: 'budget',\n })\n }\n\n const postStepCtx = makeContext(\n config.intent,\n state,\n evals,\n history,\n budget,\n stepIndex + 1,\n started,\n spentCostUsd,\n controller.signal,\n emitter,\n )\n let postStepStop: StopDecision\n try {\n postStepStop = config.shouldStop\n ? await config.shouldStop(postStepCtx)\n : defaultStopDecision(evals)\n } catch (err) {\n runtimeErrors.push(runtimeError('stop-policy', stepIndex + 1, err))\n return finish(emitter, {\n intent: config.intent,\n pass: false,\n completed: false,\n reason: runtimeErrors[runtimeErrors.length - 1]!.message,\n score: averageScore(evals),\n steps: history,\n finalState: state,\n finalEvals: evals,\n wallMs: Date.now() - started,\n spentCostUsd,\n runId: emitter?.runId ?? null,\n failureClass: 'unknown',\n runtimeErrors,\n stoppedBy: 'runtime-error',\n })\n }\n if (postStepStop.stop) {\n return finish(emitter, {\n intent: config.intent,\n pass: postStepStop.pass,\n completed: true,\n reason: postStepStop.reason,\n score: postStepStop.score,\n steps: history,\n finalState: state,\n finalEvals: evals,\n wallMs: Date.now() - started,\n spentCostUsd,\n runId: emitter?.runId ?? null,\n failureClass: postStepStop.failureClass,\n runtimeErrors,\n stoppedBy: 'stop-policy',\n })\n }\n }\n\n return finish(emitter, {\n intent: config.intent,\n pass: false,\n completed: false,\n reason: `budget exhausted: maxSteps=${budget.maxSteps}`,\n steps: history,\n finalState: state,\n finalEvals: evals,\n wallMs: Date.now() - started,\n spentCostUsd,\n runId: emitter?.runId ?? null,\n failureClass: 'budget_exceeded',\n runtimeErrors,\n stoppedBy: 'budget',\n })\n } catch (err) {\n runtimeErrors.push(runtimeError('act', history.length, err))\n return finish(emitter, {\n intent: config.intent,\n pass: false,\n completed: false,\n reason: runtimeErrors[runtimeErrors.length - 1]!.message,\n steps: history,\n finalState: undefined,\n finalEvals: [],\n wallMs: Date.now() - started,\n spentCostUsd,\n runId: emitter?.runId ?? null,\n failureClass: 'unknown',\n runtimeErrors,\n stoppedBy: 'runtime-error',\n })\n } finally {\n if (wallTimer) clearTimeout(wallTimer)\n if (config.signal) config.signal.removeEventListener('abort', upstreamAbort)\n }\n}\n\nexport function stopOnNoProgress<TState, TAction>(\n maxNoProgressSteps: number,\n options: Omit<ControlStopPolicies<TState, TAction>, 'maxNoProgressSteps'> = {},\n): ControlStopPolicies<TState, TAction> {\n return { ...options, maxNoProgressSteps }\n}\n\nexport function stopOnRepeatedAction<TState, TAction>(\n maxRepeatedActions: number,\n options: Omit<ControlStopPolicies<TState, TAction>, 'maxRepeatedActions'> = {},\n): ControlStopPolicies<TState, TAction> {\n return { ...options, maxRepeatedActions }\n}\n\nexport function objectiveEval(input: Omit<ControlEvalResult, 'objective'>): ControlEvalResult {\n return { ...input, objective: true }\n}\n\nexport function subjectiveEval(input: Omit<ControlEvalResult, 'objective'>): ControlEvalResult {\n return { ...input, objective: false }\n}\n\nfunction normalizeBudget(input: Partial<ControlBudget> | undefined): ControlBudget {\n const raw = { ...DEFAULT_BUDGET, ...input } as Record<string, unknown>\n if (!Number.isInteger(raw.maxSteps) || (raw.maxSteps as number) < 1) {\n throw new RangeError(\n `ControlRuntime budget.maxSteps must be an integer >= 1, got ${String(raw.maxSteps)}`,\n )\n }\n const budget: ControlBudget = { maxSteps: raw.maxSteps as number }\n if (raw.maxWallMs !== undefined) {\n if (\n typeof raw.maxWallMs !== 'number' ||\n !Number.isFinite(raw.maxWallMs) ||\n raw.maxWallMs <= 0\n ) {\n throw new RangeError(\n `ControlRuntime budget.maxWallMs must be a positive finite number, got ${String(raw.maxWallMs)}`,\n )\n }\n budget.maxWallMs = raw.maxWallMs\n }\n if (raw.maxCostUsd !== undefined) {\n if (\n typeof raw.maxCostUsd !== 'number' ||\n !Number.isFinite(raw.maxCostUsd) ||\n raw.maxCostUsd < 0\n ) {\n throw new RangeError(\n `ControlRuntime budget.maxCostUsd must be a nonnegative finite number, got ${String(raw.maxCostUsd)}`,\n )\n }\n budget.maxCostUsd = raw.maxCostUsd\n }\n return budget\n}\n\nfunction normalizeActionCostUsd(\n costUsd: number | undefined,\n runtimeErrors: ControlRuntimeError[],\n stepIndex: number,\n): number | undefined {\n if (costUsd === undefined) return undefined\n if (!Number.isFinite(costUsd) || costUsd < 0) {\n runtimeErrors.push(\n runtimeError('act', stepIndex, new Error(`invalid action costUsd: ${String(costUsd)}`)),\n )\n return undefined\n }\n return costUsd\n}\n\nexport function allCriticalPassed(evals: ControlEvalResult[]): boolean {\n return evals.every(\n (result) => result.passed || (result.severity !== 'critical' && result.severity !== 'error'),\n )\n}\n\nfunction makeContext<TState, TAction, TActionResult, TEval extends ControlEvalResult>(\n intent: string,\n state: TState,\n evals: TEval[],\n history: ControlStep<TState, TAction, TActionResult, TEval>[],\n budget: ControlBudget,\n stepIndex: number,\n started: number,\n spentCostUsd: number,\n abortSignal: AbortSignal,\n emitter?: TraceEmitter,\n): ControlContext<TState, TAction, TActionResult, TEval> {\n return {\n intent,\n state,\n evals,\n history,\n budget,\n stepIndex,\n wallMs: Date.now() - started,\n spentCostUsd,\n remainingCostUsd:\n budget.maxCostUsd === undefined ? undefined : Math.max(0, budget.maxCostUsd - spentCostUsd),\n abortSignal,\n emitter,\n }\n}\n\nfunction defaultStopDecision(evals: ControlEvalResult[]): StopDecision {\n if (!evals.length) return { stop: false, pass: false, reason: 'no evals yet' }\n const pass = allCriticalPassed(evals)\n return pass\n ? { stop: true, pass: true, reason: 'all critical evals passed', score: averageScore(evals) }\n : {\n stop: false,\n pass: false,\n reason: 'critical evals still failing',\n score: averageScore(evals),\n }\n}\n\nfunction averageScore(evals: ControlEvalResult[]): number | undefined {\n const scored = evals\n .map((result) => result.score)\n .filter((score): score is number => typeof score === 'number')\n if (!scored.length) return undefined\n return Math.round((scored.reduce((sum, score) => sum + score, 0) / scored.length) * 1000) / 1000\n}\n\nfunction budgetStopDecision(\n budget: ControlBudget,\n spentCostUsd: number,\n): { stop: boolean; reason: string } {\n if (budget.maxCostUsd !== undefined && spentCostUsd >= budget.maxCostUsd) {\n return {\n stop: true,\n reason: `budget exhausted: maxCostUsd=${budget.maxCostUsd}`,\n }\n }\n return { stop: false, reason: '' }\n}\n\nasync function recordCostBudget(\n emitter: TraceEmitter | undefined,\n budget: ControlBudget,\n spentCostUsd: number,\n handle: SpanHandle | undefined,\n runtimeErrors: ControlRuntimeError[],\n stepIndex: number,\n): Promise<void> {\n if (!emitter || budget.maxCostUsd === undefined) return\n const maxCostUsd = budget.maxCostUsd\n await runTrace(runtimeErrors, stepIndex, () =>\n emitter.recordBudget({\n dimension: 'usd',\n limit: maxCostUsd,\n consumed: spentCostUsd,\n remaining: Math.max(0, maxCostUsd - spentCostUsd),\n breached: spentCostUsd >= maxCostUsd,\n spanId: handle?.span.spanId,\n }),\n )\n}\n\nasync function recordEvalSpans(\n emitter: TraceEmitter | undefined,\n evals: ControlEvalResult[],\n phase: string,\n runtimeErrors: ControlRuntimeError[],\n stepIndex: number,\n targetSpanId?: string,\n): Promise<void> {\n if (!emitter) return\n for (const result of evals) {\n await runTrace(runtimeErrors, stepIndex, () =>\n emitter.recordJudge({\n judgeId: result.objective ? 'objective-validator' : 'subjective-judge',\n targetSpanId: targetSpanId ?? emitter.runId,\n name: `control-eval/${result.id}`,\n dimension: result.id,\n score: typeof result.score === 'number' ? result.score : result.passed ? 1 : 0,\n rationale: result.detail,\n evidence: result.evidence,\n attributes: {\n phase,\n passed: result.passed,\n severity: result.severity,\n objective: result.objective,\n },\n }),\n )\n }\n}\n\nasync function runOnStep<TState, TAction, TActionResult, TEval extends ControlEvalResult>(\n onStep: ControlRuntimeConfig<TState, TAction, TActionResult, TEval>['onStep'] | undefined,\n step: ControlStep<TState, TAction, TActionResult, TEval>,\n runtimeErrors: ControlRuntimeError[],\n): Promise<void> {\n if (!onStep) return\n try {\n await onStep(step)\n } catch (err) {\n runtimeErrors.push(runtimeError('on-step', step.index, err))\n }\n}\n\nasync function runTrace<T>(\n runtimeErrors: ControlRuntimeError[],\n stepIndex: number,\n write: () => Promise<T | undefined> | T | undefined,\n): Promise<T | undefined> {\n try {\n return await write()\n } catch (err) {\n runtimeErrors.push(runtimeError('trace', stepIndex, err))\n return undefined\n }\n}\n\nfunction fingerprintState<TState, TAction>(\n state: TState,\n policies?: ControlStopPolicies<TState, TAction>,\n): string {\n if (policies?.stateFingerprint) return policies.stateFingerprint(state)\n return stableFingerprint(state)\n}\n\nfunction fingerprintAction<TState, TAction>(\n action: TAction,\n policies?: ControlStopPolicies<TState, TAction>,\n): string {\n if (policies?.actionFingerprint) return policies.actionFingerprint(action)\n return stableFingerprint(action)\n}\n\nfunction stableFingerprint(value: unknown): string {\n if (typeof value === 'string') return value\n if (typeof value === 'number' || typeof value === 'boolean' || value == null) return String(value)\n try {\n return JSON.stringify(sortForFingerprint(value))\n } catch {\n return String(value)\n }\n}\n\nfunction sortForFingerprint(value: unknown): unknown {\n if (Array.isArray(value)) return value.map(sortForFingerprint)\n if (!value || typeof value !== 'object') return value\n const record = value as Record<string, unknown>\n const sorted: Record<string, unknown> = {}\n for (const key of Object.keys(record).sort()) {\n sorted[key] = sortForFingerprint(record[key])\n }\n return sorted\n}\n\nfunction abortReason(signal: AbortSignal): string {\n const reason = signal.reason\n if (reason instanceof Error) return reason.message\n return reason ? String(reason) : 'aborted'\n}\n\nfunction runtimeError(\n phase: ControlRuntimeError['phase'],\n stepIndex: number,\n err: unknown,\n): ControlRuntimeError {\n const message = err instanceof Error ? err.message : String(err)\n return { phase, stepIndex, message }\n}\n\nasync function finish<TState, TAction, TActionResult, TEval extends ControlEvalResult>(\n emitter: TraceEmitter | undefined,\n result: ControlRunResult<TState, TAction, TActionResult, TEval>,\n): Promise<ControlRunResult<TState, TAction, TActionResult, TEval>> {\n await runTrace(result.runtimeErrors, result.steps.length, () =>\n emitter?.endRun({\n pass: result.pass,\n score: result.score ?? averageScore(result.finalEvals),\n failureClass: result.failureClass,\n notes: result.reason,\n }),\n )\n return result\n}\n","/**\n * Walk a personas directory and return every file matching the convention\n * `NN-slug.{yaml,yml,json,md}`. Sorted by filename so the numeric prefix\n * gives stable persona ordering for reproducibility. Consumers filter\n * through `include` / `exclude`.\n */\n\nimport { promises as fs } from 'node:fs'\nimport { basename, extname, join } from 'node:path'\n\nexport interface DiscoverPersonasOptions {\n /**\n * Regex applied to filenames. Files that don't match are skipped.\n * Default: `^[0-9]{2}-.+\\.(yaml|yml|json|md)$`.\n */\n pattern?: RegExp\n /**\n * Filenames (or basenames) to skip. Use this to exclude WIP / archived\n * personas without removing the file.\n */\n exclude?: readonly string[]\n /**\n * If set, return only personas whose basename contains one of these\n * substrings (post-pattern filter).\n */\n include?: readonly string[]\n /** Recurse into subdirectories. Default false. */\n recursive?: boolean\n}\n\nexport interface DiscoveredPersona {\n /** Absolute file path. */\n path: string\n /** Filename without directory. */\n filename: string\n /** Filename without extension — the conventional persona id. */\n id: string\n}\n\nconst DEFAULT_PATTERN = /^\\d{2}-.+\\.(yaml|yml|json|md)$/\n\nexport async function discoverPersonas(\n dir: string,\n opts: DiscoverPersonasOptions = {},\n): Promise<DiscoveredPersona[]> {\n const pattern = opts.pattern ?? DEFAULT_PATTERN\n const exclude = new Set(opts.exclude ?? [])\n const include = opts.include\n\n async function walk(d: string): Promise<DiscoveredPersona[]> {\n let entries: Array<{ name: string; isDir: boolean }>\n try {\n const raw = await fs.readdir(d, { withFileTypes: true })\n entries = raw.map((e) => ({ name: e.name, isDir: e.isDirectory() }))\n } catch (err) {\n const code = (err as NodeJS.ErrnoException).code\n if (code === 'ENOENT') return []\n throw err\n }\n const out: DiscoveredPersona[] = []\n for (const entry of entries) {\n const full = join(d, entry.name)\n if (entry.isDir) {\n if (opts.recursive) out.push(...(await walk(full)))\n continue\n }\n if (!pattern.test(entry.name)) continue\n if (exclude.has(entry.name) || exclude.has(basename(entry.name, extname(entry.name))))\n continue\n if (include && include.length > 0) {\n const id = basename(entry.name, extname(entry.name))\n const matched = include.some((needle) => entry.name.includes(needle) || id.includes(needle))\n if (!matched) continue\n }\n out.push({\n path: full,\n filename: entry.name,\n id: basename(entry.name, extname(entry.name)),\n })\n }\n return out\n }\n\n const results = await walk(dir)\n results.sort((a, b) => a.filename.localeCompare(b.filename))\n return results\n}\n","import type { ChatClient, ChatRequest } from './analyst/chat-client'\nimport type { ProductClient } from './client'\nimport { ConvergenceTracker } from './convergence'\nimport { CostLedger, type CostLedgerHandle } from './cost-ledger'\nimport { warnDeprecatedOnce } from './deprecation'\nimport { assertServedModel } from './integrity/served-model'\nimport {\n costReceiptFromLlm,\n costReceiptFromLlmError,\n maximumChargeForLlmRequest,\n} from './llm-client'\nimport { MetricsCollector } from './metrics'\nimport type { DriverResult, DriverState, PersonaConfig, PersonaRigor, TurnMetrics } from './types'\n\nexport interface AgentDriverConfig {\n client: ProductClient\n driverModel?: string\n /** System prompt context for the driver LLM to understand the product */\n productContext?: string\n /** Shared account for driver-model calls. */\n costLedger?: CostLedgerHandle\n}\n\n/**\n * Per-rigor stance the driver LLM adopts. Scales how hard the simulated\n * user interrogates the agent — see `PersonaConfig.rigor`.\n */\nconst RIGOR_STANCE: Record<PersonaRigor, string> = {\n cooperative:\n 'Your stance: a pragmatic early adopter. You accept reasonable answers and only push back on clear gaps or outright errors.',\n demanding:\n 'Your stance: an experienced professional with no time to waste. You do not accept vague, hedged, or generic answers — you expect specifics, and you say so plainly when you do not get them.',\n relentless:\n 'Your stance: a senior partner reviewing this work for a client who will litigate if it is wrong. You interrogate every claim. You accept nothing undefended. You find the single weakest point in every answer and attack it. Courteous, never satisfied.',\n}\n\n/**\n * AgentDriver — meta-agent that plays a persona against the real product.\n *\n * Uses a driver LLM (Claude/GPT-4o) to decide what to say each turn.\n * Not scripted — the driver gets the current product state and decides\n * the next realistic user message.\n *\n * @deprecated A one-product driver welded to `ProductClient` does not belong\n * in the generic substrate. Moves to the product repo in the next major\n * (tangle-network/agent-runtime#694). A driver is an `AgentProfile` on a\n * graph edge; use the agent-graph path once it lands, or vendor this class.\n */\nexport class AgentDriver {\n private chat: ChatClient\n private client: ProductClient\n private driverModel: string\n private productContext: string\n private costLedger: CostLedgerHandle\n\n constructor(chat: ChatClient, config: AgentDriverConfig) {\n warnDeprecatedOnce(\n 'AgentDriver',\n 'AgentDriver is deprecated and moves to the product repo in the next major (tangle-network/agent-runtime#694).',\n )\n this.chat = chat\n this.client = config.client\n this.driverModel = config.driverModel ?? 'claude-sonnet-4-6'\n this.productContext = config.productContext ?? ''\n this.costLedger = config.costLedger ?? new CostLedger()\n }\n\n /**\n * Run a persona through the product.\n *\n * Returns metrics on how many turns to completion, cost curve,\n * quality curve, and convergence curve.\n */\n async run(persona: PersonaConfig): Promise<DriverResult> {\n const costTags = { driverRunId: globalThis.crypto.randomUUID() }\n // Setup: create workspace + thread\n const email = `eval-driver-${Date.now()}@test.agent-eval.local`\n await this.client.signup(`Driver ${persona.role}`, email, 'eval-driver-pass')\n await this.client.login(email, 'eval-driver-pass')\n const workspaceId = await this.client.createWorkspace(`${persona.role} Eval`)\n const threadId = await this.client.createThread(workspaceId)\n\n const metrics = new MetricsCollector(this.client, workspaceId)\n const convergence = new ConvergenceTracker(persona.completionCriteria)\n const turnMetrics: TurnMetrics[] = []\n const conversationHistory: { role: string; content: string }[] = []\n\n let completed = false\n let turnsToCompletion: number | null = null\n let criteriaMetAtTurn: number | null = null\n\n for (let turn = 1; turn <= persona.maxTurns; turn++) {\n // Get current product state\n const state = await metrics.getState()\n\n // Ask driver LLM what to say\n const userMessage = await this.decideNextMessage(\n persona,\n state,\n conversationHistory,\n costTags,\n )\n\n if (userMessage === 'DONE') {\n completed = true\n turnsToCompletion = turn - 1\n console.log(` SIGNED OFF by simulated ${persona.role} after turn ${turn - 1}`)\n break\n }\n\n // Send to product\n const turnStart = Date.now()\n const response = await this.client.chat(workspaceId, threadId, userMessage)\n const latency = Date.now() - turnStart\n\n conversationHistory.push(\n { role: 'user', content: userMessage },\n { role: 'assistant', content: response.text },\n )\n\n // Wait for post-processor\n await new Promise((r) => setTimeout(r, 2000))\n\n // Handle pending approvals\n await this.handleApprovals(persona, workspaceId, state)\n\n // Check convergence\n const postState = await metrics.getState()\n const conv = convergence.record(turn, postState)\n\n // Collect metrics\n const codeBlockCount = (response.text.match(/```\\w+\\n/g) || []).length\n const m = await metrics.collect(\n turn,\n latency,\n response.text.length,\n codeBlockCount,\n response.blocks.length,\n Object.values(conv.criteriaStatus).filter(Boolean).length,\n persona.completionCriteria.length,\n )\n turnMetrics.push(m)\n\n // Print turn status\n const criteriaStr = Object.entries(conv.criteriaStatus)\n .map(([k, v]) => `${k}:${v ? '+' : '-'}`)\n .join(' ')\n console.log(\n ` [turn ${turn}] ${conv.completionPercent.toFixed(0)}% — ${criteriaStr} (${(latency / 1000).toFixed(1)}s)`,\n )\n\n // Nominal criteria met is recorded, not a stop condition. The\n // simulated professional keeps pressure-testing until genuinely\n // satisfied — a criteria-met-but-sloppy answer must still be defended.\n if (conv.complete && criteriaMetAtTurn === null) {\n criteriaMetAtTurn = turn\n console.log(` criteria met at turn ${turn} — driver continues pressure-testing`)\n }\n }\n\n const finalState = await metrics.getState()\n\n return {\n personaId: persona.id,\n completed,\n turnsToCompletion,\n criteriaMetAtTurn,\n totalTurns: turnMetrics.length,\n metrics: turnMetrics,\n finalState,\n convergenceCurve: convergence.getCurve(),\n totalCostUsd: this.costLedger.summary({ tags: costTags }).totalCostUsd,\n finalQualityScore: null,\n }\n }\n\n /** Use the driver LLM to decide what the \"user\" says next */\n private async decideNextMessage(\n persona: PersonaConfig,\n state: DriverState,\n history: { role: string; content: string }[],\n costTags: Record<string, string>,\n ): Promise<string> {\n return decideNextUserTurn(this.chat, {\n persona,\n state,\n history,\n productContext: this.productContext,\n model: this.driverModel,\n costLedger: this.costLedger,\n costTags,\n })\n }\n\n /** Handle pending approvals based on persona feedback patterns */\n private async handleApprovals(\n persona: PersonaConfig,\n workspaceId: string,\n _state: DriverState,\n ): Promise<void> {\n const approvals = await this.client.getApprovals(workspaceId)\n const pending = approvals.filter((a) => a.status === 'pending')\n\n for (const action of pending) {\n // Check if any feedback pattern triggers a rejection\n const rejection = persona.feedbackPatterns?.find((fp) => {\n const title = action.title.toLowerCase()\n return title.includes(fp.trigger.toLowerCase())\n })\n\n if (rejection) {\n await this.client.rejectAction(workspaceId, action.id, rejection.response)\n console.log(` rejected: ${action.title} — ${rejection.response.slice(0, 60)}`)\n } else {\n await this.client.approveAction(workspaceId, action.id)\n console.log(` approved: ${action.title}`)\n }\n }\n }\n}\n\n/** Describe which nominal completion criteria are met, for the driver prompt. */\nfunction describeCompletion(persona: PersonaConfig, state: DriverState): string {\n const results = persona.completionCriteria.map((c) => {\n const met = c.check(state)\n return `${c.name}: ${met ? 'MET' : 'NOT MET'}`\n })\n const metCount = results.filter((r) => r.includes('MET') && !r.includes('NOT')).length\n return `${metCount}/${persona.completionCriteria.length} — ${results.join(', ')}`\n}\n\n/**\n * Build the driver LLM's system prompt. The simulated user is an\n * adversarial senior professional: it judges the agent's last response by a\n * professional standard, refuses vague answers, challenges undefended\n * claims, probes the persona's pressure points without revealing them, and\n * signs off (DONE) only when a real practitioner would act on the work\n * unmodified. Pure function of persona, product state, and product context\n * — exported so harness authors can inspect and regression-test it.\n *\n * @deprecated A role expressed as a code function can never be optimized.\n * Removal is a major; until then, treat this output as SEED data for a\n * registry-backed directive prompt (tangle-network/agent-runtime#694).\n */\nexport function buildDriverSystemPrompt(\n persona: PersonaConfig,\n state: DriverState,\n productContext = '',\n): string {\n warnDeprecatedOnce(\n 'buildDriverSystemPrompt',\n 'buildDriverSystemPrompt is deprecated: roles belong in registry-backed prompt data, not code (tangle-network/agent-runtime#694).',\n )\n const rigor: PersonaRigor = persona.rigor ?? 'demanding'\n const expertise = persona.expertise ? ` You are ${persona.expertise}.` : ''\n\n const pressure =\n persona.pressurePoints && persona.pressurePoints.length > 0\n ? `\\nA competent ${persona.role} here MUST get the agent to address each of:\\n${persona.pressurePoints\n .map((p) => ` - ${p}`)\n .join(\n '\\n',\n )}\\nDo NOT hand these to the agent. Probe whether it surfaces them itself. If it misses one, press on exactly that gap until it delivers or demonstrably fails.\\n`\n : ''\n\n const curveballs =\n persona.curveballs && persona.curveballs.length > 0\n ? `\\nOnce the agent is coasting on easy answers, introduce ONE of these as a genuine new development — never as a quiz:\\n${persona.curveballs\n .map((c) => ` - ${c}`)\n .join('\\n')}\\n`\n : ''\n\n return `You are role-playing a real ${persona.role} putting an AI agent through its paces.${expertise}\nYour objective: ${persona.goal}\nYou are deciding whether this agent's work is good enough to stake your professional reputation on. Assume it is not — until it proves otherwise.\n\n${RIGOR_STANCE[rigor]}\n${productContext ? `Product context:\\n${productContext}\\n` : ''}Current workspace state:\n- Tasks: ${state.tasks} | Events: ${state.events}\n- Proposals: pending=${state.proposals.pending}, approved=${state.proposals.approved}, rejected=${state.proposals.rejected}\n- Vault files (${state.vaultFiles.length}): ${state.vaultFiles.slice(0, 10).join(', ')}${state.vaultFiles.length > 10 ? ' …' : ''}\n- Nominal task criteria: ${describeCompletion(persona, state)}\n${pressure}${curveballs}\nHow to choose your next message:\n1. Silently judge the agent's last response the way a ${persona.role} would. Is every claim defended with a specific authority, figure, or mechanism? Or is it vague, hedged, or generic?\n2. If it is vague or hand-waved — do NOT move on. Name the gap and demand the specific authority / figure / mechanism. \"It depends\" is not an answer; force the decision.\n3. If it makes a claim you can challenge — challenge it. Make the agent defend or correct it.\n4. If it missed something a ${persona.role} would catch — press on exactly that, without naming it for the agent.\n5. If it is genuinely solid — escalate: go a layer deeper, or introduce a curveball.\n6. First message — state your situation as you really would: realistic, specific, with the messy detail, but do not coach the agent.\n\nSign-off: respond with exactly \"DONE\" only when a ${persona.role} would act on this work without redoing it. Nominal task completion is NOT sign-off — sloppy-but-complete still fails. If the agent never gets there, keep pushing; never sign off on weak work.\n\nOutput ONLY your next message to the agent — in character, first person, no meta-commentary, no stage directions.`\n}\n\nexport interface DecideNextUserTurnOpts {\n persona: PersonaConfig\n state: DriverState\n /** Conversation so far — alternating user/assistant messages, oldest first. */\n history: { role: string; content: string }[]\n /** Optional product context woven into the driver prompt. */\n productContext?: string\n /** Driver LLM model. Defaults to claude-sonnet-4-6. */\n model?: string\n /** Shared account for the paid driver-model call. */\n costLedger?: CostLedgerHandle\n /** Attribution tags merged into the paid-call receipt. */\n costTags?: Record<string, string>\n}\n\n/**\n * Decide the simulated user's next turn — the reactive, adversarial\n * turn-generation core of `AgentDriver`, exposed standalone so an in-process\n * eval harness can drive multi-shot conversations without the `ProductClient`\n * workspace machinery. Returns the next user message, or the literal \"DONE\"\n * when the simulated professional would sign off.\n *\n * @deprecated The persona-driver loop becomes a 2-node agent graph (driver\n * profile + delegates edge); removal is a major\n * (tangle-network/agent-runtime#694).\n */\nexport async function decideNextUserTurn(\n chat: ChatClient,\n opts: DecideNextUserTurnOpts,\n): Promise<string> {\n warnDeprecatedOnce(\n 'decideNextUserTurn',\n 'decideNextUserTurn is deprecated: the persona-driver loop becomes a 2-node agent graph (tangle-network/agent-runtime#694).',\n )\n const { persona, state, history, productContext = '', model = 'claude-sonnet-4-6' } = opts\n\n const lastResponse =\n history.length > 0\n ? history[history.length - 1]!.content.slice(0, 2000)\n : '(no conversation yet — this is the first message)'\n\n const recentHistory = history\n .slice(-6)\n .map((h) => `${h.role}: ${h.content.slice(0, 500)}`)\n .join('\\n\\n')\n\n const request = {\n model,\n messages: [\n { role: 'system', content: buildDriverSystemPrompt(persona, state, productContext) },\n {\n role: 'user',\n content: recentHistory\n ? `Recent conversation:\\n${recentHistory}\\n\\nThe agent's latest response:\\n${lastResponse}`\n : 'No conversation yet. Send your opening message — in character, phrased as this person actually would.',\n },\n ],\n temperature: 0.5,\n maxTokens: 700,\n } satisfies ChatRequest\n const paid = await (opts.costLedger ?? new CostLedger()).runPaidCall({\n channel: 'driver',\n phase: 'driver-turn',\n actor: 'decideNextUserTurn',\n model,\n tags: opts.costTags,\n maximumCharge:\n chat.maximumAttempts === undefined\n ? undefined\n : maximumChargeForLlmRequest(request, { maximumAttempts: chat.maximumAttempts }),\n execute: (signal, callId) => chat.chat(request, { signal, idempotencyKey: callId }),\n receipt: costReceiptFromLlm,\n receiptFromError: costReceiptFromLlmError,\n })\n if (!paid.succeeded) throw paid.error\n // Hold the transport to its own word: a persona turn written by a different\n // model is not this driver model's behaviour. A transport that echoes no id\n // cannot be made to prove identity here — callers needing that proof enable\n // it at the client (`LlmClientOptions.assertServedModel`).\n assertServedModel(model, paid.value.servedModel, {\n allowUnreported: true,\n context: 'decideNextUserTurn',\n })\n return paid.value.content.trim()\n}\n","/**\n * Propose / Verify / Review — the core multi-shot primitive.\n *\n * shot N: propose(state, priorReview) → new state\n * verify(state) → pass/fail, optional layers\n * review(state, verification, memory) → observations + next-shot\n * instruction + shouldContinue\n * memory.append(entry)\n *\n * Roles are strictly separated:\n *\n * - The WORKER is whatever the caller wraps in `propose`. It is\n * stateful — caller owns its resume/session mechanism.\n * - The VERIFIER grades the state. It produces the ground truth.\n * The reviewer cannot overturn or downgrade a verification layer.\n * - The REVIEWER is stateless per call. Its continuity is the\n * `ReviewMemoryStore` — durable JSONL by default, or any store\n * implementing the interface. It reads memory + trace summary +\n * verification and directs the NEXT proposer shot.\n *\n * This shape is load-bearing. The reviewer never grades; the verifier\n * never directs. Two processes, two prompts, two concerns — which is\n * what keeps the loop from confirmation-biasing itself into \"all\n * passed\" when it didn't.\n *\n * Short-circuits and soft-fails are both first-class:\n * - verify.pass === true → reviewer LLM call is skipped, memory\n * records a success entry, loop exits.\n * - review throws → the shot still counts; the loop uses the\n * last-known instruction (or `fallbackInstruction`) for the next\n * propose call. A transient reviewer failure must NEVER abort a\n * valid arc.\n *\n * Composable: `propose` itself can be another `runProposeReview` call.\n * That's the dogfooding path — a harness built on this primitive is in\n * turn evaluable by it.\n */\n\nimport { appendFileSync, existsSync, mkdirSync, readFileSync } from 'node:fs'\nimport { dirname } from 'node:path'\nimport { type SpanHandle, TraceEmitter } from './trace/emitter'\nimport type { FailureClass } from './trace/schema'\nimport type { TraceStore } from './trace/store'\n\n// ── Types ────────────────────────────────────────────────────────────\n\nexport interface Verification {\n pass: boolean\n score?: number\n failingLayers?: string[]\n details?: unknown\n}\n\nexport interface Review {\n observations: string\n diagnosis: string\n nextShotInstruction: string\n shouldContinue: boolean\n confidence: number\n}\n\nexport interface ReviewMemoryEntry extends Review {\n shot: number\n timestamp: number\n verification: {\n pass: boolean\n score?: number\n failingLayers?: string[]\n }\n}\n\nexport interface ProposeInput<State> {\n shot: number\n goal: string\n state: State\n priorReview: Review | null\n abortSignal: AbortSignal\n emitter?: TraceEmitter\n}\n\nexport interface ProposeOutput<State, Summary = unknown> {\n state: State\n traceSummary?: Summary\n}\n\nexport interface ReviewInput<State, Summary = unknown> {\n shot: number\n goal: string\n state: State\n verification: Verification\n traceSummary: Summary | undefined\n memory: ReviewMemoryEntry[]\n}\n\nexport type ProposeFn<State, Summary = unknown> = (\n input: ProposeInput<State>,\n) => Promise<ProposeOutput<State, Summary>>\n\nexport type VerifyFn<State> = (state: State) => Promise<Verification>\n\nexport type ReviewFn<State, Summary = unknown> = (\n input: ReviewInput<State, Summary>,\n) => Promise<Review>\n\nexport interface ReviewMemoryStore {\n load(): Promise<ReviewMemoryEntry[]>\n append(entry: ReviewMemoryEntry): Promise<void>\n}\n\nexport interface ProposeReviewConfig<State, Summary = unknown> {\n goal: string\n initialState: State\n propose: ProposeFn<State, Summary>\n verify: VerifyFn<State>\n review: ReviewFn<State, Summary>\n /** Hard shot cap. Default 10. */\n maxShots?: number\n /** Wall-clock cap in ms. Default 10 min. */\n maxWallMs?: number\n /**\n * If the reviewer returns confidence ≤ floor on `confidenceFloorWindow`\n * consecutive shots, terminate early. Default floor 0.3, window 2.\n * Set window to 0 or floor to <0 to disable.\n */\n confidenceFloor?: number\n confidenceFloorWindow?: number\n /** Defaults to an in-memory store if omitted. */\n memory?: ReviewMemoryStore\n /** If provided, emit a Run + per-shot spans. */\n store?: TraceStore\n scenarioId?: string\n projectId?: string\n variantId?: string\n /**\n * Used when the reviewer soft-fails on shot 1 (no prior instruction to\n * fall back to). Default is a generic \"inspect failures and fix\".\n */\n fallbackInstruction?: string\n}\n\nexport interface ProposeReviewShot<State, Summary = unknown> {\n shot: number\n state: State\n verification: Verification\n traceSummary: Summary | undefined\n review: Review\n reviewAvailable: boolean\n reviewError?: string\n durationMs: number\n}\n\nexport interface ProposeReviewReport<State, Summary = unknown> {\n runId: string | null\n completed: boolean\n shots: ProposeReviewShot<State, Summary>[]\n finalState: State\n finalVerification: Verification\n failureClass?: FailureClass\n wallMs: number\n score: number\n}\n\n// ── Memory stores ────────────────────────────────────────────────────\n\nexport function inMemoryReviewStore(initial: ReviewMemoryEntry[] = []): ReviewMemoryStore {\n const entries: ReviewMemoryEntry[] = [...initial]\n return {\n async load() {\n return [...entries]\n },\n async append(entry) {\n entries.push(entry)\n },\n }\n}\n\nexport function jsonlReviewStore(path: string): ReviewMemoryStore {\n return {\n async load() {\n if (!existsSync(path)) return []\n const raw = readFileSync(path, 'utf8')\n const out: ReviewMemoryEntry[] = []\n for (const line of raw.split('\\n')) {\n const trimmed = line.trim()\n if (!trimmed) continue\n try {\n out.push(JSON.parse(trimmed) as ReviewMemoryEntry)\n } catch {\n // A corrupt line is an observability problem, not a correctness\n // one — skip it rather than aborting the loop.\n }\n }\n return out\n },\n async append(entry) {\n mkdirSync(dirname(path), { recursive: true })\n appendFileSync(path, `${JSON.stringify(entry)}\\n`)\n },\n }\n}\n\n// ── Core loop ────────────────────────────────────────────────────────\n\nconst DEFAULT_FALLBACK_INSTRUCTION =\n 'Inspect the verification failures above. Fix the critical issues first, then the major ones. Do not restate the failures — act on them.'\n\nexport async function runProposeReview<State, Summary = unknown>(\n config: ProposeReviewConfig<State, Summary>,\n): Promise<ProposeReviewReport<State, Summary>> {\n const maxShots = config.maxShots ?? 10\n const maxWallMs = config.maxWallMs ?? 10 * 60 * 1000\n const confidenceFloor = config.confidenceFloor ?? 0.3\n const confidenceFloorWindow = config.confidenceFloorWindow ?? 2\n const memory = config.memory ?? inMemoryReviewStore()\n const fallbackInstruction = config.fallbackInstruction ?? DEFAULT_FALLBACK_INSTRUCTION\n\n const emitter = config.store ? new TraceEmitter(config.store) : null\n if (emitter) {\n await emitter.startRun({\n scenarioId: config.scenarioId ?? 'propose-review',\n projectId: config.projectId,\n variantId: config.variantId,\n layer: 'meta',\n tags: {\n goal: config.goal.slice(0, 120),\n maxShots: String(maxShots),\n },\n })\n }\n\n const abort = new AbortController()\n const wallStart = Date.now()\n const wallTimer = setTimeout(\n () => abort.abort(new Error('propose-review wall timeout')),\n maxWallMs,\n )\n\n const shots: ProposeReviewShot<State, Summary>[] = []\n let state = config.initialState\n let priorReview: Review | null = null\n let lastVerification: Verification = { pass: false }\n let failureClass: FailureClass | undefined\n let completed = false\n let lowConfidenceStreak = 0\n\n try {\n for (let shot = 1; shot <= maxShots; shot++) {\n if (abort.signal.aborted) {\n failureClass = 'timeout'\n break\n }\n\n const shotStart = Date.now()\n const shotHandle = emitter ? await emitter.span({ kind: 'tool', name: `shot-${shot}` }) : null\n\n // 1. Propose.\n let proposeOut: ProposeOutput<State, Summary>\n try {\n proposeOut = await config.propose({\n shot,\n goal: config.goal,\n state,\n priorReview,\n abortSignal: abort.signal,\n emitter: emitter ?? undefined,\n })\n } catch (err) {\n await shotHandle?.fail(err instanceof Error ? err : String(err))\n failureClass = 'unknown'\n throw err\n }\n state = proposeOut.state\n const traceSummary = proposeOut.traceSummary\n\n // 2. Verify.\n let verification: Verification\n try {\n verification = await config.verify(state)\n } catch (err) {\n await shotHandle?.fail(err instanceof Error ? err : String(err))\n failureClass = 'unknown'\n throw err\n }\n lastVerification = verification\n\n // 3. Review — short-circuit on pass; soft-fail on throw.\n const memorySnapshot = await memory.load()\n const verificationDigest = {\n pass: verification.pass,\n score: verification.score,\n failingLayers: verification.failingLayers ?? [],\n }\n\n let review: Review\n let reviewAvailable = true\n let reviewError: string | undefined\n\n if (verification.pass) {\n review = {\n observations: 'verification passed — skipping reviewer LLM call',\n diagnosis: 'no failures to diagnose',\n nextShotInstruction: '(done)',\n shouldContinue: false,\n confidence: 1,\n }\n } else {\n try {\n review = await config.review({\n shot,\n goal: config.goal,\n state,\n verification,\n traceSummary,\n memory: memorySnapshot,\n })\n review = coerceReview(review)\n } catch (err) {\n reviewAvailable = false\n reviewError = err instanceof Error ? err.message : String(err)\n const lastInstruction =\n memorySnapshot.length > 0\n ? memorySnapshot[memorySnapshot.length - 1]!.nextShotInstruction\n : fallbackInstruction\n review = {\n observations: '(reviewer unavailable — using last-known instruction)',\n diagnosis: reviewError,\n nextShotInstruction: lastInstruction,\n shouldContinue: true,\n confidence: 0.3,\n }\n }\n }\n\n const entry: ReviewMemoryEntry = {\n shot,\n timestamp: Date.now(),\n ...review,\n verification: verificationDigest,\n }\n await memory.append(entry)\n\n const shotRecord: ProposeReviewShot<State, Summary> = {\n shot,\n state,\n verification,\n traceSummary,\n review,\n reviewAvailable,\n reviewError,\n durationMs: Date.now() - shotStart,\n }\n shots.push(shotRecord)\n\n await shotHandle?.end({\n attributes: {\n verificationPass: verification.pass,\n verificationScore: verification.score ?? null,\n reviewShouldContinue: review.shouldContinue,\n reviewConfidence: review.confidence,\n reviewAvailable,\n },\n } as Partial<SpanHandle['span']>)\n\n // 4. Exit rules.\n if (verification.pass) {\n completed = true\n break\n }\n if (!review.shouldContinue) {\n break\n }\n if (confidenceFloorWindow > 0 && review.confidence <= confidenceFloor) {\n lowConfidenceStreak += 1\n if (lowConfidenceStreak >= confidenceFloorWindow) break\n } else {\n lowConfidenceStreak = 0\n }\n\n priorReview = review\n }\n\n if (!completed && !failureClass) {\n failureClass = shots.length >= maxShots ? 'budget_exceeded' : 'unknown'\n }\n } finally {\n clearTimeout(wallTimer)\n }\n\n const score = lastVerification.pass\n ? 1\n : typeof lastVerification.score === 'number'\n ? lastVerification.score\n : 0\n\n if (emitter) {\n await emitter.endRun({\n pass: completed,\n score,\n failureClass,\n notes: `${shots.length} shot(s); final pass=${lastVerification.pass}`,\n })\n }\n\n return {\n runId: emitter?.runId ?? null,\n completed,\n shots,\n finalState: state,\n finalVerification: lastVerification,\n failureClass,\n wallMs: Date.now() - wallStart,\n score,\n }\n}\n\n// ── Reviewer helper (LLM-backed) ─────────────────────────────────────\n\nexport type LlmJsonCall = (req: { system: string; user: string }) => Promise<unknown>\n\nexport interface LlmReviewerConfig<State, Summary = unknown> {\n callJson: LlmJsonCall\n renderState?: (state: State) => string\n renderTraceSummary?: (summary: Summary | undefined) => string\n /** Appended to the default system prompt. */\n systemPromptAddendum?: string\n}\n\nconst REVIEWER_SYSTEM_PROMPT = `You are a senior reviewer directing a multi-shot build loop.\nYou do NOT grade — the verifier already did. Your job is to direct the worker's next shot.\nYou are blind to the worker's inner monologue. You see what it DID, not what it thought.\nReturn STRICT JSON matching the schema. No prose outside the JSON.`\n\nexport function createLlmReviewer<State, Summary = unknown>(\n cfg: LlmReviewerConfig<State, Summary>,\n): ReviewFn<State, Summary> {\n const renderState = cfg.renderState ?? ((s: State) => safeJson(s))\n const renderTraceSummary =\n cfg.renderTraceSummary ??\n ((s: Summary | undefined) => (s === undefined ? '(none)' : safeJson(s)))\n const system = cfg.systemPromptAddendum\n ? `${REVIEWER_SYSTEM_PROMPT}\\n\\n${cfg.systemPromptAddendum}`\n : REVIEWER_SYSTEM_PROMPT\n\n return async (input) => {\n const memoryBlock =\n input.memory.length === 0\n ? '(no prior shots — this is shot 1)'\n : input.memory\n .map((m) =>\n [\n `shot ${m.shot} — verification.pass=${m.verification.pass}` +\n (typeof m.verification.score === 'number'\n ? ` score=${m.verification.score.toFixed(2)}`\n : '') +\n ` confidence=${m.confidence.toFixed(2)} failing=[${(m.verification.failingLayers ?? []).join(',')}]`,\n ` observations: ${m.observations.slice(0, 400)}`,\n ` diagnosis: ${m.diagnosis.slice(0, 400)}`,\n ` instruction given: ${m.nextShotInstruction.slice(0, 400)}`,\n ].join('\\n'),\n )\n .join('\\n\\n')\n\n const user = [\n `=== GOAL ===`,\n input.goal,\n ``,\n `=== SHOT NUMBER ===`,\n String(input.shot),\n ``,\n `=== CURRENT STATE ===`,\n renderState(input.state),\n ``,\n `=== TRACE SUMMARY ===`,\n renderTraceSummary(input.traceSummary),\n ``,\n `=== VERIFICATION ===`,\n summarizeVerification(input.verification),\n ``,\n `=== REVIEWER MEMORY (prior shots) ===`,\n memoryBlock,\n ``,\n `=== YOUR TASK ===`,\n `Return STRICT JSON:`,\n `{`,\n ` \"observations\": string (20..2000 chars, first-person worker behavior — quote counts, errors, loops)`,\n ` \"diagnosis\": string (20..1500 chars, root cause, NOT a restatement of verification)`,\n ` \"nextShotInstruction\": string (40..3000 chars, concrete directive to the worker)`,\n ` \"shouldContinue\": boolean (false if verification.pass, or if thrashing, or unachievable)`,\n ` \"confidence\": number in [0,1]`,\n `}`,\n ].join('\\n')\n\n const raw = await cfg.callJson({ system, user })\n return coerceReview(raw as Partial<Review>)\n }\n}\n\n// ── Helpers ──────────────────────────────────────────────────────────\n\nfunction coerceReview(raw: Partial<Review> | null | undefined): Review {\n if (!raw || typeof raw !== 'object') {\n throw new Error('reviewer returned non-object')\n }\n const observations = typeof raw.observations === 'string' ? raw.observations : ''\n const diagnosis = typeof raw.diagnosis === 'string' ? raw.diagnosis : ''\n const nextShotInstruction =\n typeof raw.nextShotInstruction === 'string' ? raw.nextShotInstruction : ''\n if (!observations || !diagnosis || !nextShotInstruction) {\n throw new Error('reviewer missing required string fields')\n }\n if (typeof raw.shouldContinue !== 'boolean') {\n throw new Error('reviewer missing shouldContinue boolean')\n }\n const confidenceRaw = Number(raw.confidence)\n if (!Number.isFinite(confidenceRaw)) {\n throw new Error('reviewer confidence not finite')\n }\n return {\n observations,\n diagnosis,\n nextShotInstruction,\n shouldContinue: raw.shouldContinue,\n confidence: Math.max(0, Math.min(1, confidenceRaw)),\n }\n}\n\nfunction summarizeVerification(v: Verification): string {\n const header =\n `pass=${v.pass}` +\n (typeof v.score === 'number' ? ` score=${v.score.toFixed(3)}` : '') +\n (v.failingLayers && v.failingLayers.length > 0\n ? ` failing=[${v.failingLayers.join(', ')}]`\n : '')\n const details = v.details === undefined ? '' : `\\n${safeJson(v.details).slice(0, 1500)}`\n return header + details\n}\n\nfunction safeJson(x: unknown): string {\n try {\n return JSON.stringify(x, null, 2)\n } catch {\n return String(x)\n }\n}\n","import {\n type ControlRunResult,\n type ControlRuntimeConfig,\n objectiveEval,\n runAgentControlLoop,\n} from './control-runtime'\nimport {\n inMemoryReviewStore,\n type ProposeFn,\n type ProposeOutput,\n type Review,\n type ReviewFn,\n type ReviewMemoryEntry,\n type ReviewMemoryStore,\n type Verification,\n type VerifyFn,\n} from './propose-review'\nimport type { FailureClass } from './trace/schema'\nimport type { TraceStore } from './trace/store'\n\nexport interface ProposeReviewControlState<State, Summary = unknown> {\n shot: number\n state: State\n priorReview: Review | null\n verification: Verification\n traceSummary?: Summary\n memory: ReviewMemoryEntry[]\n completed: boolean\n reviewAvailable: boolean\n reviewError?: string\n}\n\nexport interface ProposeReviewControlAction {\n type: 'propose-review-shot'\n shot: number\n}\n\nexport interface ProposeReviewControlResult<State, Summary = unknown> {\n state: State\n verification: Verification\n traceSummary?: Summary\n review: Review | null\n reviewAvailable: boolean\n reviewError?: string\n}\n\nexport interface ProposeReviewControlConfig<State, Summary = unknown> {\n goal: string\n initialState: State\n propose: ProposeFn<State, Summary>\n verify: VerifyFn<State>\n review: ReviewFn<State, Summary>\n maxShots?: number\n maxWallMs?: number\n memory?: ReviewMemoryStore\n store?: TraceStore\n scenarioId?: string\n projectId?: string\n variantId?: string\n fallbackInstruction?: string\n confidenceFloor?: number\n confidenceFloorWindow?: number\n failureClassFromVerification?: (verification: Verification) => FailureClass | undefined\n actionFailure?: ControlRuntimeConfig<\n ProposeReviewControlState<State, Summary>,\n ProposeReviewControlAction,\n ProposeReviewControlResult<State, Summary>\n >['actionFailure']\n}\n\nconst DEFAULT_FALLBACK_INSTRUCTION =\n 'Inspect the verification failures above. Fix the critical issues first, then the major ones. Do not restate the failures — act on them.'\n\nexport async function runProposeReviewAsControlLoop<State, Summary = unknown>(\n config: ProposeReviewControlConfig<State, Summary>,\n): Promise<\n ControlRunResult<\n ProposeReviewControlState<State, Summary>,\n ProposeReviewControlAction,\n ProposeReviewControlResult<State, Summary>\n >\n> {\n const maxShots = config.maxShots ?? 10\n const confidenceFloor = config.confidenceFloor ?? 0.3\n const confidenceFloorWindow = config.confidenceFloorWindow ?? 2\n const memory = config.memory ?? inMemoryReviewStore()\n const fallbackInstruction = config.fallbackInstruction ?? DEFAULT_FALLBACK_INSTRUCTION\n const failureClassFromVerification =\n config.failureClassFromVerification ?? controlFailureClassFromVerification\n let lowConfidenceStreak = 0\n\n let current: ProposeReviewControlState<State, Summary> = {\n shot: 0,\n state: config.initialState,\n priorReview: null,\n verification: { pass: false },\n memory: await memory.load(),\n completed: false,\n reviewAvailable: false,\n }\n\n return runAgentControlLoop({\n intent: config.goal,\n budget: { maxSteps: maxShots, maxWallMs: config.maxWallMs },\n store: config.store,\n scenarioId: config.scenarioId ?? 'propose-review-control',\n projectId: config.projectId,\n variantId: config.variantId,\n actionFailure: config.actionFailure ?? 'stop',\n observe: () => current,\n validate: ({ state }) => [\n objectiveEval({\n id: 'verification',\n passed: state.verification.pass,\n score: state.verification.score,\n severity: 'critical',\n detail: state.verification.pass\n ? 'verification passed'\n : `verification failed${state.verification.failingLayers?.length ? `: ${state.verification.failingLayers.join(', ')}` : ''}`,\n }),\n ],\n shouldStop: ({ state }) => {\n if (state.verification.pass) {\n return {\n stop: true,\n pass: true,\n reason: 'verification passed',\n score: state.verification.score,\n }\n }\n if (state.completed) {\n return {\n stop: true,\n pass: false,\n reason: 'reviewer stopped continuation',\n score: state.verification.score,\n failureClass: failureClassFromVerification(state.verification),\n }\n }\n return {\n stop: false,\n pass: false,\n reason: 'verification still failing',\n score: state.verification.score,\n }\n },\n decide: ({ state }) => ({\n type: 'continue',\n action: { type: 'propose-review-shot', shot: state.shot + 1 },\n reason: state.priorReview?.nextShotInstruction ?? fallbackInstruction,\n }),\n act: async (action, ctx) => {\n const shot = action.shot\n const proposeOut: ProposeOutput<State, Summary> = await config.propose({\n shot,\n goal: config.goal,\n state: current.state,\n priorReview: current.priorReview,\n abortSignal: ctx.abortSignal,\n emitter: ctx.emitter,\n })\n\n const nextState = proposeOut.state\n const verification = await config.verify(nextState)\n let review: Review | null = null\n let reviewAvailable = false\n let reviewError: string | undefined\n let shouldContinue = !verification.pass\n\n if (!verification.pass) {\n try {\n review = await config.review({\n shot,\n goal: config.goal,\n state: nextState,\n verification,\n traceSummary: proposeOut.traceSummary,\n memory: await memory.load(),\n })\n reviewAvailable = true\n shouldContinue = review.shouldContinue\n lowConfidenceStreak = review.confidence <= confidenceFloor ? lowConfidenceStreak + 1 : 0\n if (confidenceFloorWindow > 0 && lowConfidenceStreak >= confidenceFloorWindow)\n shouldContinue = false\n } catch (err) {\n reviewError = err instanceof Error ? err.message : String(err)\n review = current.priorReview ?? {\n observations: 'Reviewer unavailable.',\n diagnosis: reviewError,\n nextShotInstruction: fallbackInstruction,\n shouldContinue: true,\n confidence: 0,\n }\n shouldContinue = true\n }\n } else {\n review = {\n observations: 'Verification passed.',\n diagnosis: 'No further revision needed.',\n nextShotInstruction: '',\n shouldContinue: false,\n confidence: 1,\n }\n }\n\n const entry: ReviewMemoryEntry = {\n ...(review ?? {\n observations: 'No review.',\n diagnosis: '',\n nextShotInstruction: fallbackInstruction,\n shouldContinue,\n confidence: 0,\n }),\n shot,\n timestamp: Date.now(),\n verification: {\n pass: verification.pass,\n score: verification.score,\n failingLayers: verification.failingLayers,\n },\n }\n await memory.append(entry)\n\n current = {\n shot,\n state: nextState,\n priorReview: review,\n verification,\n traceSummary: proposeOut.traceSummary,\n memory: await memory.load(),\n completed: verification.pass || !shouldContinue,\n reviewAvailable,\n reviewError,\n }\n\n return {\n state: nextState,\n verification,\n traceSummary: proposeOut.traceSummary,\n review,\n reviewAvailable,\n reviewError,\n }\n },\n })\n}\n\nexport function controlFailureClassFromVerification(\n verification: Verification,\n): FailureClass | undefined {\n if (verification.pass) return undefined\n return verification.failingLayers?.length ? 'instruction_following' : 'unknown'\n}\n","/**\n * Capability-headroom gate — \"can this task set even SEE the capability\n * you're about to A/B?\"\n *\n * A capability A/B (grant one arm a tool, a skill, extra context — anything)\n * can only detect the capability on tasks the capability-ABSENT baseline\n * FAILS. A task the baseline already passes is saturated: the treatment arm\n * has no headroom to demonstrate anything, and averaging saturated tasks into\n * the comparison dilutes a real effect toward a false null. Calibrate before\n * measuring: run the baseline arm first, classify every task's headroom, and\n * refuse to run the comparison when no task has a gap.\n *\n * Fail-closed on unknown outcomes: a baseline run whose outcome could not be\n * determined (infra loss, unverified, missing) NEVER counts as a failure —\n * treating \"couldn't tell\" as \"failed\" would manufacture headroom out of\n * telemetry gaps and launder infra noise into a treatment effect.\n *\n * Domain-free by construction: the capability under test never appears here.\n * Callers decide what the baseline arm lacks; this module only classifies\n * baseline outcomes per task.\n */\n\nimport { ValidationError } from './errors'\n\n/** One baseline-arm (capability-absent) observation of one task. */\nexport interface HeadroomInput {\n /** Stable task identity; multiple rows per task are multiple baseline reps. */\n taskId: string\n /** Baseline outcome. 'unknown' = the outcome could not be determined —\n * distinct from 'fail' and never counted as one. */\n baselineOutcome: 'pass' | 'fail' | 'unknown'\n}\n\n/** Headroom classification for one task.\n * - 'gap': the baseline fails it — the comparison can see the capability here.\n * - 'saturated': the baseline already passes it — no headroom.\n * - 'unknown': every baseline outcome is unknown — fail-closed, not a gap. */\nexport type HeadroomClass = 'gap' | 'saturated' | 'unknown'\n\nexport interface TaskHeadroom {\n taskId: string\n /** Total baseline observations for this task (known + unknown). */\n n: number\n /** Observations with a known ('pass' | 'fail') outcome — the evidence the\n * classification actually rests on. A large `n` with a small `nKnown`\n * means the headroom verdict is thin, not well-replicated. */\n nKnown: number\n /** Pass rate over KNOWN outcomes only; NaN when every outcome is unknown\n * (no data ≠ measured zero). */\n baselinePassRate: number\n headroom: HeadroomClass\n}\n\nexport interface CapabilityHeadroomOptions {\n /** A task counts as 'gap' when its baseline pass rate is ≤ this. Default 0\n * (the baseline must fail every known rep). Must be in [0, 1) — a\n * threshold of 1 would classify a fully-saturated task as a gap. */\n keepThreshold?: number\n}\n\nexport interface CapabilityHeadroomResult {\n /** Per-task classification, sorted by `taskId`. */\n tasks: TaskHeadroom[]\n summary: {\n tasksWithGap: number\n tasksSaturated: number\n tasksUnknown: number\n /** Total unknown-outcome reps across ALL tasks (including tasks that\n * still classified via their known reps) — the size of the telemetry\n * hole behind the classifications. */\n repsUnknown: number\n }\n}\n\n/**\n * Classify every task's baseline headroom from capability-absent baseline\n * outcomes.\n *\n * A task is 'gap' when it has ≥ 1 known outcome and its pass rate over known\n * outcomes is ≤ `keepThreshold`; 'saturated' when the rate exceeds the\n * threshold; 'unknown' when every outcome is unknown. Unknown reps never\n * count toward the rate in either direction (fail-closed — see the module\n * doc), and evidence strength stays visible: each task reports `nKnown`\n * alongside `n`, and the summary totals the unknown reps in `repsUnknown`.\n * Throws on empty input, an out-of-range `keepThreshold`, or an\n * unrecognized outcome value (rows are often projected from untyped records).\n */\nexport function capabilityHeadroom(\n rows: readonly HeadroomInput[],\n opts: CapabilityHeadroomOptions = {},\n): CapabilityHeadroomResult {\n const keepThreshold = opts.keepThreshold ?? 0\n if (!Number.isFinite(keepThreshold) || keepThreshold < 0 || keepThreshold >= 1) {\n throw new ValidationError(\n `capabilityHeadroom: keepThreshold must be in [0, 1), got ${keepThreshold}`,\n )\n }\n if (rows.length === 0) {\n throw new ValidationError(\n 'capabilityHeadroom: no baseline rows supplied — run the capability-absent baseline arm first',\n )\n }\n\n // taskId → { n, passes, known }\n const byTask = new Map<string, { n: number; passes: number; known: number }>()\n for (const row of rows) {\n if (\n row.baselineOutcome !== 'pass' &&\n row.baselineOutcome !== 'fail' &&\n row.baselineOutcome !== 'unknown'\n ) {\n throw new ValidationError(\n `capabilityHeadroom: unrecognized baselineOutcome '${row.baselineOutcome}' for task '${row.taskId}' (expected 'pass' | 'fail' | 'unknown')`,\n )\n }\n const agg = byTask.get(row.taskId) ?? { n: 0, passes: 0, known: 0 }\n agg.n++\n if (row.baselineOutcome !== 'unknown') {\n agg.known++\n if (row.baselineOutcome === 'pass') agg.passes++\n }\n byTask.set(row.taskId, agg)\n }\n\n const tasks: TaskHeadroom[] = [...byTask.entries()]\n .sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0))\n .map(([taskId, agg]) => {\n if (agg.known === 0) {\n return {\n taskId,\n n: agg.n,\n nKnown: 0,\n baselinePassRate: Number.NaN,\n headroom: 'unknown' as const,\n }\n }\n const baselinePassRate = agg.passes / agg.known\n return {\n taskId,\n n: agg.n,\n nKnown: agg.known,\n baselinePassRate,\n headroom: baselinePassRate <= keepThreshold ? ('gap' as const) : ('saturated' as const),\n }\n })\n\n const summary = {\n tasksWithGap: tasks.filter((t) => t.headroom === 'gap').length,\n tasksSaturated: tasks.filter((t) => t.headroom === 'saturated').length,\n tasksUnknown: tasks.filter((t) => t.headroom === 'unknown').length,\n repsUnknown: tasks.reduce((sum, t) => sum + (t.n - t.nKnown), 0),\n }\n return { tasks, summary }\n}\n\nexport interface AssertCapabilityHeadroomOptions {\n /** Minimum tasks classified 'gap' for the comparison to proceed. Default 1. */\n minTasksWithGap?: number\n}\n\n/**\n * The go/no-go guard: throws when fewer than `minTasksWithGap` tasks have\n * baseline headroom — i.e. the benchmark cannot see the capability, so any\n * comparison run on it would measure noise. Call between the baseline\n * calibration run and the treatment run.\n */\nexport function assertCapabilityHeadroom(\n result: CapabilityHeadroomResult,\n opts: AssertCapabilityHeadroomOptions = {},\n): void {\n const minTasksWithGap = opts.minTasksWithGap ?? 1\n if (!Number.isInteger(minTasksWithGap) || minTasksWithGap < 1) {\n throw new ValidationError(\n `assertCapabilityHeadroom: minTasksWithGap must be an integer ≥ 1, got ${minTasksWithGap}`,\n )\n }\n const { tasksWithGap, tasksSaturated, tasksUnknown } = result.summary\n if (tasksWithGap < minTasksWithGap) {\n const total = result.tasks.length\n throw new ValidationError(\n `assertCapabilityHeadroom: only ${tasksWithGap} of ${total} task(s) have baseline headroom ` +\n `(need ≥ ${minTasksWithGap}). ${tasksSaturated} saturated (baseline already passes), ` +\n `${tasksUnknown} unknown (no determinable baseline outcome). A capability A/B on this ` +\n `task set cannot detect the capability — add tasks the baseline fails, or fix baseline ` +\n `outcome capture, before measuring.`,\n )\n }\n}\n","/**\n * Cost tracker — token + USD accounting per scenario and per run.\n *\n * Adapted from generic usage-event accounting. Every\n * optimizer needs to know \"is the quality gain worth the cost delta?\",\n * and every dashboard needs dollars-per-completed-task. MODEL_PRICING\n * from metrics.ts stays authoritative for estimate math; this module\n * adds the aggregation + per-scenario roll-up that was duplicated\n * across 4 verticals.\n */\n\nimport { estimateCost } from './metrics'\n\nexport interface TokenSpec {\n inputTokens: number\n outputTokens: number\n cachedTokens?: number\n reasoningTokens?: number\n}\n\nexport interface CostEntry extends TokenSpec {\n scenarioId: string\n model: string\n /** Override estimate with an observed cost (e.g. from provider response). */\n actualCostUsd?: number\n timestamp: number\n /** Free-form tags (variant id, round #, etc.). */\n tags?: Record<string, string>\n}\n\nexport interface ScenarioCost {\n scenarioId: string\n entries: CostEntry[]\n totalInputTokens: number\n totalOutputTokens: number\n totalCachedTokens: number\n totalCostUsd: number\n /** Pass flag — set by consumer via markOutcome; used for cost-per-completed-task. */\n completed?: boolean\n}\n\nexport class CostTracker {\n private byScenario = new Map<string, ScenarioCost>()\n\n record(entry: Omit<CostEntry, 'timestamp'> & { timestamp?: number }): CostEntry {\n const full: CostEntry = { timestamp: entry.timestamp ?? Date.now(), ...entry }\n assertNonNegative(full.inputTokens, 'inputTokens')\n assertNonNegative(full.outputTokens, 'outputTokens')\n let bucket = this.byScenario.get(full.scenarioId)\n if (!bucket) {\n bucket = {\n scenarioId: full.scenarioId,\n entries: [],\n totalInputTokens: 0,\n totalOutputTokens: 0,\n totalCachedTokens: 0,\n totalCostUsd: 0,\n }\n this.byScenario.set(full.scenarioId, bucket)\n }\n bucket.entries.push(full)\n bucket.totalInputTokens += full.inputTokens\n bucket.totalOutputTokens += full.outputTokens\n bucket.totalCachedTokens += full.cachedTokens ?? 0\n bucket.totalCostUsd += costFor(full)\n return full\n }\n\n markOutcome(scenarioId: string, completed: boolean): void {\n const bucket = this.byScenario.get(scenarioId)\n if (!bucket) throw new Error(`CostTracker.markOutcome: unknown scenario \"${scenarioId}\"`)\n bucket.completed = completed\n }\n\n /**\n * Convenience: record + markOutcome in one call from a\n * `{ usage, verdict }`-shaped response (starter-foundry's\n * `invokeMetaJudge` returns this shape; consumers that wrap any\n * judge/critic can follow the same convention).\n *\n * `usage.model` must be present in `MODEL_PRICING` for cost math to\n * populate; otherwise totalCostUsd stays at 0 for the entry but\n * tokens still aggregate.\n */\n recordVerdict(\n verdict: {\n usage?: {\n inputTokens: number\n outputTokens: number\n model: string\n cachedTokens?: number\n reasoningTokens?: number\n }\n verdict?: 'pass' | 'fail' | 'borderline' | string\n },\n scenarioId: string,\n tags?: Record<string, string>,\n ): CostEntry | null {\n if (!verdict.usage) return null\n const entry = this.record({\n scenarioId,\n model: verdict.usage.model,\n inputTokens: verdict.usage.inputTokens,\n outputTokens: verdict.usage.outputTokens,\n cachedTokens: verdict.usage.cachedTokens,\n reasoningTokens: verdict.usage.reasoningTokens,\n tags,\n })\n this.markOutcome(scenarioId, verdict.verdict === 'pass')\n return entry\n }\n\n get(scenarioId: string): ScenarioCost | undefined {\n return this.byScenario.get(scenarioId)\n }\n\n list(): ScenarioCost[] {\n return [...this.byScenario.values()]\n }\n\n summary(): CostSummary {\n const scenarios = this.list()\n const completed = scenarios.filter((s) => s.completed === true)\n const totalCost = scenarios.reduce((a, s) => a + s.totalCostUsd, 0)\n const totalInput = scenarios.reduce((a, s) => a + s.totalInputTokens, 0)\n const totalOutput = scenarios.reduce((a, s) => a + s.totalOutputTokens, 0)\n const totalCompletedCost = completed.reduce((a, s) => a + s.totalCostUsd, 0)\n return {\n scenarioCount: scenarios.length,\n completedCount: completed.length,\n totalInputTokens: totalInput,\n totalOutputTokens: totalOutput,\n totalCostUsd: totalCost,\n avgCostPerScenarioUsd: scenarios.length ? totalCost / scenarios.length : 0,\n costPerCompletedTaskUsd: completed.length ? totalCompletedCost / completed.length : null,\n }\n }\n}\n\nexport interface CostSummary {\n scenarioCount: number\n completedCount: number\n totalInputTokens: number\n totalOutputTokens: number\n totalCostUsd: number\n avgCostPerScenarioUsd: number\n /** Total USD / completed scenarios — null when nothing completed. */\n costPerCompletedTaskUsd: number | null\n}\n\nfunction costFor(entry: CostEntry): number {\n if (typeof entry.actualCostUsd === 'number' && Number.isFinite(entry.actualCostUsd)) {\n return entry.actualCostUsd\n }\n return estimateCost(entry.inputTokens, entry.outputTokens, entry.model)\n}\n\nfunction assertNonNegative(n: number, name: string): void {\n if (!Number.isFinite(n) || n < 0) {\n throw new Error(`CostTracker: ${name} must be a non-negative finite number, got ${n}`)\n }\n}\n","/**\n * Toolchain error-count extractor.\n *\n * Given stderr/stdout from a compiler or test runner, count the number\n * of reported errors/failures. Patterns are deliberately narrow —\n * unknown stderr returns `null` rather than zero so callers can\n * distinguish \"no errors\" from \"different toolchain, couldn't parse\".\n *\n * All patterns are anchored to the start of a line and use bounded\n * character classes to avoid catastrophic backtracking on pathological\n * inputs.\n *\n * Add new toolchains by appending to {@link ERROR_COUNT_PATTERNS};\n * order matters only in the sense that the first matching pattern wins.\n */\n\nexport interface ErrorCountPattern {\n /** Stable identifier for logging + tests. */\n name: string\n /** Must be global (`g` flag) — the extractor counts matches. */\n regex: RegExp\n /** Optional post-processing to extract a count from a single captured match. */\n transform?: (match: RegExpMatchArray) => number\n}\n\nexport const ERROR_COUNT_PATTERNS: ErrorCountPattern[] = [\n {\n // tsc / ts-node: `src/foo.ts(12,3): error TS1234: ...`\n name: 'typescript-tsc',\n regex: /[\\w./-]+\\(\\d+,\\d+\\): error TS\\d+:/g,\n },\n {\n // pytest: `FAILED tests/test_foo.py::test_bar`\n name: 'pytest-failed',\n regex: /^FAILED\\s+\\S+/gm,\n },\n {\n // rustc: `error[E0308]: ...` or `error: ...`\n name: 'rustc',\n regex: /^error(?:\\[[A-Z]\\d+\\])?:/gm,\n },\n {\n // go build: `./foo.go:12:3: ...` — any file:line:col: is an error line\n name: 'golang',\n regex: /^\\.\\/[\\w./-]+\\.go:\\d+:\\d+:/gm,\n },\n {\n // eslint default formatter per-line: ` 12:34 error message rule-id`\n name: 'eslint',\n regex: /^\\s+\\d+:\\d+\\s+error\\s+/gm,\n },\n {\n // eslint summary line: `✖ 17 problems (12 errors, 5 warnings)`\n // Use this only when the per-line formatter isn't present; transform\n // reads the errors count directly.\n name: 'eslint-summary',\n regex: /✖\\s+\\d+\\s+problems?\\s+\\((\\d+)\\s+errors?/gm,\n transform: (m) => Number(m[1] ?? 0),\n },\n]\n\nexport interface ExtractOptions {\n /** Restrict to named patterns — default: all patterns. */\n only?: string[]\n /** Additional patterns to consider BEFORE the built-in list. */\n extra?: ErrorCountPattern[]\n}\n\nexport interface ExtractResult {\n /** Total count of matched errors, or null when no pattern matched. */\n count: number | null\n /** Name of the pattern that matched, or null. */\n matched: string | null\n /** Original matches for callers that want to surface specifics. */\n samples: string[]\n}\n\n/**\n * Try each pattern in order; return the first with matches.\n *\n * Returning `null` (instead of zero) on no-match is deliberate — a\n * callsite that greps for \"typescript errors\" on cargo output should\n * NOT treat that as \"zero TS errors\" because the toolchain is wrong.\n */\nexport function extractErrorCount(text: string, opts: ExtractOptions = {}): ExtractResult {\n if (!text) return { count: null, matched: null, samples: [] }\n\n const patterns = [...(opts.extra ?? []), ...ERROR_COUNT_PATTERNS].filter(\n (p) => !opts.only || opts.only.includes(p.name),\n )\n\n for (const p of patterns) {\n const matches = Array.from(text.matchAll(p.regex))\n if (matches.length === 0) continue\n\n const count = p.transform\n ? matches.reduce((sum, m) => sum + p.transform!(m), 0)\n : matches.length\n\n return {\n count,\n matched: p.name,\n samples: matches.slice(0, 5).map((m) => m[0]),\n }\n }\n\n return { count: null, matched: null, samples: [] }\n}\n","import { type ControlEvalResult, objectiveEval } from '../control-runtime'\nimport type { TraceEmitter } from '../trace/emitter'\nimport type {\n DataAcquisitionPlan,\n KnowledgeAcquisitionMode,\n KnowledgeBundle,\n KnowledgeImportance,\n KnowledgeReadinessReport,\n KnowledgeRecommendedAction,\n KnowledgeRequirement,\n UserQuestion,\n} from './types'\n\nexport interface ScoreKnowledgeReadinessOptions {\n taskId: string\n requirements: KnowledgeRequirement[]\n evidenceIds?: string[]\n claimIds?: string[]\n wikiPageIds?: string[]\n userAnswers?: Record<string, string>\n metadata?: Record<string, unknown>\n now?: Date\n}\n\nexport function scoreKnowledgeReadiness(\n options: ScoreKnowledgeReadinessOptions,\n): KnowledgeReadinessReport {\n const now = options.now ?? new Date()\n const requirements = options.requirements.map(normalizeRequirement)\n const missing = requirements.filter((requirement) => isRequirementMissing(requirement, now))\n const blockingMissingRequirements = missing.filter(isBlockingGap)\n const nonBlockingGaps = missing.filter((requirement) => !isBlockingGap(requirement))\n const readinessScore = weightedReadinessAt(requirements, now)\n const bundle: KnowledgeBundle = {\n taskId: options.taskId,\n requirements,\n evidenceIds: unique([\n ...(options.evidenceIds ?? []),\n ...requirements.flatMap((r) => r.evidenceIds),\n ]),\n claimIds: unique(options.claimIds ?? []),\n wikiPageIds: unique(options.wikiPageIds ?? []),\n userAnswers: options.userAnswers ?? {},\n missing,\n readinessScore,\n metadata: options.metadata,\n }\n const recommendedAction = chooseRecommendedAction(blockingMissingRequirements, nonBlockingGaps)\n const severity =\n blockingMissingRequirements.length > 0\n ? 'critical'\n : nonBlockingGaps.some((gap) => gap.importance === 'high')\n ? 'warning'\n : 'info'\n const reason =\n blockingMissingRequirements.length > 0\n ? `${blockingMissingRequirements.length} blocking knowledge requirement(s) are missing.`\n : nonBlockingGaps.length > 0\n ? `${nonBlockingGaps.length} non-blocking knowledge gap(s) remain.`\n : 'All declared knowledge requirements are ready.'\n\n return {\n taskId: options.taskId,\n readinessScore,\n blockingMissingRequirements,\n nonBlockingGaps,\n recommendedAction,\n bundle,\n severity,\n reason,\n }\n}\n\nexport function blockingKnowledgeEval(\n report: KnowledgeReadinessReport,\n options: { id?: string; minimumScore?: number; emitter?: TraceEmitter } = {},\n): ControlEvalResult {\n const minimumScore = options.minimumScore ?? 0.7\n const passed =\n report.blockingMissingRequirements.length === 0 && report.readinessScore >= minimumScore\n if (options.emitter) {\n void options.emitter\n .emit({\n kind: 'custom',\n payload: knowledgeReadinessTracePayload(report, { passed, minimumScore }),\n })\n .catch(() => undefined)\n }\n return objectiveEval({\n id: options.id ?? 'knowledge-ready',\n passed,\n score: report.readinessScore,\n severity: passed ? 'info' : report.severity,\n detail: report.reason,\n evidence: report.blockingMissingRequirements.map((r) => r.id).join(', ') || undefined,\n metadata: { knowledgeReadiness: report },\n })\n}\n\nexport function knowledgeReadinessTracePayload(\n report: KnowledgeReadinessReport,\n options: { passed?: boolean; minimumScore?: number } = {},\n): Record<string, unknown> {\n return {\n kind: 'readiness_scored',\n taskId: report.taskId,\n passed: options.passed ?? report.blockingMissingRequirements.length === 0,\n readinessScore: report.readinessScore,\n minimumScore: options.minimumScore,\n blockingRequirementIds: report.blockingMissingRequirements.map((r) => r.id),\n nonBlockingRequirementIds: report.nonBlockingGaps.map((r) => r.id),\n recommendedAction: report.recommendedAction,\n severity: report.severity,\n reason: report.reason,\n }\n}\n\nexport function userQuestionsForKnowledgeGaps(gaps: KnowledgeRequirement[]): UserQuestion[] {\n return gaps\n .filter((gap) => gap.acquisitionMode === 'ask_user' || gap.fallbackPolicy === 'ask')\n .map((gap) => ({\n id: `question_${gap.id}`,\n question: `Please provide: ${gap.description}`,\n reason: `Required for ${gap.requiredFor.join(', ') || 'the task'}.`,\n requirementId: gap.id,\n importance: gap.importance,\n answerType: gap.sensitivity === 'secret' ? 'credential' : 'free_text',\n impactIfUnknown: impactFor(gap),\n }))\n}\n\nexport function acquisitionPlansForKnowledgeGaps(\n gaps: KnowledgeRequirement[],\n): DataAcquisitionPlan[] {\n const byMode = new Map<string, KnowledgeRequirement[]>()\n for (const gap of gaps) {\n const mode = planMode(gap.acquisitionMode)\n if (!mode) continue\n const bucket = byMode.get(mode) ?? []\n bucket.push(gap)\n byMode.set(mode, bucket)\n }\n return [...byMode.entries()].map(([mode, requirements]) => ({\n id: `acquire_${mode}`,\n requirementIds: requirements.map((r) => r.id),\n mode: mode as DataAcquisitionPlan['mode'],\n description: descriptionForPlan(mode as DataAcquisitionPlan['mode'], requirements),\n priority: maxImportance(requirements.map((r) => r.importance)),\n questions: mode === 'ask_user' ? userQuestionsForKnowledgeGaps(requirements) : undefined,\n }))\n}\n\nfunction normalizeRequirement(requirement: KnowledgeRequirement): KnowledgeRequirement {\n return {\n ...requirement,\n confidenceNeeded: clamp01(requirement.confidenceNeeded),\n currentConfidence: clamp01(requirement.currentConfidence),\n evidenceIds: unique(requirement.evidenceIds),\n }\n}\n\nfunction weightedReadinessAt(requirements: KnowledgeRequirement[], now: Date): number {\n if (requirements.length === 0) return 1\n let weightSum = 0\n let scoreSum = 0\n for (const requirement of requirements) {\n const weight = importanceWeight(requirement.importance)\n const score = isExpired(requirement, now)\n ? 0\n : requirement.confidenceNeeded <= 0\n ? 1\n : Math.min(1, requirement.currentConfidence / requirement.confidenceNeeded)\n weightSum += weight\n scoreSum += weight * score\n }\n return clamp01(scoreSum / weightSum)\n}\n\nfunction isRequirementMissing(requirement: KnowledgeRequirement, now: Date): boolean {\n return isExpired(requirement, now) || requirement.currentConfidence < requirement.confidenceNeeded\n}\n\nfunction isExpired(requirement: KnowledgeRequirement, now: Date): boolean {\n if (!requirement.validUntil) return false\n const deadline = Date.parse(requirement.validUntil)\n if (!Number.isFinite(deadline)) return true\n return deadline <= now.getTime()\n}\n\nfunction isBlockingGap(requirement: KnowledgeRequirement): boolean {\n return (\n requirement.importance === 'blocking' ||\n requirement.fallbackPolicy === 'block' ||\n requirement.sensitivity === 'secret'\n )\n}\n\nfunction chooseRecommendedAction(\n blocking: KnowledgeRequirement[],\n nonBlocking: KnowledgeRequirement[],\n): KnowledgeRecommendedAction {\n const gaps = blocking.length > 0 ? blocking : nonBlocking\n if (gaps.length === 0) return 'run_agent'\n if (gaps.some((gap) => gap.acquisitionMode === 'ask_user' || gap.fallbackPolicy === 'ask'))\n return 'ask_user'\n if (gaps.some((gap) => gap.acquisitionMode === 'query_connector')) return 'query_connectors'\n if (\n gaps.some(\n (gap) => gap.acquisitionMode === 'inspect_repo' || gap.acquisitionMode === 'run_command',\n )\n )\n return 'inspect_repo'\n if (gaps.some((gap) => gap.acquisitionMode === 'search_web')) return 'collect_web_data'\n if (gaps.some((gap) => gap.acquisitionMode === 'not_available')) return 'abort_or_rescope'\n if (nonBlocking.some((gap) => gap.importance === 'high')) return 'build_domain_wiki'\n return 'continue_with_caveat'\n}\n\nfunction planMode(mode: KnowledgeAcquisitionMode): DataAcquisitionPlan['mode'] | null {\n if (mode === 'infer_low_confidence' || mode === 'not_available') return null\n return mode\n}\n\nfunction descriptionForPlan(\n mode: DataAcquisitionPlan['mode'],\n requirements: KnowledgeRequirement[],\n): string {\n const labels = requirements.map((r) => r.description).join('; ')\n if (mode === 'ask_user') return `Ask the user for: ${labels}`\n if (mode === 'search_web') return `Search web or documentation sources for: ${labels}`\n if (mode === 'query_connector') return `Query configured connectors for: ${labels}`\n if (mode === 'inspect_repo') return `Inspect repository context for: ${labels}`\n if (mode === 'run_command') return `Run local commands to collect: ${labels}`\n return `Build domain wiki evidence for: ${labels}`\n}\n\nfunction impactFor(requirement: KnowledgeRequirement): string {\n if (requirement.fallbackPolicy === 'block') return 'The agent should not run until this is known.'\n if (requirement.fallbackPolicy === 'continue_with_caveat')\n return 'The agent may continue, but must disclose uncertainty.'\n if (requirement.fallbackPolicy === 'use_default')\n return 'The agent will use the configured default if skipped.'\n return 'The agent should ask before continuing.'\n}\n\nfunction maxImportance(values: KnowledgeImportance[]): KnowledgeImportance {\n const order: KnowledgeImportance[] = ['blocking', 'high', 'medium', 'low']\n return order.find((value) => values.includes(value)) ?? 'low'\n}\n\nfunction importanceWeight(importance: KnowledgeImportance): number {\n if (importance === 'blocking') return 8\n if (importance === 'high') return 4\n if (importance === 'medium') return 2\n return 1\n}\n\nfunction clamp01(value: number): number {\n if (!Number.isFinite(value)) return 0\n return Math.max(0, Math.min(1, value))\n}\n\nfunction unique<T>(items: T[]): T[] {\n return [...new Set(items)]\n}\n","/**\n * Cross-profile leaderboard — rank agent profiles (or any grouping) over a corpus\n * of RunRecords on pass-rate with a Wilson CI, joined with the cost / token /\n * latency rollup every benchmark wants next to the score.\n *\n * This is substrate, not benchmark-specific: any consumer of agent-eval gets a\n * cross-harness × model leaderboard without re-implementing grouping, binomial\n * CIs, or the observability join. The benchmark supplies only what \"passed\"\n * means; everything else composes existing primitives (`wilson`, the RunRecord\n * cost/token/wall fields, the AgentProfileCell grouping key).\n */\nimport type { RunRecord } from './run-record'\nimport { wilson } from './statistics'\n\nexport interface LeaderboardRow {\n /** Group key — the agent-profile cellId by default, else a caller dimension. */\n key: string\n /** Display label: `harness · model` when the profile carries them, else the key. */\n label: string\n harness?: string\n model?: string\n rank: number\n /** Measured runs in this group. */\n n: number\n passRate: number\n passRateCi95: [number, number]\n /** Observability rollup — means over the group; null when no run reported it. */\n meanCostUsd: number | null\n meanTokensIn: number | null\n meanTokensOut: number | null\n meanWallMs: number | null\n}\n\nexport interface LeaderboardOptions {\n /** Per-run pass predicate — the benchmark defines what \"passed\" means (real-build\n * hit-rate, test-pass, etc.). The leaderboard owns only the grouping + stats. */\n passed: (record: RunRecord) => boolean\n /** Group key. Default: the agent-profile cellId (harness × model × dimensions),\n * so persona/harness/model sweeps separate without parsing labels. */\n groupBy?: (record: RunRecord) => string\n}\n\nfunction mean(xs: number[]): number | null {\n return xs.length ? xs.reduce((a, b) => a + b, 0) / xs.length : null\n}\n\n/**\n * Group `records`, compute pass-rate + Wilson CI + cost/token/latency means per\n * group, and rank by pass-rate (cost as the tiebreaker — cheaper wins a tie).\n * Pure projection: no I/O, deterministic, safe to call on any RunRecord[].\n */\nexport function leaderboard(records: RunRecord[], opts: LeaderboardOptions): LeaderboardRow[] {\n const keyOf = opts.groupBy ?? ((r: RunRecord) => r.agentProfile?.cellId ?? 'ungrouped')\n const groups = new Map<string, RunRecord[]>()\n for (const r of records) {\n const k = keyOf(r)\n const g = groups.get(k)\n if (g) g.push(r)\n else groups.set(k, [r])\n }\n\n const rows: LeaderboardRow[] = [...groups.entries()].map(([key, rs]) => {\n const passes = rs.filter((r) => opts.passed(r)).length\n const ci = wilson(passes, rs.length)\n const profile = rs[0]!.agentProfile\n const harness = profile?.harness?.id\n const model = profile?.model\n const knownCosts = rs.map((r) => r.costUsd).filter(isFiniteNumber)\n return {\n key,\n label: harness && model ? `${harness} · ${model}` : key,\n ...(harness ? { harness } : {}),\n ...(model ? { model } : {}),\n rank: 0,\n n: rs.length,\n passRate: ci.estimate,\n passRateCi95: [ci.lower, ci.upper],\n meanCostUsd: knownCosts.length === rs.length ? mean(knownCosts) : null,\n meanTokensIn: mean(rs.map((r) => r.tokenUsage.input)),\n meanTokensOut: mean(rs.map((r) => r.tokenUsage.output)),\n meanWallMs: mean(rs.map((r) => r.wallMs)),\n }\n })\n\n rows.sort(\n (a, b) => b.passRate - a.passRate || (a.meanCostUsd ?? Infinity) - (b.meanCostUsd ?? Infinity),\n )\n rows.forEach((row, i) => {\n row.rank = i + 1\n })\n return rows\n}\n\nfunction isFiniteNumber(value: unknown): value is number {\n return typeof value === 'number' && Number.isFinite(value)\n}\n","/**\n * Deterministic held-out partitioning over stable ids.\n *\n * A promotion gate's paired-delta math needs a fixed partition: the same\n * scenario id lands in the same bucket forever, regardless of when it ran or\n * which loop emitted the record — otherwise the gate has nothing paired to\n * compare against. Picking one global split per run is wrong: every run then\n * stamps either ALL search or ALL holdout, and no id is ever observed on both\n * sides. Per-id deterministic hashing fixes that.\n *\n * Two consumers hand-roll this (agent-builder's `deterministicSplit` and the\n * frontier persona-splitter). The substrate already has a 3-way benchmark\n * `deterministicSplit` in `./benchmarks`; this is the generic, validated batch\n * partitioner: it takes a list of ids, splits them by a stable FNV-1a hash, and\n * fails loud when the inputs can't support a trustworthy held-out comparison\n * (duplicate ids, or a holdout set below the significance floor).\n */\n\nimport { ValidationError } from './errors'\n\n/** 32-bit FNV-1a hash. Stable, allocation-free, deterministic across runtimes —\n * the same id+seed maps to the same bucket on every machine and process. */\nexport function fnv1a32(input: string): number {\n let h = 0x811c9dc5\n for (let i = 0; i < input.length; i++) {\n h ^= input.charCodeAt(i) & 0xff\n h = Math.imul(h, 0x01000193)\n }\n return h >>> 0\n}\n\n/** Map an id+seed to the half-open unit interval [0, 1) deterministically. */\nexport function hashToUnit(id: string, seed: string): number {\n // Newline separator: 'ab' + '\\n' + 'c' can't collide with 'a' + '\\n' + 'bc'.\n return fnv1a32(`${id}\\n${seed}`) / 0x1_0000_0000\n}\n\nexport interface PartitionHeldOutOptions {\n /** Partition seed. Bumping it reshuffles every assignment — do that only when\n * the corpus/policy changes meaningfully so old and new records can't pair.\n * Default 'held-out-v1'. */\n seed?: string\n /** Fraction routed to the held-out bucket, in (0, 1). Default 0.5. */\n holdoutFraction?: number\n /**\n * Minimum held-out ids required for the split to be admissible. Below this,\n * a paired comparison has too few observations to be significant, so the\n * partition throws rather than hand back an underpowered holdout. Default 1\n * (only the empty-holdout degenerate case is rejected). Raise it to enforce\n * real statistical power. */\n minHoldout?: number\n /** Same floor for the search side. Default 1. */\n minSearch?: number\n}\n\nexport interface HeldOutPartition {\n /** Ids the optimizer is allowed to read/optimize against. */\n search: string[]\n /** Ids reserved for gated, held-out evaluation. */\n holdout: string[]\n seed: string\n holdoutFraction: number\n}\n\n/**\n * Assign a single id to `'search'` or `'holdout'` deterministically. Same\n * `(id, seed)` always returns the same tag — the invariant the gate relies on.\n * Use this in a `splitTag:` field literal when stamping records one at a time;\n * use `partitionHeldOut` when you have the whole id list up front and want the\n * validated disjoint split.\n */\nexport function assignHeldOutTag(\n id: string,\n options: { seed?: string; holdoutFraction?: number } = {},\n): 'search' | 'holdout' {\n const seed = options.seed ?? 'held-out-v1'\n const holdoutFraction = options.holdoutFraction ?? 0.5\n assertFraction(holdoutFraction)\n return hashToUnit(id, seed) < holdoutFraction ? 'holdout' : 'search'\n}\n\n/**\n * Partition a list of stable ids into disjoint `search` / `holdout` sets by a\n * deterministic hash. Fail-loud:\n * - empty input throws,\n * - duplicate ids throw (a dup would be observed on both sides, double-counting),\n * - a holdout (or search) set below its floor throws (underpowered comparison).\n *\n * Order within each bucket follows the input order, so the result is stable and\n * reproducible.\n */\nexport function partitionHeldOut(\n ids: string[],\n options: PartitionHeldOutOptions = {},\n): HeldOutPartition {\n const seed = options.seed ?? 'held-out-v1'\n const holdoutFraction = options.holdoutFraction ?? 0.5\n const minHoldout = options.minHoldout ?? 1\n const minSearch = options.minSearch ?? 1\n assertFraction(holdoutFraction)\n if (ids.length === 0) {\n throw new ValidationError('partitionHeldOut: no ids supplied')\n }\n\n const seen = new Set<string>()\n const search: string[] = []\n const holdout: string[] = []\n for (const id of ids) {\n if (typeof id !== 'string' || id.length === 0) {\n throw new ValidationError(\n `partitionHeldOut: ids must be non-empty strings, got ${JSON.stringify(id)}`,\n )\n }\n if (seen.has(id)) {\n throw new ValidationError(\n `partitionHeldOut: duplicate id \"${id}\" — a paired comparison must not double-count`,\n )\n }\n seen.add(id)\n if (hashToUnit(id, seed) < holdoutFraction) holdout.push(id)\n else search.push(id)\n }\n\n if (holdout.length < minHoldout) {\n throw new ValidationError(\n `partitionHeldOut: holdout set has ${holdout.length} id(s), below the floor of ${minHoldout} ` +\n `(n=${ids.length}, holdoutFraction=${holdoutFraction}) — too few for a significant comparison`,\n )\n }\n if (search.length < minSearch) {\n throw new ValidationError(\n `partitionHeldOut: search set has ${search.length} id(s), below the floor of ${minSearch} ` +\n `(n=${ids.length}, holdoutFraction=${holdoutFraction})`,\n )\n }\n\n return { search, holdout, seed, holdoutFraction }\n}\n\nfunction assertFraction(f: number): void {\n if (!Number.isFinite(f) || f <= 0 || f >= 1) {\n throw new ValidationError(`partitionHeldOut: holdoutFraction must be in (0, 1), got ${f}`)\n }\n}\n","/**\n * Export side of the product benchmark bundle contract: convert product\n * eval run directories (`records.jsonl` of `RunRecord` rows + trace/raw\n * artifacts) into a portable `product-benchmark-manifest.json` +\n * `product-benchmark-records.jsonl` bundle that\n * `validateProductBenchmarkRun` accepts.\n *\n * Product-specific policy (safety-split detection, tool-call recovery,\n * profile id fallback, artifact materialization) enters through explicit\n * options; everything else is the shared union of the tax/legal/creative\n * exporters. Scenario catalogs, smoke runners, and CLIs stay in the\n * products.\n *\n * Input rows are checked structurally, not with `validateRunRecord`:\n * product harnesses record bare model aliases and partial provenance, and\n * the bundle contract's own validators re-check every field that matters\n * on the way out.\n */\n\nimport { spawnSync } from 'node:child_process'\nimport { createHash } from 'node:crypto'\nimport { cpSync, existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs'\nimport { basename, dirname, isAbsolute, join, relative, resolve } from 'node:path'\nimport { ValidationError } from '../errors'\nimport { type RunRecord, runTaskScore } from '../run-record'\nimport type {\n ProductBenchmarkManifest,\n ProductBenchmarkRecord,\n ProductBenchmarkSplit,\n RuntimeResolution,\n} from './index'\nimport { validateProductBenchmarkManifest, validateProductBenchmarkRecord } from './index'\n\n/** Full mutable-surface superset a product arm may declare. */\nexport const productBenchmarkMutableSurfaces = [\n 'prompt',\n 'resources.files',\n 'tools',\n 'mcp',\n 'hooks',\n 'subagents',\n] as const\n\nexport interface ProductBenchmarkExportOptions {\n /** Source eval run directories, each containing a `records.jsonl` of RunRecord rows. */\n readonly runDirs: readonly string[]\n /** Destination directory for the bundle (manifest + records + materialized source runs). */\n readonly outDir: string\n readonly projectId: string\n readonly benchmarkId: string\n /** Repo-relative path of the product's canonical agent profile source. */\n readonly agentProfilePath: string\n /** Pass threshold applied when a row carries no explicit `outcome.raw.pass`. Default 0.7. */\n readonly passThreshold?: number\n /**\n * First scenario tag. Defaults to `projectId` with a trailing `-agent`\n * stripped (`tax-agent` → `tax`), matching the product exporters.\n */\n readonly scenarioTagPrefix?: string\n /** Profile id used when a row has no `agentProfile.profileId`. Defaults to the row's arm id. */\n readonly fallbackProfileId?: string\n /** Arm mutable surfaces recorded in the manifest. Defaults to the full superset. */\n readonly mutableSurfaces?: readonly string[]\n /**\n * Copy each run dir into `<outDir>/source-runs/` and record\n * bundle-relative artifact paths (portable, self-contained). When false,\n * artifacts keep absolute paths into the original run dirs. Default true.\n */\n readonly materializeSourceRuns?: boolean\n /**\n * Override split classification for a row. Return undefined to fall back\n * to the default (`outcome.raw.safety === 1` → safety, then splitTag).\n */\n readonly classifySplit?: (record: RunRecord) => ProductBenchmarkSplit | undefined\n /** Recovers a tool-call count when the row's raw bag carries none (e.g. from turn artifacts). */\n readonly toolCallFallback?: (record: RunRecord, runDir: string) => number\n /** Backend version recorded per row. Defaults to the cwd package.json's `@tangle-network/sandbox` range. */\n readonly backendVersion?: string\n /**\n * Explicit substrate versions for the manifest, merged over what the cwd\n * package.json / node_modules resolve. Use when a substrate package is not\n * installed where the export runs — the validator refuses an `'unknown'`\n * version, so provide the real one rather than shipping the sentinel.\n */\n readonly substrate?: Partial<ProductBenchmarkManifest['substrate']>\n}\n\nexport interface ProductBenchmarkSingleRunExportOptions\n extends Omit<ProductBenchmarkExportOptions, 'runDirs'> {\n readonly runDir: string\n}\n\nexport interface ProductBenchmarkExportResult {\n readonly manifestPath: string\n readonly recordsPath: string\n readonly records: number\n}\n\ninterface ResolvedExportOptions {\n readonly projectId: string\n readonly benchmarkId: string\n readonly agentProfilePath: string\n readonly passThreshold: number\n readonly scenarioTagPrefix: string\n readonly fallbackProfileId?: string\n readonly mutableSurfaces: readonly string[]\n readonly classifySplit?: (record: RunRecord) => ProductBenchmarkSplit | undefined\n readonly toolCallFallback?: (record: RunRecord, runDir: string) => number\n readonly backendVersion: string\n}\n\n// ── Provenance helpers ───────────────────────────────────────────────\n\nfunction sha256(value: string): string {\n return `sha256:${createHash('sha256').update(value).digest('hex')}`\n}\n\nfunction safePathPart(value: string): string {\n return (\n value\n .replace(/[^a-zA-Z0-9_.-]+/g, '-')\n .replace(/^-+|-+$/g, '')\n .slice(0, 80) || 'artifact'\n )\n}\n\nfunction git(args: readonly string[], fallback: string): string {\n const res = spawnSync('git', args, { cwd: process.cwd(), encoding: 'utf8' })\n const value = res.status === 0 ? res.stdout.trim() : ''\n return value.length > 0 ? value : fallback\n}\n\nfunction knownEnv(name: string): string | undefined {\n const value = process.env[name]?.trim()\n return value && value !== 'unknown' ? value : undefined\n}\n\nfunction ciBranchName(): string | undefined {\n const direct =\n knownEnv('GITHUB_HEAD_REF') ?? knownEnv('GITHUB_REF_NAME') ?? knownEnv('VERCEL_GIT_COMMIT_REF')\n if (direct) return direct\n const ref = knownEnv('GITHUB_REF')\n return ref?.startsWith('refs/heads/') ? ref.slice('refs/heads/'.length) : undefined\n}\n\nfunction repoBranch(): string {\n const ci = ciBranchName()\n if (ci) return ci\n const branch = git(['branch', '--show-current'], '')\n if (branch) return branch\n const name = git(['name-rev', '--name-only', '--exclude=tags/*', 'HEAD'], '')\n if (name && name !== 'undefined') return name\n return `detached:${git(['rev-parse', '--short', 'HEAD'], 'unknown')}`\n}\n\n/** Repo identity from the exporting process's cwd. `'unknown'` values are flagged by `validateProductBenchmarkRun`. */\nexport function productBenchmarkRepoIdentity(): ProductBenchmarkManifest['repo'] {\n return {\n url: git(['config', '--get', 'remote.origin.url'], 'unknown'),\n commit: git(['rev-parse', 'HEAD'], 'unknown'),\n branch: repoBranch(),\n }\n}\n\n/** The declared range from the cwd package.json when present, else the\n * INSTALLED version read from node_modules (covers transitive installs —\n * a product that gets sandbox via agent-runtime still records real\n * provenance), else the `'unknown'` sentinel the validator refuses. */\nfunction packageVersion(name: string): string {\n const pkg = JSON.parse(readFileSync(resolve('package.json'), 'utf8')) as {\n name?: string\n version?: string\n dependencies?: Record<string, string>\n devDependencies?: Record<string, string>\n }\n if (pkg.name === name && pkg.version) return pkg.version\n const declared = pkg.dependencies?.[name] ?? pkg.devDependencies?.[name]\n if (declared) return declared\n const installed = resolve('node_modules', name, 'package.json')\n if (existsSync(installed)) {\n const installedPkg = JSON.parse(readFileSync(installed, 'utf8')) as { version?: string }\n if (installedPkg.version) return installedPkg.version\n }\n return 'unknown'\n}\n\n// ── Run record ingestion ─────────────────────────────────────────────\n\nfunction readRunRecords(path: string): RunRecord[] {\n const lines = readFileSync(path, 'utf8')\n .split('\\n')\n .map((line) => line.trim())\n .filter(Boolean)\n return lines.map((line, index) => {\n let parsed: unknown\n try {\n parsed = JSON.parse(line)\n } catch (err) {\n throw new ValidationError(\n `${path}:${index + 1}: ${err instanceof Error ? err.message : String(err)}`,\n { cause: err },\n )\n }\n return expectRunRecordShape(parsed, `${path}:${index + 1}`)\n })\n}\n\nfunction expectRunRecordShape(value: unknown, path: string): RunRecord {\n if (!value || typeof value !== 'object' || Array.isArray(value)) {\n throw new ValidationError(`${path}: run record must be an object`)\n }\n const obj = value as Record<string, unknown>\n for (const key of ['runId', 'model'] as const) {\n if (typeof obj[key] !== 'string' || obj[key].length === 0) {\n throw new ValidationError(`${path}: run record ${key} must be a non-empty string`)\n }\n }\n for (const key of ['costUsd', 'wallMs'] as const) {\n if (typeof obj[key] !== 'number' || !Number.isFinite(obj[key])) {\n throw new ValidationError(`${path}: run record ${key} must be a finite number`)\n }\n }\n const tokenUsage = obj.tokenUsage as Record<string, unknown> | undefined\n if (\n !tokenUsage ||\n typeof tokenUsage.input !== 'number' ||\n typeof tokenUsage.output !== 'number'\n ) {\n throw new ValidationError(`${path}: run record tokenUsage.input/output must be numbers`)\n }\n const outcome = obj.outcome as Record<string, unknown> | undefined\n if (!outcome?.raw || typeof outcome.raw !== 'object') {\n throw new ValidationError(`${path}: run record outcome.raw must be an object`)\n }\n return value as RunRecord\n}\n\n// ── Row mapping ──────────────────────────────────────────────────────\n\nfunction clamp01(value: number): number {\n return Math.max(0, Math.min(1, value))\n}\n\nfunction splitOf(record: RunRecord, opts: ResolvedExportOptions): ProductBenchmarkSplit {\n const custom = opts.classifySplit?.(record)\n if (custom) return custom\n if ((record.outcome.raw as Record<string, number>).safety === 1) return 'safety'\n if (record.splitTag === 'holdout') return 'holdout'\n if (record.splitTag === 'dev') return 'dev'\n return 'practice'\n}\n\n/** Ungated: a published benchmark record is audit evidence, so the score must\n * stay the measured one. KNOWN HOLE: a realness-gated run still publishes with\n * `pass: true`. The fix mirrors `RolloutLine` — carry the gate as a field on\n * `ProductBenchmarkRecord` and force `pass: false` — which is a schema change,\n * not a call swap, and is tracked separately from this correctness fix. */\nfunction scoreOf(record: RunRecord): number {\n const score = runTaskScore(record)\n if (score !== undefined) return clamp01(score)\n if (\n (record.outcome.judgeScores?.failedJudges?.length ?? 0) > 0 ||\n (record.outcome.raw.judge_error_count ?? 0) > 0\n ) {\n throw new ValidationError(\n `Run ${record.runId} has incomplete judge evidence; product benchmark rows require a complete task score`,\n )\n }\n throw new ValidationError(\n `Run ${record.runId} has no task score; product benchmark rows require an explicit score`,\n )\n}\n\nfunction rawPassOf(record: RunRecord): boolean | null {\n const rawPass = (record.outcome.raw as Record<string, unknown>).pass\n if (typeof rawPass === 'boolean') return rawPass\n if (typeof rawPass === 'number' && Number.isFinite(rawPass)) return rawPass >= 1\n return null\n}\n\nfunction passOf(record: RunRecord, score: number, threshold: number): boolean {\n const rawPass = rawPassOf(record)\n const hasTaskFailure = record.failureClass !== undefined && record.failureClass !== 'success'\n if (rawPass !== null) return rawPass && !hasTaskFailure\n return score >= threshold && !hasTaskFailure\n}\n\nfunction failureOf(\n record: RunRecord,\n score: number,\n threshold: number,\n): Pick<ProductBenchmarkRecord['outcome'], 'failureClass' | 'failureDetail'> {\n if (record.failureClass !== undefined && record.failureClass !== 'success') {\n return {\n failureClass: record.failureClass,\n failureDetail: record.failureMode ?? null,\n }\n }\n const belowThreshold = `quality-below-threshold: ${Math.round(score * 100)}% < ${Math.round(threshold * 100)}%`\n if (rawPassOf(record) === false) {\n return {\n failureClass: 'unknown',\n failureDetail: score < threshold ? belowThreshold : 'product-pass-failed',\n }\n }\n if (passOf(record, score, threshold)) {\n return { failureClass: null, failureDetail: null }\n }\n return { failureClass: 'unknown', failureDetail: belowThreshold }\n}\n\nfunction numericDimensions(record: RunRecord): Record<string, number> {\n const dimensions: Record<string, number> = {}\n for (const [key, value] of Object.entries(record.outcome.raw ?? {})) {\n if (typeof value === 'number' && Number.isFinite(value)) dimensions[key] = value\n }\n if (Object.keys(dimensions).length === 0) dimensions.score = scoreOf(record)\n return dimensions\n}\n\nfunction armIdOf(record: RunRecord): string {\n if (record.candidateId) return record.candidateId\n const variant = record.agentProfile?.dimensions?.variant\n if (typeof variant === 'string' && variant.length > 0) return variant\n const variantId = record.agentProfile?.dimensions?.variantId\n if (typeof variantId === 'string' && variantId.length > 0) return variantId\n return 'production-profile'\n}\n\nfunction backendOf(record: RunRecord): string {\n const backend = record.agentProfile?.dimensions?.backend\n return typeof backend === 'string' && backend.length > 0 ? backend : 'unknown'\n}\n\nfunction modelProvider(record: RunRecord): string {\n const backend = backendOf(record)\n if (backend === 'cli-bridge') return 'cli-bridge'\n if (backend === 'sandbox') return 'router'\n if (record.model.startsWith('router/')) return 'router'\n return backend === 'unknown' ? 'router' : backend\n}\n\nfunction runtimeResolution(record: RunRecord, opts: ResolvedExportOptions): RuntimeResolution {\n const reasoningEffort = record.agentProfile?.dimensions?.reasoningLevel\n return {\n model: record.agentProfile?.model ?? record.model,\n harness: record.agentProfile?.harness?.id ?? `${opts.projectId}-canonical-eval`,\n backend: backendOf(record),\n ...(typeof reasoningEffort === 'string' && reasoningEffort.length > 0\n ? { reasoningEffort }\n : {}),\n }\n}\n\nfunction sourceProfileHash(record: RunRecord): string {\n return (\n record.agentProfile?.sourceProfile?.hash ??\n record.agentProfile?.cellId ??\n sha256(\n JSON.stringify({\n candidateId: record.candidateId,\n promptHash: record.promptHash,\n configHash: record.configHash,\n }),\n )\n )\n}\n\nfunction materializedProfileHash(record: RunRecord, runtime: RuntimeResolution): string {\n return sha256(\n JSON.stringify({ sourceProfileHash: sourceProfileHash(record), model: runtime.model }),\n )\n}\n\nfunction profileIdOf(\n record: RunRecord,\n armId: string,\n runtime: RuntimeResolution,\n opts: ResolvedExportOptions,\n): string {\n const base = record.agentProfile?.profileId ?? opts.fallbackProfileId ?? armId\n const withArm = base.endsWith(`:${armId}`) ? base : `${base}:${armId}`\n return `${withArm}:${runtime.model}`\n}\n\nfunction toolCallsOf(record: RunRecord, runDir: string, opts: ResolvedExportOptions): number {\n const raw = record.outcome.raw as Record<string, unknown>\n const primary = Number(raw.tool_call_count ?? raw.tool_calls ?? raw.toolCalls ?? 0)\n if (Number.isFinite(primary) && primary > 0) return primary\n const fallback = opts.toolCallFallback?.(record, runDir)\n if (fallback !== undefined && Number.isFinite(fallback) && fallback > 0) return fallback\n return Number.isFinite(primary) ? primary : 0\n}\n\n// ── Artifact layout ──────────────────────────────────────────────────\n\nconst TRACE_CANDIDATES = ['traces.jsonl', 'traces', 'trace', 'trace-store'] as const\nconst RAW_CANDIDATES = ['raws.jsonl', 'raw-events'] as const\nconst SCORE_CANDIDATES = ['scores.json', 'manifest.json'] as const\n\nfunction firstExisting(runDir: string, candidates: readonly string[]): string {\n return candidates.find((candidate) => existsSync(join(runDir, candidate))) ?? candidates[0]!\n}\n\nfunction relativeArtifacts(runDir: string): ProductBenchmarkRecord['artifacts'] {\n return {\n records: 'records.jsonl',\n traces: firstExisting(runDir, TRACE_CANDIDATES),\n raws: firstExisting(runDir, RAW_CANDIDATES),\n scores: firstExisting(runDir, SCORE_CANDIDATES),\n workspace: existsSync(join(runDir, 'workspace')) ? 'workspace' : '.',\n }\n}\n\nfunction absoluteArtifacts(runDir: string): ProductBenchmarkRecord['artifacts'] {\n const rel = relativeArtifacts(runDir)\n return {\n records: resolve(runDir, rel.records),\n traces: resolve(runDir, rel.traces),\n raws: resolve(runDir, rel.raws),\n scores: resolve(runDir, rel.scores),\n workspace: resolve(runDir, rel.workspace),\n }\n}\n\nfunction materializeRunArtifacts(\n runDir: string,\n outDir: string,\n index: number,\n): ProductBenchmarkRecord['artifacts'] {\n if (resolve(runDir) === resolve(outDir)) return relativeArtifacts(runDir)\n const rel = relative(runDir, outDir)\n if (rel && !rel.startsWith('..') && !isAbsolute(rel)) {\n throw new ValidationError(`outDir must not be nested inside runDir: ${outDir}`)\n }\n const id = `${String(index + 1).padStart(2, '0')}-${safePathPart(basename(runDir))}-${sha256(runDir).slice(7, 19)}`\n const destRel = join('source-runs', id)\n const destAbs = join(outDir, destRel)\n mkdirSync(dirname(destAbs), { recursive: true })\n cpSync(runDir, destAbs, { recursive: true, force: true })\n const source = relativeArtifacts(runDir)\n return {\n records: join(destRel, source.records),\n traces: join(destRel, source.traces),\n raws: join(destRel, source.raws),\n scores: join(destRel, source.scores),\n workspace: source.workspace === '.' ? destRel : join(destRel, source.workspace),\n }\n}\n\nfunction existsArtifact(artifactRoot: string, value: string): boolean {\n return existsSync(resolve(artifactRoot, value))\n}\n\n// ── Record + manifest construction ───────────────────────────────────\n\n/** Map one RunRecord row to a validated product benchmark record. */\nexport function runRecordToProductBenchmarkRecord(\n record: RunRecord,\n runDir: string,\n artifactRoot: string,\n artifacts: ProductBenchmarkRecord['artifacts'],\n options: ProductBenchmarkExportOptions | ProductBenchmarkSingleRunExportOptions,\n): ProductBenchmarkRecord {\n const opts = resolveOptions(options)\n const runtime = runtimeResolution(record, opts)\n const score = scoreOf(record)\n const failure = failureOf(record, score, opts.passThreshold)\n const armId = armIdOf(record)\n const inputTokens = record.tokenUsage.input\n const outputTokens = record.tokenUsage.output\n const toolCallCount = toolCallsOf(record, runDir, opts)\n const dimensions = numericDimensions(record)\n if (record.costUsd === null) {\n throw new ValidationError(\n `run '${record.runId}' has no USD cost; product benchmark exports require priced runs`,\n )\n }\n const costUsd = record.costUsd\n if (!('tool_calls' in dimensions)) dimensions.tool_calls = toolCallCount\n const product: ProductBenchmarkRecord = {\n schemaVersion: 1,\n projectId: opts.projectId,\n benchmarkId: opts.benchmarkId,\n runId: record.runId,\n scenarioId: record.scenarioId,\n split: splitOf(record, opts),\n armId,\n rep: Number(record.seed ?? 0) + 1,\n agentProfile: {\n id: profileIdOf(record, armId, runtime, opts),\n hash: materializedProfileHash(record, runtime),\n path: opts.agentProfilePath,\n declared: runtime,\n resolved: runtime,\n },\n model: { provider: modelProvider(record), id: record.model },\n backend: { kind: backendOf(record), version: opts.backendVersion },\n outcome: {\n pass: passOf(record, score, opts.passThreshold),\n score,\n dimensions,\n ...failure,\n },\n usage: {\n inputTokens,\n outputTokens,\n costUsd,\n // Rounded: the bundle contract requires integer milliseconds.\n wallMs: Math.round(record.wallMs),\n toolCalls: toolCallCount,\n },\n integrity: {\n realBackend: inputTokens + outputTokens > 0,\n rawCapture: existsArtifact(artifactRoot, artifacts.raws),\n traceCapture: existsArtifact(artifactRoot, artifacts.traces),\n noStubRows: inputTokens + outputTokens > 0,\n priced: costUsd > 0,\n profileMaterialized: Boolean(record.agentProfile?.cellId),\n },\n artifacts,\n }\n return validateProductBenchmarkRecord(product)\n}\n\n/** One record per arm id, failing loud when records sharing an arm id\n * disagree on any attribute the manifest arm carries (profile, model,\n * backend, harness, reasoning effort) — an id-only dedup would silently\n * keep one policy and misrepresent the rest. */\nfunction uniqueArmRecords(records: readonly ProductBenchmarkRecord[]): ProductBenchmarkRecord[] {\n const byArm = new Map<string, ProductBenchmarkRecord>()\n for (const record of records) {\n const prior = byArm.get(record.armId)\n if (!prior) {\n byArm.set(record.armId, record)\n continue\n }\n const fields = [\n ['profileId', prior.agentProfile.id, record.agentProfile.id],\n ['model', prior.agentProfile.resolved.model, record.agentProfile.resolved.model],\n ['backend', prior.agentProfile.resolved.backend, record.agentProfile.resolved.backend],\n ['harness', prior.agentProfile.resolved.harness, record.agentProfile.resolved.harness],\n [\n 'reasoningEffort',\n prior.agentProfile.resolved.reasoningEffort,\n record.agentProfile.resolved.reasoningEffort,\n ],\n ] as const\n for (const [name, a, b] of fields) {\n if (a !== b) {\n throw new ValidationError(\n `records for arm '${record.armId}' disagree on ${name} (${String(a)} vs ${String(b)}) — one arm id must map to one policy`,\n )\n }\n }\n }\n return [...byArm.values()]\n}\n\n/** One record per scenario id, failing loud on a divergent split — the\n * manifest scenario carries one split, so two records disagreeing would be\n * silently misfiled. */\nfunction uniqueScenarioRecords(\n records: readonly ProductBenchmarkRecord[],\n): ProductBenchmarkRecord[] {\n const byScenario = new Map<string, ProductBenchmarkRecord>()\n for (const record of records) {\n const prior = byScenario.get(record.scenarioId)\n if (!prior) {\n byScenario.set(record.scenarioId, record)\n continue\n }\n if (prior.split !== record.split) {\n throw new ValidationError(\n `records for scenario '${record.scenarioId}' disagree on split (${prior.split} vs ${record.split})`,\n )\n }\n }\n return [...byScenario.values()]\n}\n\n/** Derive the bundle manifest from already-normalized records. */\nexport function buildProductBenchmarkManifest(\n records: readonly ProductBenchmarkRecord[],\n options: Pick<\n ProductBenchmarkExportOptions,\n 'outDir' | 'projectId' | 'benchmarkId' | 'scenarioTagPrefix' | 'mutableSurfaces' | 'substrate'\n >,\n): ProductBenchmarkManifest {\n if (records.length === 0) {\n throw new ValidationError('cannot build a product benchmark manifest from zero records')\n }\n const scenarioTagPrefix = options.scenarioTagPrefix ?? defaultScenarioTagPrefix(options.projectId)\n const mutableSurfaces = options.mutableSurfaces ?? productBenchmarkMutableSurfaces\n const byProfile = new Map<string, ProductBenchmarkManifest['profiles'][number]>()\n for (const record of records) {\n byProfile.set(record.agentProfile.id, {\n id: record.agentProfile.id,\n profileHash: record.agentProfile.hash,\n agentProfilePath: record.agentProfile.path,\n })\n }\n const manifest: ProductBenchmarkManifest = {\n schemaVersion: 1,\n projectId: options.projectId,\n benchmarkId: options.benchmarkId,\n repo: productBenchmarkRepoIdentity(),\n substrate: {\n agentEval: packageVersion('@tangle-network/agent-eval'),\n agentRuntime: packageVersion('@tangle-network/agent-runtime'),\n agentInterface: packageVersion('@tangle-network/agent-interface'),\n sandbox: packageVersion('@tangle-network/sandbox'),\n ...options.substrate,\n },\n profiles: [...byProfile.values()],\n arms: uniqueArmRecords(records).map((record) => ({\n id: record.armId,\n profileId: record.agentProfile.id,\n mutableSurfaces: [...mutableSurfaces],\n policyAxes: {\n carrier: record.armId.includes('policy') ? 'resource-file' : 'profile',\n model: record.agentProfile.resolved.model,\n backend: record.agentProfile.resolved.backend,\n harness: record.agentProfile.resolved.harness,\n ...(record.agentProfile.resolved.reasoningEffort !== undefined\n ? { reasoningEffort: record.agentProfile.resolved.reasoningEffort }\n : {}),\n },\n })),\n scenarios: uniqueScenarioRecords(records).map((record) => ({\n id: record.scenarioId,\n split: record.split,\n tags: [scenarioTagPrefix, options.benchmarkId, record.split],\n sourceAllowedForSynthesis: false,\n })),\n budgets: {\n maxUsd: records.reduce((sum, record) => sum + record.usage.costUsd, 0),\n maxCells: records.length,\n maxWallMs: records.reduce((sum, record) => sum + record.usage.wallMs, 0),\n },\n expectedArtifactDir: resolve(options.outDir),\n }\n return validateProductBenchmarkManifest(manifest)\n}\n\n// ── Entry points ─────────────────────────────────────────────────────\n\n/** Single-run convenience wrapper over `exportProductBenchmarkRuns`. */\nexport function exportProductBenchmark(\n options: ProductBenchmarkSingleRunExportOptions,\n): ProductBenchmarkExportResult {\n const { runDir, ...rest } = options\n return exportProductBenchmarkRuns({ ...rest, runDirs: [runDir] })\n}\n\n/**\n * Export one or more product eval run dirs into a validated product\n * benchmark bundle at `outDir`. Both the manifest and every record are\n * run through the contract validators before anything is written.\n */\nexport function exportProductBenchmarkRuns(\n options: ProductBenchmarkExportOptions,\n): ProductBenchmarkExportResult {\n const opts = resolveOptions(options)\n const outDir = resolve(options.outDir)\n const runDirs = options.runDirs.map((runDir) => resolve(runDir))\n if (runDirs.length === 0) throw new ValidationError('export requires at least one run directory')\n const materialize = options.materializeSourceRuns !== false\n const rows = runDirs.flatMap((runDir) => {\n const sourceRecordsPath = join(runDir, 'records.jsonl')\n if (!existsSync(sourceRecordsPath)) throw new ValidationError(`missing ${sourceRecordsPath}`)\n const records = readRunRecords(sourceRecordsPath)\n if (records.length === 0) throw new ValidationError(`${sourceRecordsPath} is empty`)\n return records.map((record) => ({ record, runDir }))\n })\n mkdirSync(outDir, { recursive: true })\n const artifactsByRunDir = new Map<string, ProductBenchmarkRecord['artifacts']>()\n for (const [index, runDir] of runDirs.entries()) {\n artifactsByRunDir.set(\n runDir,\n materialize ? materializeRunArtifacts(runDir, outDir, index) : absoluteArtifacts(runDir),\n )\n }\n const artifactRoot = materialize ? outDir : '/'\n const normalized = rows.map(({ record, runDir }) =>\n runRecordToProductBenchmarkRecord(\n record,\n runDir,\n artifactRoot,\n artifactsByRunDir.get(runDir)!,\n { ...options, runDirs, backendVersion: opts.backendVersion },\n ),\n )\n const manifest = buildProductBenchmarkManifest(normalized, {\n outDir,\n projectId: opts.projectId,\n benchmarkId: opts.benchmarkId,\n scenarioTagPrefix: opts.scenarioTagPrefix,\n mutableSurfaces: opts.mutableSurfaces,\n ...(options.substrate !== undefined ? { substrate: options.substrate } : {}),\n })\n const manifestPath = join(outDir, 'product-benchmark-manifest.json')\n const recordsPath = join(outDir, 'product-benchmark-records.jsonl')\n writeFileSync(manifestPath, `${JSON.stringify(manifest, null, 2)}\\n`)\n writeFileSync(recordsPath, `${normalized.map((record) => JSON.stringify(record)).join('\\n')}\\n`)\n return { manifestPath, recordsPath, records: normalized.length }\n}\n\nfunction defaultScenarioTagPrefix(projectId: string): string {\n return projectId.replace(/-agent$/, '') || projectId\n}\n\nfunction resolveOptions(\n options: ProductBenchmarkExportOptions | ProductBenchmarkSingleRunExportOptions,\n): ResolvedExportOptions {\n return {\n projectId: options.projectId,\n benchmarkId: options.benchmarkId,\n agentProfilePath: options.agentProfilePath,\n passThreshold: options.passThreshold ?? 0.7,\n scenarioTagPrefix: options.scenarioTagPrefix ?? defaultScenarioTagPrefix(options.projectId),\n ...(options.fallbackProfileId !== undefined\n ? { fallbackProfileId: options.fallbackProfileId }\n : {}),\n mutableSurfaces: options.mutableSurfaces ?? productBenchmarkMutableSurfaces,\n ...(options.classifySplit !== undefined ? { classifySplit: options.classifySplit } : {}),\n ...(options.toolCallFallback !== undefined\n ? { toolCallFallback: options.toolCallFallback }\n : {}),\n backendVersion: options.backendVersion ?? packageVersion('@tangle-network/sandbox'),\n }\n}\n","import { existsSync, readFileSync, statSync } from 'node:fs'\nimport { dirname, join } from 'node:path'\nimport { ValidationError } from '../errors'\nimport { FAILURE_CLASSES, type FailureClass } from '../trace/schema'\n\nexport const productBenchmarkSplits = ['practice', 'dev', 'holdout', 'safety', 'sentinel'] as const\n\nexport type ProductBenchmarkSplit = (typeof productBenchmarkSplits)[number]\n\nexport interface ProductBenchmarkRepoRef {\n readonly url: string\n readonly commit: string\n readonly branch: string\n}\n\nexport interface ProductBenchmarkSubstrateVersions {\n readonly agentEval: string\n readonly agentRuntime: string\n readonly agentInterface: string\n readonly sandbox: string\n readonly agentBench?: string\n}\n\nexport interface ProductBenchmarkProfileRef {\n readonly id: string\n readonly profileHash: string\n readonly agentProfilePath: string\n}\n\nexport interface ProductBenchmarkArm {\n readonly id: string\n readonly profileId: string\n readonly mutableSurfaces: readonly string[]\n readonly policyAxes: Record<string, unknown>\n}\n\nexport interface ProductBenchmarkScenario {\n readonly id: string\n readonly split: ProductBenchmarkSplit\n readonly tags: readonly string[]\n readonly sourceAllowedForSynthesis: boolean\n}\n\nexport interface ProductBenchmarkBudgets {\n readonly maxUsd: number\n readonly maxCells: number\n readonly maxWallMs: number\n}\n\nexport interface ProductBenchmarkManifest {\n readonly schemaVersion: 1\n readonly projectId: string\n readonly benchmarkId: string\n readonly repo: ProductBenchmarkRepoRef\n readonly substrate: ProductBenchmarkSubstrateVersions\n readonly profiles: readonly ProductBenchmarkProfileRef[]\n readonly arms: readonly ProductBenchmarkArm[]\n readonly scenarios: readonly ProductBenchmarkScenario[]\n readonly budgets: ProductBenchmarkBudgets\n readonly expectedArtifactDir: string\n}\n\nexport interface AgentProfileRuntimeReceipt {\n readonly model: string\n readonly harness: string\n readonly backend: string\n readonly reasoningEffort?: string\n}\n\nexport type RuntimeResolution = AgentProfileRuntimeReceipt\n\nexport interface ProductBenchmarkRecord {\n readonly schemaVersion: 1\n readonly projectId: string\n readonly benchmarkId: string\n readonly runId: string\n readonly scenarioId: string\n readonly split: ProductBenchmarkSplit\n readonly armId: string\n readonly rep: number\n readonly agentProfile: {\n readonly id: string\n readonly hash: string\n readonly path: string\n readonly declared: RuntimeResolution\n readonly resolved: RuntimeResolution\n }\n readonly model: {\n readonly provider: string\n readonly id: string\n }\n readonly backend: {\n readonly kind: string\n readonly version: string\n }\n readonly outcome: {\n readonly pass: boolean\n readonly score: number\n readonly dimensions: Record<string, number>\n readonly failureClass: Exclude<FailureClass, 'success'> | null\n readonly failureDetail: string | null\n }\n readonly usage: {\n readonly inputTokens: number\n readonly outputTokens: number\n readonly costUsd: number\n readonly wallMs: number\n readonly toolCalls: number\n }\n readonly integrity: {\n readonly realBackend: boolean\n readonly rawCapture: boolean\n readonly traceCapture: boolean\n readonly noStubRows: boolean\n readonly priced: boolean\n readonly profileMaterialized: boolean\n }\n readonly artifacts: {\n readonly records: string\n readonly traces: string\n readonly raws: string\n readonly scores: string\n readonly workspace: string\n }\n}\n\nexport interface ProductBenchmarkRunInput {\n readonly manifestPath: string\n readonly recordsPath: string\n readonly artifactRoot?: string\n readonly checkArtifacts?: boolean\n}\n\nexport interface ProductBenchmarkValidationReport {\n readonly manifestPath: string\n readonly recordsPath: string\n readonly records: number\n /** Manifest repo fields that are empty or the `'unknown'` export sentinel. */\n readonly repoFailures: readonly string[]\n /** Manifest substrate versions that are empty or the `'unknown'` export\n * sentinel — a bundle without substrate identity is not reproducible. */\n readonly substrateFailures: readonly string[]\n readonly projects: readonly string[]\n readonly benchmarks: readonly string[]\n readonly arms: readonly string[]\n readonly scenarios: readonly string[]\n readonly passed: number\n readonly failed: number\n readonly inputTokens: number\n readonly outputTokens: number\n readonly costUsd: number\n readonly wallMs: number\n readonly integrityFailures: readonly string[]\n readonly missingArtifacts: readonly string[]\n}\n\nexport interface ProductBenchmarkArtifactPaths {\n readonly manifestPath: string\n readonly recordsPath: string\n}\n\nfunction isObject(value: unknown): value is Record<string, unknown> {\n return Boolean(value) && typeof value === 'object' && !Array.isArray(value)\n}\n\nfunction fail(path: string, message: string): never {\n throw new ValidationError(`${path}: ${message}`)\n}\n\nfunction wrapValidationError(path: string, err: unknown): never {\n if (err instanceof ValidationError) {\n throw new ValidationError(`${path}: ${err.message}`, { cause: err })\n }\n throw new ValidationError(`${path}: ${err instanceof Error ? err.message : String(err)}`, {\n cause: err,\n })\n}\n\nfunction expectObject(value: unknown, path: string): Record<string, unknown> {\n if (!isObject(value)) fail(path, 'must be an object')\n return value\n}\n\nfunction expectString(value: unknown, path: string): string {\n if (typeof value !== 'string' || value.trim().length === 0)\n fail(path, 'must be a non-empty string')\n return value\n}\n\nfunction expectFailureClass(value: unknown, path: string): Exclude<FailureClass, 'success'> {\n const parsed = expectString(value, path)\n if (parsed === 'success' || !FAILURE_CLASSES.includes(parsed as FailureClass)) {\n fail(path, `expected a non-success FailureClass, received ${JSON.stringify(parsed)}`)\n }\n return parsed as Exclude<FailureClass, 'success'>\n}\n\nfunction expectBoolean(value: unknown, path: string): boolean {\n if (typeof value !== 'boolean') fail(path, 'must be a boolean')\n return value\n}\n\nfunction expectNumber(\n value: unknown,\n path: string,\n opts: { readonly min?: number; readonly max?: number; readonly integer?: boolean } = {},\n): number {\n if (typeof value !== 'number' || !Number.isFinite(value)) fail(path, 'must be a finite number')\n if (opts.integer && !Number.isInteger(value)) fail(path, 'must be an integer')\n if (opts.min !== undefined && value < opts.min) fail(path, `must be >= ${opts.min}`)\n if (opts.max !== undefined && value > opts.max) fail(path, `must be <= ${opts.max}`)\n return value\n}\n\nfunction expectStringArray(value: unknown, path: string): string[] {\n if (!Array.isArray(value)) fail(path, 'must be an array')\n return value.map((entry, index) => expectString(entry, `${path}[${index}]`))\n}\n\nfunction expectObjectArray(value: unknown, path: string): Record<string, unknown>[] {\n if (!Array.isArray(value)) fail(path, 'must be an array')\n return value.map((entry, index) => expectObject(entry, `${path}[${index}]`))\n}\n\nfunction expectSplit(value: unknown, path: string): ProductBenchmarkSplit {\n const split = expectString(value, path)\n if (!productBenchmarkSplits.includes(split as ProductBenchmarkSplit)) {\n fail(path, `must be one of ${productBenchmarkSplits.join(', ')}`)\n }\n return split as ProductBenchmarkSplit\n}\n\nfunction optionalString(value: unknown, path: string): string | undefined {\n if (value === undefined) return undefined\n return expectString(value, path)\n}\n\nfunction expectDimensions(value: unknown, path: string): Record<string, number> {\n const obj = expectObject(value, path)\n const out: Record<string, number> = {}\n for (const [key, raw] of Object.entries(obj)) out[key] = expectNumber(raw, `${path}.${key}`)\n return out\n}\n\nfunction expectRuntimeResolution(value: unknown, path: string): RuntimeResolution {\n const obj = expectObject(value, path)\n return {\n model: expectString(obj.model, `${path}.model`),\n harness: expectString(obj.harness, `${path}.harness`),\n backend: expectString(obj.backend, `${path}.backend`),\n ...(obj.reasoningEffort !== undefined\n ? { reasoningEffort: optionalString(obj.reasoningEffort, `${path}.reasoningEffort`) }\n : {}),\n }\n}\n\nexport function validateProductBenchmarkManifest(value: unknown): ProductBenchmarkManifest {\n const obj = expectObject(value, 'manifest')\n if (obj.schemaVersion !== 1) fail('manifest.schemaVersion', 'must be 1')\n const repo = expectObject(obj.repo, 'manifest.repo')\n const substrate = expectObject(obj.substrate, 'manifest.substrate')\n const profiles = expectObjectArray(obj.profiles, 'manifest.profiles').map((profile, index) => ({\n id: expectString(profile.id, `manifest.profiles[${index}].id`),\n profileHash: expectString(profile.profileHash, `manifest.profiles[${index}].profileHash`),\n agentProfilePath: expectString(\n profile.agentProfilePath,\n `manifest.profiles[${index}].agentProfilePath`,\n ),\n }))\n const arms = expectObjectArray(obj.arms, 'manifest.arms').map((arm, index) => ({\n id: expectString(arm.id, `manifest.arms[${index}].id`),\n profileId: expectString(arm.profileId, `manifest.arms[${index}].profileId`),\n mutableSurfaces: expectStringArray(\n arm.mutableSurfaces,\n `manifest.arms[${index}].mutableSurfaces`,\n ),\n policyAxes: expectObject(arm.policyAxes, `manifest.arms[${index}].policyAxes`),\n }))\n const scenarios = expectObjectArray(obj.scenarios, 'manifest.scenarios').map(\n (scenario, index) => ({\n id: expectString(scenario.id, `manifest.scenarios[${index}].id`),\n split: expectSplit(scenario.split, `manifest.scenarios[${index}].split`),\n tags: expectStringArray(scenario.tags, `manifest.scenarios[${index}].tags`),\n sourceAllowedForSynthesis: expectBoolean(\n scenario.sourceAllowedForSynthesis,\n `manifest.scenarios[${index}].sourceAllowedForSynthesis`,\n ),\n }),\n )\n const budgets = expectObject(obj.budgets, 'manifest.budgets')\n if (profiles.length === 0) fail('manifest.profiles', 'must contain at least one profile')\n if (arms.length === 0) fail('manifest.arms', 'must contain at least one arm')\n if (scenarios.length === 0) fail('manifest.scenarios', 'must contain at least one scenario')\n assertUnique(\n profiles.map((profile) => profile.id),\n 'manifest.profiles.id',\n )\n assertUnique(\n arms.map((arm) => arm.id),\n 'manifest.arms.id',\n )\n assertUnique(\n scenarios.map((scenario) => scenario.id),\n 'manifest.scenarios.id',\n )\n const profileIds = new Set(profiles.map((profile) => profile.id))\n for (const arm of arms) {\n if (!profileIds.has(arm.profileId))\n fail(`manifest.arms.${arm.id}.profileId`, `unknown profile ${arm.profileId}`)\n }\n return {\n schemaVersion: 1,\n projectId: expectString(obj.projectId, 'manifest.projectId'),\n benchmarkId: expectString(obj.benchmarkId, 'manifest.benchmarkId'),\n repo: {\n url: expectString(repo.url, 'manifest.repo.url'),\n commit: expectString(repo.commit, 'manifest.repo.commit'),\n branch: expectString(repo.branch, 'manifest.repo.branch'),\n },\n substrate: {\n agentEval: expectString(substrate.agentEval, 'manifest.substrate.agentEval'),\n agentRuntime: expectString(substrate.agentRuntime, 'manifest.substrate.agentRuntime'),\n agentInterface: expectString(substrate.agentInterface, 'manifest.substrate.agentInterface'),\n sandbox: expectString(substrate.sandbox, 'manifest.substrate.sandbox'),\n ...(substrate.agentBench !== undefined\n ? { agentBench: expectString(substrate.agentBench, 'manifest.substrate.agentBench') }\n : {}),\n },\n profiles,\n arms,\n scenarios,\n budgets: {\n maxUsd: expectNumber(budgets.maxUsd, 'manifest.budgets.maxUsd', { min: 0 }),\n maxCells: expectNumber(budgets.maxCells, 'manifest.budgets.maxCells', {\n min: 0,\n integer: true,\n }),\n maxWallMs: expectNumber(budgets.maxWallMs, 'manifest.budgets.maxWallMs', {\n min: 0,\n integer: true,\n }),\n },\n expectedArtifactDir: expectString(obj.expectedArtifactDir, 'manifest.expectedArtifactDir'),\n }\n}\n\nexport function validateProductBenchmarkRecord(value: unknown): ProductBenchmarkRecord {\n const obj = expectObject(value, 'record')\n if (obj.schemaVersion !== 1) fail('record.schemaVersion', 'must be 1')\n const agentProfile = expectObject(obj.agentProfile, 'record.agentProfile')\n const model = expectObject(obj.model, 'record.model')\n const backend = expectObject(obj.backend, 'record.backend')\n const outcome = expectObject(obj.outcome, 'record.outcome')\n const usage = expectObject(obj.usage, 'record.usage')\n const integrity = expectObject(obj.integrity, 'record.integrity')\n const artifacts = expectObject(obj.artifacts, 'record.artifacts')\n const outcomePass = expectBoolean(outcome.pass, 'record.outcome.pass')\n const failureClass =\n outcome.failureClass === null\n ? null\n : expectFailureClass(outcome.failureClass, 'record.outcome.failureClass')\n const failureDetail =\n outcome.failureDetail === null\n ? null\n : expectString(outcome.failureDetail, 'record.outcome.failureDetail')\n if (outcomePass && (failureClass !== null || failureDetail !== null)) {\n fail('record.outcome', 'a passing row cannot carry failure evidence')\n }\n if (!outcomePass && failureClass === null) {\n fail('record.outcome.failureClass', 'a failed row requires a failure class')\n }\n if (failureClass === null && failureDetail !== null) {\n fail('record.outcome.failureDetail', 'failure detail requires a failure class')\n }\n const record: ProductBenchmarkRecord = {\n schemaVersion: 1,\n projectId: expectString(obj.projectId, 'record.projectId'),\n benchmarkId: expectString(obj.benchmarkId, 'record.benchmarkId'),\n runId: expectString(obj.runId, 'record.runId'),\n scenarioId: expectString(obj.scenarioId, 'record.scenarioId'),\n split: expectSplit(obj.split, 'record.split'),\n armId: expectString(obj.armId, 'record.armId'),\n rep: expectNumber(obj.rep, 'record.rep', { min: 1, integer: true }),\n agentProfile: {\n id: expectString(agentProfile.id, 'record.agentProfile.id'),\n hash: expectString(agentProfile.hash, 'record.agentProfile.hash'),\n path: expectString(agentProfile.path, 'record.agentProfile.path'),\n declared: expectRuntimeResolution(agentProfile.declared, 'record.agentProfile.declared'),\n resolved: expectRuntimeResolution(agentProfile.resolved, 'record.agentProfile.resolved'),\n },\n model: {\n provider: expectString(model.provider, 'record.model.provider'),\n id: expectString(model.id, 'record.model.id'),\n },\n backend: {\n kind: expectString(backend.kind, 'record.backend.kind'),\n version: expectString(backend.version, 'record.backend.version'),\n },\n outcome: {\n pass: outcomePass,\n score: expectNumber(outcome.score, 'record.outcome.score', { min: 0, max: 1 }),\n dimensions: expectDimensions(outcome.dimensions, 'record.outcome.dimensions'),\n failureClass,\n failureDetail,\n },\n usage: {\n inputTokens: expectNumber(usage.inputTokens, 'record.usage.inputTokens', {\n min: 0,\n integer: true,\n }),\n outputTokens: expectNumber(usage.outputTokens, 'record.usage.outputTokens', {\n min: 0,\n integer: true,\n }),\n costUsd: expectNumber(usage.costUsd, 'record.usage.costUsd', { min: 0 }),\n wallMs: expectNumber(usage.wallMs, 'record.usage.wallMs', { min: 0, integer: true }),\n toolCalls: expectNumber(usage.toolCalls, 'record.usage.toolCalls', { min: 0, integer: true }),\n },\n integrity: {\n realBackend: expectBoolean(integrity.realBackend, 'record.integrity.realBackend'),\n rawCapture: expectBoolean(integrity.rawCapture, 'record.integrity.rawCapture'),\n traceCapture: expectBoolean(integrity.traceCapture, 'record.integrity.traceCapture'),\n noStubRows: expectBoolean(integrity.noStubRows, 'record.integrity.noStubRows'),\n priced: expectBoolean(integrity.priced, 'record.integrity.priced'),\n profileMaterialized: expectBoolean(\n integrity.profileMaterialized,\n 'record.integrity.profileMaterialized',\n ),\n },\n artifacts: {\n records: expectString(artifacts.records, 'record.artifacts.records'),\n traces: expectString(artifacts.traces, 'record.artifacts.traces'),\n raws: expectString(artifacts.raws, 'record.artifacts.raws'),\n scores: expectString(artifacts.scores, 'record.artifacts.scores'),\n workspace: expectString(artifacts.workspace, 'record.artifacts.workspace'),\n },\n }\n if (record.integrity.realBackend && record.usage.inputTokens + record.usage.outputTokens === 0) {\n fail('record.usage', 'realBackend rows must carry non-zero token usage')\n }\n return record\n}\n\nexport function productBenchmarkIntegrityFailures(record: ProductBenchmarkRecord): string[] {\n const failures: string[] = []\n for (const [key, value] of Object.entries(record.integrity)) {\n if (!value) failures.push(`${record.runId}:${key}=false`)\n }\n return failures\n}\n\nexport function readProductBenchmarkRecords(path: string): ProductBenchmarkRecord[] {\n const lines = readFileSync(path, 'utf8')\n .split('\\n')\n .map((line) => line.trim())\n .filter(Boolean)\n const records: ProductBenchmarkRecord[] = []\n for (const [index, line] of lines.entries()) {\n try {\n records.push(validateProductBenchmarkRecord(JSON.parse(line)))\n } catch (err) {\n wrapValidationError(`${path}:${index + 1}`, err)\n }\n }\n return records\n}\n\nexport function readProductBenchmarkManifest(path: string): ProductBenchmarkManifest {\n try {\n return validateProductBenchmarkManifest(JSON.parse(readFileSync(path, 'utf8')))\n } catch (err) {\n wrapValidationError(path, err)\n }\n}\n\nexport function validateProductBenchmarkRun(\n input: ProductBenchmarkRunInput,\n): ProductBenchmarkValidationReport {\n const manifest = readProductBenchmarkManifest(input.manifestPath)\n const records = readProductBenchmarkRecords(input.recordsPath)\n const manifestProjectBench = `${manifest.projectId}/${manifest.benchmarkId}`\n const integrityFailures = records.flatMap(productBenchmarkIntegrityFailures)\n const missingArtifacts =\n input.checkArtifacts === false\n ? []\n : records.flatMap((record) =>\n missingArtifactsForRecord(record, input.artifactRoot ?? dirname(input.recordsPath)),\n )\n for (const [index, record] of records.entries()) {\n const recordProjectBench = `${record.projectId}/${record.benchmarkId}`\n if (recordProjectBench !== manifestProjectBench) {\n fail(\n `records[${index}]`,\n `project/benchmark ${recordProjectBench} does not match manifest ${manifestProjectBench}`,\n )\n }\n if (!manifest.arms.some((arm) => arm.id === record.armId))\n fail(`records[${index}].armId`, `unknown arm ${record.armId}`)\n if (!manifest.scenarios.some((scenario) => scenario.id === record.scenarioId)) {\n fail(`records[${index}].scenarioId`, `unknown scenario ${record.scenarioId}`)\n }\n }\n const repoFailures = (['url', 'commit', 'branch'] as const)\n .filter((key) => manifest.repo[key].trim().length === 0 || manifest.repo[key] === 'unknown')\n .map((key) => `manifest.repo.${key}`)\n const substrateFailures = (['agentEval', 'agentRuntime', 'agentInterface', 'sandbox'] as const)\n .filter(\n (key) => manifest.substrate[key].trim().length === 0 || manifest.substrate[key] === 'unknown',\n )\n .map((key) => `manifest.substrate.${key}`)\n return {\n manifestPath: input.manifestPath,\n recordsPath: input.recordsPath,\n records: records.length,\n repoFailures,\n substrateFailures,\n projects: sortedUnique(records.map((record) => record.projectId)),\n benchmarks: sortedUnique(records.map((record) => record.benchmarkId)),\n arms: sortedUnique(records.map((record) => record.armId)),\n scenarios: sortedUnique(records.map((record) => record.scenarioId)),\n passed: records.filter((record) => record.outcome.pass).length,\n failed: records.filter((record) => !record.outcome.pass).length,\n inputTokens: sum(records, (record) => record.usage.inputTokens),\n outputTokens: sum(records, (record) => record.usage.outputTokens),\n costUsd: sum(records, (record) => record.usage.costUsd),\n wallMs: sum(records, (record) => record.usage.wallMs),\n integrityFailures,\n missingArtifacts,\n }\n}\n\nfunction missingArtifactsForRecord(record: ProductBenchmarkRecord, artifactRoot: string): string[] {\n const missing: string[] = []\n for (const [key, value] of Object.entries(record.artifacts)) {\n const path = resolveArtifactPath(value, artifactRoot)\n if (!existsSync(path)) missing.push(`${record.runId}:${key}:${value}`)\n }\n return missing\n}\n\nfunction resolveArtifactPath(value: string, artifactRoot: string): string {\n return value.startsWith('/') ? value : join(artifactRoot, value)\n}\n\nfunction assertUnique(values: readonly string[], path: string): void {\n const seen = new Set<string>()\n for (const value of values) {\n if (seen.has(value)) fail(path, `duplicate ${value}`)\n seen.add(value)\n }\n}\n\nfunction sortedUnique(values: readonly string[]): string[] {\n return [...new Set(values)].sort()\n}\n\nfunction sum<T>(items: readonly T[], fn: (item: T) => number): number {\n return items.reduce((total, item) => total + fn(item), 0)\n}\n\nexport function findProductBenchmarkArtifacts(\n runDir: string,\n): ProductBenchmarkArtifactPaths | null {\n const manifestPath = join(runDir, 'product-benchmark-manifest.json')\n const recordsPath = join(runDir, 'product-benchmark-records.jsonl')\n if (\n existsSync(manifestPath) &&\n statSync(manifestPath).isFile() &&\n existsSync(recordsPath) &&\n statSync(recordsPath).isFile()\n ) {\n return { manifestPath, recordsPath }\n }\n return null\n}\n\n/**\n * Fail-loud gate over a bundle directory: locates the manifest + records,\n * runs `validateProductBenchmarkRun`, and throws with every repo,\n * integrity, and artifact failure listed. Returns the report when clean.\n */\nexport function assertProductBenchmarkRun(runDir: string): ProductBenchmarkValidationReport {\n const artifacts = findProductBenchmarkArtifacts(runDir)\n if (!artifacts) {\n fail(runDir, 'missing product-benchmark-manifest.json or product-benchmark-records.jsonl')\n }\n const report = validateProductBenchmarkRun({ ...artifacts, artifactRoot: runDir })\n const failures = [\n ...report.repoFailures,\n ...report.substrateFailures,\n ...report.integrityFailures,\n ...report.missingArtifacts,\n ]\n if (failures.length > 0) {\n fail(runDir, `product benchmark validation failed:\\n${failures.join('\\n')}`)\n }\n return report\n}\n\nexport type {\n ProductBenchmarkExportOptions,\n ProductBenchmarkExportResult,\n ProductBenchmarkSingleRunExportOptions,\n} from './export'\nexport {\n buildProductBenchmarkManifest,\n exportProductBenchmark,\n exportProductBenchmarkRuns,\n productBenchmarkMutableSurfaces,\n productBenchmarkRepoIdentity,\n runRecordToProductBenchmarkRecord,\n} from './export'\n","import type { RunSplitTag } from './run-record'\n\nexport interface RuntimeTrajectoryHookEvent {\n id: string\n runId: string\n scenarioId?: string\n target: string\n phase: string\n timestamp: number\n stepIndex?: number\n parentId?: string\n payload?: unknown\n metadata?: Record<string, unknown>\n}\n\nexport interface RuntimeTrajectoryRecord {\n id?: string\n scenarioId?: string\n splitTag?: RunSplitTag\n runtimeEvents?: unknown\n [key: string]: unknown\n}\n\nexport interface RuntimeTrajectoryRunRecord {\n runId: string\n scenarioId?: string\n splitTag: RunSplitTag\n}\n\nexport interface RuntimeTrajectoryEvidenceSummary {\n recordCount: number\n recordWithRuntimeEventsCount: number\n runtimeRunCount: number\n lifecycleEventCount: number\n defaultedSplitCount: number\n}\n\nexport interface RuntimeTrajectoryEvidenceProjection {\n runs: RuntimeTrajectoryRunRecord[]\n events: RuntimeTrajectoryHookEvent[]\n summary: RuntimeTrajectoryEvidenceSummary\n diagnostics: string[]\n}\n\nexport interface ProjectRuntimeTrajectoryEvidenceOptions<\n TRecord extends RuntimeTrajectoryRecord = RuntimeTrajectoryRecord,\n> {\n records: TRecord[]\n defaultSplitTag?: RunSplitTag\n recordIdOf?: (record: TRecord, index: number) => string | undefined\n scenarioIdOf?: (record: TRecord, index: number) => string | undefined\n}\n\nconst DEFAULT_SPLIT_TAG: RunSplitTag = 'search'\n\nexport function projectRuntimeTrajectoryEvidence<TRecord extends RuntimeTrajectoryRecord>(\n options: ProjectRuntimeTrajectoryEvidenceOptions<TRecord>,\n): RuntimeTrajectoryEvidenceProjection {\n const diagnostics: string[] = []\n const runsById = new Map<string, RuntimeTrajectoryRunRecord>()\n const events: RuntimeTrajectoryHookEvent[] = []\n let recordWithRuntimeEventsCount = 0\n let defaultedSplitCount = 0\n\n for (let recordIndex = 0; recordIndex < options.records.length; recordIndex += 1) {\n const record = options.records[recordIndex]!\n const key = runtimeTrajectoryRecordKey(record, recordIndex, options.recordIdOf)\n const splitTag = record.splitTag ?? options.defaultSplitTag ?? DEFAULT_SPLIT_TAG\n if (record.splitTag === undefined) defaultedSplitCount += 1\n\n const rawEvents = record.runtimeEvents\n if (!Array.isArray(rawEvents)) {\n diagnostics.push(\n `${key}: runtimeEvents is not an array; no runtime run join can be extracted`,\n )\n continue\n }\n if (rawEvents.length === 0) {\n diagnostics.push(`${key}: no runtimeEvents; no runtime run join can be extracted`)\n continue\n }\n recordWithRuntimeEventsCount += 1\n\n for (let index = 0; index < rawEvents.length; index += 1) {\n const event = parseRuntimeTrajectoryHookEvent(rawEvents[index])\n if (!event) {\n diagnostics.push(`${key}: runtimeEvents[${index}] is not a RuntimeHookEvent`)\n continue\n }\n events.push(event)\n\n const scenarioId =\n event.scenarioId ??\n stringOrUndefined(options.scenarioIdOf?.(record, recordIndex)) ??\n stringOrUndefined(record.scenarioId)\n const prior = runsById.get(event.runId)\n if (!prior) {\n runsById.set(event.runId, { runId: event.runId, scenarioId, splitTag })\n continue\n }\n if (prior.scenarioId !== scenarioId || prior.splitTag !== splitTag) {\n diagnostics.push(`${key}: runId ${event.runId} has conflicting scenario/split metadata`)\n }\n }\n }\n\n const runs = [...runsById.values()]\n return {\n runs,\n events,\n summary: {\n recordCount: options.records.length,\n recordWithRuntimeEventsCount,\n runtimeRunCount: runs.length,\n lifecycleEventCount: events.length,\n defaultedSplitCount,\n },\n diagnostics,\n }\n}\n\nexport function parseRuntimeTrajectoryHookEvent(input: unknown): RuntimeTrajectoryHookEvent | null {\n if (!isRecord(input)) return null\n if (typeof input.id !== 'string' || input.id.length === 0) return null\n if (typeof input.runId !== 'string' || input.runId.length === 0) return null\n if (typeof input.target !== 'string' || input.target.length === 0) return null\n if (typeof input.phase !== 'string' || input.phase.length === 0) return null\n if (typeof input.timestamp !== 'number' || !Number.isFinite(input.timestamp)) return null\n\n return {\n id: input.id,\n runId: input.runId,\n scenarioId: stringOrUndefined(input.scenarioId),\n target: input.target,\n phase: input.phase,\n timestamp: input.timestamp,\n stepIndex: finiteNumberOrUndefined(input.stepIndex),\n parentId: stringOrUndefined(input.parentId),\n payload: input.payload,\n metadata: isRecord(input.metadata) ? { ...input.metadata } : undefined,\n }\n}\n\nfunction runtimeTrajectoryRecordKey<TRecord extends RuntimeTrajectoryRecord>(\n record: TRecord,\n index: number,\n recordIdOf?: (record: TRecord, index: number) => string | undefined,\n): string {\n return (\n stringOrUndefined(recordIdOf?.(record, index)) ??\n stringOrUndefined(record.id) ??\n `record[${index}]`\n )\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\nfunction stringOrUndefined(value: unknown): string | undefined {\n return typeof value === 'string' && value.length > 0 ? value : undefined\n}\n\nfunction finiteNumberOrUndefined(value: unknown): number | undefined {\n return typeof value === 'number' && Number.isFinite(value) ? value : undefined\n}\n","import type { FeedbackLabel, ProposedSideEffect } from './feedback-trajectory'\n\nexport interface ActionExecutionPolicy {\n allowedTypes?: string[]\n blockedTypes?: string[]\n alwaysRequireApprovalTypes?: string[]\n autoApproveTypes?: string[]\n requireApprovalForExternalSideEffects?: boolean\n requireApprovalAboveCostUsd?: number\n maxActionCostUsd?: number\n remainingBudgetUsd?: number\n expectedOutcomeRequired?: boolean\n killCriteriaRequired?: boolean\n}\n\nexport interface ActionPolicyDecision {\n allowed: boolean\n blocked: boolean\n requiresApproval: boolean\n reasons: string[]\n label?: FeedbackLabel\n}\n\nexport function evaluateActionPolicy(\n action: ProposedSideEffect,\n policy: ActionExecutionPolicy = {},\n options: { createdAt?: string } = {},\n): ActionPolicyDecision {\n const reasons: string[] = []\n let blocked = false\n let requiresApproval = Boolean(action.requiresApproval)\n\n if (policy.allowedTypes?.length && !policy.allowedTypes.includes(action.type)) {\n blocked = true\n reasons.push(`action type \"${action.type}\" is not allowed`)\n }\n if (policy.blockedTypes?.includes(action.type)) {\n blocked = true\n reasons.push(`action type \"${action.type}\" is blocked`)\n }\n if (policy.alwaysRequireApprovalTypes?.includes(action.type)) {\n requiresApproval = true\n reasons.push(`action type \"${action.type}\" requires approval`)\n }\n if (policy.requireApprovalForExternalSideEffects && action.externalSideEffect) {\n requiresApproval = true\n reasons.push('external side effect requires approval')\n }\n if (\n policy.requireApprovalAboveCostUsd !== undefined &&\n (action.costUsd ?? 0) > policy.requireApprovalAboveCostUsd\n ) {\n requiresApproval = true\n reasons.push(\n `cost ${action.costUsd} exceeds approval threshold ${policy.requireApprovalAboveCostUsd}`,\n )\n }\n if (policy.maxActionCostUsd !== undefined && (action.costUsd ?? 0) > policy.maxActionCostUsd) {\n blocked = true\n reasons.push(`cost ${action.costUsd} exceeds max action cost ${policy.maxActionCostUsd}`)\n }\n if (\n policy.remainingBudgetUsd !== undefined &&\n (action.costUsd ?? 0) > policy.remainingBudgetUsd\n ) {\n blocked = true\n reasons.push(`cost ${action.costUsd} exceeds remaining budget ${policy.remainingBudgetUsd}`)\n }\n if (policy.expectedOutcomeRequired && !action.metadata?.expectedOutcome) {\n blocked = true\n reasons.push('expected outcome is required')\n }\n if (policy.killCriteriaRequired && !action.metadata?.killCriteria) {\n blocked = true\n reasons.push('kill criteria are required')\n }\n if (policy.autoApproveTypes?.includes(action.type) && requiresApproval) {\n reasons.push(\n `action type \"${action.type}\" is auto-approved only when no approval policy applies`,\n )\n }\n\n if (!reasons.length) reasons.push(requiresApproval ? 'approval required' : 'action allowed')\n\n const label =\n blocked || requiresApproval\n ? {\n source: 'policy' as const,\n kind: blocked ? ('policy_block' as const) : ('comment' as const),\n value: { actionType: action.type, blocked, requiresApproval },\n reason: reasons.join('; '),\n severity: blocked ? ('critical' as const) : ('warning' as const),\n createdAt: options.createdAt ?? new Date().toISOString(),\n metadata: { action, policy },\n }\n : undefined\n\n return {\n allowed: !blocked,\n blocked,\n requiresApproval: !blocked && requiresApproval,\n reasons,\n label,\n }\n}\n","/**\n * Deploy gate layer — would the agent's build actually publish?\n *\n * The product Blueprint Agent fronts promises \"go from idea to live URL.\"\n * Pre-Gen-48 the eval stopped at install/typecheck/build/serve — every\n * one of which can pass while `vite build` (or `next build`, etc) fails\n * on a production-only constraint (env-var requirement, dynamic import\n * not statically resolvable, missing public asset).\n *\n * Deploy gate runs the production build via the supplied {@link DeployRunner}\n * and asserts:\n * - command exited 0\n * - artifact dir contains an entry point (index.html for static SPAs,\n * equivalent per framework family)\n *\n * Ships with a canonical `vite` runner. Additional runners\n * (wrangler-deploy --dry-run, next-build, etc.) plug in as factories.\n */\n\nimport type { Layer, LayerResult } from './multi-layer-verifier'\n\n// ─── Types ──────────────────────────────────────────────────────────────\n\nexport type DeployFamily = 'frontend-static' | 'nextjs' | 'remix' | 'fullstack-ts'\n\nexport interface DeployRunResult {\n ok: boolean\n /** Stdout/stderr tail surfaced as evidence. Bounded in caller. */\n output?: string\n /** Wall-clock duration of the build command. */\n durationMs?: number\n /** Path to artifact directory the runner expects (dist/, .next/, build/, etc). */\n artifactDir?: string\n /** True iff artifactDir contains the family's expected entry point. */\n artifactValid?: boolean\n}\n\nexport interface DeployRunner {\n /** Run the production build. The runner owns command + cwd. */\n run(): Promise<DeployRunResult>\n}\n\nexport interface DeployGateLayerInput {\n /** Build the runner per call. */\n runner: () => DeployRunner | Promise<DeployRunner>\n /** Family hint — for logging, surfaced in diagnostics. */\n family?: DeployFamily\n /** Layer name. Default `deploy`. */\n name?: string\n /** Layer dependencies — default `['build']`. */\n dependsOn?: string[]\n /** Weight in blendedScore. Default 1. */\n weight?: number\n /** Cap (ms). Default 120s — prod builds are slower than dev. */\n capMs?: number\n /** When true, treat artifactValid=false as a fail (default true). */\n requireArtifact?: boolean\n}\n\n// ─── Layer factory ──────────────────────────────────────────────────────\n\n/**\n * Build a deploy gate layer that runs the production build and verifies\n * the artifact. Pass: ok && artifactValid. Score: 1.0 (pass) or 0 (fail).\n *\n * For families where artifact-validation isn't applicable (e.g. a\n * server-rendered build that prints a manifest), set `requireArtifact:\n * false` and rely on the runner's own ok signal.\n */\nexport function deployGateLayer<Env = unknown>(input: DeployGateLayerInput): Layer<Env> {\n const requireArtifact = input.requireArtifact ?? true\n return {\n name: input.name ?? 'deploy',\n dependsOn: input.dependsOn ?? ['build'],\n weight: input.weight ?? 1,\n capMs: input.capMs ?? 120_000,\n run: async (ctx) => {\n const start = Date.now()\n let runner: DeployRunner\n try {\n runner = await input.runner()\n } catch (err) {\n return {\n layer: input.name ?? 'deploy',\n status: 'error',\n durationMs: Date.now() - start,\n findings: [\n {\n severity: 'major',\n message: `deploy runner failed to start: ${err instanceof Error ? err.message : String(err)}`,\n },\n ],\n reason: 'runner-init-failed',\n }\n }\n let result: DeployRunResult\n try {\n result = await runner.run()\n } catch (err) {\n return {\n layer: input.name ?? 'deploy',\n status: 'error',\n durationMs: Date.now() - start,\n findings: [\n {\n severity: 'major',\n message: `deploy command threw: ${err instanceof Error ? err.message : String(err)}`,\n },\n ],\n reason: 'runner-throw',\n }\n }\n if (ctx.signal.aborted) {\n return {\n layer: input.name ?? 'deploy',\n status: 'timeout',\n durationMs: Date.now() - start,\n findings: [],\n reason: 'aborted by overall cap',\n }\n }\n\n const artifactOk = !requireArtifact || result.artifactValid === true\n const pass = result.ok && artifactOk\n const findings: LayerResult['findings'] = []\n if (!result.ok) {\n findings.push({\n severity: 'critical',\n message: 'deploy build exited non-zero',\n evidence: (result.output ?? '').slice(-1200),\n })\n }\n if (result.ok && requireArtifact && !result.artifactValid) {\n findings.push({\n severity: 'major',\n message: `deploy build succeeded but artifact ${result.artifactDir ?? '(unknown)'} is invalid or empty`,\n })\n }\n return {\n layer: input.name ?? 'deploy',\n status: pass ? 'pass' : 'fail',\n score: pass ? 1 : 0,\n durationMs: Date.now() - start,\n findings,\n reason: pass\n ? `deploy build OK${input.family ? ` (${input.family})` : ''}${result.artifactDir ? ` → ${result.artifactDir}` : ''}`\n : !result.ok\n ? 'build command failed'\n : 'artifact missing or invalid',\n diagnostics: {\n deployBuildOk: result.ok ? 1 : 0,\n deployArtifactOk: result.artifactValid === true ? 1 : 0,\n deployBuildMs: result.durationMs ?? null,\n },\n }\n },\n }\n}\n\n// ─── Canonical vite runner ──────────────────────────────────────────────\n\nexport interface ViteDeployRunnerInput {\n /** Workdir to build. The runner cd's here. */\n workdir: string\n /**\n * Function to run a shell command in `workdir`. Same shape as\n * agent-eval's CommandRunner.run for compositional reuse.\n */\n exec: (\n cmd: string,\n opts?: { cwd?: string; timeoutMs?: number },\n ) => Promise<{ stdout: string; stderr: string; exitCode: number }>\n /**\n * Function to test whether a path exists in the workdir. Inject\n * `(p) => existsSync(join(workdir, p))` for host runs.\n */\n exists: (relativePath: string) => boolean | Promise<boolean>\n /** Build command. Default `npm run build`. */\n buildCommand?: string\n /** Artifact directory to validate. Default `dist`. */\n artifactDir?: string\n /** Entry-point file under artifactDir. Default `index.html`. */\n artifactEntry?: string\n /** Per-build cap (ms). Default 90s. */\n timeoutMs?: number\n}\n\n/**\n * Canonical runner for `frontend-static` family — runs the build script,\n * validates `<artifactDir>/<artifactEntry>` exists. Use as the `runner:`\n * factory for {@link deployGateLayer}.\n */\nexport function viteDeployRunner(input: ViteDeployRunnerInput): DeployRunner {\n return {\n run: async () => {\n const start = Date.now()\n const cmd = input.buildCommand ?? 'npm run build'\n const artifactDir = input.artifactDir ?? 'dist'\n const artifactEntry = input.artifactEntry ?? 'index.html'\n const timeoutMs = input.timeoutMs ?? 90_000\n const result = await input.exec(cmd, { cwd: input.workdir, timeoutMs })\n const ok = result.exitCode === 0\n let artifactValid = false\n try {\n const entryExists = await input.exists(`${artifactDir}/${artifactEntry}`)\n artifactValid = ok && Boolean(entryExists)\n } catch {\n artifactValid = false\n }\n const tail = ((result.stderr || result.stdout) ?? '').slice(-1500)\n return {\n ok,\n output: tail,\n durationMs: Date.now() - start,\n artifactDir,\n artifactValid,\n }\n },\n }\n}\n\n// ─── Canonical wrangler runner ──────────────────────────────────────────\n\nexport interface WranglerDeployRunnerInput {\n workdir: string\n exec: (\n cmd: string,\n opts?: { cwd?: string; timeoutMs?: number },\n ) => Promise<{ stdout: string; stderr: string; exitCode: number }>\n exists: (relativePath: string) => boolean | Promise<boolean>\n /** Build command. Default `npm run build`. */\n buildCommand?: string\n /** Wrangler dry-run command. Default `npx wrangler deploy --dry-run --outdir dist`. */\n dryRunCommand?: string\n /** Per-step cap (ms). Default 120s. */\n timeoutMs?: number\n}\n\n/**\n * Canonical runner for the `fullstack-ts` family on Cloudflare Workers\n * (Remix / React Router v7 / Hono on Workers). Detects wrangler.toml or\n * wrangler.jsonc in the workdir, builds, then `wrangler deploy --dry-run`\n * to catch missing bindings, syntax errors in wrangler config, and\n * import-time crashes that don't surface in `tsc`.\n *\n * No wrangler config = skip with \"no wrangler\" evidence (not a failure\n * — the gate caller decides whether to require deploy validation).\n */\nexport function wranglerDeployRunner(input: WranglerDeployRunnerInput): DeployRunner {\n return {\n run: async () => {\n const start = Date.now()\n const buildCmd = input.buildCommand ?? 'npm run build'\n const dryCmd = input.dryRunCommand ?? 'npx wrangler deploy --dry-run --outdir dist'\n const timeoutMs = input.timeoutMs ?? 120_000\n\n const hasToml = await input.exists('wrangler.toml')\n const hasJsonc = hasToml ? false : await input.exists('wrangler.jsonc')\n if (!hasToml && !hasJsonc) {\n return {\n ok: false,\n output: 'no wrangler config found (wrangler.toml / wrangler.jsonc absent)',\n durationMs: Date.now() - start,\n artifactDir: 'dist',\n artifactValid: false,\n }\n }\n\n const build = await input.exec(buildCmd, { cwd: input.workdir, timeoutMs })\n if (build.exitCode !== 0) {\n const tail = ((build.stderr || build.stdout) ?? '').slice(-1500)\n return {\n ok: false,\n output: `build failed: ${tail}`,\n durationMs: Date.now() - start,\n artifactDir: 'dist',\n artifactValid: false,\n }\n }\n\n const dry = await input.exec(dryCmd, { cwd: input.workdir, timeoutMs })\n if (dry.exitCode !== 0) {\n const tail = ((dry.stderr || dry.stdout) ?? '').slice(-1500)\n return {\n ok: false,\n output: `wrangler dry-run failed: ${tail}`,\n durationMs: Date.now() - start,\n artifactDir: 'dist',\n artifactValid: false,\n }\n }\n\n const tail = ((dry.stdout || dry.stderr) ?? '').slice(-1500)\n return {\n ok: true,\n output: tail,\n durationMs: Date.now() - start,\n artifactDir: 'dist',\n artifactValid: true,\n }\n },\n }\n}\n","/**\n * HeldOutGate — first-class held-out paired-delta promotion gate.\n *\n * Encodes the \"honesty override\" pattern that lived inline in\n * `~/webb/redteam/scripts/agent-eval-autoresearch.ts:138–171`.\n * The optimizer's best-guess is one thing; what we should actually\n * ship is another. The gate is the line between them.\n *\n * A candidate is promoted iff ALL FOUR pass:\n *\n * 0. **Coverage**: on BOTH splits, the fraction of DEALT work items that\n * carry a real score on BOTH arms is at least `minCoverage`\n * (default 1 — all of them). See \"Missing scores are missing data\".\n * 1. **Productive runs**: the candidate has at least\n * `minProductiveRuns` paired observations on items where BOTH\n * candidate and baseline produced a real (non-silent) score.\n * 2. **Paired delta**: the lower bound of the CI on the per-item\n * holdout delta (candidate − baseline) is strictly greater than\n * `pairedDeltaThreshold`. WHICH paired statistic carries that CI\n * depends on the outcome's shape — see \"Choosing the statistic\".\n * 3. **Overfit gap**: the candidate's gap between search-split\n * score and holdout-split score is no worse (more positive)\n * than the baseline's gap by more than `overfitGapThreshold`.\n * \"Better on search, worse on holdout\" is the canonical\n * overfit pattern; this catches it.\n *\n * ## Missing scores are missing data\n *\n * Gates 1-3 all read numbers off the items where BOTH arms produced a finite\n * score. Without gate 0 that set is a SILENT FILTER: an item the candidate\n * crashed on, timed out on, or never wrote a row for simply left the\n * comparison, and the verdict was computed over whatever survived. Measured on\n * the pre-0.134 gate: 26 held-out items, a candidate that produced no score at\n * all on 20 of them, promoted at every threshold from −0.05 to +0.30 on the 6\n * it answered (`unpairedBaselineRuns: 20` sat in the evidence, read by\n * nothing); the control — the same 20 failures scored as the 0 they earned —\n * was correctly refused at a mean paired delta of −0.3808. An agent that fails\n * 77% of its tasks was promoted, and every guarantee gates 1-3 provide sat\n * behind that filter.\n *\n * The gate does NOT impute a value for those items. It cannot: it does not know\n * the failure value of the caller's metric (0 on [0,1]? 0 on 0-100? a\n * lower-is-better latency?), and guessing one is exactly the silent assumption\n * this gate exists to remove. A caller who DOES know it writes it onto the\n * record before calling — that is the caller's decision to make and to be\n * accountable for, and it then travels in the run corpus where an auditor can\n * see it. What the gate does instead is REFUSE, and report the full coverage\n * accounting (`GateEvidence.holdoutCoverage` / `searchCoverage`) so the caller\n * can see exactly which items went dark and on which arm.\n *\n * The denominator is MEASURED, never assumed: it is the set of work items the\n * comparison was DEALT, which is what `pairRunRecords` reports when it is given\n * every row of a split rather than only the scored ones. There is no list of\n * \"expected\" scenarios to keep in sync and nothing to trust — an item counts as\n * dealt because a row for it exists on at least one arm.\n *\n * ## Choosing the statistic\n *\n * The median paired delta is the robust default, but it goes BLIND wherever\n * ties dominate: with more than half the pairs tied its sample value is exactly\n * 0 whatever the shift on the rest, and the whole bootstrap CI collapses to\n * [0, 0]. `low > threshold` is then \"no\" forever at a non-negative threshold\n * and \"yes\" forever at a negative one — the gate refuses real gains AND\n * promotes real regressions. Measured: 76 held-out items with 15 candidate\n * wins, 5 candidate losses and 56 ties is a real +13.2pp lift whose median\n * paired delta is 0; the median-CI gate refused it at every non-negative\n * threshold while PROMOTING the mirror-image −13.2pp regression at any\n * negative one.\n *\n * So the statistic is picked by the shape of the data, in three cases:\n *\n * 1. **Two-point (pass/fail) outcomes on ANY encoding** — every value on both\n * arms is either 0 or one common positive level, so {0,1} and {0,100} and\n * {0,5} all qualify (see `pairedBinaryScale`). The estimand is the change in\n * success rate, rescaled into the caller's native units. Two statistics\n * answer about it and BOTH must agree before anything is promoted:\n * `pairedRiskDifferenceScore` (Tango's score interval) supplies the\n * interval, and McNemar's exact test — carried on\n * `pairedRiskDifferenceExact` — holds a veto at any non-negative threshold.\n * The score interval is the one that decides because it is valid at a\n * NONZERO margin, which is the only thing a noninferiority threshold asks\n * about; the exact test's own Clopper-Pearson interval is conditional on the\n * discordant count and is therefore a valid interval only at margin 0.\n * McNemar's b/c/p ship as evidence.\n * 2. **Everything else** — the bootstrap CI of the MEAN paired delta. The mean\n * is the estimator that answers the gate's own question (\"by how much did\n * the score move\") in the caller's units, and it is well defined on every\n * shape the median loses: tie-dominated vectors, low-cardinality lattices\n * (block scores in {⅔, 1} from averaging pass/fail leaves; integer 0-100\n * judge dimensions), and mixed arms. Measured: 26 blocks of 3 pass/fail\n * leaves carrying a real +12.8pp lift, only 23% of pairs tied, give a\n * median CI of [0, 0.333] — a lower bound of exactly 0 refuses a real lift\n * at threshold 0, which is the original bug one lattice over. There is\n * therefore no tie-fraction cutoff: any cutoff leaves the lattice case open\n * on the far side of it. `heldoutSignificance` has defaulted to the mean\n * since #316 for the same reason.\n *\n * Set `deltaStatistic: 'median'` to force the median on every input — the\n * pre-0.134 behaviour, kept for callers who want outlier robustness and accept\n * the blindness that comes with it.\n *\n * ## Fail closed\n *\n * A ZERO-WIDTH CI carries no information about how far the estimate could be\n * wrong, wherever it sits. At [0, 0] it cannot tell a gain from a regression\n * and it clears every negative threshold. Away from zero it fails the opposite\n * way: n identical positive deltas give [g, g], which clears threshold 0 on no\n * spread at all. Both are an absence of evidence, so the gate refuses with\n * `indeterminate_delta` rather than answering \"promote\".\n *\n * The decision carries a machine-readable `rejectionCode` plus an\n * `evidence` block with every number the gate looked at, so the\n * downstream researcher / paper / dashboard can re-derive the\n * verdict without re-running.\n *\n * See also:\n * - `src/statistics.ts` for `pairedBootstrap` + `wilcoxonSignedRank`, and\n * `pairedRiskDifferenceScore` / `pairedRiskDifferenceExact` (+\n * `pairedBinaryScale`) for the binary path\n * - `src/run-record.ts` for the input row schema\n * - `src/reference-replay.ts` for the older, reference-replay-\n * specific promotion path (still useful for replay-style evals).\n */\n\nimport { pairRunRecords } from './paired-arms'\nimport { minimumPairsForPairedDeltaTest } from './paired-delta-test'\nimport {\n decidePairedPromotion,\n type PairedDecisionShape,\n type PairedDecisionStatistic,\n pairedDecisionShape,\n} from './paired-promotion-decision'\nimport { isRealnessGated, observedSplitScore, type ScorePreference } from './rollout/reward'\nimport type { RunRecord } from './run-record'\nimport { wilcoxonSignedRank } from './statistics'\n\nexport type HeldOutGateRejectionCode =\n | 'few_runs'\n | 'incomplete_coverage'\n | 'missing_split_scores'\n | 'missing_cost'\n | 'negative_delta'\n | 'indeterminate_delta'\n | 'overfit_gap'\n | 'cost_ceiling'\n\n/**\n * How much of one split's DEALT work the comparison actually measured.\n *\n * `answered + unscoredPairs + candidateOnly + baselineOnly === dealt` — a\n * complete, mutually exclusive partition of the item slots the split was dealt,\n * so nothing can leave the comparison without appearing in exactly one bucket.\n */\nexport interface SplitCoverage {\n /** Work items the split was dealt: every item with a row on either arm. */\n dealt: number\n /** Dealt items carrying a finite score on BOTH arms — the only ones any\n * paired statistic can read. */\n answered: number\n /** Dealt items with a row on both arms where at least one row carried no\n * finite score: a run happened and produced nothing (crash, timeout, judge\n * failure). Measured absence, not an absent item. */\n unscoredPairs: number\n /** Dealt items only the candidate produced a row for. */\n candidateOnly: number\n /** Dealt items only the baseline produced a row for. */\n baselineOnly: number\n /** `answered / dealt`, or 0 when nothing was dealt. 1 means every dealt item\n * was scored on both arms. */\n coverage: number\n}\n\nexport interface HeldOutGateConfig {\n /** Minimum number of paired (candidate, baseline) holdout observations\n * required before promotion. The exact small-sample test may require more\n * observations at the selected confidence. */\n minProductiveRuns?: number\n /** The CI lower bound on the paired holdout delta must exceed this to\n * promote. Read in the same units as the holdout scores: with binary\n * (0/1) outcomes that is a change in success RATE (0.05 = +5pp).\n * Default 0. */\n pairedDeltaThreshold?: number\n /**\n * Which paired statistic carries the promotion CI.\n *\n * `'auto'` (default) picks by outcome shape — two-point outcomes on the exact\n * paired risk difference, everything else on the mean bootstrap (see the\n * module header). `'median'` forces the median bootstrap on every input,\n * including shapes where it is structurally blind and will refuse a real lift\n * and accept a real regression. Set it for outlier robustness on genuinely\n * continuous outcomes, or to reproduce a pre-0.134 verdict.\n */\n deltaStatistic?: 'auto' | 'median'\n /** Maximum allowed worsening of (search − holdout) gap relative to\n * baseline. Default 0.15 (i.e. candidate may overfit by up to 15\n * absolute score points more than baseline before rejection). */\n overfitGapThreshold?: number\n /** Stable label of the baseline candidate. Required — paper-grade\n * evaluation never compares two unlabelled candidates. */\n baselineKey: string\n /** Confidence level for the bootstrap CI. Default 0.95. */\n confidence?: number\n /** Bootstrap resamples. Default 2000. */\n bootstrapResamples?: number\n /** Optional deterministic seed for the bootstrap. Default undefined\n * (Math.random). */\n seed?: number\n /**\n * Smallest acceptable `answered / dealt` fraction, required on BOTH splits.\n * Default 1: every work item the comparison was dealt must carry a real score\n * on both arms before the gate will decide anything.\n *\n * The default is 1 because a missing score is missing data, and a promotion\n * computed over \"the items that happened to answer\" is a promotion computed\n * over a set the candidate selected by failing (see the module header). One\n * split below `minCoverage` rejects with `incomplete_coverage`.\n *\n * Lowering it is a real, defensible choice for a caller who accepts a known\n * flake rate — but it must be DECLARED, not inherited: the shrunken\n * denominator then still ships in `GateEvidence.holdoutCoverage` /\n * `searchCoverage`, so the verdict can never be read without it. Must be in\n * [0, 1]; anything else throws rather than clamping.\n */\n minCoverage?: number\n /**\n * Hard ceiling on the candidate's median per-task USD cost. When the\n * candidate clears the quality gates (paired-delta + overfit-gap) but\n * its median cost exceeds this number, the gate rejects with\n * `cost_ceiling`. Default `undefined` = no cost ceiling, behaving\n * exactly like the pre-cost gate.\n *\n * This exists because \"we ship the better prompt\" is only an honest\n * pitch when the better prompt also fits a customer-stated budget.\n * Cost is read from `RunRecord.costUsd`; a null amount rejects a\n * configured cost check because the limit cannot be proven.\n */\n costPerTaskCeiling?: number\n}\n\n/** Which paired statistic a `HeldOutGate` verdict was decided on. One\n * definition, shared with every other gate that decides a paired interval. */\nexport type DeltaStatistic = PairedDecisionStatistic\n\nexport interface GateEvidence {\n /** Number of paired (candidate, baseline) holdout observations used. */\n productiveRuns: number\n /** Candidate holdout rows with no baseline row at the same work identity. */\n unpairedCandidateRuns: number\n /** Baseline holdout rows with no candidate row at the same work identity. */\n unpairedBaselineRuns: number\n /**\n * How much of the dealt HOLDOUT work carried a score on both arms — the\n * denominator behind `productiveRuns`, `medianPairedDelta`, `pairedCI` and\n * `holdoutScore`. A `coverage` below 1 means those numbers describe a\n * SUBSET of the items the comparison was dealt, and which items are in that\n * subset was decided by whichever arm went dark.\n */\n holdoutCoverage: SplitCoverage\n /**\n * The same accounting for the SEARCH split — the denominator behind\n * `searchScore`, and therefore behind both overfit gaps.\n */\n searchCoverage: SplitCoverage\n /** Median of paired holdout deltas, or null when there are no pairs.\n * ALWAYS the literal median — a diagnostic, not necessarily the statistic\n * the verdict keyed on (see `deltaStatistic` / `decidingDelta`). On binary\n * outcomes this is normally 0 by construction. */\n medianPairedDelta: number | null\n /** Which paired statistic the promotion CI was computed on, and therefore\n * what `decidingDelta` / `pairedCI` mean. `'median_bootstrap'` = bootstrap\n * CI on the median paired delta (continuous outcomes).\n * `'mean_bootstrap'` = bootstrap CI on the mean paired delta, used when ties\n * dominate and pin the median at 0. `'paired_risk_difference'` = change in\n * success rate on a two-point (pass/fail) outcome, on an EXACT conditional\n * interval dual to McNemar's exact test, rescaled to the outcome's native\n * units (so a 0-100 dimension reports points, not a rate). */\n deltaStatistic: DeltaStatistic\n /** Point estimate of `deltaStatistic` — the number the `pairedDeltaThreshold`\n * check is about. Null when no CI was computed. */\n decidingDelta: number | null\n /** CI on `deltaStatistic`, if computed. The gate promotes iff\n * `pairedCI.low > pairedDeltaThreshold`. */\n pairedCI: { low: number; high: number } | null\n /** Wilcoxon signed-rank p-value, if computed. Always the Wilcoxon, on both\n * paths, so this field never changes meaning. */\n pairedPValue: number | null\n /** McNemar's exact paired-binary test on the holdout pairs, or null when the\n * outcomes were not two-point (or no CI was computed). `b` = candidate-only\n * wins, `c` = baseline-only wins; only these discordant pairs carry signal.\n * When present it is not merely reported: the promotion interval is dual to\n * this p-value, so a promotion at a non-negative threshold implies\n * `pValue < 1 − confidence`. */\n mcnemar: { b: number; c: number; nDiscordant: number; pValue: number } | null\n /** The common positive level of a two-point outcome — 1 for {0,1}, 100 for a\n * 0-100 pass/fail dimension — or null when the outcome is not two-point.\n * Non-null is exactly the condition for the `paired_risk_difference` path,\n * and it is the factor `decidingDelta` / `pairedCI` were rescaled by. */\n binaryScale: number | null\n /** Fraction of paired holdout deltas that are exact ties, or null when there\n * are no pairs. At or above 0.5 the median paired delta is pinned at 0 by\n * construction; this is the diagnostic for why a median-decided verdict\n * (`deltaStatistic: 'median'`) saw nothing. */\n tieFraction: number | null\n /** Mean candidate score on the search split, or null when absent. */\n searchScore: number | null\n /** Mean candidate score on the holdout split, or null when absent. */\n holdoutScore: number | null\n /** Candidate (search − holdout) gap, or null when either side is absent. */\n overfitGap: number | null\n /** Baseline (search − holdout) gap, or null when either side is absent. */\n baselineOverfitGap: number | null\n /** Median per-task USD cost across the candidate's runs. Recorded\n * even when no `costPerTaskCeiling` is configured so downstream\n * dashboards (intelligence.tangle.tools) can render \\$/task per\n * generation regardless of gating policy. */\n medianCandidateCost: number | null\n /** Median per-task USD cost across the baseline runs, for\n * symmetric reporting. */\n medianBaselineCost: number | null\n /**\n * Runs (candidate + baseline) dropped before pairing because the\n * authenticity gate flagged them as gamed. Surfaced rather than silent: a\n * promotion decision computed over a shrunken pool has to say by how much,\n * and a nonzero count here is itself the finding.\n */\n realnessGatedRuns: number\n}\n\nexport interface GateDecision {\n /** Final promote/no-promote verdict. */\n promote: boolean\n /** The candidate that was evaluated. */\n candidateId: string\n /** The baseline it was compared against. */\n baselineId: string\n /** Every number the gate looked at, for audit + paper export. */\n evidence: GateEvidence\n /** Human-readable reason. */\n reason: string\n /** Machine-readable rejection code, or null on promote. */\n rejectionCode: HeldOutGateRejectionCode | null\n}\n\n/**\n * Held-out paired-delta promotion gate. Construct once with config,\n * call `evaluate(candidateRuns, baselineRuns)` per (candidate,\n * baseline) pair. Stateless across calls.\n */\nexport class HeldOutGate {\n private readonly minProductiveRuns: number\n private readonly pairedDeltaThreshold: number\n private readonly overfitGapThreshold: number\n private readonly baselineKey: string\n private readonly confidence: number\n private readonly resamples: number\n private readonly seed?: number\n private readonly costPerTaskCeiling?: number\n private readonly minCoverage: number\n private readonly deltaStatistic: 'auto' | 'median'\n\n constructor(config: HeldOutGateConfig) {\n if (!config.baselineKey) {\n throw new Error('HeldOutGate: baselineKey is required')\n }\n if (\n config.minCoverage !== undefined &&\n !(Number.isFinite(config.minCoverage) && config.minCoverage >= 0 && config.minCoverage <= 1)\n ) {\n throw new Error(\n `HeldOutGate: minCoverage must be a finite fraction in [0, 1], got ${config.minCoverage}`,\n )\n }\n this.minCoverage = config.minCoverage ?? 1\n this.confidence = config.confidence ?? 0.95\n this.minProductiveRuns = Math.max(\n config.minProductiveRuns ?? 3,\n minimumPairsForPairedDeltaTest(this.confidence),\n )\n this.pairedDeltaThreshold = config.pairedDeltaThreshold ?? 0\n this.overfitGapThreshold = config.overfitGapThreshold ?? 0.15\n this.baselineKey = config.baselineKey\n this.resamples = config.bootstrapResamples ?? 2000\n this.seed = config.seed\n this.deltaStatistic = config.deltaStatistic ?? 'auto'\n if (\n config.costPerTaskCeiling !== undefined &&\n !(Number.isFinite(config.costPerTaskCeiling) && config.costPerTaskCeiling > 0)\n ) {\n throw new Error('HeldOutGate: costPerTaskCeiling must be a positive finite number')\n }\n this.costPerTaskCeiling = config.costPerTaskCeiling\n }\n\n /** Decide whether `candidate` should replace `baseline`.\n * Pairing is by `(experimentId, scenarioId, seed)`.\n * Missing or duplicate identities throw instead of comparing by position. */\n evaluate(candidate: RunRecord[], baseline: RunRecord[]): GateDecision {\n const candidateId = inferCandidateId(candidate, this.baselineKey)\n const baselineId = this.baselineKey\n assertScenarioIdentities([...candidate, ...baseline])\n\n // Runs flagged as gamed are dropped from BOTH sides before anything is\n // paired. This is a promotion decision, and the whole point of the\n // authenticity gate is that a faked success must not buy a promotion; the\n // count ships in the evidence so the shrunken pool is never invisible.\n const realnessGatedRuns = [...candidate, ...baseline].filter(isRealnessGated).length\n const honestCandidate = candidate.filter((run) => !isRealnessGated(run))\n const honestBaseline = baseline.filter((run) => !isRealnessGated(run))\n\n const candidateSearch = scoredRuns(honestCandidate, 'search')\n const baselineSearch = scoredRuns(honestBaseline, 'search')\n const candidateHoldout = scoredRuns(honestCandidate, 'holdout')\n const baselineHoldout = scoredRuns(honestBaseline, 'holdout')\n const searchPairing = pairRunRecords(baselineSearch, candidateSearch)\n const holdoutPairing = pairRunRecords(baselineHoldout, candidateHoldout)\n // The DEALT denominators, measured over every row of each split — scored or\n // not — so an item that produced no number is still counted as work the\n // comparison was given. `splitCoverage` re-pairs the unfiltered rows with\n // the same primitive the decision pairs with, which is the only way the\n // \"dealt\" set can be derived rather than assumed.\n const searchCoverage = splitCoverage(honestBaseline, honestCandidate, 'search')\n const holdoutCoverage = splitCoverage(honestBaseline, honestCandidate, 'holdout')\n // `scoredRuns` admits only rows whose split score is a finite number, so\n // the non-null assertion below cannot fire on data the pairing saw.\n const splitScoreOf = (run: RunRecord, split: ScorePreference): number =>\n observedSplitScore(run, split) as number\n const beforeSearch = searchPairing.pairs.map((pair) => splitScoreOf(pair.baseline, 'search'))\n const afterSearch = searchPairing.pairs.map((pair) => splitScoreOf(pair.treatment, 'search'))\n const beforeHoldout = holdoutPairing.pairs.map((pair) => splitScoreOf(pair.baseline, 'holdout'))\n const afterHoldout = holdoutPairing.pairs.map((pair) => splitScoreOf(pair.treatment, 'holdout'))\n\n const productiveRuns = beforeHoldout.length\n\n const candidateSearchMean = meanOrNull(afterSearch)\n const candidateHoldoutMean = meanOrNull(afterHoldout)\n const baselineSearchMean = meanOrNull(beforeSearch)\n const baselineHoldoutMean = meanOrNull(beforeHoldout)\n\n const overfitGap = diffOrNull(candidateSearchMean, candidateHoldoutMean)\n const baselineOverfitGap = diffOrNull(baselineSearchMean, baselineHoldoutMean)\n\n // Cost summary — surfaced in evidence regardless of gating policy so\n // downstream dashboards always know what the candidate cost.\n //\n // The population is the rows that DECIDED this verdict: the matched pairs\n // on both splits, and nothing else. Taking the median over every row the\n // caller happened to pass is a denominator nobody measured, and it is\n // trivially movable — 48 rows tagged `dev` at $0.0001, which the gate never\n // scores and the coverage check never counts, drag a real $5.00/task\n // candidate to a reported $0.0001 and clear a $1.00 ceiling. Deriving the\n // population from the pairing rather than from a list of split tags means\n // there is no tag to sit outside the rule: a row either decided the verdict\n // or it does not describe its cost.\n const medianCandidateCost = completeCostMedian([\n ...searchPairing.pairs.map((pair) => pair.treatment),\n ...holdoutPairing.pairs.map((pair) => pair.treatment),\n ])\n const medianBaselineCost = completeCostMedian([\n ...searchPairing.pairs.map((pair) => pair.baseline),\n ...holdoutPairing.pairs.map((pair) => pair.baseline),\n ])\n const commonEvidence = {\n productiveRuns,\n unpairedCandidateRuns: holdoutPairing.unpairedTreatment.length,\n unpairedBaselineRuns: holdoutPairing.unpairedBaseline.length,\n searchScore: candidateSearchMean,\n holdoutScore: candidateHoldoutMean,\n overfitGap,\n baselineOverfitGap,\n medianCandidateCost,\n medianBaselineCost,\n realnessGatedRuns,\n searchCoverage,\n holdoutCoverage,\n }\n /** Evidence for the early exits, where no CI was computed at all. The\n * statistic that WOULD have decided is still reported so a caller can see\n * which branch their data lands in without producing a verdict. */\n const earlyShape = this.chooseShape(beforeHoldout, afterHoldout)\n const noCiEvidence = {\n ...commonEvidence,\n medianPairedDelta: productiveRuns > 0 ? medianDelta(beforeHoldout, afterHoldout) : null,\n deltaStatistic: earlyShape.statistic,\n decidingDelta: null,\n pairedCI: null,\n pairedPValue: null,\n mcnemar: null,\n binaryScale: earlyShape.binaryScale,\n tieFraction: earlyShape.tieFraction,\n }\n\n const missingSplitScores = [\n candidateSearch.length === 0 ? 'candidate search' : null,\n candidateHoldout.length === 0 ? 'candidate holdout' : null,\n baselineSearch.length === 0 ? 'baseline search' : null,\n baselineHoldout.length === 0 ? 'baseline holdout' : null,\n ].filter((label): label is string => label !== null)\n if (missingSplitScores.length > 0) {\n return {\n promote: false,\n candidateId,\n baselineId,\n evidence: noCiEvidence,\n reason: `missing_split_scores: ${missingSplitScores.join(', ')} score evidence is absent`,\n rejectionCode: 'missing_split_scores',\n }\n }\n\n // COVERAGE — before every statistic, because every statistic below reads\n // only the items that answered. A candidate that went dark on most of its\n // work does not get judged on the remainder; missing scores are missing\n // data, and the gate refuses rather than shrinking the denominator to the\n // subset that happened to answer. Checked ahead of `few_runs` because \"6 of\n // 26 items produced no score\" is the finding, and \"6 paired observations\"\n // is only its shadow.\n const shortfalls = (\n [\n ['holdout', holdoutCoverage],\n ['search', searchCoverage],\n ] as const\n ).filter(([, cov]) => cov.coverage < this.minCoverage)\n if (shortfalls.length > 0) {\n return {\n promote: false,\n candidateId,\n baselineId,\n evidence: noCiEvidence,\n reason:\n `incomplete_coverage: ${shortfalls.map(([split, cov]) => describeCoverage(split, cov)).join('; ')}` +\n ` — required ${fmt(this.minCoverage)} of every dealt item scored on both arms.` +\n ' A missing score is missing data, not an absent item: the gate will not decide on the subset that answered',\n rejectionCode: 'incomplete_coverage',\n }\n }\n\n if (productiveRuns < this.minProductiveRuns) {\n return {\n promote: false,\n candidateId,\n baselineId,\n evidence: noCiEvidence,\n reason: `few_runs: ${productiveRuns} paired holdout observation(s) < min ${this.minProductiveRuns}`,\n rejectionCode: 'few_runs',\n }\n }\n if (overfitGap === null || baselineOverfitGap === null) {\n throw new Error('HeldOutGate: complete split scores did not produce overfit gaps')\n }\n\n // The paired holdout delta, decided by the one shared rule (see\n // `paired-promotion-decision.ts`): the estimator comes from the outcome's\n // shape, McNemar vetoes at a non-negative threshold, and a zero-width\n // interval is refused. `medianPairedDelta` stays the literal median on\n // EVERY path so the number that made the old gate blind remains visible.\n const decision = decidePairedPromotion(beforeHoldout, afterHoldout, {\n threshold: this.pairedDeltaThreshold,\n confidence: this.confidence,\n resamples: this.resamples,\n seed: this.seed,\n minPairs: this.minProductiveRuns,\n statistic: this.deltaStatistic === 'median' ? 'median' : 'mean',\n })\n const literalMedian = medianDelta(beforeHoldout, afterHoldout)\n const wilcoxon = wilcoxonSignedRank(beforeHoldout, afterHoldout)\n const { delta: decidingDelta, low, high, label: deltaLabel } = decision\n\n const evidence: GateEvidence = {\n ...commonEvidence,\n medianPairedDelta: literalMedian,\n deltaStatistic: decision.statistic,\n decidingDelta,\n pairedCI: { low, high },\n pairedPValue: wilcoxon.p,\n mcnemar: decision.mcnemar,\n binaryScale: decision.binaryScale,\n tieFraction: decision.tieFraction,\n }\n\n // FAIL CLOSED on a ZERO-WIDTH interval, wherever it sits. [0, 0] cannot\n // tell a gain from a regression and clears every negative threshold, which\n // is exactly how a tie-pinned median laundered a −13.2pp regression into a\n // promotion. But the same emptiness away from zero is just as false a\n // certainty and it fails the other way: n identical positive deltas give\n // [g, g], which clears threshold 0 with no spread to support it. Under a\n // bounded asymmetric null whose true mean paired delta is exactly 0 — 2 %\n // of pairs dropping by 1.0, the rest gaining 0.0204 — every sample that\n // misses the drop is exactly that shape, and a `low === 0 && high === 0`\n // test promotes 65.65 % of them at n = 20 against a nominal 5 %.\n if (decision.indeterminate) {\n return {\n promote: false,\n candidateId,\n baselineId,\n evidence,\n reason:\n `indeterminate_delta: ${decision.indeterminateCause}, so the paired holdout CI is ` +\n `[${fmt(low)}, ${fmt(high)}] and carries no direction — ` +\n `it cannot clear threshold ${fmt(this.pairedDeltaThreshold)} on evidence`,\n rejectionCode: 'indeterminate_delta',\n }\n }\n\n // The exact test is a VETO on the two-point path. Redundant by construction\n // — `pairedRiskDifferenceExact`'s interval is dual to this p-value, so\n // `low > 0` already implies `pValue < 1 − confidence` (verified over 8108\n // (b, c, ties, confidence) shapes) — and kept anyway so that swapping the\n // estimator for one without that duality (the Wald interval, which\n // undercovers on a handful of discordant pairs) cannot silently reintroduce\n // \"promotes what the exact test refuses\". Only applies at a non-negative\n // threshold: a negative threshold is a non-inferiority question, which\n // McNemar's test of \"no difference\" is not the right test for.\n const exactTestVetoes = decision.exactTestVetoes\n\n // Negative-delta gate (the paired-delta evidence must clear the threshold).\n if (!decision.clearsThreshold || exactTestVetoes) {\n const detail = exactTestVetoes\n ? ` McNemar exact p=${decision.mcnemar?.pValue.toExponential(2)} does not reject at α=${fmt(1 - this.confidence)}.`\n : decision.methodDetail\n return {\n promote: false,\n candidateId,\n baselineId,\n evidence,\n reason:\n `negative_delta: paired holdout ${deltaLabel} Δ=${fmt(decidingDelta)} ` +\n `CI=[${fmt(low)}, ${fmt(high)}] does not clear threshold ${fmt(this.pairedDeltaThreshold)}.${detail}`,\n rejectionCode: 'negative_delta',\n }\n }\n\n // Overfit-gap gate. We allow some absolute slack —\n // candidate.gap ≤ baseline.gap + overfitGapThreshold.\n if (overfitGap > baselineOverfitGap + this.overfitGapThreshold) {\n return {\n promote: false,\n candidateId,\n baselineId,\n evidence,\n reason:\n `overfit_gap: candidate gap=${fmt(overfitGap)} exceeds baseline gap=${fmt(baselineOverfitGap)} ` +\n `by more than ${fmt(this.overfitGapThreshold)}`,\n rejectionCode: 'overfit_gap',\n }\n }\n\n // Cost-ceiling gate. Runs after quality gates so a cost-driven\n // rejection always carries a \"you cleared quality but blew budget\"\n // story rather than masking a quality failure.\n if (this.costPerTaskCeiling !== undefined && medianCandidateCost === null) {\n return {\n promote: false,\n candidateId,\n baselineId,\n evidence,\n reason: 'missing_cost: candidate cost evidence is incomplete',\n rejectionCode: 'missing_cost',\n }\n }\n if (\n this.costPerTaskCeiling !== undefined &&\n medianCandidateCost !== null &&\n medianCandidateCost > this.costPerTaskCeiling\n ) {\n return {\n promote: false,\n candidateId,\n baselineId,\n evidence,\n reason:\n `cost_ceiling: candidate median cost $${fmt(medianCandidateCost)} ` +\n `exceeds ceiling $${fmt(this.costPerTaskCeiling)} (baseline $${fmt(medianBaselineCost)})`,\n rejectionCode: 'cost_ceiling',\n }\n }\n\n return {\n promote: true,\n candidateId,\n baselineId,\n evidence,\n reason:\n `promote: paired holdout ${deltaLabel} Δ=${fmt(decidingDelta)} ` +\n `CI=[${fmt(low)}, ${fmt(high)}] over ${productiveRuns} pairs; ` +\n `overfit gap candidate=${fmt(overfitGap)} vs baseline=${fmt(baselineOverfitGap)}; ` +\n `median cost candidate=$${fmt(medianCandidateCost)} vs baseline=$${fmt(medianBaselineCost)}`,\n rejectionCode: null,\n }\n }\n\n /**\n * Which paired statistic decides this data, and the shape facts behind it —\n * for the early exits, where no interval is computed. Delegates to\n * {@link pairedDecisionShape} so the reported shape can never disagree with\n * the shape the decision actually routes on.\n */\n private chooseShape(before: number[], after: number[]): PairedDecisionShape {\n return pairedDecisionShape(before, after, this.deltaStatistic === 'median' ? 'median' : 'mean')\n }\n}\n\n// ── Helpers ──────────────────────────────────────────────────────────\n\nfunction inferCandidateId(candidate: RunRecord[], baselineKey: string): string {\n for (const run of candidate) {\n if (run.candidateId && run.candidateId !== baselineKey) return run.candidateId\n }\n // All candidate rows match the baseline key — caller mistake, but\n // surface the symptom rather than throwing inside the gate.\n return candidate[0]?.candidateId ?? '(unknown candidate)'\n}\n\nfunction assertScenarioIdentities(runs: RunRecord[]): void {\n for (const run of runs) {\n if (typeof run.scenarioId !== 'string' || run.scenarioId.trim() === '') {\n throw new Error(`HeldOutGate: run ${run.runId} is missing scenarioId`)\n }\n }\n}\n\n/**\n * Rows carrying a finite score on one split. RAW (`observedSplitScore`) by\n * choice: the gated runs are already removed by the caller, so applying the\n * gate again here would only zero runs that are no longer in the set, and the\n * reported means must describe the runs that actually decided the promotion.\n */\nfunction scoredRuns(runs: RunRecord[], split: ScorePreference): RunRecord[] {\n return runs.filter((run) => {\n if (run.splitTag !== split) return false\n const v = observedSplitScore(run, split)\n return typeof v === 'number' && Number.isFinite(v)\n })\n}\n\n/** Every row tagged to one split, scored or not — the work the split was\n * DEALT, as opposed to the work it managed to measure. */\nfunction dealtRuns(runs: RunRecord[], split: ScorePreference): RunRecord[] {\n return runs.filter((run) => run.splitTag === split)\n}\n\nfunction hasFiniteScore(run: RunRecord, split: ScorePreference): boolean {\n const v = observedSplitScore(run, split)\n return typeof v === 'number' && Number.isFinite(v)\n}\n\n/**\n * Partition one split's dealt work into answered / unscored / one-armed.\n *\n * Pairs the UNFILTERED rows with the same `pairRunRecords` the decision uses,\n * so the denominator comes out of the same identity rules as the numerator and\n * cannot drift from it. Deliberately a SECOND pairing rather than a widening of\n * the decision's own: the decision keeps pairing exactly the rows it always\n * paired, so this check can only ever add a refusal, never move a verdict that\n * was already being made on a complete set.\n */\nfunction splitCoverage(\n baseline: RunRecord[],\n candidate: RunRecord[],\n split: ScorePreference,\n): SplitCoverage {\n const pairing = pairRunRecords(dealtRuns(baseline, split), dealtRuns(candidate, split))\n let answered = 0\n for (const pair of pairing.pairs) {\n if (hasFiniteScore(pair.baseline, split) && hasFiniteScore(pair.treatment, split)) answered += 1\n }\n const unscoredPairs = pairing.pairs.length - answered\n const candidateOnly = pairing.unpairedTreatment.length\n const baselineOnly = pairing.unpairedBaseline.length\n const dealt = pairing.pairs.length + candidateOnly + baselineOnly\n return {\n dealt,\n answered,\n unscoredPairs,\n candidateOnly,\n baselineOnly,\n coverage: dealt === 0 ? 0 : answered / dealt,\n }\n}\n\nfunction describeCoverage(split: string, cov: SplitCoverage): string {\n const dark = [\n cov.unscoredPairs > 0 ? `${cov.unscoredPairs} ran on both arms but produced no score` : null,\n cov.baselineOnly > 0 ? `${cov.baselineOnly} only the baseline produced a row for` : null,\n cov.candidateOnly > 0 ? `${cov.candidateOnly} only the candidate produced a row for` : null,\n ].filter((part): part is string => part !== null)\n return (\n `${split} scored ${cov.answered} of ${cov.dealt} dealt items (coverage ${fmt(cov.coverage)})` +\n (dark.length > 0 ? ` — ${dark.join(', ')}` : '')\n )\n}\n\nfunction meanOrNull(xs: number[]): number | null {\n if (xs.length === 0) return null\n return xs.reduce((s, x) => s + x, 0) / xs.length\n}\n\nfunction diffOrNull(a: number | null, b: number | null): number | null {\n if (a === null || b === null) return null\n return a - b\n}\n\nfunction medianDelta(before: number[], after: number[]): number {\n const ds = before.map((b, i) => after[i]! - b).sort((x, y) => x - y)\n if (ds.length === 0) throw new Error('HeldOutGate: median delta requires at least one pair')\n const mid = Math.floor(ds.length / 2)\n return ds.length % 2 === 0 ? (ds[mid - 1]! + ds[mid]!) / 2 : ds[mid]!\n}\n\nfunction medianFinite(xs: number[]): number | null {\n const ys = xs.filter((x) => Number.isFinite(x)).sort((x, y) => x - y)\n if (ys.length === 0) return null\n const mid = Math.floor(ys.length / 2)\n return ys.length % 2 === 0 ? (ys[mid - 1]! + ys[mid]!) / 2 : ys[mid]!\n}\n\nfunction completeCostMedian(runs: RunRecord[]): number | null {\n if (runs.length === 0) return null\n const costs: number[] = []\n for (const run of runs) {\n const provenance = run.costProvenance\n if (provenance.kind === 'uncaptured') return null\n costs.push(provenance.usd)\n }\n return medianFinite(costs)\n}\n\nfunction fmt(x: number | null): string {\n if (x === null) return 'n/a'\n return x.toFixed(4)\n}\n","/**\n * Hidden-criteria grading firewall — grade an agent on criteria it never saw.\n *\n * A trustworthy benchmark splits every scenario's data by WHERE each field is\n * allowed to flow, then proves the held-out / judge-only fields never reach the\n * agent during the run. The coding bench expresses this with four destinations\n * (prompt / develop-against / held-out suite / rubric); this module lifts the\n * domain-FREE core out of it so research, legal, tax, content — any domain —\n * can declare the same routing and get the same firewall enforcement and the\n * same held-out-weighted composite, plugging in its OWN grader.\n *\n * Two reusable pieces, both domain-agnostic:\n *\n * 1. FIELD ROUTING BY DESTINATION. A scenario declares each field's\n * `FieldDestination`; `assertNoHiddenLeak` is a pure checker that throws if\n * a grading-only or judge-only field's value appears in what reaches the\n * agent. The domain decides which fields exist and where they go — the\n * substrate only enforces \"hidden stays hidden\".\n *\n * 2. HIDDEN-CRITERIA GRADING. The domain supplies its own grader\n * `(artifact, hiddenCriteria) => { passRate, total }` — the coding\n * node-test executor is ONE such grader a consumer plugs in; the substrate\n * bakes in NO node/test/TS/exec/regex. `gradeOnHidden` runs that grader\n * behind the firewall and `blendHeldout` composes its pass rate with a\n * judge score into the final number the leaderboard ranks on.\n *\n * Shape mirrors `treatment-gate`/`authenticity`: pure predicates and pure\n * composition over already-computed values, fail-loud, with the\n * \"which field / which weight / which grader\" decisions left as parameters and\n * no domain literal anywhere in the module.\n *\n * Lives next to `test-graded-scenario` and `partition-held-out` — it is a\n * scorecard/grading concept that makes sense without a running agent loop.\n */\n\nimport type { JudgeScore } from './campaign/types'\nimport { ValidationError } from './errors'\n\n// ── 1. field routing by destination ──────────────────────────────────────────\n\n/**\n * Where one scenario field is allowed to flow. The firewall guarantee is keyed\n * on this tag, not on a field name — a domain can have any number of fields per\n * destination.\n *\n * - `agent-visible` reaches the agent's context during the run (the prompt,\n * the task statement — what the agent reads to act).\n * - `develop-against` seeded into the agent's environment during the run so it\n * can iterate (a visible example/test/reference). The\n * agent MAY read it — that is intentional (real TDD). Not\n * a leak: it is example-grade, not the grading criteria.\n * - `grading-only` the hidden criteria. Used ONLY at grading, after the run\n * — the held-out suite / answer key / hidden requirements.\n * Must NEVER reach the agent context. This is what makes a\n * good score un-memorizable.\n * - `judge-only` grading context for the judge only (rubric anchors,\n * design intent). Lives with the judge, never in the agent\n * context.\n */\nexport type FieldDestination = 'agent-visible' | 'develop-against' | 'grading-only' | 'judge-only'\n\n/** The destinations a value must be kept OUT of the agent context for. */\nconst hiddenDestinations: ReadonlySet<FieldDestination> = new Set<FieldDestination>([\n 'grading-only',\n 'judge-only',\n])\n\n/** True for the destinations whose values must never reach the agent context. */\nexport function isHiddenDestination(destination: FieldDestination): boolean {\n return hiddenDestinations.has(destination)\n}\n\n/**\n * A scenario's fields routed by destination. The domain owns the field set\n * (`TFields` — a record of its named fields to their string-renderable values)\n * and declares one `FieldDestination` per field. `routeFields` builds this from\n * a domain's `(value, destination)` map; the firewall reads it.\n */\nexport interface RoutedField {\n /** The field's name — for diagnostics only. */\n name: string\n /** The field's value as it would be rendered into text. The firewall compares\n * this against the agent context, so a domain that ships structured data\n * passes a stable string projection (e.g. JSON) of the hidden value. */\n value: string\n destination: FieldDestination\n}\n\n/**\n * Route a domain's named fields by destination into the firewall's input shape.\n * The `routing` declares each field's destination; the `values` carry each\n * field's renderable string. A field present in `routing` but missing from\n * `values` is an authoring error (fail loud) — every routed field must have a\n * value the firewall can check.\n */\nexport function routeFields<TName extends string>(\n routing: Readonly<Record<TName, FieldDestination>>,\n values: Readonly<Record<TName, string>>,\n): RoutedField[] {\n const out: RoutedField[] = []\n for (const name of Object.keys(routing) as TName[]) {\n const value = values[name]\n if (value === undefined) {\n throw new ValidationError(\n `routed field \"${name}\" has a destination but no value — every routed field must carry its value`,\n )\n }\n out.push({ name, value, destination: routing[name] })\n }\n return out\n}\n\n/** A single detected leak: a hidden field whose value appears in the agent context. */\nexport interface HiddenLeak {\n field: string\n destination: FieldDestination\n}\n\nexport interface NoLeakOptions {\n /** Minimum hidden-value length to check. A hidden value shorter than this is\n * skipped — a one-word or empty hidden field would substring-match innocuous\n * prose and is not meaningful evidence of a leak. Default 12. */\n minMatchLength?: number\n}\n\n/**\n * The FIREWALL. Throws `ValidationError` if any `grading-only`/`judge-only`\n * field's value is found inside `agentContext` — the exact text that reaches the\n * agent during the run (its prompt, its seeded files concatenated, whatever the\n * caller assembled). `agent-visible` and `develop-against` fields are never\n * checked: they are meant to be there.\n *\n * Substring containment is the check: it is domain-free and catches the failure\n * that matters — a hidden answer key, held-out case, or rubric anchor pasted\n * into the prompt. Returns the routed fields on success so a caller can chain.\n */\nexport function assertNoHiddenLeak(\n fields: readonly RoutedField[],\n agentContext: string,\n opts: NoLeakOptions = {},\n): readonly RoutedField[] {\n const minLen = opts.minMatchLength ?? 12\n const leaks: HiddenLeak[] = []\n for (const field of fields) {\n if (!isHiddenDestination(field.destination)) continue\n const needle = field.value.trim()\n if (needle.length < minLen) continue\n if (agentContext.includes(needle)) {\n leaks.push({ field: field.name, destination: field.destination })\n }\n }\n if (leaks.length > 0) {\n const detail = leaks.map((l) => `\"${l.field}\" (${l.destination})`).join(', ')\n throw new ValidationError(\n `hidden-criteria firewall breached: ${leaks.length} hidden field(s) reached the agent context: ${detail}`,\n )\n }\n return fields\n}\n\n/** Collect the values a domain may safely render into the agent context — the\n * `agent-visible` (and, by intent, `develop-against`) fields — so a caller can\n * ASSEMBLE the context from the routing rather than hand-picking fields and\n * risking a slip. `develop-against` is included because it is seeded into the\n * agent's environment during the run on purpose. */\nexport function agentVisibleFields(fields: readonly RoutedField[]): RoutedField[] {\n return fields.filter((f) => !isHiddenDestination(f.destination))\n}\n\n// ── 2. hidden-criteria grading ────────────────────────────────────────────────\n\n/** What a hidden-criteria grader reports. `passRate = passed / total` over the\n * hidden checks; `total === 0` means the criteria never ran (e.g. the artifact\n * did not even load) — an honest zero, never a spurious pass. */\nexport interface HiddenGradeResult {\n /** Hidden checks that passed. */\n passed: number\n /** Total hidden checks attempted. 0 when the criteria could not run at all. */\n total: number\n /** `passed / total`, or 0 when `total === 0`. The PRIMARY correctness score. */\n passRate: number\n /** Free-form provenance the caller may record (runner output, reason for 0). */\n notes?: string\n}\n\n/**\n * The domain's grader: given the agent's artifact and the HIDDEN criteria,\n * return a pass rate. This is the ONE seam a non-coding domain implements — the\n * coding node-test executor is a single implementation of it; a legal grader\n * checks the brief against hidden required holdings, a research grader checks an\n * answer against held-out facts, a tax grader runs hidden return assertions.\n * The substrate calls it ONLY at grading time, behind the firewall.\n *\n * `THidden` is the domain's hidden-criteria payload (the held-out suite, the\n * answer key, the hidden requirements) — opaque to the substrate.\n */\nexport type HiddenCriteriaGrader<TArtifact, THidden> = (\n artifact: TArtifact,\n hiddenCriteria: THidden,\n signal?: AbortSignal,\n) => Promise<HiddenGradeResult> | HiddenGradeResult\n\n/** Normalize a grader's raw `{passed, total}` into a `HiddenGradeResult` with a\n * consistent, fail-loud `passRate` — the canonical \"honest zero on no-run\"\n * rule, single-sourced so every domain grader gets it. */\nexport function hiddenGrade(passed: number, total: number, notes?: string): HiddenGradeResult {\n const p = Number.isFinite(passed) && passed > 0 ? Math.floor(passed) : 0\n const t = Number.isFinite(total) && total > 0 ? Math.floor(total) : 0\n const passRate = t > 0 ? Math.min(1, p / t) : 0\n return { passed: Math.min(p, t > 0 ? t : p), total: t, passRate, notes }\n}\n\n/**\n * Run a domain's hidden-criteria grader behind the firewall. Before grading, it\n * re-asserts the firewall against the agent context the run actually used —\n * proving (at grading time, on real data) that the hidden criteria never\n * reached the agent — then invokes the grader and returns its pass rate. A\n * domain that wants the firewall and the grader wired together in one call uses\n * this; a domain that already asserted the firewall at dispatch time can call\n * its grader directly and feed the result to `blendHeldout`.\n */\nexport async function gradeOnHidden<TArtifact, THidden>(args: {\n artifact: TArtifact\n hiddenCriteria: THidden\n grader: HiddenCriteriaGrader<TArtifact, THidden>\n /** The routed fields + the exact agent context, re-checked before grading. */\n firewall: { fields: readonly RoutedField[]; agentContext: string; options?: NoLeakOptions }\n signal?: AbortSignal\n}): Promise<HiddenGradeResult> {\n assertNoHiddenLeak(args.firewall.fields, args.firewall.agentContext, args.firewall.options)\n const result = await args.grader(args.artifact, args.hiddenCriteria, args.signal)\n return hiddenGrade(result.passed, result.total, result.notes)\n}\n\n// ── the composite: hidden correctness (PRIMARY) + judge quality (secondary) ────\n\n/** Weights for the held-out / judge blend. Must be finite and non-negative;\n * they are renormalized to sum to 1 so a caller can pass any positive ratio. */\nexport interface BlendWeights {\n /** Weight on the hidden-criteria pass rate (the primary, ungameable score). */\n heldout: number\n /** Weight on the judge's quality composite (the secondary style/quality score). */\n judge: number\n}\n\n/** Default blend: 0.7 hidden correctness, 0.3 judge quality. The coding bench's\n * long-standing split — execution truth dominates, style refines. */\nexport const defaultBlendWeights: BlendWeights = { heldout: 0.7, judge: 0.3 }\n\n/** The input shape a judge's `score` receives — exactly `JudgeConfig.score`'s\n * argument: the artifact, plus any scenario/signal fields the judge carries.\n * `withHeldoutBlend` only reads `artifact`; the rest rides through. */\nexport interface JudgeScoreInput<TArtifact> {\n artifact: TArtifact\n /** Pass-through for the judge's extra input fields (scenario, signal). */\n [key: string]: unknown\n}\n\nfunction normalizeWeights(weights: BlendWeights): { heldout: number; judge: number } {\n const h = Number.isFinite(weights.heldout) && weights.heldout >= 0 ? weights.heldout : 0\n const j = Number.isFinite(weights.judge) && weights.judge >= 0 ? weights.judge : 0\n const sum = h + j\n if (sum <= 0) {\n throw new ValidationError(\n 'blend weights must have a positive sum (got heldout+judge <= 0) — cannot weight a composite by zero',\n )\n }\n return { heldout: h / sum, judge: j / sum }\n}\n\n/**\n * Compose the PRIMARY hidden-criteria pass rate with the SECONDARY judge\n * composite into the single score the leaderboard ranks on. Weights are\n * renormalized, so a solution that fails the hidden criteria is capped low no\n * matter how the judge felt about its style, while a stylistically-mediocre but\n * CORRECT solution still earns the bulk of the points. Both inputs are clamped\n * to [0,1] — a judge on a non-unit scale must be normalized by the caller first.\n */\nexport function blendHeldout(\n heldoutPassRate: number,\n judgeScore: number,\n weights: BlendWeights = defaultBlendWeights,\n): number {\n const w = normalizeWeights(weights)\n const heldout = clampUnit(heldoutPassRate)\n const judge = clampUnit(judgeScore)\n return w.heldout * heldout + w.judge * judge\n}\n\n/**\n * Wrap a judge's `score` so the `composite` it REPORTS is the held-out-weighted\n * blend. The judge still scores its quality dimensions (recorded, secondary),\n * but the composite that downstream selection/scorecard reads becomes\n * `blendHeldout(heldoutPassRate(artifact), judgeComposite, weights)`. The held-\n * out pass rate is read off the artifact via `heldoutPassRate` — already\n * computed before the judge runs — so no second grading pass is needed.\n *\n * Generic over the artifact type, inferred from `heldoutPassRate`, so it\n * composes with both a `campaign` `JudgeConfig.score` and a bare scoring\n * function. The input is the judge's `{ artifact, ... }` — any extra fields\n * (`scenario`, `signal`) ride through untouched via the index signature.\n */\nexport function withHeldoutBlend<TArtifact>(\n score: (input: JudgeScoreInput<TArtifact>) => JudgeScore | Promise<JudgeScore>,\n heldoutPassRate: (artifact: TArtifact) => number,\n weights: BlendWeights = defaultBlendWeights,\n): (input: JudgeScoreInput<TArtifact>) => Promise<JudgeScore> {\n return async (input: JudgeScoreInput<TArtifact>): Promise<JudgeScore> => {\n const base = await score(input)\n if (base.failed) return base\n const rate = clampUnit(heldoutPassRate(input.artifact))\n const composite = blendHeldout(rate, base.composite, weights)\n const w = normalizeWeights(weights)\n return {\n ...base,\n composite,\n notes:\n `composite=${composite.toFixed(3)} ` +\n `(held-out ${(rate * 100).toFixed(0)}% × ${w.heldout.toFixed(2)} + ` +\n `quality ${base.composite.toFixed(3)} × ${w.judge.toFixed(2)})` +\n (base.notes ? ` — ${base.notes}` : ''),\n }\n }\n}\n\nfunction clampUnit(value: number): number {\n if (!Number.isFinite(value)) return 0\n return Math.max(0, Math.min(1, value))\n}\n","/**\n * Single-backend guard: assert the agent and the rubric judge run through the\n * SAME backend config, so the judge can't silently re-route through a\n * different (often paid) backend than the agent.\n *\n * The bug class: `--backend cli-bridge` rewires the agent, but the judge still\n * reads `process.env.TANGLE_API_KEY` → router. Cost is billed against the\n * router, the eval reports the cli-bridge model, and the data is unusable.\n * Four consumers hand-roll this comparison (legal at `canonical.ts:702-795`);\n * this is the one substrate copy.\n *\n * Complements `assertRealBackend` (records → stub vs real) and\n * `assertCrossFamily` (judge-ensemble family diversity): this one compares two\n * backend *configs* before the run.\n */\n\nimport { AgentEvalError } from '../errors'\n\n/**\n * Minimal backend-config shape the assertion reads. Consumers may pass richer\n * types — only these five fields are inspected.\n */\nexport interface BackendDescriptor {\n /** Backend route — e.g. `'tcloud' | 'cli-bridge' | 'sandbox' | 'direct-provider'`;\n * free-form for consumer extensibility. */\n kind: string\n /** Resolved base URL. Compared lexically (trailing slash stripped). */\n baseUrl: string\n /** Model id (with snapshot suffix). Compared lexically. */\n model: string\n /** Optional provider override. Compared when both set; flagged when only\n * one side sets it. */\n provider?: string\n /** Bearer token. Values are NEVER compared (security) — only that EITHER\n * both are set OR both are empty. Mismatched presence is a divergence. */\n apiKey?: string\n}\n\nexport interface AssertSingleBackendOptions {\n /** When true, ANY field divergence fails. When false (default), only\n * `kind` / `baseUrl` / `provider` / `apiKeyPresence` divergence throws —\n * a different judge `model` on the same route is allowed (the legal\n * pattern: a cheaper judge model). */\n strict?: boolean\n agentLabel?: string\n judgeLabel?: string\n}\n\nexport type SingleBackendField = 'kind' | 'baseUrl' | 'model' | 'provider' | 'apiKeyPresence'\n\nexport interface SingleBackendDivergence {\n field: SingleBackendField\n agent: string | undefined\n judge: string | undefined\n}\n\nexport interface SingleBackendReport {\n /** True when agent + judge agree per the configured strictness. */\n ok: boolean\n /** Every divergence detected (includes `model` even when non-blocking). */\n divergences: ReadonlyArray<SingleBackendDivergence>\n}\n\nexport class SingleBackendError extends AgentEvalError {\n constructor(\n message: string,\n public readonly report: SingleBackendReport,\n ) {\n super('backend_integrity', message)\n this.name = 'SingleBackendError'\n }\n}\n\nfunction stripSlash(url: string): string {\n return url.replace(/\\/+$/, '')\n}\n\n/**\n * Throw `SingleBackendError` when the agent and judge backends diverge in a\n * way that would re-route the judge through a different backend than the\n * agent. Returns the report so callers can log it in either case.\n */\nexport function assertSingleBackend(\n agent: BackendDescriptor,\n judge: BackendDescriptor,\n opts: AssertSingleBackendOptions = {},\n): SingleBackendReport {\n const divergences: SingleBackendDivergence[] = []\n\n if (agent.kind !== judge.kind) {\n divergences.push({ field: 'kind', agent: agent.kind, judge: judge.kind })\n }\n if (stripSlash(agent.baseUrl) !== stripSlash(judge.baseUrl)) {\n divergences.push({ field: 'baseUrl', agent: agent.baseUrl, judge: judge.baseUrl })\n }\n if (agent.model !== judge.model) {\n divergences.push({ field: 'model', agent: agent.model, judge: judge.model })\n }\n // provider: compare when both set; flag when exactly one is set.\n if (agent.provider !== judge.provider) {\n divergences.push({ field: 'provider', agent: agent.provider, judge: judge.provider })\n }\n // apiKey: presence only, never the value.\n const agentHasKey = Boolean(agent.apiKey)\n const judgeHasKey = Boolean(judge.apiKey)\n if (agentHasKey !== judgeHasKey) {\n divergences.push({\n field: 'apiKeyPresence',\n agent: agentHasKey ? 'set' : 'empty',\n judge: judgeHasKey ? 'set' : 'empty',\n })\n }\n\n const blocking = opts.strict ? divergences : divergences.filter((d) => d.field !== 'model')\n const ok = blocking.length === 0\n const report: SingleBackendReport = { ok, divergences }\n\n if (!ok) {\n const agentLabel = opts.agentLabel ?? 'agent'\n const judgeLabel = opts.judgeLabel ?? 'judge'\n const detail = blocking\n .map((d) => `${d.field}: ${agentLabel}=${d.agent ?? '∅'} vs ${judgeLabel}=${d.judge ?? '∅'}`)\n .join('; ')\n throw new SingleBackendError(\n `single-backend: ${agentLabel} and ${judgeLabel} backends diverge — the judge would ` +\n `re-route through a different backend than the agent (${detail})`,\n report,\n )\n }\n\n return report\n}\n","/**\n * Intent-match judge — \"did the agent build the right APP, ignoring\n * whether every feature is wired up?\"\n *\n * Distinct from {@link runSemanticConceptJudge} which scores per-concept\n * presence. The semantic judge can return 0/4 concepts present even\n * when the agent built a thoughtful, polished, on-brief app that just\n * lacks one or two features. The semantic judge can also return 4/4\n * present even when the agent shipped the wrong project (keyword-rich\n * stub).\n *\n * Intent-match asks ONE question:\n * \"Looking at the agent's work as a whole — independent of feature\n * coverage — is this an honest attempt at the user's request?\"\n *\n * Returns a 0–1 score and a 1-sentence evidence string. Use as a sanity\n * check on `completenessScore`-style metrics: if intent-match is high\n * and concept count is low, the agent built the right thing but is\n * missing features (ship and iterate). If intent-match is low, the\n * agent built the wrong thing (reject regardless of concept count).\n *\n * Soft-fails on LLM/JSON error (`available: false`) so callers can\n * treat failure as \"judge skipped.\"\n */\n\nimport { CostLedger, type CostLedgerHandle, type CostReceipt } from './cost-ledger'\nimport {\n callLlmJson,\n costReceiptFromLlm,\n costReceiptFromLlmError,\n type LlmCallRequest,\n type LlmClientOptions,\n maximumChargeForLlmRequest,\n} from './llm-client'\n\nexport const INTENT_MATCH_JUDGE_VERSION = 'intent-match-judge-v1-2026-04-24'\n\nexport interface IntentMatchInput {\n /** The full natural-language prompt the agent was handed. */\n userRequest: string\n /** Top-level source files from the agent's workdir. */\n sourceFiles: Array<{ path: string; content: string }>\n /** Rendered HTML the preview returned, when available. */\n servedHtml?: string\n /** Optional metadata to inject (id, vertical, difficulty). */\n artifactLabel?: string\n artifactDescription?: string\n}\n\nexport interface IntentMatchResult {\n kind: 'intent-match'\n version: string\n /** 0..1 — 1 = unmistakably the right app, 0 = unrelated to the brief. */\n score: number\n /** One-sentence rationale citing concrete evidence (file or HTML). */\n evidence: string\n durationMs: number\n costUsd: number | null\n available: boolean\n error?: string\n}\n\nexport interface IntentMatchOptions {\n model?: string\n timeoutMs?: number\n maxTokens?: number\n maxSourceChars?: number\n maxPerFileChars?: number\n maxHtmlChars?: number\n llm?: LlmClientOptions\n costLedger?: CostLedgerHandle\n costPhase?: string\n costTags?: Record<string, string>\n signal?: AbortSignal\n}\n\nconst DEFAULT_MODEL = 'claude-sonnet-4-6'\nconst DEFAULT_TIMEOUT = 300_000\nconst DEFAULT_MAX_TOKENS = 800\nconst DEFAULT_MAX_SOURCE = 25_000\nconst DEFAULT_MAX_PER_FILE = 12_000\nconst DEFAULT_MAX_HTML = 20_000\n\nconst INTENT_SCHEMA = {\n type: 'object',\n additionalProperties: false,\n required: ['score', 'evidence'],\n properties: {\n score: { type: 'number', minimum: 0, maximum: 1 },\n evidence: { type: 'string', minLength: 10, maxLength: 400 },\n },\n}\n\nfunction truncate(body: string, cap: number, label: string): string {\n if (body.length <= cap) return body\n return `${body.slice(0, cap)}\\n… [truncated ${body.length - cap} chars of ${label}]`\n}\n\nfunction buildPrompt(input: IntentMatchInput, opts: Required<IntentMatchOptions>): string {\n const sourceBlob = input.sourceFiles\n .filter((f) => f.content.length <= opts.maxPerFileChars)\n .map((f) => `--- FILE: ${f.path} ---\\n${f.content}`)\n .join('\\n\\n')\n const html = input.servedHtml ?? ''\n\n return `You are evaluating whether an agent built THE RIGHT APP for a user request.\n\nYou are NOT scoring feature coverage. You are NOT scoring code quality.\nYou are answering ONE question: when a person looks at this work, do they\nsee an honest attempt at the user's request — or do they see the wrong\nproject entirely?\n\nUSER REQUEST:\n${input.userRequest}\n\n${input.artifactLabel ? `ARTIFACT METADATA:\\n name: ${input.artifactLabel}\\n description: ${input.artifactDescription ?? ''}\\n\\n` : ''}${html ? `SERVED HTML (what the preview returns):\\n${truncate(html, opts.maxHtmlChars, 'HTML')}\\n\\n` : ''}SOURCE FILES (the agent's workdir):\n${truncate(sourceBlob, opts.maxSourceChars, 'source')}\n\nScore 0–1:\n 1.0 — unmistakably the right app. Even with bugs, gaps, or missing\n features, a reviewer would say \"yes, this is what was asked for.\"\n 0.7 — recognizable. Domain matches; some required surface areas exist.\n A reviewer would say \"right direction, lots of work needed.\"\n 0.4 — partially related. Wrong framing or wrong product entirely but\n with some shared keywords or a tangential overlap.\n 0.0 — wrong project. The agent shipped something unrelated to the\n request (e.g. asked for an NFT mint page, shipped a generic\n landing page with zero NFT-related code).\n\nEvidence: one sentence citing the strongest concrete signal — a file\nname, a route, a rendered headline, a missing core surface. Don't\nrestate the request.\n\nExamples:\n - \"src/App.tsx renders <MintWidget /> with mint-1/mint-5 buttons and\n wagmi imports — clearly the requested NFT mint page.\" → 0.95\n - \"src/App.tsx is the default Vite React template; no\n mint/wallet/contract code in any file under src/.\" → 0.05\n\nReturn STRICT JSON. No prose outside.`\n}\n\n/**\n * Run the intent-match judge. Soft-fails to available=false on error.\n */\nexport async function runIntentMatchJudge(\n input: IntentMatchInput,\n options: IntentMatchOptions = {},\n): Promise<IntentMatchResult> {\n const start = Date.now()\n const opts: Required<IntentMatchOptions> = {\n model: options.model ?? DEFAULT_MODEL,\n timeoutMs: options.timeoutMs ?? DEFAULT_TIMEOUT,\n maxTokens: options.maxTokens ?? DEFAULT_MAX_TOKENS,\n maxSourceChars: options.maxSourceChars ?? DEFAULT_MAX_SOURCE,\n maxPerFileChars: options.maxPerFileChars ?? DEFAULT_MAX_PER_FILE,\n maxHtmlChars: options.maxHtmlChars ?? DEFAULT_MAX_HTML,\n llm: options.llm ?? {},\n costLedger: options.costLedger ?? new CostLedger(),\n costPhase: options.costPhase ?? 'judge.intent-match',\n costTags: options.costTags ?? {},\n signal: options.signal ?? new AbortController().signal,\n }\n\n if (input.sourceFiles.length === 0 && !input.servedHtml) {\n return {\n kind: 'intent-match',\n version: INTENT_MATCH_JUDGE_VERSION,\n score: 0,\n evidence: 'no source files and no served HTML — nothing to evaluate',\n durationMs: 0,\n costUsd: null,\n available: false,\n error: 'no input artifact',\n }\n }\n\n let receipt: CostReceipt | undefined\n try {\n const request = {\n model: opts.model,\n messages: [\n {\n role: 'system' as const,\n content:\n 'You are a holistic code reviewer answering one question: did the agent build the right app for the user. Return strict JSON. No prose outside.',\n },\n { role: 'user' as const, content: buildPrompt(input, opts) },\n ],\n jsonSchema: { name: 'intent_match_judge', schema: INTENT_SCHEMA },\n temperature: 0,\n maxTokens: opts.maxTokens,\n timeoutMs: opts.timeoutMs,\n } satisfies LlmCallRequest\n const paid = await opts.costLedger.runPaidCall({\n channel: 'judge',\n phase: opts.costPhase,\n actor: 'intent-match',\n model: opts.model,\n ...(Object.keys(opts.costTags).length > 0 ? { tags: opts.costTags } : {}),\n maximumCharge: maximumChargeForLlmRequest(request, opts.llm),\n signal: opts.signal,\n execute: (signal, callId) =>\n callLlmJson<{ score: number; evidence: string }>(request, {\n ...opts.llm,\n signal,\n idempotencyKey: callId,\n }),\n receipt: ({ result }) => costReceiptFromLlm(result),\n receiptFromError: costReceiptFromLlmError,\n })\n receipt = paid.receipt\n if (!paid.succeeded) throw paid.error\n const { value } = paid.value\n\n const score = Math.max(0, Math.min(1, Number(value?.score ?? 0)))\n return {\n kind: 'intent-match',\n version: INTENT_MATCH_JUDGE_VERSION,\n score: Number(score.toFixed(3)),\n evidence: String(value?.evidence ?? '').slice(0, 400),\n durationMs: Date.now() - start,\n costUsd: paid.receipt.costUnknown ? null : paid.receipt.costUsd,\n available: true,\n }\n } catch (err) {\n return {\n kind: 'intent-match',\n version: INTENT_MATCH_JUDGE_VERSION,\n score: 0,\n evidence: '',\n durationMs: Date.now() - start,\n costUsd: receipt && !receipt.costUnknown ? receipt.costUsd : null,\n available: false,\n error: err instanceof Error ? err.message : String(err),\n }\n }\n}\n\n/**\n * Factory: pin LLM options once, return a closure.\n */\nexport function createIntentMatchJudge(\n options: IntentMatchOptions = {},\n): (input: IntentMatchInput) => Promise<IntentMatchResult> {\n return (input) => runIntentMatchJudge(input, options)\n}\n","/**\n * Judge-ensemble reducer — folds N independent judge verdicts on the same\n * artifact into one aggregate score.\n *\n * The pattern every multi-model judge re-implements: run K uncorrelated judges\n * (different model families remove within-family bias), then reduce their\n * per-dimension verdicts to a single composite + an inter-rater disagreement\n * signal. This is the pure reduction — no LLM, no I/O — so a lift it produces\n * is attributable to the scores, not to where they came from.\n *\n * Fail-loud: a judge that errored or returned malformed output is recorded in\n * `failedJudges` with `perDimension: null`, never folded into a zero. If EVERY\n * judge failed the reducer throws — a silent zero here would corrupt the result.\n */\n\nimport type { LlmUsage } from './llm-client'\nimport { clamp01 } from './run-score'\nimport { weightedComposite } from './statistics'\n\n/** One judge's verdict. `perDimension: null` ⇒ that judge call failed (threw or\n * returned malformed output) — recorded, never folded into a zero. */\nexport interface JudgeVerdict<D extends string = string> {\n /** Judge identity (typically the model id) — the `perJudge` / `failedJudges` key. */\n model: string\n /** Per-dimension scores, or `null` when the judge failed. */\n perDimension: Record<D, number> | null\n /** Optional one-line rationale; the first non-empty one becomes the aggregate's. */\n rationale?: string\n /** Optional reported cost, committed by the caller's CostLedger. */\n costUsd?: number\n /** Optional provider usage, committed by the caller's CostLedger. */\n usage?: LlmUsage\n /** Optional per-dimension reasoning/evidence. Carried through to\n * `EnsembleAggregate.verdicts` verbatim — never folded into the math. */\n detail?: Partial<Record<D, { reasoning?: string; evidence?: string }>>\n}\n\n/** The aggregated ensemble result. */\nexport interface EnsembleAggregate<D extends string = string> {\n /** Mean over SURVIVING judges, per dimension (absent-everywhere ⇒ 0). */\n perDimension: Record<D, number>\n /** Weighted mean of `perDimension` (uniform unless `weights` given). */\n composite: number\n /** Each surviving judge's clamped per-dimension scores, for trace drill-down. */\n perJudge: Record<string, Record<D, number>>\n /** Max over dimensions of (max − min) across survivors — the inter-rater signal. */\n maxDisagreement: number\n /** Models whose verdict was null (failed). */\n failedJudges: string[]\n /** First non-empty survivor rationale, or `'llm-judge'`. */\n rationale: string\n /** The input verdicts, verbatim — drill-down to raw scores, `detail`\n * reasoning/evidence, and per-verdict cost without re-running judges. */\n verdicts: JudgeVerdict<D>[]\n}\n\n/**\n * Reduce per-judge verdicts to one aggregate. Generic over the rubric: pass the\n * stable-ordered `dimensionKeys` the judges scored.\n *\n * - Per-dimension score = mean over surviving judges (out-of-range clamped to [0,1]).\n * - `composite` = `weightedComposite` of `perDimension`. No `weights` ⇒ uniform\n * over every dimension. A partial `weights` map selects AND weights exactly the\n * named dimensions (others excluded from the composite) — the substrate's\n * sum-normalized weighting, not re-implemented here.\n * - Throws if `verdicts` or `dimensionKeys` is empty, or if every judge failed.\n */\nexport function aggregateJudgeVerdicts<D extends string>(\n verdicts: readonly JudgeVerdict<D>[],\n dimensionKeys: readonly D[],\n weights?: Partial<Record<D, number>>,\n): EnsembleAggregate<D> {\n if (verdicts.length === 0) {\n throw new Error('aggregateJudgeVerdicts: no verdicts to aggregate')\n }\n if (dimensionKeys.length === 0) {\n throw new Error('aggregateJudgeVerdicts: dimensionKeys is empty')\n }\n\n const perJudge: Record<string, Record<D, number>> = {}\n const failedJudges: string[] = []\n const dimAcc = {} as Record<D, number[]>\n for (const d of dimensionKeys) dimAcc[d] = []\n let rationale = ''\n\n // Same model sampled k times (best-of-N judging) gets keys 'm', 'm#2',\n // 'm#3'… so repeat votes land as distinct perJudge/failedJudges entries\n // instead of overwriting each other.\n const seenCount = new Map<string, number>()\n const keyFor = (model: string): string => {\n const n = (seenCount.get(model) ?? 0) + 1\n seenCount.set(model, n)\n return n === 1 ? model : `${model}#${n}`\n }\n\n for (const v of verdicts) {\n const key = keyFor(v.model)\n if (!v.perDimension) {\n failedJudges.push(key)\n continue\n }\n const dims = {} as Record<D, number>\n for (const d of dimensionKeys) dims[d] = clamp01(Number(v.perDimension[d]))\n perJudge[key] = dims\n for (const d of dimensionKeys) dimAcc[d].push(dims[d])\n if (!rationale && typeof v.rationale === 'string' && v.rationale) rationale = v.rationale\n }\n\n if (failedJudges.length === verdicts.length) {\n throw new Error(`aggregateJudgeVerdicts: all ${verdicts.length} judges failed`)\n }\n\n const perDimension = {} as Record<D, number>\n for (const d of dimensionKeys) {\n const vals = dimAcc[d]\n perDimension[d] = vals.length === 0 ? 0 : vals.reduce((s, x) => s + x, 0) / vals.length\n }\n\n let maxDisagreement = 0\n for (const d of dimensionKeys) {\n const vals = dimAcc[d]\n if (vals.length < 2) continue\n const spread = Math.max(...vals) - Math.min(...vals)\n if (spread > maxDisagreement) maxDisagreement = spread\n }\n\n const w: Record<string, number> = {}\n if (weights) {\n for (const [d, weight] of Object.entries(weights)) {\n if (weight !== undefined) w[d] = weight as number\n }\n } else {\n for (const d of dimensionKeys) w[d] = 1 / dimensionKeys.length\n }\n const composite = weightedComposite({ dims: perDimension, weights: w }).composite\n\n return {\n perDimension,\n composite,\n perJudge,\n maxDisagreement,\n failedJudges,\n rationale: rationale || 'llm-judge',\n verdicts: [...verdicts],\n }\n}\n","/**\n * Wrap a single judge LLM call with retry, optional fallback-model\n * rotation, exponential backoff, and a typed `JudgeRetryOutcome`. Callers\n * MUST inspect `succeeded` before using `value`; on failure the library\n * returns `value: null` rather than substituting a default, so a judge\n * abort cannot silently corrupt a downstream composite.\n *\n * Reporting contract: callers ship `TrialResult.judgeSucceeded = succeeded`\n * and `TrialResult.judgeAttempts = attempts` so `aggregateTrialsByMode`\n * with `mode: 'exclude-failed'` drops the trial.\n */\n\nimport { backoffMs, isTransientLlmError } from './llm-client'\n\n/** Retry policy for judge LLM calls. */\nexport interface JudgeRetryPolicy {\n /** Max attempts per model. Default 3 (one initial + two retries). */\n maxAttempts?: number\n /** Per-attempt timeout in ms. Default 300_000. */\n timeoutMs?: number\n /**\n * Models to try, in order. The first model is the primary; subsequent\n * models are fallbacks invoked only when ALL retries on the previous\n * model have been exhausted. Example: `['claude-code/sonnet', 'kimi-code/k2p6']`\n * runs claude-code up to maxAttempts times, then falls back to kimi.\n * If omitted, the caller's judge function controls model selection and\n * the retries apply to that single model.\n */\n models?: readonly string[]\n /** Exponential backoff function, default `attempt → min(500 * 2^attempt, 16_000)`. */\n backoffMs?: (attempt: number) => number\n /**\n * Predicate deciding whether an error should trigger a retry. Defaults to\n * `isTransientLlmError` — the package-wide classifier shared with\n * `callLlm` — which retries aborts/timeouts, network faults, HTTP/2\n * transport faults, and any `LlmCallError` with status in {429,502,503,504}.\n * JSON-parse and schema-rejection errors are NOT retriable (the model\n * needs prompt adjustment, not another shot).\n */\n isRetryable?: (err: unknown) => boolean\n}\n\n/** Outcome of a wrapped judge invocation. */\nexport interface JudgeRetryOutcome<T> {\n /** The judge's returned value when `succeeded === true`. */\n value: T | null\n /** True iff one of the attempts completed without throwing. */\n succeeded: boolean\n /** Total attempts made across all models. */\n attempts: number\n /** Which model the successful attempt used (when succeeded). */\n modelUsed?: string\n /** Last error captured when `succeeded === false`. */\n error?: Error\n /** Per-attempt error log for forensics. */\n attemptErrors: Array<{ attempt: number; model: string; error: string }>\n}\n\nconst DEFAULT_MAX_ATTEMPTS = 3\nconst DEFAULT_TIMEOUT_MS = 300_000\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms))\n}\n\n/**\n * Wrap a judge call with retry + fallback-model + typed outcome semantics.\n *\n * The `judgeFn` signature is `(model: string, signal: AbortSignal) => Promise<T>`.\n * The signal will be aborted at `timeoutMs`. Callers should pass the signal\n * to their underlying fetch/SDK call so the abort actually fires.\n *\n * Returns a typed outcome — callers MUST inspect `succeeded` before using\n * `value`. The library refuses to default to a silent zero score because a\n * synthetic zero is indistinguishable from a real low score downstream.\n */\nexport async function withJudgeRetry<T>(\n judgeFn: (model: string, signal: AbortSignal) => Promise<T>,\n policy: JudgeRetryPolicy = {},\n): Promise<JudgeRetryOutcome<T>> {\n const maxAttempts = policy.maxAttempts ?? DEFAULT_MAX_ATTEMPTS\n const timeoutMs = policy.timeoutMs ?? DEFAULT_TIMEOUT_MS\n const backoff = policy.backoffMs ?? backoffMs\n const isRetryable = policy.isRetryable ?? isTransientLlmError\n const models =\n policy.models && policy.models.length > 0 ? policy.models : [undefined as unknown as string]\n\n let totalAttempts = 0\n const attemptErrors: JudgeRetryOutcome<T>['attemptErrors'] = []\n let lastError: Error | undefined\n\n for (const model of models) {\n for (let attempt = 0; attempt < maxAttempts; attempt++) {\n totalAttempts += 1\n const controller = new AbortController()\n const timer = setTimeout(() => controller.abort(new Error('TimeoutError')), timeoutMs)\n try {\n const value = await judgeFn(model as string, controller.signal)\n clearTimeout(timer)\n return {\n value,\n succeeded: true,\n attempts: totalAttempts,\n modelUsed: model,\n attemptErrors,\n }\n } catch (err) {\n clearTimeout(timer)\n const errObj = err instanceof Error ? err : new Error(String(err))\n lastError = errObj\n attemptErrors.push({\n attempt: totalAttempts,\n model: model ?? '(default)',\n error: errObj.message,\n })\n if (!isRetryable(errObj)) {\n // Non-retriable (e.g., JSON parse, schema rejection): break out of\n // attempts on this model AND skip the fallback rotation — a\n // permanent error here will be permanent on the fallback too.\n return {\n value: null,\n succeeded: false,\n attempts: totalAttempts,\n error: errObj,\n attemptErrors,\n }\n }\n if (attempt < maxAttempts - 1) {\n await sleep(backoff(attempt))\n }\n }\n }\n // Exhausted attempts on this model — fall through to next model in the\n // rotation (if any). The backoff between MODEL rotations is the same\n // as the last per-attempt backoff (already slept above).\n }\n\n return {\n value: null,\n succeeded: false,\n attempts: totalAttempts,\n error: lastError,\n attemptErrors,\n }\n}\n","/**\n * Multi-model judge panel — `ensembleJudge` builds a campaign `JudgeConfig`\n * that fans one artifact out to K judge models and reduces their verdicts\n * through `aggregateJudgeVerdicts` (src/judge-ensemble.ts).\n *\n * The panel is the fail-loud composition of the substrate's existing judge\n * primitives:\n * - `assertCrossFamily` (construction-time) — a single-family panel is\n * correlated bias, not independent signal.\n * - `withJudgeRetry` (per model, opt-in) — transient-fault retry with a\n * typed outcome; a judge that exhausts retries is recorded as failed,\n * never folded into a zero.\n * - `aggregateJudgeVerdicts` — the pure reducer; throws when EVERY judge\n * failed so a silent zero can't reach the gate.\n *\n * The returned `JudgeScore` is on the campaign [0,1] scale and carries the\n * ensemble extras (`maxDisagreement`, `failedJudges`, `perJudge`) declared\n * on the canonical `JudgeScore` in src/campaign/types.ts.\n */\n\nimport type { JudgeConfig, JudgeScore } from './campaign/types'\nimport {\n CostLedger,\n type CostLedgerHandle,\n type CostReceiptInput,\n type MaximumCharge,\n} from './cost-ledger'\nimport { aggregateJudgeVerdicts, type JudgeVerdict } from './judge-ensemble'\nimport { assertCrossFamily } from './judge-families'\nimport { type JudgeRetryPolicy, withJudgeRetry } from './judge-retry'\nimport { contentHash } from './verdict-cache'\n\nexport interface EnsembleJudgeOptions<D extends string> {\n /** Judge name — becomes the returned `JudgeConfig.name`. */\n name: string\n /** Rubric dimensions every model scores. Keys of the verdict's `perDimension`. */\n dimensions: D[]\n /** Judge model ids — one `scoreWith` call per entry. List a model twice to\n * sample it twice (votes are suffix-keyed `model#2` so none overwrite). */\n models: string[]\n /** Explicit scoring revision for closure state not visible in the static panel config. */\n judgeVersion?: string\n /**\n * Score the artifact with one model. Throw (or reject) on failure — the\n * panel records that model as a failed judge; it is never folded into a\n * zero. Verdict scores are clamped to [0,1] by the reducer.\n */\n scoreWith: (\n model: string,\n input: { artifact: unknown; scenario?: unknown; signal: AbortSignal },\n ) => Promise<JudgeVerdict<D>>\n /** Recover usage from a failed provider response when its error retains one. */\n receiptFromError?: (error: Error, model: string) => CostReceiptInput | undefined\n /** Used by direct score calls; campaigns supply their run ledger in score(). */\n costLedger?: CostLedgerHandle\n /** Required per model when the shared ledger has a dollar cap. */\n maximumCharge?: MaximumCharge | ((model: string) => MaximumCharge)\n /**\n * Per-model retry policy, applied via `withJudgeRetry`. The panel's\n * `models` list drives the fan-out, so `retry.models` (the fallback\n * rotation) is overridden to each panel model in turn.\n */\n retry?: JudgeRetryPolicy\n /** Enforce `assertCrossFamily` over `models` at construction. Default true.\n * Opt out only for deliberate single-family panels (e.g. self-consistency\n * sampling of one model).\n *\n * Construction-time only, over the REQUESTED ids: it cannot see a gateway\n * that answers several ids from one provider. `scoreWith` owns the served\n * side — check the id the provider echoed with `assertServedModel`\n * (./integrity/served-model) inside your judge call. */\n crossFamily?: boolean\n /** Composite weights forwarded to `aggregateJudgeVerdicts`: a partial map\n * selects AND weights exactly the named dimensions. Omit for uniform. */\n weights?: Partial<Record<D, number>>\n}\n\n/**\n * Build a campaign-shaped `JudgeConfig` whose `score()` runs every panel\n * model in parallel and reduces the surviving verdicts to one canonical\n * `JudgeScore` in [0,1].\n *\n * Failure semantics: a model whose `scoreWith` throws (or exhausts `retry`)\n * lands in `failedJudges` and is excluded from the means. When EVERY model\n * fails, `aggregateJudgeVerdicts` throws — the campaign engine records a\n * failed cell instead of averaging a fabricated zero.\n */\nexport function ensembleJudge<D extends string>(\n opts: EnsembleJudgeOptions<D>,\n): JudgeConfig<unknown> {\n if (opts.models.length === 0) {\n throw new Error(`ensembleJudge '${opts.name}': models is empty — nothing to score with`)\n }\n if (opts.dimensions.length === 0) {\n throw new Error(`ensembleJudge '${opts.name}': dimensions is empty — nothing to score`)\n }\n if (opts.crossFamily !== false) {\n assertCrossFamily(opts.models)\n }\n const declaredJudgeVersion = opts.judgeVersion?.trim()\n if (opts.judgeVersion !== undefined && !declaredJudgeVersion) {\n throw new Error(`ensembleJudge '${opts.name}': judgeVersion must be non-empty when provided`)\n }\n const judgeVersion =\n declaredJudgeVersion ??\n contentHash({\n kind: 'ensembleJudge',\n models: opts.models,\n dimensions: opts.dimensions,\n weights: opts.weights ?? null,\n crossFamily: opts.crossFamily ?? true,\n maximumCharge:\n typeof opts.maximumCharge === 'function'\n ? opts.maximumCharge.toString()\n : (opts.maximumCharge ?? null),\n retry: opts.retry\n ? {\n maxAttempts: opts.retry.maxAttempts ?? null,\n timeoutMs: opts.retry.timeoutMs ?? null,\n models: opts.retry.models ?? null,\n backoffMs: opts.retry.backoffMs?.toString() ?? null,\n isRetryable: opts.retry.isRetryable?.toString() ?? null,\n }\n : null,\n scoreWith: opts.scoreWith.toString(),\n })\n const directCostLedger = opts.costLedger ?? new CostLedger()\n\n const scoreOne = async (args: {\n model: string\n artifact: unknown\n scenario?: unknown\n signal: AbortSignal\n costLedger: CostLedgerHandle\n costPhase: string\n costTags?: Record<string, string>\n }): Promise<JudgeVerdict<D>> => {\n const outcome = await withJudgeRetry(\n async (model, retrySignal) => {\n const paid = await args.costLedger.runPaidCall({\n channel: 'judge',\n phase: args.costPhase,\n actor: `${opts.name}.${model}`,\n model,\n maximumCharge:\n typeof opts.maximumCharge === 'function'\n ? opts.maximumCharge(model)\n : opts.maximumCharge,\n tags: args.costTags,\n signal: AbortSignal.any([args.signal, retrySignal]),\n execute: (signal) =>\n opts.scoreWith(model, { artifact: args.artifact, scenario: args.scenario, signal }),\n receipt: (verdict) => {\n const cachedTokens = verdict.usage?.cachedPromptTokens ?? 0\n const usageUnknown = !verdict.usage || verdict.usage.captured === false\n return {\n model: verdict.model,\n inputTokens: Math.max(0, (verdict.usage?.promptTokens ?? 0) - cachedTokens),\n outputTokens: verdict.usage?.completionTokens ?? 0,\n cachedTokens: cachedTokens > 0 ? cachedTokens : undefined,\n usageUnknown,\n ...(verdict.costUsd === undefined ? {} : { actualCostUsd: verdict.costUsd }),\n }\n },\n receiptFromError: (error) => opts.receiptFromError?.(error, model),\n })\n if (!paid.succeeded) throw paid.error\n return paid.value\n },\n opts.retry\n ? { ...opts.retry, models: [args.model] }\n : { maxAttempts: 1, models: [args.model], isRetryable: () => false },\n )\n if (!outcome.succeeded || outcome.value === null) {\n return {\n model: args.model,\n perDimension: null,\n rationale: outcome.error?.message ?? 'judge failed',\n }\n }\n return outcome.value\n }\n\n return {\n name: opts.name,\n dimensions: opts.dimensions.map((d) => ({ key: d, description: d })),\n judgeVersion,\n async score({\n artifact,\n scenario,\n signal,\n costLedger,\n costPhase,\n costTags,\n }): Promise<JudgeScore> {\n const verdicts = await Promise.all(\n opts.models.map((model) =>\n scoreOne({\n model,\n artifact,\n scenario,\n signal,\n costLedger: costLedger ?? directCostLedger,\n costPhase: costPhase ?? 'judge',\n costTags,\n }),\n ),\n )\n // All-failed throws here — propagate so the engine records a failed cell.\n const agg = aggregateJudgeVerdicts(verdicts, opts.dimensions, opts.weights)\n const score: JudgeScore = {\n dimensions: agg.perDimension,\n composite: agg.composite,\n notes: agg.rationale,\n maxDisagreement: agg.maxDisagreement,\n perJudge: agg.perJudge,\n }\n if (agg.failedJudges.length > 0) score.failedJudges = agg.failedJudges\n return score\n },\n }\n}\n","/**\n * Keyword-coverage judge — baseline complement to the semantic concept\n * judge.\n *\n * Where {@link runSemanticConceptJudge} uses an LLM to read source code\n * and decide whether a concept is REALLY implemented (not just\n * keyword-mentioned), this judge does the cheap, deterministic version:\n * fetch the served preview, concatenate every linked CSS/JS asset, and\n * substring-match each expected concept's keywords against the\n * concatenated haystack. Optional `requiredElement` selector adds a\n * structural gate so \"supply counter\" can require an actual `<input>` or\n * `<table>`, not just a comment containing the word.\n *\n * Use both judges. Keyword coverage is a fast 0-cost gate — a stub page\n * with the right keywords passes here, fails the semantic judge. Score\n * divergence between the two is itself a signal: high keyword coverage\n * + low semantic = \"the agent slapped the right words on the right\n * scaffold but didn't wire any of it up.\"\n *\n * Pure functions, soft-fail on fetch error, no LLM dependency.\n */\n\n// ─── Types ──────────────────────────────────────────────────────────────\n\nexport interface KeywordConceptSpec {\n name: string\n keywords: string[]\n /**\n * Optional CSS selector that must match in the HTML for the concept\n * to count as present. Tiny subset:\n * - `tag` (e.g. `form`)\n * - `tag[attr=\"value\"]` (e.g. `input[type=\"number\"]`)\n * - `tag[attr]` (presence only)\n * Anything more complex is rejected with `null` (treated as\n * \"unenforced\", not \"failed\").\n */\n requiredElement?: string\n}\n\nexport interface KeywordCoverageFinding {\n concept: string\n found: boolean\n matchedKeywords: string[]\n /** True iff the optional requiredElement selector matched; null when no selector. */\n requiredElementPresent: boolean | null\n}\n\nexport interface KeywordCoverageResult {\n /** 0..1 share of concepts satisfied. */\n score: number\n presentCount: number\n totalCount: number\n findings: KeywordCoverageFinding[]\n durationMs: number\n /** Total bytes assembled across html + linked assets. */\n totalAssembledBytes: number\n /** Soft-failure reason if the audit couldn't run. */\n error?: string\n}\n\nexport interface KeywordCoverageOptions {\n /** Override fetch implementation — for tests. */\n fetch?: typeof fetch\n /** Per-asset fetch timeout (default 3s). */\n assetTimeoutMs?: number\n /** Initial-HTML fetch timeout (default 5s). */\n htmlTimeoutMs?: number\n}\n\n// ─── Selector matcher ──────────────────────────────────────────────────\n\n/**\n * Element-presence check using a tiny CSS-selector subset. Returns\n * null when the selector isn't supported — caller treats that as\n * \"unenforced\" rather than \"failed.\"\n */\nexport function htmlContainsElement(html: string, selector: string): boolean | null {\n const tagOnly = /^([a-zA-Z][\\w-]*)$/.exec(selector)\n if (tagOnly) {\n const re = new RegExp(`<${tagOnly[1]}\\\\b`, 'i')\n return re.test(html)\n }\n const tagAttrEq = /^([a-zA-Z][\\w-]*)\\[([\\w-]+)\\s*=\\s*[\"']?([^\"'\\]]+)[\"']?\\]$/.exec(selector)\n if (tagAttrEq) {\n const [, tag, attr, value] = tagAttrEq\n const re = new RegExp(\n `<${tag}\\\\b[^>]*\\\\b${attr}\\\\s*=\\\\s*[\"']${value!.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')}[\"']`,\n 'i',\n )\n return re.test(html)\n }\n const tagAttrPresence = /^([a-zA-Z][\\w-]*)\\[([\\w-]+)\\]$/.exec(selector)\n if (tagAttrPresence) {\n const [, tag, attr] = tagAttrPresence\n const re = new RegExp(`<${tag}\\\\b[^>]*\\\\b${attr}\\\\b`, 'i')\n return re.test(html)\n }\n return null\n}\n\n// ─── Asset extraction ─────────────────────────────────────────────────\n\n/**\n * Pull every `<link rel=stylesheet href>` and `<script src>` from a\n * raw HTML body. Returns absolute URLs resolved against `baseUrl`.\n * Permissive regex — agent-authored markup doesn't always quote\n * attributes the same way.\n */\nexport function extractAssetUrls(html: string, baseUrl: string): string[] {\n const urls = new Set<string>()\n const linkRe = /<link\\b[^>]*\\bhref\\s*=\\s*[\"']([^\"']+)[\"'][^>]*>/gi\n const scriptRe = /<script\\b[^>]*\\bsrc\\s*=\\s*[\"']([^\"']+)[\"'][^>]*>/gi\n for (const re of [linkRe, scriptRe]) {\n let match: RegExpExecArray | null = re.exec(html)\n while (match !== null) {\n const raw = match[1]!\n try {\n urls.add(new URL(raw, baseUrl).toString())\n } catch {\n // unresolvable refs (e.g. data: URLs) — skip\n }\n match = re.exec(html)\n }\n }\n return Array.from(urls)\n}\n\n// ─── Coverage scorer ──────────────────────────────────────────────────\n\n/**\n * Score expected concepts against an already-fetched HTML payload + any\n * pre-fetched CSS/JS assets. Use when the runner has the bytes in hand\n * and doesn't want a fresh HTTP round-trip — e.g. sandbox runtime where\n * the preview content was fetched via curl from inside the container.\n */\nexport function runKeywordCoverageJudge(\n html: string,\n expectedConcepts: ReadonlyArray<KeywordConceptSpec>,\n assets: ReadonlyArray<string> = [],\n): KeywordCoverageResult {\n const start = Date.now()\n if (expectedConcepts.length === 0) {\n return {\n score: 0,\n presentCount: 0,\n totalCount: 0,\n findings: [],\n durationMs: 0,\n totalAssembledBytes: 0,\n }\n }\n const haystack = `${html}\\n${assets.join('\\n')}`.toLowerCase()\n const findings: KeywordCoverageFinding[] = expectedConcepts.map((concept) => {\n const matchedKeywords: string[] = []\n for (const kw of concept.keywords) {\n if (haystack.includes(kw.toLowerCase())) matchedKeywords.push(kw)\n }\n const requiredElementPresent = concept.requiredElement\n ? htmlContainsElement(html, concept.requiredElement)\n : null\n const passesElementGate = requiredElementPresent === null || requiredElementPresent === true\n const found = matchedKeywords.length > 0 && passesElementGate\n return { concept: concept.name, found, matchedKeywords, requiredElementPresent }\n })\n const presentCount = findings.filter((f) => f.found).length\n return {\n score: presentCount / expectedConcepts.length,\n presentCount,\n totalCount: expectedConcepts.length,\n findings,\n durationMs: Date.now() - start,\n totalAssembledBytes: haystack.length,\n }\n}\n\n/**\n * URL-fetch flavor — GET the preview, parallel-fetch every linked\n * stylesheet + script (with bounded timeouts, soft-fail individually),\n * then score via {@link runKeywordCoverageJudge}.\n */\nexport async function runKeywordCoverageJudgeUrl(\n previewUrl: string,\n expectedConcepts: ReadonlyArray<KeywordConceptSpec>,\n options: KeywordCoverageOptions = {},\n): Promise<KeywordCoverageResult> {\n const start = Date.now()\n const fetchFn = options.fetch ?? globalThis.fetch\n const htmlTimeout = options.htmlTimeoutMs ?? 5_000\n const assetTimeout = options.assetTimeoutMs ?? 3_000\n\n if (expectedConcepts.length === 0) {\n return {\n score: 0,\n presentCount: 0,\n totalCount: 0,\n findings: [],\n durationMs: 0,\n totalAssembledBytes: 0,\n }\n }\n\n let html = ''\n try {\n const resp = await fetchFn(previewUrl, {\n redirect: 'follow',\n signal: AbortSignal.timeout(htmlTimeout),\n })\n if (!resp.ok) {\n return softFail(expectedConcepts, start, `preview HTTP ${resp.status}`)\n }\n html = await resp.text()\n } catch (err) {\n return softFail(expectedConcepts, start, err instanceof Error ? err.message : String(err))\n }\n\n const assetUrls = extractAssetUrls(html, previewUrl)\n const assetBodies = await Promise.all(\n assetUrls.map(async (u) => {\n try {\n const r = await fetchFn(u, {\n redirect: 'follow',\n signal: AbortSignal.timeout(assetTimeout),\n })\n if (!r.ok) return ''\n return await r.text()\n } catch {\n return ''\n }\n }),\n )\n\n return runKeywordCoverageJudge(html, expectedConcepts, assetBodies)\n}\n\nfunction softFail(\n expectedConcepts: ReadonlyArray<KeywordConceptSpec>,\n start: number,\n error: string,\n): KeywordCoverageResult {\n return {\n score: 0,\n presentCount: 0,\n totalCount: expectedConcepts.length,\n findings: expectedConcepts.map((c) => ({\n concept: c.name,\n found: false,\n matchedKeywords: [],\n requiredElementPresent: null,\n })),\n durationMs: Date.now() - start,\n totalAssembledBytes: 0,\n error,\n }\n}\n","/**\n * Multi-layer verifier — ordered pipeline of verification layers.\n *\n * Different contract from {@link JudgeRunner} (which runs parallel\n * specs against a sandbox). MultiLayerVerifier is a DAG of layers\n * (install → typecheck → build → lint → serve → semantic → …) with\n * dependency-based skip, per-layer findings, soft-fail semantics, and\n * an aggregated `blendedScore` across all passed layers.\n *\n * Use when you want:\n * - ordered stages where a failing upstream stage skips downstream ones\n * - each stage produces rich `findings` (severity + message + evidence)\n * - a single composite score across stages with per-stage weights\n * - soft-fail stages whose failure doesn't abort the pipeline\n *\n * Use {@link JudgeRunner} when you want:\n * - N independent judges running in parallel against the same artifact\n * - no inter-judge dependencies\n * - boolean `passed` per judge + overall\n *\n * Both primitives compose — JudgeRunner can be invoked as a single\n * layer inside a MultiLayerVerifier if that suits the caller.\n */\n\nimport { packageVersion } from './package-version'\nimport { certificationEvidenceDigest, type DefaultVerdict } from './verdict'\n\n// ─── Types ──────────────────────────────────────────────────────────────\n\nexport type LayerStatus = 'pass' | 'fail' | 'skipped' | 'error' | 'timeout'\n\nexport type Severity = 'critical' | 'major' | 'minor' | 'info'\n\nexport interface Finding {\n severity: Severity\n message: string\n evidence?: string\n /** Optional layer name the finding belongs to (set by the verifier if omitted). */\n layer?: string\n /**\n * Free-form structured payload — used by `multiToolchainLayer` to attach\n * `{ adapter: 'pnpm' }`, by judges to attach evidence pointers, etc.\n * Renderers MAY interrogate; agent-eval primitives never assume shape.\n */\n detail?: Record<string, unknown>\n}\n\nexport interface LayerResult {\n layer: string\n status: LayerStatus\n /** Origin of an `error` or `timeout`. Defaults to `execution`. */\n errorSource?: 'execution' | 'judge'\n /** 0..1 score, optional — layers that don't produce a numeric score omit. */\n score?: number\n durationMs: number\n findings: Finding[]\n /** Short human-readable summary (one line). */\n reason?: string\n /**\n * Numeric layer-level diagnostics: error counts, warning counts,\n * cyclomatic complexity, total adapter wall-time, etc. Keyed by\n * diagnostic name; null = \"diagnostic not applicable / not measured.\"\n * Renderers that know the keys can display them; ones that don't,\n * ignore. Free-form on purpose — consumers type the value shape in\n * their own namespace.\n */\n diagnostics?: Record<string, number | null>\n /** Any rich per-layer detail — rendered as-is by consumers that know the layer. */\n detail?: Record<string, unknown>\n}\n\nexport interface VerifyContext<Env = unknown> {\n /** Per-run opaque context the caller provides. Layers destructure what they need. */\n env: Env\n /** Previously-computed results from layers that already ran. */\n prior: Record<string, LayerResult>\n /** Signal — if aborted, layers MUST bail within reasonable wall. */\n signal: AbortSignal\n}\n\nexport interface Layer<Env = unknown> {\n name: string\n /** Origin assigned when this layer errors or times out. Defaults to `execution`. */\n errorSource?: 'execution' | 'judge'\n /** Stages that must have `status: 'pass'` before this layer runs. */\n dependsOn?: string[]\n /**\n * Weight in the composite `blendedScore`. Default 1.0. Layers with weight 0\n * contribute findings but not score.\n */\n weight?: number\n /**\n * If true, a `fail` status contributes to `blendedScore` (as 0) instead of\n * being dropped — use for layers whose failure is a real signal. Default:\n * fail drops from numerator + denominator, matching VB's existing semantics.\n */\n failContributesToScore?: boolean\n /** Optional per-layer wall-cap in ms. Honored by the verifier (AbortSignal). */\n capMs?: number\n run: (ctx: VerifyContext<Env>) => Promise<LayerResult> | LayerResult\n}\n\nexport interface VerifyOptions<Env = unknown> {\n env: Env\n /**\n * Overall wall cap. Default: sum of layer capMs, or Infinity if any layer\n * omits a cap. The verifier short-circuits remaining layers on overall cap.\n */\n overallCapMs?: number\n /** Called with each layer result as it completes. */\n onLayer?: (result: LayerResult) => void\n}\n\n/** Extends the substrate verdict spine: `valid` = `allPass`; `score` is the\n * complete task score or 0 when the configured scoring panel was incomplete. */\nexport interface VerificationReport extends DefaultVerdict {\n layers: LayerResult[]\n passCount: number\n failCount: number\n skippedCount: number\n errorCount: number\n /** True iff the configured scoring panel completed and every layer passed. */\n allPass: boolean\n /**\n * Diagnostic weighted mean across contributing layers. This may represent a\n * partial panel. It is 0 when no layer contributed.\n */\n blendedScore: number\n /**\n * Complete task-quality measurement.\n * Present when at least one layer produced a valid score, every other layer\n * completed successfully or contributed an explicit scored failure, and no\n * result is missing because of a failure, skip, error, or timeout.\n * Use this field, not `blendedScore`, when creating task labels.\n */\n taskScore?: number\n durationMs: number\n startedAt: string\n finishedAt: string\n}\n\n// ─── Helpers ────────────────────────────────────────────────────────────\n\n/**\n * Grade a semantic-concept-style judge result into a single layer status.\n *\n * Pass when overall score >= threshold AND no critical-severity concept gap.\n * Fail otherwise. Use inside a `Layer.run` when wrapping a concept judge.\n *\n * Generalized from VerticalBench H3 fix: `failingConcepts.length === 0` was\n * too strict — a single concept at 6/10 failed the entire layer despite\n * overall score being >= 0.7. Now we trust the judge's own `severity` field:\n * `critical` findings veto; `major`/`minor` reduce the score but don't veto.\n */\nexport function gradeSemanticStatus(input: {\n score: number\n findings: Array<{ severity: Severity; present?: boolean; score?: number }>\n available: boolean\n threshold?: number\n}): LayerStatus {\n if (!input.available) return 'error'\n const threshold = input.threshold ?? 0.7\n const criticalGaps = input.findings.filter(\n (f) => f.severity === 'critical' && (f.present === false || (f.score ?? 0) < 7),\n )\n return input.score >= threshold && criticalGaps.length === 0 ? 'pass' : 'fail'\n}\n\n// ─── Verifier ───────────────────────────────────────────────────────────\n\n/**\n * Ordered DAG of verification layers with dependency-based skipping, per-layer findings, soft-fail semantics, and a blended composite score across all passed layers.\n */\nexport class MultiLayerVerifier<Env = unknown> {\n constructor(private readonly layers: Layer<Env>[]) {\n const seen = new Set<string>()\n for (const l of layers) {\n if (seen.has(l.name)) throw new Error(`MultiLayerVerifier: duplicate layer name \"${l.name}\"`)\n seen.add(l.name)\n }\n for (const l of layers) {\n for (const dep of l.dependsOn ?? []) {\n if (!seen.has(dep)) {\n throw new Error(\n `MultiLayerVerifier: layer \"${l.name}\" depends on \"${dep}\" which is not registered`,\n )\n }\n }\n }\n }\n\n async run(opts: VerifyOptions<Env>): Promise<VerificationReport> {\n const startedAtMs = Date.now()\n const startedAt = new Date(startedAtMs).toISOString()\n const controller = new AbortController()\n const overallCap = opts.overallCapMs\n const overallTimer =\n overallCap != null\n ? setTimeout(() => controller.abort(new Error('overall cap exceeded')), overallCap)\n : null\n\n const results: LayerResult[] = []\n const byName: Record<string, LayerResult> = {}\n\n try {\n for (const layer of this.layers) {\n // Skip if any dependency didn't pass.\n const unmet = (layer.dependsOn ?? []).filter((d) => byName[d]?.status !== 'pass')\n if (unmet.length > 0) {\n const skipped: LayerResult = {\n layer: layer.name,\n status: 'skipped',\n durationMs: 0,\n findings: [],\n reason: `skipped — upstream not passing: ${unmet.join(', ')}`,\n }\n results.push(skipped)\n byName[layer.name] = skipped\n opts.onLayer?.(skipped)\n continue\n }\n\n // Per-layer cap — compose with overall signal.\n const perLayerController = new AbortController()\n const mergedSignal = mergeSignals(controller.signal, perLayerController.signal)\n const layerTimer =\n layer.capMs != null\n ? setTimeout(\n () => perLayerController.abort(new Error(`layer ${layer.name} cap`)),\n layer.capMs,\n )\n : null\n\n const layerStart = Date.now()\n let result: LayerResult\n let rejectOnAbort: (() => void) | undefined\n const abortPromise = new Promise<never>((_resolve, reject) => {\n const rejectWithReason = (): void => {\n const reason = mergedSignal.reason\n reject(reason instanceof Error ? reason : new Error(String(reason ?? 'aborted')))\n }\n if (mergedSignal.aborted) {\n rejectWithReason()\n return\n }\n mergedSignal.addEventListener('abort', rejectWithReason, { once: true })\n rejectOnAbort = () => mergedSignal.removeEventListener('abort', rejectWithReason)\n })\n try {\n result = await Promise.race([\n Promise.resolve(\n layer.run({ env: opts.env, prior: { ...byName }, signal: mergedSignal }),\n ),\n abortPromise,\n ])\n } catch (err) {\n const aborted = mergedSignal.aborted\n result = {\n layer: layer.name,\n status: aborted ? 'timeout' : 'error',\n errorSource: layer.errorSource ?? 'execution',\n durationMs: Date.now() - layerStart,\n findings: [\n {\n severity: 'major',\n message: err instanceof Error ? err.message : String(err),\n layer: layer.name,\n },\n ],\n reason: err instanceof Error ? err.message : String(err),\n }\n } finally {\n rejectOnAbort?.()\n if (layerTimer) clearTimeout(layerTimer)\n }\n\n if (result.status === 'error' || result.status === 'timeout') {\n result.errorSource ??= layer.errorSource ?? 'execution'\n }\n\n // Normalize findings to attach layer name if omitted.\n result.findings = result.findings.map((f) => ({ ...f, layer: f.layer ?? layer.name }))\n results.push(result)\n byName[layer.name] = result\n opts.onLayer?.(result)\n\n if (controller.signal.aborted) break\n }\n\n const report = aggregate(this.layers, results, startedAt, startedAtMs)\n return report\n } finally {\n if (overallTimer) clearTimeout(overallTimer)\n }\n }\n}\n\nfunction aggregate<Env>(\n layers: Layer<Env>[],\n results: LayerResult[],\n startedAt: string,\n startedAtMs: number,\n): VerificationReport {\n const weightByName = new Map<string, number>()\n const failContribByName = new Map<string, boolean>()\n for (const l of layers) {\n weightByName.set(l.name, l.weight ?? 1)\n failContribByName.set(l.name, l.failContributesToScore ?? false)\n }\n\n let passCount = 0\n let failCount = 0\n let skippedCount = 0\n let errorCount = 0\n let scoredWeightSum = 0\n let scoredWeightedTotal = 0\n\n for (const r of results) {\n const weight = weightByName.get(r.layer) ?? 1\n const failContrib = failContribByName.get(r.layer) ?? false\n if (r.status === 'pass') passCount++\n else if (r.status === 'fail') failCount++\n else if (r.status === 'skipped') skippedCount++\n else errorCount++\n\n if (isValidTaskMeasurement(r) && weight > 0) {\n if (r.status === 'pass') {\n scoredWeightSum += weight\n scoredWeightedTotal += weight * r.score\n } else if (r.status === 'fail') {\n if (failContrib) {\n scoredWeightSum += weight\n scoredWeightedTotal += weight * r.score\n }\n }\n // skipped / error / timeout layers don't contribute\n }\n }\n\n const finishedAtMs = Date.now()\n const blendedScore = scoredWeightSum > 0 ? scoredWeightedTotal / scoredWeightSum : 0\n const resultByName = new Map(results.map((result) => [result.layer, result]))\n const completeTaskMeasurement =\n scoredWeightSum > 0 &&\n results.length === layers.length &&\n layers.every((layer) => {\n const result = resultByName.get(layer.name)\n if (!result) return false\n if ((layer.weight ?? 1) <= 0) return true\n if (result.status === 'pass') {\n return result.score === undefined || isValidTaskMeasurement(result)\n }\n return (\n result.status === 'fail' &&\n layer.failContributesToScore === true &&\n isValidTaskMeasurement(result)\n )\n })\n const taskScore =\n completeTaskMeasurement && scoredWeightSum > 0 && Number.isFinite(blendedScore)\n ? blendedScore\n : undefined\n const allPass =\n taskScore !== undefined &&\n results.length === layers.length &&\n failCount === 0 &&\n skippedCount === 0 &&\n errorCount === 0\n // Layers that produced no measurement are the steps this composite\n // certificate rests on without verifying — named per layer, never folded\n // into the blend silently.\n const assumptions = results\n .filter((r) => r.status === 'skipped' || r.status === 'error' || r.status === 'timeout')\n .map((r) => `layer '${r.layer}' ${r.status} — its obligations are unverified`)\n return {\n layers: results,\n passCount,\n failCount,\n skippedCount,\n errorCount,\n allPass,\n blendedScore,\n ...(taskScore === undefined ? {} : { taskScore }),\n valid: allPass,\n score: taskScore ?? 0,\n certification: {\n strategy: 'composite',\n checker: { name: 'agent-eval:multi-layer-verifier', version: packageVersion() },\n assumptions,\n evidenceDigest: certificationEvidenceDigest(results),\n },\n durationMs: finishedAtMs - startedAtMs,\n startedAt,\n finishedAt: new Date(finishedAtMs).toISOString(),\n }\n}\n\nfunction isValidTaskMeasurement(\n result: LayerResult,\n): result is LayerResult & { status: 'pass' | 'fail'; score: number } {\n return (\n (result.status === 'pass' || result.status === 'fail') &&\n typeof result.score === 'number' &&\n Number.isFinite(result.score) &&\n result.score >= 0 &&\n result.score <= 1\n )\n}\n\nfunction mergeSignals(a: AbortSignal, b: AbortSignal): AbortSignal {\n if (a.aborted) return a\n if (b.aborted) return b\n const c = new AbortController()\n const onAbort = (signal: AbortSignal) => () => c.abort(signal.reason)\n a.addEventListener('abort', onAbort(a), { once: true })\n b.addEventListener('abort', onAbort(b), { once: true })\n return c.signal\n}\n","/**\n * Declarative oracles — ground-truth assertions without an LLM.\n *\n * Lifted from browser-agent-driver's _oracle.mjs. When you know the\n * expected outcome exactly (a URL, a text fragment, a JSON shape), you\n * don't need an LLM judge — you need a regex. These oracles are\n * composable pass/fail checks over an observation bundle.\n *\n * Each oracle returns { pass, detail, evidence? } and has a short `id` for\n * reporting. `evaluateOracles` runs a batch and lands the aggregate in the\n * shared verdict spine (`DefaultVerdict`, docs/verdicts.md) with a\n * `'test'`-strategy certification: an oracle set IS a small answer key,\n * and certifies nothing outside its own coverage.\n */\n\nimport { packageVersion } from './package-version'\nimport { certificationEvidenceDigest, type DefaultVerdict } from './verdict'\n\nexport interface OracleObservation {\n /** Final observable text output from the agent (response, page snapshot, stdout). */\n text?: string\n /** Final URL — for browser-style scenarios. */\n url?: string\n /** Any structured JSON the agent produced. */\n json?: unknown\n /** Free-form context used by custom oracles. */\n context?: Record<string, unknown>\n}\n\nexport interface OracleResult {\n id: string\n pass: boolean\n detail: string\n evidence?: string\n}\n\nexport interface Oracle {\n id: string\n check(obs: OracleObservation): OracleResult\n}\n\nexport function textInSnapshot(needle: string, opts: { caseSensitive?: boolean } = {}): Oracle {\n const id = `text-in-snapshot(${needle})`\n return {\n id,\n check(obs) {\n const hay = obs.text ?? ''\n const found = opts.caseSensitive\n ? hay.includes(needle)\n : hay.toLowerCase().includes(needle.toLowerCase())\n return {\n id,\n pass: found,\n detail: found ? `\"${needle}\" found` : `\"${needle}\" not present in observation`,\n evidence: found ? excerpt(hay, needle, opts.caseSensitive) : undefined,\n }\n },\n }\n}\n\nexport function urlContains(fragment: string): Oracle {\n const id = `url-contains(${fragment})`\n return {\n id,\n check(obs) {\n const url = obs.url ?? ''\n const pass = url.toLowerCase().includes(fragment.toLowerCase())\n return {\n id,\n pass,\n detail: pass ? `url ok (${url})` : `url \"${url}\" missing \"${fragment}\"`,\n evidence: url,\n }\n },\n }\n}\n\nexport function jsonShape(expected: Record<string, unknown>): Oracle {\n const id = `json-shape(${Object.keys(expected).join(',')})`\n return {\n id,\n check(obs) {\n const json = obs.json\n if (!isObject(json)) {\n return { id, pass: false, detail: 'observation.json missing or not an object' }\n }\n for (const [k, v] of Object.entries(expected)) {\n if (!(k in json)) return { id, pass: false, detail: `key \"${k}\" missing` }\n const actual = (json as Record<string, unknown>)[k]\n if (typeof v === 'string' && v.startsWith('re:')) {\n const re = new RegExp(v.slice(3))\n if (typeof actual !== 'string' || !re.test(actual)) {\n return { id, pass: false, detail: `key \"${k}\" failed regex ${v}` }\n }\n } else if (actual !== v) {\n return {\n id,\n pass: false,\n detail: `key \"${k}\" = ${JSON.stringify(actual)}, expected ${JSON.stringify(v)}`,\n }\n }\n }\n return { id, pass: true, detail: 'all keys match' }\n },\n }\n}\n\nexport function regexMatches(pattern: RegExp): Oracle {\n const id = `regex(${pattern.source})`\n return {\n id,\n check(obs) {\n const hay = obs.text ?? ''\n const m = hay.match(pattern)\n return {\n id,\n pass: m !== null,\n detail: m ? `matched \"${m[0]}\"` : `pattern ${pattern.source} not matched`,\n evidence: m?.[0],\n }\n },\n }\n}\n\n/**\n * Anti-bot detector — distinguishes genuine failures from blocked navigation\n * (cloudflare, recaptcha, etc). Returns an Oracle that PASSES when no block\n * marker is present; on block, detail names the blocker so runners can tag\n * results as \"blocked\" rather than \"failed\". Lifted from browser-agent-driver.\n */\nexport function notBlocked(): Oracle {\n const id = 'not-blocked'\n const markers: Array<{ name: string; re: RegExp }> = [\n { name: 'cloudflare', re: /just a moment|verifying you are human|cf-chl-|cloudflare/i },\n { name: 'recaptcha', re: /recaptcha|i'?m not a robot|challenge.?form/i },\n { name: 'hcaptcha', re: /hcaptcha/i },\n { name: 'akamai', re: /akamai|pragma: no-cache/i },\n { name: 'perimeterx', re: /perimeterx|px-captcha/i },\n { name: 'rate-limit', re: /rate.?limit|429 too many requests/i },\n { name: 'access-denied', re: /access denied|403 forbidden/i },\n ]\n return {\n id,\n check(obs) {\n const hay = obs.text ?? ''\n for (const { name, re } of markers) {\n if (re.test(hay)) {\n return {\n id,\n pass: false,\n detail: `blocked by ${name}`,\n evidence: (hay.match(re) ?? [])[0],\n }\n }\n }\n return { id, pass: true, detail: 'no anti-bot block detected' }\n },\n }\n}\n\n/** Extends the substrate verdict spine: `valid` = every oracle passed (and\n * at least one ran); `score` = ratio of oracles passed; `scores` = per-\n * oracle 0|1 keyed by oracle id. */\nexport interface OracleReport extends DefaultVerdict {\n results: OracleResult[]\n passCount: number\n failCount: number\n}\n\n/** Run all oracles against one observation and aggregate. */\nexport function evaluateOracles(obs: OracleObservation, oracles: Oracle[]): OracleReport {\n const results = oracles.map((o) => o.check(obs))\n const passCount = results.filter((r) => r.pass).length\n const failCount = results.length - passCount\n const scores: Record<string, number> = {}\n for (const r of results) scores[r.id] = r.pass ? 1 : 0\n return {\n results,\n passCount,\n failCount,\n valid: failCount === 0 && results.length > 0,\n score: results.length ? passCount / results.length : 0,\n scores,\n notes: `${passCount}/${results.length} oracles passed`,\n certification: {\n strategy: 'test',\n checker: { name: 'agent-eval:declarative-oracles', version: packageVersion() },\n assumptions: [],\n evidenceDigest: certificationEvidenceDigest(results),\n },\n }\n}\n\nfunction excerpt(hay: string, needle: string, caseSensitive = false): string {\n const haySearch = caseSensitive ? hay : hay.toLowerCase()\n const needleSearch = caseSensitive ? needle : needle.toLowerCase()\n const idx = haySearch.indexOf(needleSearch)\n if (idx === -1) return ''\n const start = Math.max(0, idx - 20)\n const end = Math.min(hay.length, idx + needle.length + 20)\n return (start > 0 ? '…' : '') + hay.slice(start, end) + (end < hay.length ? '…' : '')\n}\n\nfunction isObject(v: unknown): v is Record<string, unknown> {\n return typeof v === 'object' && v !== null && !Array.isArray(v)\n}\n","/**\n * Treatment-applied gate — \"did the treatment's tool actually fire this run?\"\n *\n * A tool-treatment A/B (mount a search provider, a browser, a code-exec\n * sandbox, a retrieval MCP — anything one arm gets and the other doesn't) only\n * means something on the treatment arm if that arm actually EXERCISED the tool.\n * A treatment run that never called the mounted tool is not a weak data point\n * — it is a NON-data-point: the manipulation never happened, so the run cannot\n * speak to the treatment and must be excluded from the objective, the same way\n * an infra-tainted run is excluded.\n *\n * This is the manipulation/validity precondition that protects the paired A/B\n * tests downstream (`mcnemar`, `pairedRiskDifference`): they must only ever see\n * runs where the treatment was applied, or they measure noise and report it as\n * an effect.\n *\n * Shape mirrors `authenticity`'s `gateRealness`: a pure predicate over already-\n * computed signals, with explicit fail-open/fail-closed discipline. It is not a\n * trace parser — the tool-call telemetry it reads is the deterministic\n * `toolHistogram` that `computeTraceMetrics(spans)` already produces (OTLP\n * tool-name extraction via `TOOL_NAME_ATTR_KEYS`), or the `ToolSpan[]` a\n * `toolSpans(store, runId)` query returns. The gate never re-derives either.\n *\n * General by construction:\n * - The \"which tool counts as the treatment\" decision is a `matches` PARAMETER\n * — a `(toolName: string) => boolean`. There is no `search`/`web`/`fetch`\n * literal anywhere in this module; a search A/B passes its own matcher.\n * - The \"is THIS run a treatment arm (vs a control)\" decision is the caller's\n * policy and stays at the call site. The gate only answers the narrower,\n * domain-free question: \"given this run's telemetry, did a matching tool\n * fire?\" — so it generalizes to any tool-treatment, not search.\n *\n * Fail-open on telemetry absence: when NO tool calls were captured at all\n * (`sum(toolHistogram) === 0`), the gate cannot distinguish \"the agent used no\n * tools\" from \"this harness's tool calls weren't recorded\". Quarantining on a\n * telemetry gap would silently delete real runs, so the default is\n * applied=true / gated=false. Pass `failOpenWhenNoTelemetry: false` to flip to\n * fail-closed for harnesses where tool capture is guaranteed.\n */\n\nimport type { RunRecord } from './run-record'\nimport type { ToolSpan } from './trace/schema'\nimport type { BehavioralMetrics } from './trace-analyst/behavioral-metrics'\nimport { computeTraceMetrics } from './trace-analyst/behavioral-metrics'\nimport type { TraceAnalystSpan } from './trace-analyst/types'\n\n/** A tool-name matcher: does this tool name belong to the treatment under test?\n * The caller supplies it — the substrate ships no `search` (or any) literal. */\nexport type ToolMatcher = (toolName: string) => boolean\n\nexport interface TreatmentGateInput {\n /** Tool-call counts by tool name — exactly `computeTraceMetrics(spans).toolHistogram`.\n * The gate consumes this; it does not parse spans itself. */\n toolHistogram: Readonly<Record<string, number>>\n /** Which tool names count as the treatment firing. A parameter, never baked in. */\n matches: ToolMatcher\n}\n\nexport interface TreatmentGateOptions {\n /** When the histogram is empty (no tool telemetry captured), treat the run as\n * applied rather than quarantining it. Default true — a telemetry gap must\n * never be mistaken for \"treatment not applied\". Set false only when tool\n * capture is guaranteed for this harness. */\n failOpenWhenNoTelemetry?: boolean\n}\n\nexport interface TreatmentGate {\n /** True iff the treatment's tool is considered to have fired this run. False\n * ONLY when telemetry was present and no matching call appears. */\n applied: boolean\n /** Objective-exclusion flag, parallel to `outcome.realness.gated`: a gated run\n * is dropped from the objective denominator and reported as\n * treatment-not-applied (like infra-loss). `gated === !applied`. */\n gated: boolean\n reason?: string\n /** How many recorded tool calls matched the treatment matcher. */\n matchedCalls: number\n /** Total recorded tool calls (`sum(toolHistogram)`) — 0 means no telemetry. */\n observedTools: number\n}\n\n/**\n * Core predicate. Gated (treatment-not-applied) ONLY when telemetry was\n * captured AND zero matching calls appear; an empty histogram fails open.\n */\nexport function gateTreatmentApplied(\n input: TreatmentGateInput,\n opts: TreatmentGateOptions = {},\n): TreatmentGate {\n const failOpen = opts.failOpenWhenNoTelemetry ?? true\n\n let observedTools = 0\n let matchedCalls = 0\n for (const [tool, count] of Object.entries(input.toolHistogram)) {\n const n = Number.isFinite(count) && count > 0 ? count : 0\n observedTools += n\n if (n > 0 && input.matches(tool)) matchedCalls += n\n }\n\n if (observedTools === 0) {\n return failOpen\n ? {\n applied: true,\n gated: false,\n reason: 'no tool telemetry captured — fail-open (not quarantined)',\n matchedCalls: 0,\n observedTools: 0,\n }\n : {\n applied: false,\n gated: true,\n reason: 'no tool telemetry captured — fail-closed',\n matchedCalls: 0,\n observedTools: 0,\n }\n }\n\n if (matchedCalls === 0) {\n return {\n applied: false,\n gated: true,\n reason: `treatment tool never fired (${observedTools} tool calls, 0 matched)`,\n matchedCalls: 0,\n observedTools,\n }\n }\n\n return { applied: true, gated: false, matchedCalls, observedTools }\n}\n\n/**\n * Convenience: gate from an already-computed `BehavioralMetrics` (the common\n * case — analysts already hold `computeTraceMetrics(spans)` for the run). Reads\n * the metrics' `toolHistogram`; does no re-derivation.\n */\nexport function gateTreatmentFromMetrics(\n metrics: Pick<BehavioralMetrics, 'toolHistogram'>,\n matches: ToolMatcher,\n opts?: TreatmentGateOptions,\n): TreatmentGate {\n return gateTreatmentApplied({ toolHistogram: metrics.toolHistogram, matches }, opts)\n}\n\n/**\n * Convenience: gate directly from analyst spans, reusing the substrate's\n * deterministic histogram builder. For callers holding the trace store's typed\n * `ToolSpan[]` instead, see {@link gateTreatmentFromToolSpans}.\n */\nexport function gateTreatmentFromSpans(\n spans: readonly TraceAnalystSpan[],\n matches: ToolMatcher,\n opts?: TreatmentGateOptions,\n): TreatmentGate {\n return gateTreatmentFromMetrics(computeTraceMetrics(spans), matches, opts)\n}\n\n/**\n * Convenience: gate from the trace store's canonical `ToolSpan[]` (e.g. the\n * result of `toolSpans(store, runId)`). Counts by `toolName` — the typed\n * tool-call field — so it needs no OTLP attribute extraction.\n */\nexport function gateTreatmentFromToolSpans(\n toolSpans: readonly ToolSpan[],\n matches: ToolMatcher,\n opts?: TreatmentGateOptions,\n): TreatmentGate {\n const toolHistogram: Record<string, number> = {}\n for (const s of toolSpans) {\n if (s.toolName) toolHistogram[s.toolName] = (toolHistogram[s.toolName] ?? 0) + 1\n }\n return gateTreatmentApplied({ toolHistogram, matches }, opts)\n}\n\n/** Measurable runs count toward the objective; treatment-not-applied runs are\n * excluded (like infra-loss), NOT counted as treatment failures. This is a\n * partition over the existing exclusion-flag pattern — it adds no new\n * classification enum. */\nexport type TreatmentClass = 'measurable' | 'treatment-not-applied'\n\n/**\n * Map a gate verdict onto a single measurable-vs-excluded label keyed on a\n * `RunRecord`, so consumers (paired A/B filters, reporters) read the partition\n * in one place instead of re-implementing the fail-open guard inline. The\n * `RunRecord` is accepted so callers key on the canonical run row, mirroring\n * how `outcome.realness.gated` rides along on the record; the verdict itself is\n * the gate's, not re-derived here.\n */\nexport function classifyTreatment(_record: RunRecord, gate: TreatmentGate): TreatmentClass {\n return gate.gated ? 'treatment-not-applied' : 'measurable'\n}\n","/**\n * Anti-slop quality judge.\n *\n * Deterministic pattern-based quality check — no LLM call. Catches the\n * 80% of AI slop that every production agent leaks:\n * - Banned phrases (voice-specific: \"delve\", \"it's worth noting\", etc.)\n * - N-gram repetition (same phrase over and over)\n * - Hedging overuse (\"I could be wrong, but...\")\n * - Apology padding (\"I'm so sorry for the confusion...\")\n * - Unused opening formulas (\"Great question!\")\n * - Length bounds (too short to be useful, too long to be read)\n *\n * Produces a JudgeScore in the same shape as LLM judges so it composes into\n * any `JudgeFn` array transparently.\n */\n\nimport type { JudgeFn, JudgeInput, JudgeScore } from './types'\n\nexport interface AntiSlopConfig {\n /** Domain label — appears in the JudgeScore output */\n domain?: string\n\n /** Case-insensitive substrings that must not appear. Each occurrence = penalty. */\n bannedPhrases?: string[]\n\n /** Regexes matching opening formulas to penalize (e.g. /^great question/i). */\n bannedOpenings?: RegExp[]\n\n /** Regexes matching hedges (e.g. /i could be wrong/i). Ratio of hedged sentences drives score. */\n hedgingPatterns?: RegExp[]\n\n /** Regexes matching apology padding. */\n apologyPatterns?: RegExp[]\n\n /** Fraction of sentences that can be duplicates before penalty (default 0.15 = 15%). */\n repetitionThreshold?: number\n\n /** Min output length in chars; below this the turn is deemed too terse. */\n minLength?: number\n\n /** Max output length in chars; above this the turn is deemed too verbose. */\n maxLength?: number\n\n /** How heavily each violation class reduces the score (default 1). */\n penaltyWeights?: Partial<Record<SlopCategory, number>>\n}\n\nexport type SlopCategory =\n | 'banned_phrase'\n | 'banned_opening'\n | 'hedging'\n | 'apology'\n | 'repetition'\n | 'length'\n\nconst DEFAULT_HEDGES: RegExp[] = [\n /\\bi\\s+could\\s+be\\s+wrong\\b/i,\n /\\bi\\s+think\\s+maybe\\b/i,\n /\\bit\\s+might\\s+be\\s+that\\b/i,\n /\\bperhaps\\s+(?:you\\s+)?could\\b/i,\n]\n\nconst DEFAULT_APOLOGIES: RegExp[] = [\n /\\bi\\s+(?:apologize|apologise)\\s+(?:for|if)\\b/i,\n /\\bi'?m\\s+(?:so\\s+|really\\s+)?sorry\\s+(?:for|if|about)\\b/i,\n /\\bmy\\s+apologies\\b/i,\n]\n\n/** Create a reusable Judge function from an anti-slop config. */\nexport function createAntiSlopJudge(config: AntiSlopConfig = {}): JudgeFn {\n const conf: Required<Omit<AntiSlopConfig, 'penaltyWeights'>> & {\n penaltyWeights: Record<SlopCategory, number>\n } = {\n domain: config.domain ?? 'general',\n bannedPhrases: config.bannedPhrases ?? [],\n bannedOpenings: config.bannedOpenings ?? [],\n hedgingPatterns: config.hedgingPatterns ?? DEFAULT_HEDGES,\n apologyPatterns: config.apologyPatterns ?? DEFAULT_APOLOGIES,\n repetitionThreshold: config.repetitionThreshold ?? 0.15,\n minLength: config.minLength ?? 20,\n maxLength: config.maxLength ?? 8000,\n penaltyWeights: {\n banned_phrase: 1,\n banned_opening: 1,\n hedging: 0.5,\n apology: 0.5,\n repetition: 0.75,\n length: 0.5,\n ...config.penaltyWeights,\n },\n }\n\n const judge: JudgeFn = async (_tc, input: JudgeInput): Promise<JudgeScore[]> => {\n const outputs = input.turns.map((t) => t.agentResponse ?? '')\n const report = analyzeAntiSlop(outputs, conf)\n return [\n {\n judgeName: `anti-slop(${conf.domain})`,\n dimension: 'anti_slop',\n score: report.score,\n reasoning: report.issues.length\n ? report.issues\n .slice(0, 5)\n .map((i) => `${i.category}: ${i.detail}`)\n .join('; ')\n : 'No slop patterns detected.',\n evidence: report.issues[0]?.example,\n },\n ]\n }\n return judge\n}\n\nexport interface AntiSlopIssue {\n category: SlopCategory\n detail: string\n example?: string\n}\n\nexport interface AntiSlopReport {\n /** 0–10 score; 10 is clean, lower values mean more slop. */\n score: number\n issues: AntiSlopIssue[]\n /** Count of each category for programmatic aggregation. */\n counts: Record<SlopCategory, number>\n}\n\n/**\n * Pure function — analyze one or more outputs against the config. Exposed\n * separately so consumers can build their own reporters on top.\n */\nexport function analyzeAntiSlop(\n outputs: string[],\n config: Omit<Required<AntiSlopConfig>, 'domain'> & {\n penaltyWeights: Record<SlopCategory, number>\n },\n): AntiSlopReport {\n const issues: AntiSlopIssue[] = []\n const counts: Record<SlopCategory, number> = {\n banned_phrase: 0,\n banned_opening: 0,\n hedging: 0,\n apology: 0,\n repetition: 0,\n length: 0,\n }\n\n for (const output of outputs) {\n if (!output) continue\n const lower = output.toLowerCase()\n\n for (const phrase of config.bannedPhrases) {\n const needle = phrase.toLowerCase()\n let idx = lower.indexOf(needle, 0)\n while (idx !== -1) {\n counts.banned_phrase += 1\n if (issues.length < 20) {\n issues.push({\n category: 'banned_phrase',\n detail: `\"${phrase}\"`,\n example: snippet(output, idx, phrase.length),\n })\n }\n idx = lower.indexOf(needle, idx + needle.length)\n }\n }\n\n for (const re of config.bannedOpenings) {\n if (re.test(output)) {\n counts.banned_opening += 1\n issues.push({ category: 'banned_opening', detail: re.source, example: output.slice(0, 80) })\n }\n }\n\n for (const re of config.hedgingPatterns) {\n const matches = output.match(\n new RegExp(re, re.flags.includes('g') ? re.flags : `${re.flags}g`),\n )\n if (matches) {\n counts.hedging += matches.length\n issues.push({\n category: 'hedging',\n detail: `${matches.length}x ${re.source}`,\n example: matches[0],\n })\n }\n }\n\n for (const re of config.apologyPatterns) {\n const matches = output.match(\n new RegExp(re, re.flags.includes('g') ? re.flags : `${re.flags}g`),\n )\n if (matches) {\n counts.apology += matches.length\n issues.push({\n category: 'apology',\n detail: `${matches.length}x ${re.source}`,\n example: matches[0],\n })\n }\n }\n\n // Repetition: compare sentence-level dupes\n const sentences = splitSentences(output)\n if (sentences.length >= 4) {\n const seen = new Map<string, number>()\n for (const s of sentences) {\n const key = normalizeForDupe(s)\n if (!key) continue\n seen.set(key, (seen.get(key) ?? 0) + 1)\n }\n let dupes = 0\n for (const n of seen.values()) if (n > 1) dupes += n - 1\n const ratio = dupes / sentences.length\n if (ratio > config.repetitionThreshold) {\n counts.repetition += 1\n issues.push({\n category: 'repetition',\n detail: `${(ratio * 100).toFixed(0)}% duplicated (threshold ${(config.repetitionThreshold * 100).toFixed(0)}%)`,\n })\n }\n }\n\n // Length\n if (output.length < config.minLength) {\n counts.length += 1\n issues.push({\n category: 'length',\n detail: `too short (${output.length} < ${config.minLength})`,\n })\n } else if (output.length > config.maxLength) {\n counts.length += 1\n issues.push({\n category: 'length',\n detail: `too long (${output.length} > ${config.maxLength})`,\n })\n }\n }\n\n // Score: 10 minus weighted violations, clamped. Each violation of category c\n // subtracts `penaltyWeights[c]` points. Violations beyond 10/weight saturate.\n let penalty = 0\n for (const cat of Object.keys(counts) as SlopCategory[]) {\n penalty += counts[cat] * (config.penaltyWeights[cat] ?? 1)\n }\n const score = Math.max(0, Math.min(10, 10 - penalty))\n\n return { score, issues, counts }\n}\n\nfunction snippet(source: string, at: number, len: number): string {\n const pad = 24\n const start = Math.max(0, at - pad)\n const end = Math.min(source.length, at + len + pad)\n return (start > 0 ? '…' : '') + source.slice(start, end) + (end < source.length ? '…' : '')\n}\n\nfunction splitSentences(text: string): string[] {\n // Simple sentence split — good enough for slop detection; not linguistically perfect.\n return text\n .split(/[.!?\\n]+/)\n .map((s) => s.trim())\n .filter((s) => s.length > 0)\n}\n\nfunction normalizeForDupe(s: string): string {\n return s\n .toLowerCase()\n .replace(/\\s+/g, ' ')\n .replace(/[^a-z0-9 ]/g, '')\n .trim()\n}\n","/**\n * EvalTraceStore — JSONL save / query / compare over the analysis-time\n * `RunRecord` row.\n *\n * `FileSystemTraceStore` (in `./trace/store`) persists the rich TraceSchema-v1\n * span corpus — runs, spans, events, artifacts — the runtime emits live. That\n * is NOT the thing three consumers hand-roll in `tests/eval/lib/trace-store.ts`.\n * What they hand-roll is the *analysis* layer: append each finished run as one\n * JSONL line keyed by scenario/candidate, then query it (\"every run where score\n * < 50\"), pick the best run for a scenario (few-shot seeding), and compare two\n * candidates on matched scenarios.\n *\n * The substrate already has the canonical analysis-time row — `RunRecord` — so\n * this is that query/compare API expressed over `RunRecord[]`, with a\n * JSONL-backed store. It does NOT fork `FileSystemTraceStore`; it sits beside it\n * for the analysis projection.\n */\n\nimport { ValidationError } from './errors'\nimport { isRealnessGated, trainingScore } from './rollout/reward'\nimport { isRunRecord, type RunRecord, type RunSplitTag, validateRunRecord } from './run-record'\n\n/**\n * The score the query/compare layer ranks on: holdout when present, else\n * search, with the anti-Goodhart gate applied — a run flagged as gamed reads 0\n * however high it claims to have scored.\n *\n * The gate is load-bearing here and this function did not previously apply it,\n * despite saying it did. `getBest` is few-shot exemplar selection: whatever it\n * returns is pasted into the next agent's prompt as an example to imitate.\n * Ranking on the raw number handed the highest-scoring gamed trajectory to\n * every subsequent run — propagation through the context window rather than\n * through a gradient, but propagation all the same.\n *\n * Analysis that needs to SEE the inflated number (reward-hack detection,\n * per-run reporting) reads `observedScore` from `rollout/reward.ts` directly.\n *\n * Returns `undefined` for an execution-only record (neither score present):\n * such rows are valid RunRecords, but cannot participate in score-ranked\n * queries. A gated run still reads 0 — the gate's verdict is a number, never\n * a gap.\n */\nexport function runScore(record: RunRecord): number | undefined {\n return trainingScore(record)\n}\n\nexport interface RunRecordFilter {\n experimentId?: string\n candidateId?: string\n scenarioId?: string\n model?: string\n splitTag?: RunSplitTag\n /** Inclusive lower bound on `runScore`. */\n minScore?: number\n /** Inclusive upper bound on `runScore`. */\n maxScore?: number\n /** Match a single tag in `outcome.raw` by exact numeric value. */\n rawEquals?: { key: string; value: number }\n /** Custom predicate, ANDed with the structured filters. */\n where?: (record: RunRecord) => boolean\n}\n\nfunction matches(record: RunRecord, f: RunRecordFilter): boolean {\n if (f.experimentId && record.experimentId !== f.experimentId) return false\n if (f.candidateId && record.candidateId !== f.candidateId) return false\n if (f.scenarioId && record.scenarioId !== f.scenarioId) return false\n if (f.model && record.model !== f.model) return false\n if (f.splitTag && record.splitTag !== f.splitTag) return false\n if (f.minScore !== undefined || f.maxScore !== undefined) {\n const score = runScore(record)\n if (score === undefined) return false\n if (f.minScore !== undefined && score < f.minScore) return false\n if (f.maxScore !== undefined && score > f.maxScore) return false\n }\n if (f.rawEquals && record.outcome.raw[f.rawEquals.key] !== f.rawEquals.value) return false\n if (f.where && !f.where(record)) return false\n return true\n}\n\nexport interface CandidateComparison {\n a: string\n b: string\n /** Scenario ids present for BOTH candidates — the paired comparison set. */\n pairedScenarioIds: string[]\n /** Mean `runScore` for candidate a over the paired scenarios. */\n meanA: number\n /** Mean `runScore` for candidate b over the paired scenarios. */\n meanB: number\n /** meanB − meanA. Positive ⇒ b scored higher on the matched scenarios. */\n meanDelta: number\n /** Scenarios where b beat a (strictly), tied, and a beat b. */\n bWins: number\n ties: number\n aWins: number\n /**\n * Runs of either candidate excluded from the comparison because the\n * authenticity gate flagged them (`outcome.realness.gated`).\n *\n * Excluded rather than scored 0: `runScore` is gated, so leaving them in\n * would have entered a gamed run as a silent zero, which reads as \"this\n * candidate failed the scenario\" when what happened is \"this candidate's\n * result is not evidence\". A non-zero count here is itself the finding — a\n * comparison drawn over a shrunken scenario set has to say so.\n */\n realnessGatedRuns: number\n}\n\n/**\n * Backing persistence for `EvalTraceStore`. The in-memory store is the default;\n * the JSONL file store appends one validated `RunRecord` per line. Both keep an\n * append order so `getBest` / `compareRuns` are reproducible.\n */\nexport interface RunRecordBackend {\n append(record: RunRecord): Promise<void>\n load(): Promise<RunRecord[]>\n}\n\nexport function inMemoryRunRecordBackend(initial: RunRecord[] = []): RunRecordBackend {\n const rows = initial.map((r) => validateRunRecord(r))\n return {\n async append(record) {\n rows.push(record)\n },\n async load() {\n return [...rows]\n },\n }\n}\n\n/**\n * JSONL-backed store at `path`, one `RunRecord` per line. Malformed lines fail\n * loud on load (a corrupt corpus must not silently shrink the analysis set);\n * pass `skipInvalid` only for forensics on a known-bad file.\n */\nexport function jsonlRunRecordBackend(\n path: string,\n opts: { skipInvalid?: boolean } = {},\n): RunRecordBackend {\n return {\n async append(record) {\n const fs = await import('node:fs/promises')\n const pathMod = await import('node:path')\n await fs.mkdir(pathMod.dirname(path), { recursive: true })\n await fs.appendFile(path, `${JSON.stringify(record)}\\n`, 'utf8')\n },\n async load() {\n const fs = await import('node:fs/promises')\n let raw: string\n try {\n raw = await fs.readFile(path, 'utf8')\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') return []\n throw err\n }\n const out: RunRecord[] = []\n let lineNo = 0\n for (const line of raw.split('\\n')) {\n lineNo++\n if (!line.trim()) continue\n let parsed: unknown\n try {\n parsed = JSON.parse(line)\n } catch (err) {\n if (opts.skipInvalid) continue\n throw new ValidationError(`EvalTraceStore: ${path}:${lineNo} is not valid JSON`)\n }\n if (opts.skipInvalid) {\n if (isRunRecord(parsed)) out.push(parsed)\n continue\n }\n try {\n out.push(validateRunRecord(parsed))\n } catch (err) {\n throw new ValidationError(\n `EvalTraceStore: ${path}:${lineNo} is not a valid RunRecord — ${(err as Error).message}`,\n )\n }\n }\n return out\n },\n }\n}\n\n/**\n * Query / compare layer over a `RunRecord` corpus. Append finished runs, query\n * with a structured filter, take the best run for a scenario, and compare two\n * candidates on their matched scenarios. Persistence is injected via\n * `RunRecordBackend` (in-memory by default, JSONL file via\n * `jsonlRunRecordBackend`).\n */\nexport class EvalTraceStore {\n private readonly backend: RunRecordBackend\n\n constructor(backend: RunRecordBackend = inMemoryRunRecordBackend()) {\n this.backend = backend\n }\n\n /** Validate and append one run. Throws on an invalid record — the corpus\n * stays paper-grade. */\n async append(record: RunRecord): Promise<void> {\n await this.backend.append(validateRunRecord(record))\n }\n\n async all(): Promise<RunRecord[]> {\n return this.backend.load()\n }\n\n async query(filter: RunRecordFilter = {}): Promise<RunRecord[]> {\n const rows = await this.backend.load()\n return rows.filter((r) => matches(r, filter))\n }\n\n /**\n * Highest-scoring run for a scenario (optionally restricted to a candidate).\n * Returns null when no run matches. Ties resolve to the earliest-appended run\n * so the result is stable.\n *\n * Runs flagged as gamed are DROPPED, not zeroed. The caller's use for this is\n * few-shot seeding — the returned trajectory becomes an example to copy — so\n * the same rule as SFT applies: a faked success must not be in the candidate\n * set at all. When every run for the scenario is gated the honest answer is\n * `null` (no exemplar), never the least-bad fake.\n */\n async getBest(\n scenarioId: string,\n opts: { candidateId?: string; splitTag?: RunSplitTag } = {},\n ): Promise<RunRecord | null> {\n const rows = (\n await this.query({\n scenarioId,\n candidateId: opts.candidateId,\n splitTag: opts.splitTag,\n })\n ).filter((r) => !isRealnessGated(r))\n const scored = rows.flatMap((record) => {\n const score = runScore(record)\n return score === undefined ? [] : [{ record, score }]\n })\n if (scored.length === 0) return null\n let best = scored[0]!.record\n let bestScore = scored[0]!.score\n for (let i = 1; i < scored.length; i++) {\n const s = scored[i]!.score\n if (s > bestScore) {\n best = scored[i]!.record\n bestScore = s\n }\n }\n return best\n }\n\n /**\n * Compare two candidates on the scenarios they BOTH ran. When a candidate\n * ran a scenario more than once, its best `runScore` for that scenario is\n * used. Throws when there is no paired scenario — an unpaired \"comparison\" is\n * not one.\n *\n * Realness-gated runs are excluded and counted in `realnessGatedRuns`, never\n * folded in as a zero.\n */\n async compareRuns(candidateA: string, candidateB: string): Promise<CandidateComparison> {\n if (candidateA === candidateB) {\n throw new ValidationError(\n `EvalTraceStore.compareRuns: candidates must differ (\"${candidateA}\")`,\n )\n }\n const rows = await this.backend.load()\n let realnessGatedRuns = 0\n const bestByScenario = (candidate: string): Map<string, number> => {\n const m = new Map<string, number>()\n for (const r of rows) {\n if (r.candidateId !== candidate) continue\n const sid = r.scenarioId\n if (!sid) continue\n if (isRealnessGated(r)) {\n realnessGatedRuns++\n continue\n }\n const s = runScore(r)\n if (s === undefined) continue\n const prev = m.get(sid)\n if (prev === undefined || s > prev) m.set(sid, s)\n }\n return m\n }\n const aScores = bestByScenario(candidateA)\n const bScores = bestByScenario(candidateB)\n const paired = [...aScores.keys()].filter((sid) => bScores.has(sid)).sort()\n if (paired.length === 0) {\n // Distinguish \"the corpora never overlapped\" from \"they overlap, but\n // every shared scenario lost a side to the realness gate\" — the second\n // diagnosis points at gamed runs, not at a mislabeled corpus.\n throw new ValidationError(\n realnessGatedRuns > 0\n ? `EvalTraceStore.compareRuns: \"${candidateA}\" and \"${candidateB}\" share no scenario ` +\n `with honest runs on both sides (${realnessGatedRuns} run(s) were realness-gated)`\n : `EvalTraceStore.compareRuns: \"${candidateA}\" and \"${candidateB}\" share no scenario (need scenarioId on records)`,\n )\n }\n let sumA = 0\n let sumB = 0\n let bWins = 0\n let aWins = 0\n let ties = 0\n for (const sid of paired) {\n const sa = aScores.get(sid)!\n const sb = bScores.get(sid)!\n sumA += sa\n sumB += sb\n if (sb > sa) bWins++\n else if (sb < sa) aWins++\n else ties++\n }\n const meanA = sumA / paired.length\n const meanB = sumB / paired.length\n return {\n a: candidateA,\n b: candidateB,\n pairedScenarioIds: paired,\n meanA,\n meanB,\n meanDelta: meanB - meanA,\n bWins,\n ties,\n aWins,\n realnessGatedRuns,\n }\n }\n}\n","/**\n * Backend preflight: verify the models a campaign is about to spend tokens\n * against are actually served by the router BEFORE the run starts. The PRE-hoc\n * complement to `assertRealBackend` (which inspects RunRecords AFTER the run to\n * catch a stub/unconfigured backend).\n *\n * Two checks, increasing in cost:\n * - membership (free): GET `{baseUrl}/models` once; a model is `listed` when\n * its id is in the served set.\n * - probe (spends a tiny number of tokens): POST `{baseUrl}/chat/completions`\n * per model with a 1-message, `PROBE_MAX_TOKENS`-token request; `served` is\n * whether the router reached a provider, with the HTTP `status` and the\n * body's `error.message` captured in `detail`, and `servedModel` recording\n * WHICH model answered.\n *\n * A 2xx is not proof the requested model answered — a gateway can accept one\n * id and route to another. The probe therefore compares the echoed id against\n * the requested one and reports `substitution`; `assertModelsServed` fails on\n * a substituted id exactly as it fails on a dead one, because a campaign that\n * runs on a silently-swapped model produces per-model numbers about a model it\n * never called.\n *\n * A default model the router cannot serve is a config bug. Gate a campaign on\n * `assertModelsServed` and it surfaces every dead or substituted id with its\n * status + detail instead of silently producing a stub or mislabelled run.\n */\n\nimport { AgentEvalError, ConfigError } from '../errors'\nimport {\n checkServedModel,\n PROBE_MAX_TOKENS,\n type ServedModelCheck,\n servedModelAcceptable,\n} from './served-model'\n\n/**\n * Provider signature for \"the budget ran out before an answer\". The model is\n * alive — a provider took the request and consumed the budget — so this must\n * never be scored as a dead id.\n */\nconst REASONING_BUDGET_EXHAUSTED = /reasoning[\\s_-]?budget[\\s_-]?exhausted/i\n\nexport interface ModelPreflight {\n /** The model id as supplied by the caller. */\n model: string\n /** Membership in the `{baseUrl}/models` served set. */\n listed: boolean\n /**\n * The router reached a provider for this model. `null` when `probe` was not\n * requested. True on a 2xx, and also when the provider answered by\n * exhausting its reasoning budget — that proves reachability while leaving\n * identity unproven (see `budgetExhausted`).\n */\n served: boolean | null\n /** HTTP status of the probe. `null` when not probed. */\n status: number | null\n /** Probe body's `error.message` when present, else `null`. */\n detail: string | null\n /**\n * The probe died on the token budget rather than on the model. Identity is\n * unproven, not refuted: raise `probeMaxTokens` to resolve it.\n */\n budgetExhausted: boolean\n /**\n * Identity of the model that answered the probe, compared against `model`.\n * `null` when the model was not probed or the probe failed.\n */\n substitution: ServedModelCheck | null\n}\n\nexport interface PreflightModelsOptions {\n /** Router base URL, e.g. `https://router.tangle.tools/v1`. Trailing slash tolerated. */\n baseUrl: string\n /** Bearer token sent as `Authorization: Bearer <apiKey>`. */\n apiKey: string\n /** Model ids to check. */\n models: string[]\n /** When true, additionally spend a small chat probe per model. Default false. */\n probe?: boolean\n /**\n * Output-token budget per probe. Default `PROBE_MAX_TOKENS`. Lowering it\n * below the reasoning floor makes healthy reasoning models report\n * `budgetExhausted` instead of proving their identity.\n */\n probeMaxTokens?: number\n /** Injectable fetch for tests; defaults to the global. */\n fetchImpl?: typeof fetch\n}\n\nexport interface PreflightOutcome {\n succeeded: boolean\n value: ModelPreflight[] | null\n error: string | null\n}\n\ninterface ModelsListBody {\n data?: ReadonlyArray<{ id?: unknown }>\n}\n\ninterface ChatErrorBody {\n error?: { message?: unknown }\n message?: unknown\n}\n\ninterface ChatProbeBody {\n model?: unknown\n}\n\nfunction stripSlash(url: string): string {\n return url.replace(/\\/+$/, '')\n}\n\n/** Extract `error.message` (then top-level `message`) from a chat-completions error body. */\nfunction errorMessage(body: unknown): string | null {\n if (body == null || typeof body !== 'object') return null\n const b = body as ChatErrorBody\n if (b.error && typeof b.error.message === 'string') return b.error.message\n if (typeof b.message === 'string') return b.message\n return null\n}\n\n/**\n * Check that `models` are reachable on the router. Returns a typed outcome —\n * a network failure yields `{ succeeded: false, error }`, never a throw and\n * never a partial result silently reported as success. No retries, no\n * fallbacks.\n *\n * The membership check (one GET) always runs. When `probe` is true, each model\n * additionally gets a small chat probe so a model that is listed but\n * unconfigured (a 401 `model_not_found` from the router) is caught.\n */\nexport async function preflightModels(opts: PreflightModelsOptions): Promise<PreflightOutcome> {\n const fetchImpl = opts.fetchImpl ?? fetch\n const baseUrl = stripSlash(opts.baseUrl)\n const authHeaders = { authorization: `Bearer ${opts.apiKey}` }\n const maxTokens = opts.probeMaxTokens ?? PROBE_MAX_TOKENS\n if (!Number.isInteger(maxTokens) || maxTokens <= 0) {\n return {\n succeeded: false,\n value: null,\n error: `preflightModels: probeMaxTokens must be a positive integer, got ${maxTokens}`,\n }\n }\n\n let served: Set<string>\n try {\n const res = await fetchImpl(`${baseUrl}/models`, { method: 'GET', headers: authHeaders })\n if (!res.ok) {\n const text = await res.text().catch(() => '')\n return {\n succeeded: false,\n value: null,\n error: `preflightModels: GET ${baseUrl}/models → ${res.status} ${text.slice(0, 400)}`,\n }\n }\n const body = (await res.json()) as ModelsListBody\n const ids = Array.isArray(body.data) ? body.data : []\n served = new Set(ids.map((m) => m.id).filter((id): id is string => typeof id === 'string'))\n } catch (err) {\n return {\n succeeded: false,\n value: null,\n error: `preflightModels: GET ${baseUrl}/models failed — ${err instanceof Error ? err.message : String(err)}`,\n }\n }\n\n const results: ModelPreflight[] = []\n for (const model of opts.models) {\n const listed = served.has(model)\n if (!opts.probe) {\n results.push({\n model,\n listed,\n served: null,\n status: null,\n detail: null,\n budgetExhausted: false,\n substitution: null,\n })\n continue\n }\n try {\n const res = await fetchImpl(`${baseUrl}/chat/completions`, {\n method: 'POST',\n headers: { ...authHeaders, 'content-type': 'application/json' },\n body: JSON.stringify({\n model,\n messages: [{ role: 'user', content: 'ping' }],\n max_tokens: maxTokens,\n }),\n })\n let detail: string | null = null\n let substitution: ServedModelCheck | null = null\n let budgetExhausted = false\n const body = await res.json().catch(() => null)\n if (res.ok) {\n const echoed = (body as ChatProbeBody | null)?.model\n substitution = checkServedModel(\n model,\n typeof echoed === 'string' && echoed.trim() !== '' ? echoed : null,\n )\n } else {\n detail = errorMessage(body)\n budgetExhausted = detail !== null && REASONING_BUDGET_EXHAUSTED.test(detail)\n // The provider took the request and burned the budget, so the id is\n // live. It echoed no model, so identity stays unproven and the default\n // `allowUnreported: false` still refuses the run.\n if (budgetExhausted) substitution = checkServedModel(model, null)\n }\n results.push({\n model,\n listed,\n served: res.ok || budgetExhausted,\n status: res.status,\n detail,\n budgetExhausted,\n substitution,\n })\n } catch (err) {\n return {\n succeeded: false,\n value: null,\n error: `preflightModels: probe POST ${baseUrl}/chat/completions (model ${model}) failed — ${err instanceof Error ? err.message : String(err)}`,\n }\n }\n }\n\n return { succeeded: true, value: results, error: null }\n}\n\nexport class ModelsUnreachableError extends AgentEvalError {\n constructor(\n message: string,\n public readonly results: ReadonlyArray<ModelPreflight>,\n ) {\n super('config', message)\n this.name = 'ModelsUnreachableError'\n }\n}\n\nfunction describeFailure(r: ModelPreflight): string {\n if (!r.listed) {\n const probeNote =\n r.served === false ? ` (probe ${r.status}${r.detail ? `: ${r.detail}` : ''})` : ''\n return `${r.model}: not in /models${probeNote}`\n }\n if (r.served === false) {\n return `${r.model}: listed but probe ${r.status}${r.detail ? ` — ${r.detail}` : ''}`\n }\n if (r.budgetExhausted) {\n return (\n `${r.model}: alive but the probe ran out of reasoning budget (status ${r.status}` +\n `${r.detail ? `: ${r.detail}` : ''}) — it echoed no model id, so identity is unproven. ` +\n 'Raise probeMaxTokens, or pass allowUnreported to accept reachability without identity.'\n )\n }\n // listed, probe 2xx — but a different model answered\n const s = r.substitution\n if (s?.verdict === 'unreported') {\n return `${r.model}: probe answered without echoing a model id — identity unproven`\n }\n return `${r.model}: probe answered by ${s?.served} (${s?.verdict})`\n}\n\nexport interface AssertModelsServedOptions extends PreflightModelsOptions {\n /**\n * Accept a probe answered by a different model of the same provider family.\n * Default false. Only meaningful with `probe: true`.\n */\n allowWithinFamily?: boolean\n /**\n * Accept a probe whose response echoed no model id. Default false — an\n * unidentified response cannot prove the requested model is the one running.\n */\n allowUnreported?: boolean\n}\n\n/**\n * Throw `ModelsUnreachableError` naming EVERY model that is unusable for a\n * measured run — with status, detail, and served identity per model. A model\n * is unusable when it is unlisted, when its probe fails, or when its probe is\n * answered by a different model than the one requested. Callers gate a\n * campaign on this before spending tokens. When the network call itself fails\n * the underlying outcome error is rethrown — there is no partial silent pass.\n *\n * Substitution is only detectable with `probe: true`; a membership-only check\n * proves an id is in the catalogue, never that the catalogue entry answers.\n */\nexport async function assertModelsServed(\n opts: AssertModelsServedOptions,\n): Promise<ModelPreflight[]> {\n const outcome = await preflightModels(opts)\n if (!outcome.succeeded || outcome.value === null) {\n throw new ConfigError(\n outcome.error ?? 'assertModelsServed: preflight failed without an error message',\n )\n }\n const bad = outcome.value.filter(\n (r) =>\n !r.listed ||\n r.served === false ||\n (r.substitution !== null && !servedModelAcceptable(r.substitution, opts)),\n )\n if (bad.length > 0) {\n throw new ModelsUnreachableError(\n `assertModelsServed: ${bad.length}/${outcome.value.length} model(s) unusable on the router — ${bad\n .map(describeFailure)\n .join('; ')}`,\n outcome.value,\n )\n }\n return outcome.value\n}\n","/**\n * ModelSeats — the program's model seating chart.\n *\n * One object names which model fills each role in an eval program: the worker\n * under evaluation, the judge panel, the analyst, the reflection/driver model,\n * and the verifier. Re-tiering an entire program (economy ↔ frontier) is one\n * swapped object instead of a hunt through call sites.\n *\n * Wiring points — consumers thread seats; this module implements none of them\n * (those files belong to other surfaces):\n * - `judges` → `ensembleJudge({ models: seats.judges, … })` (src/judge-panel.ts)\n * and the `JudgeConfig`s handed to `makeEvalTools({ judges })`\n * (src/eval-tools.ts).\n * - `reflection` → the model configured by a custom `SurfaceProposer` or\n * external optimization engine.\n * - `worker` → the dispatch model the agent itself calls — the model an\n * `AgentProfile` declares.\n * - `analyst` → the LLM behind `analyzeRuns` / analyst-registry kinds.\n * - `verifier` → completion-verifier / objective-checker model.\n * - campaign cells thread `judges` + driver models the same way; that wiring\n * lands with the campaign surface, not here.\n *\n * `resolveSeat` is the only read path: an unset seat with no explicit fallback\n * throws — a model id is a budget decision, never a silent default.\n */\n\nimport { ConfigError, ValidationError } from './errors'\n\nexport interface ModelSeats {\n /** The model under evaluation — what the agent itself dispatches with. */\n worker?: string\n /** Judge-panel model ids — thread into `ensembleJudge({ models })`. */\n judges?: string[]\n /** Analyst model — `analyzeRuns` / analyst-registry LLM calls. */\n analyst?: string\n /** Reflection or candidate-generation model. */\n reflection?: string\n /** Verifier model — completion/objective checking. */\n verifier?: string\n}\n\nexport type SeatName = keyof ModelSeats\n\nexport type SeatPresetName = keyof typeof seatPresets\n\n/**\n * Tier presets — plain data, swap or spread freely.\n *\n * A preset names REQUESTED ids, and a requested id is NOT a guarantee of\n * family, of provider, or of liveness. A routing gateway can accept any id\n * below and answer from a different model on HTTP 200, with only the response\n * body's `model` field betraying the swap. The served assertion is the\n * guarantee: gate a run on `assertModelsServed({ probe: true })` and assert\n * `assertServedModel` per call. `assertCrossFamily` over these ids proves the\n * configuration is diverse; only `assertCrossFamilyServed` over the ids that\n * ANSWERED proves the run was.\n *\n * `economy` names ids a live router probe answered from the provider their\n * name implies, so the judge trio spanned three provider families (deepseek /\n * zhipu / google) as configured and, at that probe, as served. A preset is\n * only as good as its last probe: ids go dead and start resolving elsewhere\n * without notice, so re-probe rather than trusting this list.\n *\n * `frontier` is deliberately EMPTY: entitled frontier ids vary per router\n * account, and a hardcoded claude/gpt-5 id 401s on keys that lack it. Supply\n * your own: `{ ...seatPresets.frontier, worker: '<your-frontier-id>', … }` —\n * `resolveSeat` throws on every seat you haven't filled.\n */\nexport const seatPresets: Record<'economy' | 'frontier', ModelSeats> = {\n economy: {\n worker: 'zai/glm-5.2',\n judges: ['deepseek-v4-pro', 'zai/glm-5.2', 'google/gemini-2.5-flash'],\n analyst: 'zai/glm-5.2',\n reflection: 'zai/glm-5.2',\n verifier: 'deepseek-v4-pro',\n },\n frontier: {},\n}\n\n/** Thrown by `resolveSeat` when a seat is unset and no fallback was given. */\nexport class SeatUnsetError extends ConfigError {\n constructor(public readonly seat: SeatName) {\n super(\n `ModelSeats: seat '${seat}' is unset and no fallback was given — ` +\n 'name a model explicitly (a model id is a budget decision, never a silent default)',\n )\n }\n}\n\n/**\n * Read one seat. Blank strings and empty arrays count as unset (env-var\n * plumbing produces them); malformed values (non-string seat, non-array or\n * blank-entry `judges`) throw `ValidationError`. When the seat is unset, an\n * explicit `fallback` is returned (`[fallback]` for `judges` — a one-model\n * panel); without one, `SeatUnsetError`.\n */\nexport function resolveSeat(seats: ModelSeats, seat: 'judges', fallback?: string): string[]\nexport function resolveSeat(\n seats: ModelSeats,\n seat: Exclude<SeatName, 'judges'>,\n fallback?: string,\n): string\nexport function resolveSeat(seats: ModelSeats, seat: SeatName, fallback?: string): string | string[]\nexport function resolveSeat(\n seats: ModelSeats,\n seat: SeatName,\n fallback?: string,\n): string | string[] {\n const value = seats[seat]\n if (seat === 'judges') {\n if (value !== undefined && !Array.isArray(value)) {\n throw new ValidationError(`ModelSeats: seat 'judges' must be a string[], got ${typeof value}`)\n }\n const models = Array.isArray(value) ? value : []\n if (models.length > 0) {\n const blank = models.findIndex((m) => typeof m !== 'string' || m.trim() === '')\n if (blank >= 0) {\n throw new ValidationError(\n `ModelSeats: judges[${blank}] is blank — every panel model must be a non-empty id`,\n )\n }\n return [...models]\n }\n } else {\n if (value !== undefined && typeof value !== 'string') {\n throw new ValidationError(`ModelSeats: seat '${seat}' must be a string, got ${typeof value}`)\n }\n if (typeof value === 'string' && value.trim() !== '') return value\n }\n if (fallback !== undefined) {\n if (fallback.trim() === '') {\n throw new ValidationError(`ModelSeats: fallback for seat '${seat}' is blank`)\n }\n return seat === 'judges' ? [fallback] : fallback\n }\n throw new SeatUnsetError(seat)\n}\n","/**\n * Versioned prompt registry.\n *\n * Every prompt used in an eval run is registered with an explicit version.\n * Reports include the content hash so A/B compares are rigorous: if the\n * hash changes between two reports, the prompt actually changed; if it\n * matches, the variance is elsewhere.\n *\n * Hash is SHA-256(content), truncated to 12 hex chars for readability.\n * Uses the Web Crypto API (works in Workers, Node 22+, browsers).\n */\n\nexport interface PromptHandle {\n /** Stable human-readable id, e.g. 'browser.system' */\n id: string\n /** Caller-chosen version string, e.g. 'v3' or '2026-04-20' */\n version: string\n /** SHA-256 of content, 12-hex-char prefix */\n hash: string\n /** Full prompt body */\n content: string\n}\n\nexport class PromptRegistry {\n private readonly entries = new Map<string, PromptHandle>() // `${id}@${version}` → handle\n\n /**\n * Register a prompt. Re-registering the same id+version with DIFFERENT\n * content throws — versions are immutable. Re-registering with the SAME\n * content is a no-op (idempotent).\n */\n async register(id: string, version: string, content: string): Promise<PromptHandle> {\n validateId(id)\n validateVersion(version)\n\n const key = makeKey(id, version)\n const hash = await hashContent(content)\n const existing = this.entries.get(key)\n if (existing) {\n if (existing.hash !== hash) {\n throw new Error(\n `Prompt ${key} already registered with a different hash (${existing.hash} vs ${hash}). Bump the version.`,\n )\n }\n return existing\n }\n const handle: PromptHandle = { id, version, hash, content }\n this.entries.set(key, handle)\n return handle\n }\n\n /** Look up a registered prompt. Throws if unknown — no implicit defaults. */\n get(id: string, version: string): PromptHandle {\n const key = makeKey(id, version)\n const handle = this.entries.get(key)\n if (!handle) throw new Error(`Prompt ${key} not registered`)\n return handle\n }\n\n /** Return all versions of an id, newest-first (lex-descending on version). */\n listVersions(id: string): PromptHandle[] {\n return [...this.entries.values()]\n .filter((h) => h.id === id)\n .sort((a, b) => b.version.localeCompare(a.version))\n }\n\n /** Snapshot the whole registry — useful for including in reports. */\n list(): PromptHandle[] {\n return [...this.entries.values()]\n }\n\n /** Verify a hash against registered content. Returns null if not found. */\n verifyHash(id: string, version: string, expectedHash: string): boolean | null {\n const handle = this.entries.get(makeKey(id, version))\n if (!handle) return null\n return handle.hash === expectedHash\n }\n}\n\n/** SHA-256(content) → first 12 hex chars. Stable across runtimes. */\nexport async function hashContent(content: string): Promise<string> {\n const bytes = new TextEncoder().encode(content)\n const digest = await crypto.subtle.digest('SHA-256', bytes)\n const full = Array.from(new Uint8Array(digest))\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('')\n return full.slice(0, 12)\n}\n\nfunction makeKey(id: string, version: string): string {\n return `${id}@${version}`\n}\n\nconst ID_RE = /^[a-z][a-z0-9._-]*$/i\nfunction validateId(id: string): void {\n if (!ID_RE.test(id)) {\n throw new Error(`Invalid prompt id \"${id}\": must match ${ID_RE}`)\n }\n}\n\nfunction validateVersion(version: string): void {\n if (!version || version.length > 64) {\n throw new Error(`Invalid version \"${version}\": must be 1–64 chars`)\n }\n}\n","import { aggregateRunScore, type RunScore, type RunScoreWeights } from './run-score'\nimport type { SteeringBundle } from './steering'\n\nexport type SteeringOptimizerBackend = 'pairwise'\n\nexport interface SteeringOptimizationRow {\n variantId: string\n scenarioId: string\n bundle: SteeringBundle\n score: RunScore\n metadata?: Record<string, unknown>\n}\n\nexport interface SteeringOptimizationSelector {\n backend: SteeringOptimizerBackend\n signature?: string\n labels?: string[]\n rationale?: string\n}\n\nexport interface SteeringOptimizationResult {\n backend: SteeringOptimizerBackend\n recommendedVariantId: string\n rationale: string\n rankings: Array<{ variantId: string; mean: number; runs: number }>\n selector?: SteeringOptimizationSelector\n skipped?: boolean\n}\n\nexport interface SteeringOptimizerConfig {\n weights?: Partial<RunScoreWeights>\n}\n\n/**\n * Rank already-evaluated steering variants.\n *\n * Model-backed candidate generation belongs to the official GEPA campaign\n * integration. This class only performs the deterministic selection it owns.\n */\nexport class PairwiseSteeringOptimizer {\n optimize(\n rows: SteeringOptimizationRow[],\n config: SteeringOptimizerConfig = {},\n ): SteeringOptimizationResult {\n const rankings = rankRows(rows, config.weights)\n if (rankings.length === 0) throw new Error('no steering optimization rows')\n return {\n backend: 'pairwise',\n recommendedVariantId: rankings[0]!.variantId,\n rationale: `Highest observed mean aggregate across ${rows.length} scored run(s).`,\n rankings,\n }\n }\n}\n\nfunction rankRows(\n rows: readonly SteeringOptimizationRow[],\n weights?: Partial<RunScoreWeights>,\n): Array<{ variantId: string; mean: number; runs: number }> {\n const buckets = new Map<string, number[]>()\n for (const row of rows) {\n const values = buckets.get(row.variantId) ?? []\n values.push(aggregateRunScore(row.score, weights))\n buckets.set(row.variantId, values)\n }\n return [...buckets.entries()]\n .map(([variantId, values]) => ({\n variantId,\n mean: values.reduce((sum, value) => sum + value, 0) / values.length,\n runs: values.length,\n }))\n .sort((a, b) => b.mean - a.mean)\n}\n"],"mappings":"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"}
|