@tangle-network/agent-eval 0.216.1 → 0.218.1
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 +137 -57
- package/README.md +2 -2
- package/dist/adapters/http.d.ts +2 -2
- package/dist/{agent-profile-VFcQncbW.d.ts → agent-profile-DTt8uGP9.d.ts} +4 -17
- package/dist/agent-profile-DTt8uGP9.d.ts.map +1 -0
- package/dist/{agent-profile-cell-BK8mlqlq.js → agent-profile-cell-B1V1gUZs.js} +4 -53
- package/dist/agent-profile-cell-B1V1gUZs.js.map +1 -0
- package/dist/{agent-profile-cell-BNp-Js9F.d.ts → agent-profile-cell-BcpFbNd5.d.ts} +2 -22
- package/dist/agent-profile-cell-BcpFbNd5.d.ts.map +1 -0
- package/dist/{agreement-irr-BEWLIF3_.js → agreement-irr-BhAqjluA.js} +5 -5
- package/dist/agreement-irr-BhAqjluA.js.map +1 -0
- package/dist/analyst/index.d.ts +36 -169
- package/dist/analyst/index.d.ts.map +1 -1
- package/dist/analyst/index.js +17 -192
- package/dist/analyst/index.js.map +1 -1
- package/dist/{analyze-runs-D68fd-su.d.ts → analyze-runs-DjlZOVXx.d.ts} +5 -5
- package/dist/{analyze-runs-D68fd-su.d.ts.map → analyze-runs-DjlZOVXx.d.ts.map} +1 -1
- package/dist/{analyze-runs-C84irm4i.js → analyze-runs-DqPJaJ4X.js} +225 -21
- package/dist/analyze-runs-DqPJaJ4X.js.map +1 -0
- package/dist/authenticity/index.d.ts +0 -23
- package/dist/authenticity/index.d.ts.map +1 -1
- package/dist/authenticity/index.js +1 -34
- package/dist/authenticity/index.js.map +1 -1
- package/dist/{benchmark-command-By0vh8q7.js → benchmark-command-BupdHRyf.js} +1225 -661
- package/dist/benchmark-command-BupdHRyf.js.map +1 -0
- package/dist/benchmarks/index.d.ts +5 -6
- package/dist/benchmarks/index.d.ts.map +1 -1
- package/dist/benchmarks/index.js +4 -4
- package/dist/benchmarks/index.js.map +1 -1
- package/dist/builder-eval/index.d.ts +3 -3
- package/dist/builder-eval/index.js +2 -2
- package/dist/builder-eval/index.js.map +1 -1
- package/dist/campaign/index.d.ts +7 -7
- package/dist/campaign/index.js +15 -15
- package/dist/{campaign-BudZ70zo.js → campaign-CGvUTnmc.js} +324 -800
- package/dist/campaign-CGvUTnmc.js.map +1 -0
- package/dist/{campaign-evidence-Clrn4hBV.js → campaign-evidence-DunzcJGv.js} +10 -18
- package/dist/{campaign-evidence-Clrn4hBV.js.map → campaign-evidence-DunzcJGv.js.map} +1 -1
- package/dist/{canonical-B2RqLofv.js → canonical-Dq2hOQ8L.js} +2 -2
- package/dist/{canonical-B2RqLofv.js.map → canonical-Dq2hOQ8L.js.map} +1 -1
- package/dist/cell-spend-DEWR3nj-.js +90 -0
- package/dist/cell-spend-DEWR3nj-.js.map +1 -0
- package/dist/{chat-client-l-MVDlDk.js → chat-client-B2pXlPdx.js} +2 -2
- package/dist/{chat-client-l-MVDlDk.js.map → chat-client-B2pXlPdx.js.map} +1 -1
- package/dist/{chat-json-call-puMArmtW.js → chat-json-call-Dm9c-b41.js} +3 -2
- package/dist/chat-json-call-Dm9c-b41.js.map +1 -0
- package/dist/{claim-q4HQhK1G.js → claim-BPVuyHuy.js} +3 -3
- package/dist/{claim-q4HQhK1G.js.map → claim-BPVuyHuy.js.map} +1 -1
- package/dist/cli.js +113 -12
- package/dist/cli.js.map +1 -1
- package/dist/{client-BzL9niqi.d.ts → client-hwo3cJjR.d.ts} +3 -16
- package/dist/client-hwo3cJjR.d.ts.map +1 -0
- package/dist/{cluster-bootstrap-qcUWYFl-.js → cluster-bootstrap-DEwwhl0C.js} +3 -3
- package/dist/{cluster-bootstrap-qcUWYFl-.js.map → cluster-bootstrap-DEwwhl0C.js.map} +1 -1
- package/dist/{produced-state-BsDmnwxc.js → completion-verifier-DbLVf3i8.js} +9 -64
- package/dist/completion-verifier-DbLVf3i8.js.map +1 -0
- package/dist/contract/index.d.ts +12 -12
- package/dist/contract/index.js +107 -403
- package/dist/contract/index.js.map +1 -1
- package/dist/{cost-ledger-BP8V4kUQ.js → cost-ledger-D0352Z4d.js} +4 -8
- package/dist/cost-ledger-D0352Z4d.js.map +1 -0
- package/dist/dataset-DQqhOCPt.d.ts.map +1 -1
- package/dist/{default-registry-COhk9g36.js → default-registry-BJ-Pq6yL.js} +314 -285
- package/dist/default-registry-BJ-Pq6yL.js.map +1 -0
- package/dist/{default-registry-DzHiGruW.d.ts → default-registry-DXgLmoDI.d.ts} +7 -50
- package/dist/default-registry-DXgLmoDI.d.ts.map +1 -0
- package/dist/{define-agent-eval-CNTPzIkp.js → define-agent-eval-BGdFKlrc.js} +170 -110
- package/dist/define-agent-eval-BGdFKlrc.js.map +1 -0
- package/dist/{define-agent-eval-WSck0CZJ.d.ts → define-agent-eval-BlH10zEw.d.ts} +8 -8
- package/dist/define-agent-eval-BlH10zEw.d.ts.map +1 -0
- package/dist/{descriptive-DboxPZrG.js → descriptive-CVNy48rR.js} +2 -2
- package/dist/{descriptive-DboxPZrG.js.map → descriptive-CVNy48rR.js.map} +1 -1
- package/dist/diagnosis/index.d.ts +4 -14
- package/dist/diagnosis/index.d.ts.map +1 -1
- package/dist/diagnosis/index.js +67 -28
- package/dist/diagnosis/index.js.map +1 -1
- package/dist/{dspy-rlm-engine-LRCu61m5.js → dspy-rlm-engine-CSMwudLO.js} +5 -10
- package/dist/dspy-rlm-engine-CSMwudLO.js.map +1 -0
- package/dist/{emitter-HcCmFQl_.d.ts → emitter-DABYYTcH.d.ts} +5 -5
- package/dist/emitter-DABYYTcH.d.ts.map +1 -0
- package/dist/emitter-DbMXUIVP.js.map +1 -1
- package/dist/{engine-3A_4jOlI.d.ts → engine-BvZ0R-36.d.ts} +17 -21
- package/dist/engine-BvZ0R-36.d.ts.map +1 -0
- package/dist/{equal-terms-BtdXayCJ.js → equal-terms-DbPGcVtI.js} +2 -2
- package/dist/equal-terms-DbPGcVtI.js.map +1 -0
- package/dist/{errors-DVZiqS7K.js → errors-BcOs5MKW.js} +2 -8
- package/dist/{errors-DVZiqS7K.js.map → errors-BcOs5MKW.js.map} +1 -1
- package/dist/eval-campaign-BUMIxKTE.js +393 -0
- package/dist/eval-campaign-BUMIxKTE.js.map +1 -0
- package/dist/{evaluation-6Yoi74gM.d.ts → evaluation-BOZ38vOH.d.ts} +7 -7
- package/dist/evaluation-BOZ38vOH.d.ts.map +1 -0
- package/dist/evaluation.d.ts +2 -2
- package/dist/evaluation.js +1 -1
- package/dist/evaluation.js.map +1 -1
- package/dist/{exact-types-ClugMJfI.d.ts → exact-types-CflbJ9f3.d.ts} +2 -2
- package/dist/{exact-types-ClugMJfI.d.ts.map → exact-types-CflbJ9f3.d.ts.map} +1 -1
- package/dist/{exec-ChJ6d5if.js → exec-CpbtOXVt.js} +2 -24
- package/dist/{exec-ChJ6d5if.js.map → exec-CpbtOXVt.js.map} +1 -1
- package/dist/execution-tracks-CpgFPpS5.js.map +1 -1
- package/dist/experiment/index.d.ts +9 -112
- package/dist/experiment/index.d.ts.map +1 -1
- package/dist/experiment/index.js +258 -311
- package/dist/experiment/index.js.map +1 -1
- package/dist/{exporters-X4xwla8A.js → exporters-DWvM16LE.js} +3 -3
- package/dist/exporters-DWvM16LE.js.map +1 -0
- package/dist/{exporters-ChTnR90l.d.ts → exporters-Dk3oEbK_.d.ts} +2 -4
- package/dist/{exporters-ChTnR90l.d.ts.map → exporters-Dk3oEbK_.d.ts.map} +1 -1
- package/dist/{external-optimizer-process-BjMGUuds.js → external-optimizer-process-C3Wm7Vhn.js} +4 -3
- package/dist/external-optimizer-process-C3Wm7Vhn.js.map +1 -0
- package/dist/{external-optimizer-subprocess-BqW0hHcI.js → external-optimizer-subprocess-B5gdLRZv.js} +9 -11
- package/dist/external-optimizer-subprocess-B5gdLRZv.js.map +1 -0
- package/dist/{extract-usage-BrnzRJ6H.js → extract-usage-BZLU01kR.js} +2 -23
- package/dist/{extract-usage-BrnzRJ6H.js.map → extract-usage-BZLU01kR.js.map} +1 -1
- package/dist/{failure-cluster-CbgEDcFJ.d.ts → failure-cluster-DN0t63Z0.d.ts} +4 -43
- package/dist/failure-cluster-DN0t63Z0.d.ts.map +1 -0
- package/dist/{failure-taxonomy-CjabTATj.js → failure-taxonomy-Bx5oWqaW.js} +2 -19
- package/dist/{failure-taxonomy-CjabTATj.js.map → failure-taxonomy-Bx5oWqaW.js.map} +1 -1
- package/dist/{feedback-trajectory-C4EG0nNH.d.ts → feedback-trajectory-BWmhRBGu.d.ts} +7 -9
- package/dist/feedback-trajectory-BWmhRBGu.d.ts.map +1 -0
- package/dist/{semantic-concept-judge-BQF8te0T.js → findings-store-BtTzPL0d.js} +9 -249
- package/dist/findings-store-BtTzPL0d.js.map +1 -0
- package/dist/fuzz.d.ts +19 -62
- package/dist/fuzz.d.ts.map +1 -1
- package/dist/fuzz.js +62 -108
- package/dist/fuzz.js.map +1 -1
- package/dist/{hf-dataset-BR2yhuNn.js → hf-dataset-CKxIJQba.js} +4 -24
- package/dist/hf-dataset-CKxIJQba.js.map +1 -0
- package/dist/hosted/index.d.ts +2 -2
- package/dist/hosted/index.js +2 -2
- package/dist/{index-CyszSg4O.d.ts → index-B16FNdW5.d.ts} +145 -360
- package/dist/index-B16FNdW5.d.ts.map +1 -0
- package/dist/{index-DV-jSzxF.d.ts → index-BLGqZ81N.d.ts} +10 -15
- package/dist/{index-DV-jSzxF.d.ts.map → index-BLGqZ81N.d.ts.map} +1 -1
- package/dist/{index-BO41eGj5.d.ts → index-CX-GAUpw.d.ts} +3 -7
- package/dist/index-CX-GAUpw.d.ts.map +1 -0
- package/dist/{index-DHKEAv3s.d.ts → index-CalAsXMR.d.ts} +8 -68
- package/dist/index-CalAsXMR.d.ts.map +1 -0
- package/dist/{index-BFRO6chs.d.ts → index-CiRwLv2R.d.ts} +5 -69
- package/dist/index-CiRwLv2R.d.ts.map +1 -0
- package/dist/{index-DPcngtwt.d.ts → index-DbMOXYnP.d.ts} +11 -36
- package/dist/index-DbMOXYnP.d.ts.map +1 -0
- package/dist/index.d.ts +211 -218
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +999 -1714
- package/dist/index.js.map +1 -1
- package/dist/{integrity-dLiDe2kD.js → integrity-C8oUeB0g.js} +326 -203
- package/dist/integrity-C8oUeB0g.js.map +1 -0
- package/dist/{integrity-BXOsAb3i.js → integrity-W4CADcFc.js} +3 -7
- package/dist/{integrity-BXOsAb3i.js.map → integrity-W4CADcFc.js.map} +1 -1
- package/dist/{integrity-DAMEDFaC.d.ts → integrity-_qgZLA5p.d.ts} +4 -6
- package/dist/{integrity-DAMEDFaC.d.ts.map → integrity-_qgZLA5p.d.ts.map} +1 -1
- package/dist/{internal-Epl-YBZW.js → internal-BTK91Bqt.js} +3 -3
- package/dist/{internal-Epl-YBZW.js.map → internal-BTK91Bqt.js.map} +1 -1
- package/dist/{interval-CELpye1n.js → interval-Dq9gt7jx.js} +3 -3
- package/dist/{interval-CELpye1n.js.map → interval-Dq9gt7jx.js.map} +1 -1
- package/dist/{journal-DfRz9kps.js → journal-C7om8Gum.js} +157 -147
- package/dist/journal-C7om8Gum.js.map +1 -0
- package/dist/json-BhdsJaOQ.js +111 -0
- package/dist/json-BhdsJaOQ.js.map +1 -0
- package/dist/{judge-calibration-BpCy5XQl.js → judge-calibration-BkXMIWA4.js} +3 -3
- package/dist/{judge-calibration-BpCy5XQl.js.map → judge-calibration-BkXMIWA4.js.map} +1 -1
- package/dist/{judge-gate-iY9s4L44.js → judge-gate-Co5tuh57.js} +4 -27
- package/dist/{judge-gate-iY9s4L44.js.map → judge-gate-Co5tuh57.js.map} +1 -1
- package/dist/{judge-gate-CE7CQAgt.d.ts → judge-gate-DsL0yFcb.d.ts} +8 -9
- package/dist/judge-gate-DsL0yFcb.d.ts.map +1 -0
- package/dist/{kind-factory-BobI5Jy3.js → kind-factory-Gy4fXixd.js} +88 -17
- package/dist/kind-factory-Gy4fXixd.js.map +1 -0
- package/dist/ledger-core/index.d.ts +2 -2
- package/dist/ledger-core/index.js +4 -4
- package/dist/ledger-core/lock-holder.d.ts +2 -0
- package/dist/ledger-core/lock-holder.js +181 -0
- package/dist/ledger-core/lock-holder.js.map +1 -0
- package/dist/{ledger-core-Gq7yp8lP.js → ledger-core-CAxUdDk0.js} +5 -84
- package/dist/ledger-core-CAxUdDk0.js.map +1 -0
- package/dist/{llm-client-CyBAoYiX.js → llm-client-_Y6ic-tf.js} +243 -355
- package/dist/llm-client-_Y6ic-tf.js.map +1 -0
- package/dist/{llm-judge-CG12SQJq.js → llm-judge-Djxh-Uhs.js} +662 -482
- package/dist/llm-judge-Djxh-Uhs.js.map +1 -0
- package/dist/lock-holder-DaJbfpci.d.ts +86 -0
- package/dist/lock-holder-DaJbfpci.d.ts.map +1 -0
- package/dist/matrix/index.d.ts +3 -3
- package/dist/matrix/index.js +3 -2
- package/dist/{matrix-Dm0BQW7U.js → matrix-B8l-Nsxd.js} +3 -88
- package/dist/matrix-B8l-Nsxd.js.map +1 -0
- package/dist/{matrix-DSrSxjjy.d.ts → matrix-CCSBna4q.d.ts} +9 -18
- package/dist/matrix-CCSBna4q.d.ts.map +1 -0
- package/dist/{mean-DHoMiudD.js → mean-BbA_JCzW.js} +39 -5
- package/dist/mean-BbA_JCzW.js.map +1 -0
- package/dist/meta-eval/index.d.ts +5 -5
- package/dist/meta-eval/index.js +10 -10
- package/dist/metrics-BKaPBtIG.js.map +1 -1
- package/dist/{mint-DNU8QPG4.d.ts → mint-BRZXuwRi.d.ts} +4 -4
- package/dist/{mint-DNU8QPG4.d.ts.map → mint-BRZXuwRi.d.ts.map} +1 -1
- package/dist/{mint-QaD5cA0u.js → mint-CbdwjTPW.js} +4 -4
- package/dist/{mint-QaD5cA0u.js.map → mint-CbdwjTPW.js.map} +1 -1
- package/dist/{multi-layer-verifier-BUaQ4C17.d.ts → multi-layer-verifier-DEgMUk6v.d.ts} +2 -2
- package/dist/{multi-layer-verifier-BUaQ4C17.d.ts.map → multi-layer-verifier-DEgMUk6v.d.ts.map} +1 -1
- package/dist/{multiplicity-DQUFcbW4.js → multiplicity-Sg0U7h8j.js} +2 -2
- package/dist/{multiplicity-DQUFcbW4.js.map → multiplicity-Sg0U7h8j.js.map} +1 -1
- package/dist/multishot/golden/index.d.ts +1 -23
- package/dist/multishot/golden/index.d.ts.map +1 -1
- package/dist/multishot/golden/index.js +3 -3
- package/dist/multishot/golden/index.js.map +1 -1
- package/dist/multishot/index.d.ts +3 -12
- package/dist/multishot/index.d.ts.map +1 -1
- package/dist/multishot/index.js +4 -3
- package/dist/multishot/index.js.map +1 -1
- package/dist/openapi.json +114 -10
- package/dist/{otel-spans-B9tUXRHF.js → otel-spans-CdN909k1.js} +3 -3
- package/dist/{otel-spans-B9tUXRHF.js.map → otel-spans-CdN909k1.js.map} +1 -1
- package/dist/{paired-arms-CwMGJsrS.js → paired-arms-Ct4LTKc1.js} +32 -9
- package/dist/paired-arms-Ct4LTKc1.js.map +1 -0
- package/dist/{paired-binary-CvpFHfKZ.js → paired-binary-B_nejA44.js} +3 -36
- package/dist/paired-binary-B_nejA44.js.map +1 -0
- package/dist/{paired-promotion-decision-DPKz8ZnF.d.ts → paired-promotion-decision-CQMJ5xGN.d.ts} +2 -34
- package/dist/paired-promotion-decision-CQMJ5xGN.d.ts.map +1 -0
- package/dist/{paired-promotion-decision-DsAPYGCm.js → paired-promotion-decision-D0SHb-ZL.js} +3 -3
- package/dist/{paired-promotion-decision-DsAPYGCm.js.map → paired-promotion-decision-D0SHb-ZL.js.map} +1 -1
- package/dist/{pareto-Cm6ndrWN.js → pareto-CTv8vozZ.js} +11 -11
- package/dist/pareto-CTv8vozZ.js.map +1 -0
- package/dist/pipelines/index.d.ts +16 -19
- package/dist/pipelines/index.d.ts.map +1 -1
- package/dist/pipelines/index.js +4 -68
- package/dist/pipelines/index.js.map +1 -1
- package/dist/{power-and-mde-Hj2ubb4B.js → power-and-mde-N5nU4_Ly.js} +3 -3
- package/dist/{power-and-mde-Hj2ubb4B.js.map → power-and-mde-N5nU4_Ly.js.map} +1 -1
- package/dist/{prime-protocol-CHKgA3a6.js → prime-protocol-BFgGrEMP.js} +3 -3
- package/dist/prime-protocol-BFgGrEMP.js.map +1 -0
- package/dist/{prime-protocol-HiB9HX7E.d.ts → prime-protocol-BWG2DQIk.d.ts} +3 -21
- package/dist/prime-protocol-BWG2DQIk.d.ts.map +1 -0
- package/dist/profile-cell.d.ts +2 -2
- package/dist/profile-cell.js +2 -2
- package/dist/{promotion-gate-BawrdPYr.d.ts → promotion-gate-CxEHRsZW.d.ts} +7 -8
- package/dist/{promotion-gate-BawrdPYr.d.ts.map → promotion-gate-CxEHRsZW.d.ts.map} +1 -1
- package/dist/{promotion-policy-KO57gbyV.js → promotion-policy-6A8osGr_.js} +4 -4
- package/dist/{promotion-policy-KO57gbyV.js.map → promotion-policy-6A8osGr_.js.map} +1 -1
- package/dist/{proposal-findings-CY1xKn_a.js → proposal-findings-n-5WBbEx.js} +3 -3
- package/dist/proposal-findings-n-5WBbEx.js.map +1 -0
- package/dist/{query-BUCZCK7F.js → query-B_RZ36an.js} +5 -5
- package/dist/query-B_RZ36an.js.map +1 -0
- package/dist/{query-DK1nWcmp.d.ts → query-Cmv_U8vf.d.ts} +4 -24
- package/dist/{query-DK1nWcmp.d.ts.map → query-Cmv_U8vf.d.ts.map} +1 -1
- package/dist/{random-ByUSnV9w.js → random-DDDcC7YU.js} +2 -2
- package/dist/{random-ByUSnV9w.js.map → random-DDDcC7YU.js.map} +1 -1
- package/dist/{raw-provider-sink-DoHz4JNG.js → raw-provider-sink-75w4FWBj.js} +2 -2
- package/dist/{raw-provider-sink-DoHz4JNG.js.map → raw-provider-sink-75w4FWBj.js.map} +1 -1
- package/dist/{redact-mtCCcT8z.d.ts → redact-DXdlFb_U.d.ts} +2 -3
- package/dist/redact-DXdlFb_U.d.ts.map +1 -0
- package/dist/{redact-B5xXKqQ3.js → redact-mtkTiJVk.js} +2 -7
- package/dist/{redact-B5xXKqQ3.js.map → redact-mtkTiJVk.js.map} +1 -1
- package/dist/{registry-D7_hm2fK.d.ts → registry-ssNoHzwD.d.ts} +4 -4
- package/dist/{registry-D7_hm2fK.d.ts.map → registry-ssNoHzwD.d.ts.map} +1 -1
- package/dist/{release-confidence-CpuP65S5.js → release-confidence-CYIFH-fp.js} +6 -11
- package/dist/release-confidence-CYIFH-fp.js.map +1 -0
- package/dist/{report-command-SC9nqb4M.js → render-Cs34y0iX.js} +625 -587
- package/dist/render-Cs34y0iX.js.map +1 -0
- package/dist/reporting.d.ts +6 -6
- package/dist/reporting.js +8 -8
- package/dist/{researcher-CEcfku-T.d.ts → researcher-GU1tV4dn.d.ts} +9 -9
- package/dist/{researcher-CEcfku-T.d.ts.map → researcher-GU1tV4dn.d.ts.map} +1 -1
- package/dist/{reward-CpCmAM8L.d.ts → reward-DrZ71vnf.d.ts} +3 -26
- package/dist/reward-DrZ71vnf.d.ts.map +1 -0
- package/dist/{reward-hacking-E0d-WVcP.js → reward-hacking-ByuETaIb.js} +3 -3
- package/dist/{reward-hacking-E0d-WVcP.js.map → reward-hacking-ByuETaIb.js.map} +1 -1
- package/dist/{reward-hacking-RVdZ6Kkt.d.ts → reward-hacking-E52wq86n.d.ts} +5 -18
- package/dist/reward-hacking-E52wq86n.d.ts.map +1 -0
- package/dist/reward-nw2xZGZG.js.map +1 -1
- package/dist/rl.d.ts +117 -295
- package/dist/rl.d.ts.map +1 -1
- package/dist/rl.js +27 -747
- package/dist/rl.js.map +1 -1
- package/dist/rollout/index.d.ts +5 -5
- package/dist/rollout/index.js +7 -8
- package/dist/{rollout-DZV1t2Wg.js → rollout-Dd1ucT_M.js} +88 -13
- package/dist/rollout-Dd1ucT_M.js.map +1 -0
- package/dist/{rubric-predictive-validity-DaFW70y9.js → rubric-predictive-validity-D3_oI72N.js} +3 -3
- package/dist/{rubric-predictive-validity-DaFW70y9.js.map → rubric-predictive-validity-D3_oI72N.js.map} +1 -1
- package/dist/{rubric-predictive-validity-C03EC7ZE.d.ts → rubric-predictive-validity-DiwT8PbL.d.ts} +2 -2
- package/dist/{rubric-predictive-validity-C03EC7ZE.d.ts.map → rubric-predictive-validity-DiwT8PbL.d.ts.map} +1 -1
- package/dist/{run-record-C1E24G2A.d.ts → run-record-CaxbLq6Y.d.ts} +4 -10
- package/dist/run-record-CaxbLq6Y.d.ts.map +1 -0
- package/dist/{run-record-C5e7FjhJ.js → run-record-CysKLB93.js} +3 -3
- package/dist/run-record-CysKLB93.js.map +1 -0
- package/dist/{run-record-Boc5IUTp.js → run-record-DhEJgoPz.js} +4 -4
- package/dist/{run-record-Boc5IUTp.js.map → run-record-DhEJgoPz.js.map} +1 -1
- package/dist/sandbox-harness-BlSOu4LX.d.ts.map +1 -1
- package/dist/{schema-CSf6qWgZ.js → schema-Bt2vLFm3.js} +2 -14
- package/dist/schema-Bt2vLFm3.js.map +1 -0
- package/dist/schema-C-ziyJD7.d.ts.map +1 -1
- package/dist/{schema-BuiujZ-g.js → schema-CvhfLjtZ.js} +78 -48
- package/dist/schema-CvhfLjtZ.js.map +1 -0
- package/dist/{schema-2g7trUwH.d.ts → schema-D6EVKzTB.d.ts} +4 -5
- package/dist/schema-D6EVKzTB.d.ts.map +1 -0
- package/dist/search/index.d.ts +3 -31
- package/dist/search/index.d.ts.map +1 -1
- package/dist/search/index.js +4 -4
- package/dist/{search-kernel-DyNEa6IU.d.ts → search-kernel-p9JB3SmL.d.ts} +10 -27
- package/dist/search-kernel-p9JB3SmL.d.ts.map +1 -0
- package/dist/{search-ledger-CVUGLDZp.js → search-ledger-ClpN4I3e.js} +7 -7
- package/dist/{search-ledger-CVUGLDZp.js.map → search-ledger-ClpN4I3e.js.map} +1 -1
- package/dist/{search-ledger-file-DDQUgvCg.js → search-ledger-file-Bd5Tioq6.js} +4 -4
- package/dist/search-ledger-file-Bd5Tioq6.js.map +1 -0
- package/dist/{search-shipper-BOSD46qv.js → search-shipper-Bg2HW3Uv.js} +4 -4
- package/dist/search-shipper-Bg2HW3Uv.js.map +1 -0
- package/dist/{search-summary-BQCSWf1g.js → search-summary-CrBuvVnf.js} +5 -5
- package/dist/{search-summary-BQCSWf1g.js.map → search-summary-CrBuvVnf.js.map} +1 -1
- package/dist/{sequential-CzK5DarL.js → sequential-BVv1sjsw.js} +2 -32
- package/dist/{sequential-CzK5DarL.js.map → sequential-BVv1sjsw.js.map} +1 -1
- package/dist/{sequential-Bf_pbE50.js → sequential-CimQrbjv.js} +5 -5
- package/dist/sequential-CimQrbjv.js.map +1 -0
- package/dist/{sequential-BhsrMupG.d.ts → sequential-KwGspfeR.d.ts} +2 -9
- package/dist/{sequential-BhsrMupG.d.ts.map → sequential-KwGspfeR.d.ts.map} +1 -1
- package/dist/{sequential-eprocess-DM_qENCl.js → sequential-eprocess-DodI6RoF.js} +2 -2
- package/dist/{sequential-eprocess-DM_qENCl.js.map → sequential-eprocess-DodI6RoF.js.map} +1 -1
- package/dist/{server-e9oWO_bN.js → server-C6M0qR8h.js} +101 -101
- package/dist/server-C6M0qR8h.js.map +1 -0
- package/dist/{single-run-lock-CV9Eyd_q.js → single-run-lock-Dekd8_Wv.js} +7 -7
- package/dist/single-run-lock-Dekd8_Wv.js.map +1 -0
- package/dist/{skillopt-optimization-method-BiwA8nfX.js → skillopt-optimization-method-5dlex7MJ.js} +1386 -1184
- package/dist/skillopt-optimization-method-5dlex7MJ.js.map +1 -0
- package/dist/{spans-BHAUXMGN.d.ts → spans-CVngGij3.d.ts} +2 -2
- package/dist/{spans-BHAUXMGN.d.ts.map → spans-CVngGij3.d.ts.map} +1 -1
- package/dist/{statistical-heldout-CYpGaoDH.d.ts → statistical-heldout-BHfLZHrm.d.ts} +8 -67
- package/dist/statistical-heldout-BHfLZHrm.d.ts.map +1 -0
- package/dist/{statistical-heldout-42NlCNDe.js → statistical-heldout-Bksv92Th.js} +3 -3
- package/dist/statistical-heldout-Bksv92Th.js.map +1 -0
- package/dist/{steps-Bg5-KVx1.d.ts → steps-DlepJPwD.d.ts} +2 -56
- package/dist/steps-DlepJPwD.d.ts.map +1 -0
- package/dist/{store-C4avFjIi.d.ts → store-B3nWRy3B.d.ts} +2 -2
- package/dist/{store-C4avFjIi.d.ts.map → store-B3nWRy3B.d.ts.map} +1 -1
- package/dist/{store-otlp-DJ9dtA5x.js → store-otlp-BteDAbHK.js} +3 -3
- package/dist/{store-otlp-DJ9dtA5x.js.map → store-otlp-BteDAbHK.js.map} +1 -1
- package/dist/{store-tool-spans-CIX5arAG.js → store-tool-spans-D5l_OfTJ.js} +8 -8
- package/dist/store-tool-spans-D5l_OfTJ.js.map +1 -0
- package/dist/{store-tool-spans-DdCSPa7C.d.ts → store-tool-spans-DZS0HWVf.d.ts} +9 -18
- package/dist/store-tool-spans-DZS0HWVf.d.ts.map +1 -0
- package/dist/storyboard/index.d.ts +4 -11
- package/dist/storyboard/index.d.ts.map +1 -1
- package/dist/storyboard/index.js +1 -16
- package/dist/storyboard/index.js.map +1 -1
- package/dist/{summary-report-V_JACR4Y.js → summary-report-BsXJoYX5.js} +88 -10
- package/dist/summary-report-BsXJoYX5.js.map +1 -0
- package/dist/{summary-report-bdFDXq0b.d.ts → summary-report-CkbRcSuu.d.ts} +25 -19
- package/dist/summary-report-CkbRcSuu.d.ts.map +1 -0
- package/dist/supervisor-run/index.d.ts +60 -28
- package/dist/supervisor-run/index.d.ts.map +1 -1
- package/dist/supervisor-run/index.js +4 -458
- package/dist/supervisor-run/index.js.map +1 -1
- package/dist/{systemone-BomhHr2c.d.ts → systemone-BMzDJb1i.d.ts} +5 -5
- package/dist/{systemone-BomhHr2c.d.ts.map → systemone-BMzDJb1i.d.ts.map} +1 -1
- package/dist/systemone-protocol.js +1 -1
- package/dist/{systemone-review-CUVcQJu6.d.ts → systemone-review-CwE6JGIp.d.ts} +2 -2
- package/dist/{systemone-review-CUVcQJu6.d.ts.map → systemone-review-CwE6JGIp.d.ts.map} +1 -1
- package/dist/{systemone-review-D7sXwsqq.js → systemone-review-DzdOJ8I6.js} +3 -3
- package/dist/{systemone-review-D7sXwsqq.js.map → systemone-review-DzdOJ8I6.js.map} +1 -1
- package/dist/systemone.d.ts +5 -5
- package/dist/systemone.js +5 -5
- package/dist/systemone.js.map +1 -1
- package/dist/{task-failure-attributes-hEmASjix.js → task-failure-attributes-BMsblaDh.js} +3 -3
- package/dist/task-failure-attributes-BMsblaDh.js.map +1 -0
- package/dist/{terminal-record-DZyQZ3pz.js → terminal-record-D4Rv-j1W.js} +244 -196
- package/dist/terminal-record-D4Rv-j1W.js.map +1 -0
- package/dist/{tool-groups-C3NEcdCM.d.ts → tool-groups-DyNz2JZ_.d.ts} +3 -3
- package/dist/tool-groups-DyNz2JZ_.d.ts.map +1 -0
- package/dist/{tool-waste-BKgvd-TP.d.ts → tool-waste-CkjzWmeY.d.ts} +25 -28
- package/dist/tool-waste-CkjzWmeY.d.ts.map +1 -0
- package/dist/{tool-waste-BlesqTqW.js → tool-waste-DLsjS_p-.js} +5 -5
- package/dist/{tool-waste-BlesqTqW.js.map → tool-waste-DLsjS_p-.js.map} +1 -1
- package/dist/{trace-questions-CM2CAocU.d.ts → trace-questions-xxwgsuMi.d.ts} +4 -9
- package/dist/{trace-questions-CM2CAocU.d.ts.map → trace-questions-xxwgsuMi.d.ts.map} +1 -1
- package/dist/trace-repair/index.d.ts +14 -211
- package/dist/trace-repair/index.d.ts.map +1 -1
- package/dist/trace-repair/index.js +865 -981
- package/dist/trace-repair/index.js.map +1 -1
- package/dist/traces.d.ts +18 -46
- package/dist/traces.d.ts.map +1 -1
- package/dist/traces.js +13 -13
- package/dist/traces.js.map +1 -1
- package/dist/trajectory-replay/index.d.ts +7 -118
- package/dist/trajectory-replay/index.d.ts.map +1 -1
- package/dist/trajectory-replay/index.js +921 -869
- package/dist/trajectory-replay/index.js.map +1 -1
- package/dist/{tree-C1XYeXvy.js → tree-B5e1uAeL.js} +132 -21
- package/dist/tree-B5e1uAeL.js.map +1 -0
- package/dist/{types-Cbe2fWBa.d.ts → types-BKCzzmit.d.ts} +3 -3
- package/dist/{types-Cbe2fWBa.d.ts.map → types-BKCzzmit.d.ts.map} +1 -1
- package/dist/{types-B3jzCp0p.js → types-BXgASBCL.js} +2 -2
- package/dist/{types-B3jzCp0p.js.map → types-BXgASBCL.js.map} +1 -1
- package/dist/{types-C1tnkEgM.d.ts → types-CW8ewATZ.d.ts} +4 -113
- package/dist/types-CW8ewATZ.d.ts.map +1 -0
- package/dist/{types-BqkVmHfv.d.ts → types-CmXY0PQf.d.ts} +2 -4
- package/dist/types-CmXY0PQf.d.ts.map +1 -0
- package/dist/{types-C02qtnG8.d.ts → types-D-mgRzlh.d.ts} +7 -28
- package/dist/types-D-mgRzlh.d.ts.map +1 -0
- package/dist/{types-IXD2HJzu.js → types-DqFMNTgK.js} +2 -4
- package/dist/types-DqFMNTgK.js.map +1 -0
- package/dist/{types-Cq8mSbq8.d.ts → types-DtkO1G9L.d.ts} +7 -9
- package/dist/{types-Cq8mSbq8.d.ts.map → types-DtkO1G9L.d.ts.map} +1 -1
- package/dist/{verdict-Dl0tiT1X.js → verdict-BGQmxQ8A.js} +3 -3
- package/dist/verdict-BGQmxQ8A.js.map +1 -0
- package/dist/{verdict-E4eRNf7-.d.ts → verdict-C24NELtN.d.ts} +2 -15
- package/dist/{verdict-E4eRNf7-.d.ts.map → verdict-C24NELtN.d.ts.map} +1 -1
- package/dist/{verdict-cache-Bm8EKL2s.js → verdict-cache-CL_7tePD.js} +2 -2
- package/dist/verdict-cache-CL_7tePD.js.map +1 -0
- package/dist/wire/index.d.ts +31 -410
- package/dist/wire/index.d.ts.map +1 -1
- package/dist/wire/index.js +2 -2
- package/docs/changes/jev-evidence-review.md +1 -1
- package/docs/changes/jev-product-adoption.md +1 -1
- package/docs/changes/jev-recorded-evidence.md +1 -1
- package/docs/design/statistics-decisions.md +18 -18
- package/docs/design.md +1 -1
- package/docs/eval-surface-map.md +1 -0
- package/docs/evaluation-integrity.md +1 -1
- package/docs/profile-json-identity.md +1 -2
- package/docs/proofs/campaign-attempt-retention-20261001/README.md +2 -2
- package/docs/public-api.md +158 -538
- package/docs/rollout.md +1 -1
- package/docs/trace-repair-admission.md +1 -1
- package/docs/wire-protocol.md +1 -1
- package/package.json +7 -2
- package/dist/active-curriculum-B_Lc9kfO.js +0 -61
- package/dist/active-curriculum-B_Lc9kfO.js.map +0 -1
- package/dist/agent-profile-VFcQncbW.d.ts.map +0 -1
- package/dist/agent-profile-cell-BK8mlqlq.js.map +0 -1
- package/dist/agent-profile-cell-BNp-Js9F.d.ts.map +0 -1
- package/dist/agreement-irr-BEWLIF3_.js.map +0 -1
- package/dist/analyze-runs-C84irm4i.js.map +0 -1
- package/dist/baseline-Udi_PLuT.js +0 -259
- package/dist/baseline-Udi_PLuT.js.map +0 -1
- package/dist/benchmark-CXmVVHH2.js +0 -562
- package/dist/benchmark-CXmVVHH2.js.map +0 -1
- package/dist/benchmark-command-By0vh8q7.js.map +0 -1
- package/dist/campaign-BudZ70zo.js.map +0 -1
- package/dist/chat-json-call-puMArmtW.js.map +0 -1
- package/dist/claude-jsonl-dZir12m6.js +0 -86
- package/dist/claude-jsonl-dZir12m6.js.map +0 -1
- package/dist/client-BzL9niqi.d.ts.map +0 -1
- package/dist/cost-ledger-BP8V4kUQ.js.map +0 -1
- package/dist/counterfactual-CPaWN99-.d.ts +0 -60
- package/dist/counterfactual-CPaWN99-.d.ts.map +0 -1
- package/dist/counterfactual-Dn3veueY.js +0 -98
- package/dist/counterfactual-Dn3veueY.js.map +0 -1
- package/dist/default-registry-COhk9g36.js.map +0 -1
- package/dist/default-registry-DzHiGruW.d.ts.map +0 -1
- package/dist/define-agent-eval-CNTPzIkp.js.map +0 -1
- package/dist/define-agent-eval-WSck0CZJ.d.ts.map +0 -1
- package/dist/dspy-rlm-engine-LRCu61m5.js.map +0 -1
- package/dist/effect-sizes-BhzEpXMc.js +0 -82
- package/dist/effect-sizes-BhzEpXMc.js.map +0 -1
- package/dist/emitter-HcCmFQl_.d.ts.map +0 -1
- package/dist/engine-3A_4jOlI.d.ts.map +0 -1
- package/dist/equal-terms-BtdXayCJ.js.map +0 -1
- package/dist/eval-campaign-90jeaCAI.js +0 -343
- package/dist/eval-campaign-90jeaCAI.js.map +0 -1
- package/dist/evaluation-6Yoi74gM.d.ts.map +0 -1
- package/dist/exporters-X4xwla8A.js.map +0 -1
- package/dist/external-optimizer-process-BjMGUuds.js.map +0 -1
- package/dist/external-optimizer-subprocess-BqW0hHcI.js.map +0 -1
- package/dist/failure-cluster-CbgEDcFJ.d.ts.map +0 -1
- package/dist/feedback-trajectory-C4EG0nNH.d.ts.map +0 -1
- package/dist/hf-dataset-BR2yhuNn.js.map +0 -1
- package/dist/index-BFRO6chs.d.ts.map +0 -1
- package/dist/index-BO41eGj5.d.ts.map +0 -1
- package/dist/index-CyszSg4O.d.ts.map +0 -1
- package/dist/index-DHKEAv3s.d.ts.map +0 -1
- package/dist/index-DPcngtwt.d.ts.map +0 -1
- package/dist/integrity-dLiDe2kD.js.map +0 -1
- package/dist/journal-DfRz9kps.js.map +0 -1
- package/dist/judge-gate-CE7CQAgt.d.ts.map +0 -1
- package/dist/kind-factory-BobI5Jy3.js.map +0 -1
- package/dist/ledger-core-Gq7yp8lP.js.map +0 -1
- package/dist/llm-client-CyBAoYiX.js.map +0 -1
- package/dist/llm-judge-CG12SQJq.js.map +0 -1
- package/dist/matrix-DSrSxjjy.d.ts.map +0 -1
- package/dist/matrix-Dm0BQW7U.js.map +0 -1
- package/dist/mean-DHoMiudD.js.map +0 -1
- package/dist/normal-DsJZtrJc.js +0 -25
- package/dist/normal-DsJZtrJc.js.map +0 -1
- package/dist/paired-arms-CwMGJsrS.js.map +0 -1
- package/dist/paired-binary-CvpFHfKZ.js.map +0 -1
- package/dist/paired-promotion-decision-DPKz8ZnF.d.ts.map +0 -1
- package/dist/pareto-Cm6ndrWN.js.map +0 -1
- package/dist/prime-protocol-CHKgA3a6.js.map +0 -1
- package/dist/prime-protocol-HiB9HX7E.d.ts.map +0 -1
- package/dist/produced-state-BsDmnwxc.js.map +0 -1
- package/dist/proposal-findings-CY1xKn_a.js.map +0 -1
- package/dist/query-BUCZCK7F.js.map +0 -1
- package/dist/redact-mtCCcT8z.d.ts.map +0 -1
- package/dist/release-confidence-CpuP65S5.js.map +0 -1
- package/dist/report-command-SC9nqb4M.js.map +0 -1
- package/dist/reward-CpCmAM8L.d.ts.map +0 -1
- package/dist/reward-hacking-RVdZ6Kkt.d.ts.map +0 -1
- package/dist/rollout-DZV1t2Wg.js.map +0 -1
- package/dist/run-record-C1E24G2A.d.ts.map +0 -1
- package/dist/run-record-C5e7FjhJ.js.map +0 -1
- package/dist/schema-2g7trUwH.d.ts.map +0 -1
- package/dist/schema-BuiujZ-g.js.map +0 -1
- package/dist/schema-CSf6qWgZ.js.map +0 -1
- package/dist/search-kernel-DyNEa6IU.d.ts.map +0 -1
- package/dist/search-ledger-file-DDQUgvCg.js.map +0 -1
- package/dist/search-shipper-BOSD46qv.js.map +0 -1
- package/dist/semantic-concept-judge-BQF8te0T.js.map +0 -1
- package/dist/sequential-Bf_pbE50.js.map +0 -1
- package/dist/server-e9oWO_bN.js.map +0 -1
- package/dist/single-run-lock-CV9Eyd_q.js.map +0 -1
- package/dist/skillopt-optimization-method-BiwA8nfX.js.map +0 -1
- package/dist/statistical-heldout-42NlCNDe.js.map +0 -1
- package/dist/statistical-heldout-CYpGaoDH.d.ts.map +0 -1
- package/dist/steps-Bg5-KVx1.d.ts.map +0 -1
- package/dist/store-tool-spans-CIX5arAG.js.map +0 -1
- package/dist/store-tool-spans-DdCSPa7C.d.ts.map +0 -1
- package/dist/student-t-DVPW7CdL.js +0 -39
- package/dist/student-t-DVPW7CdL.js.map +0 -1
- package/dist/summary-report-V_JACR4Y.js.map +0 -1
- package/dist/summary-report-bdFDXq0b.d.ts.map +0 -1
- package/dist/task-failure-attributes-hEmASjix.js.map +0 -1
- package/dist/terminal-record-DZyQZ3pz.js.map +0 -1
- package/dist/tool-groups-C3NEcdCM.d.ts.map +0 -1
- package/dist/tool-waste-BKgvd-TP.d.ts.map +0 -1
- package/dist/trajectory-Y1fmdlw7.d.ts +0 -24
- package/dist/trajectory-Y1fmdlw7.d.ts.map +0 -1
- package/dist/tree-C1XYeXvy.js.map +0 -1
- package/dist/types-BqkVmHfv.d.ts.map +0 -1
- package/dist/types-C02qtnG8.d.ts.map +0 -1
- package/dist/types-C1tnkEgM.d.ts.map +0 -1
- package/dist/types-IXD2HJzu.js.map +0 -1
- package/dist/usage-receipt-Cx3xNeyB.js +0 -76
- package/dist/usage-receipt-Cx3xNeyB.js.map +0 -1
- package/dist/verdict-Dl0tiT1X.js.map +0 -1
- package/dist/verdict-cache-Bm8EKL2s.js.map +0 -1
- package/docs/design/self-improvement-evidence-audit.md +0 -263
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
import { readFileSync, readlinkSync } from "node:fs";
|
|
2
|
+
import { hostname } from "node:os";
|
|
3
|
+
//#region src/ledger-core/lock-holder.ts
|
|
4
|
+
/**
|
|
5
|
+
* The one dead-owner rule: whether a lock's recorded holder is provably dead.
|
|
6
|
+
*
|
|
7
|
+
* A lock is safe to take over only when its holder is proved dead. A pid alone
|
|
8
|
+
* proves nothing: the OS hands a dead holder's pid to a later process, and a
|
|
9
|
+
* filesystem hands a removed lock's inode to the next lock. So a holder record
|
|
10
|
+
* carries the pid's OS start token, the boot id, the pid namespace, the host,
|
|
11
|
+
* and the identity of the lock it was written for, and the verdict is `dead`
|
|
12
|
+
* only when those facts prove it. Anything the record or this host cannot
|
|
13
|
+
* settle is `unknown`, and a caller keeps treating the lock as held.
|
|
14
|
+
*
|
|
15
|
+
* This module imports only Node built-ins, so lock owners in other packages can
|
|
16
|
+
* import `@tangle-network/agent-eval/lock-holder` without loading the rest of
|
|
17
|
+
* the package.
|
|
18
|
+
*/
|
|
19
|
+
function lockIdentity(stats) {
|
|
20
|
+
return {
|
|
21
|
+
dev: stats.dev.toString(),
|
|
22
|
+
ino: stats.ino.toString(),
|
|
23
|
+
birthtimeNs: stats.birthtimeNs.toString()
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* The identity to record for `pid` on this host. The start token is read for
|
|
28
|
+
* `pid` itself, so a lock taken on behalf of another live process records that
|
|
29
|
+
* process. Fields the host cannot report are omitted, which leaves a later
|
|
30
|
+
* verdict on the record `unknown` rather than wrong.
|
|
31
|
+
*/
|
|
32
|
+
function readLockHolderIdentity(pid = process.pid) {
|
|
33
|
+
const processStart = readProcessStart(pid);
|
|
34
|
+
const { bootId, pidNamespace } = ownHostIdentity();
|
|
35
|
+
return {
|
|
36
|
+
pid,
|
|
37
|
+
host: hostname(),
|
|
38
|
+
...processStart ? { processStart } : {},
|
|
39
|
+
...bootId ? { bootId } : {},
|
|
40
|
+
...pidNamespace ? { pidNamespace } : {}
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Decide whether `record`'s holder is dead, alive, or unknown.
|
|
45
|
+
*
|
|
46
|
+
* `currentLock` is the identity of the lock as it is now. `dead` needs a record
|
|
47
|
+
* with a start token and a lock identity, written for this very lock (equal dev,
|
|
48
|
+
* ino and a nonzero birthtime), on this host and pid namespace, and then a
|
|
49
|
+
* rebooted host, a gone pid, or a pid whose start token changed. `alive` needs
|
|
50
|
+
* the pid present with the recorded start token. Everything else is `unknown`,
|
|
51
|
+
* so a live holder's lock is never taken.
|
|
52
|
+
*/
|
|
53
|
+
function lockHolderVerdict(record, currentLock) {
|
|
54
|
+
if (!record || !Number.isSafeInteger(record.pid) || record.pid <= 0) return unknown("unreadable record");
|
|
55
|
+
if (record.host !== hostname()) return unknown("other host");
|
|
56
|
+
if (!record.processStart || !record.lock) return unknown("incomplete record");
|
|
57
|
+
if (!currentLock || currentLock.birthtimeNs === "0" || currentLock.dev !== record.lock.dev || currentLock.ino !== record.lock.ino || currentLock.birthtimeNs !== record.lock.birthtimeNs) return unknown("lock changed");
|
|
58
|
+
const own = ownHostIdentity();
|
|
59
|
+
if (record.pidNamespace !== own.pidNamespace) return unknown("other pid namespace");
|
|
60
|
+
if (record.bootId === void 0 !== (own.bootId === void 0)) return unknown("boot id unavailable");
|
|
61
|
+
if (record.bootId !== own.bootId) return {
|
|
62
|
+
liveness: "dead",
|
|
63
|
+
reason: "host rebooted"
|
|
64
|
+
};
|
|
65
|
+
if (pidIsGone(record.pid)) return {
|
|
66
|
+
liveness: "dead",
|
|
67
|
+
reason: "pid gone"
|
|
68
|
+
};
|
|
69
|
+
const start = readProcessStart(record.pid);
|
|
70
|
+
if (start === void 0) return unknown("start token unavailable");
|
|
71
|
+
if (start !== record.processStart) return {
|
|
72
|
+
liveness: "dead",
|
|
73
|
+
reason: "pid reused"
|
|
74
|
+
};
|
|
75
|
+
return { liveness: "alive" };
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Read a holder record from parsed JSON. The required fields are `pid` and
|
|
79
|
+
* `host`; an identity field that is missing or malformed is dropped, which
|
|
80
|
+
* leaves the holder named but never provably dead.
|
|
81
|
+
*/
|
|
82
|
+
function parseLockHolderRecord(value) {
|
|
83
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) return void 0;
|
|
84
|
+
const record = value;
|
|
85
|
+
if (!Number.isSafeInteger(record.pid) || record.pid <= 0) return void 0;
|
|
86
|
+
if (typeof record.host !== "string" || record.host.length === 0) return void 0;
|
|
87
|
+
const processStart = text(record.processStart);
|
|
88
|
+
const bootId = text(record.bootId);
|
|
89
|
+
const pidNamespace = text(record.pidNamespace);
|
|
90
|
+
const lock = parseLockIdentity(record.lock);
|
|
91
|
+
return {
|
|
92
|
+
pid: record.pid,
|
|
93
|
+
host: record.host,
|
|
94
|
+
...processStart ? { processStart } : {},
|
|
95
|
+
...bootId ? { bootId } : {},
|
|
96
|
+
...pidNamespace ? { pidNamespace } : {},
|
|
97
|
+
...lock ? { lock } : {}
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
function parseLockIdentity(value) {
|
|
101
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) return void 0;
|
|
102
|
+
const lock = value;
|
|
103
|
+
if (!decimal(lock.dev) || !decimal(lock.ino) || !decimal(lock.birthtimeNs)) return void 0;
|
|
104
|
+
return {
|
|
105
|
+
dev: lock.dev,
|
|
106
|
+
ino: lock.ino,
|
|
107
|
+
birthtimeNs: lock.birthtimeNs
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
function unknown(reason) {
|
|
111
|
+
return {
|
|
112
|
+
liveness: "unknown",
|
|
113
|
+
reason
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
function text(field) {
|
|
117
|
+
return typeof field === "string" && field.length > 0 ? field : void 0;
|
|
118
|
+
}
|
|
119
|
+
function decimal(field) {
|
|
120
|
+
return typeof field === "string" && /^\d+$/u.test(field);
|
|
121
|
+
}
|
|
122
|
+
/** Only ESRCH proves a pid gone; EPERM means it exists under another user. */
|
|
123
|
+
function pidIsGone(pid) {
|
|
124
|
+
try {
|
|
125
|
+
process.kill(pid, 0);
|
|
126
|
+
return false;
|
|
127
|
+
} catch (error) {
|
|
128
|
+
return error instanceof Error && "code" in error && error.code === "ESRCH";
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
let hostIdentity;
|
|
132
|
+
function ownHostIdentity() {
|
|
133
|
+
if (hostIdentity) return hostIdentity;
|
|
134
|
+
const bootId = readOptional(() => readFileSync("/proc/sys/kernel/random/boot_id", "utf8").trim());
|
|
135
|
+
const pidNamespace = readOptional(() => readlinkSync("/proc/self/ns/pid"));
|
|
136
|
+
hostIdentity = {
|
|
137
|
+
...bootId ? { bootId } : {},
|
|
138
|
+
...pidNamespace ? { pidNamespace } : {}
|
|
139
|
+
};
|
|
140
|
+
return hostIdentity;
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* The OS start token of a live pid: the same for a process's whole life and
|
|
144
|
+
* different for every later holder of its pid. `undefined` when the host cannot
|
|
145
|
+
* report one.
|
|
146
|
+
*/
|
|
147
|
+
function readProcessStart(pid) {
|
|
148
|
+
if (!Number.isSafeInteger(pid) || pid <= 0 || process.platform === "win32") return void 0;
|
|
149
|
+
if (process.platform === "linux") {
|
|
150
|
+
const stat = readOptional(() => readFileSync(`/proc/${pid}/stat`, "utf8"));
|
|
151
|
+
if (stat === void 0) return void 0;
|
|
152
|
+
const startTime = stat.slice(stat.lastIndexOf(")") + 1).trim().split(/\s+/u)[19];
|
|
153
|
+
return startTime !== void 0 && /^\d+$/u.test(startTime) ? startTime : void 0;
|
|
154
|
+
}
|
|
155
|
+
const childProcess = process.getBuiltinModule?.("node:child_process");
|
|
156
|
+
if (!childProcess) return void 0;
|
|
157
|
+
return readOptional(() => childProcess.execFileSync("ps", [
|
|
158
|
+
"-o",
|
|
159
|
+
"lstart=",
|
|
160
|
+
"-p",
|
|
161
|
+
String(pid)
|
|
162
|
+
], {
|
|
163
|
+
encoding: "utf8",
|
|
164
|
+
stdio: [
|
|
165
|
+
"ignore",
|
|
166
|
+
"pipe",
|
|
167
|
+
"ignore"
|
|
168
|
+
]
|
|
169
|
+
}).trim());
|
|
170
|
+
}
|
|
171
|
+
function readOptional(read) {
|
|
172
|
+
try {
|
|
173
|
+
return read() || void 0;
|
|
174
|
+
} catch {
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
//#endregion
|
|
179
|
+
export { lockHolderVerdict, lockIdentity, parseLockHolderRecord, readLockHolderIdentity };
|
|
180
|
+
|
|
181
|
+
//# sourceMappingURL=lock-holder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lock-holder.js","names":[],"sources":["../../src/ledger-core/lock-holder.ts"],"sourcesContent":["/**\n * The one dead-owner rule: whether a lock's recorded holder is provably dead.\n *\n * A lock is safe to take over only when its holder is proved dead. A pid alone\n * proves nothing: the OS hands a dead holder's pid to a later process, and a\n * filesystem hands a removed lock's inode to the next lock. So a holder record\n * carries the pid's OS start token, the boot id, the pid namespace, the host,\n * and the identity of the lock it was written for, and the verdict is `dead`\n * only when those facts prove it. Anything the record or this host cannot\n * settle is `unknown`, and a caller keeps treating the lock as held.\n *\n * This module imports only Node built-ins, so lock owners in other packages can\n * import `@tangle-network/agent-eval/lock-holder` without loading the rest of\n * the package.\n */\n\nimport { readFileSync, readlinkSync } from 'node:fs'\nimport { hostname } from 'node:os'\n\n/**\n * Identity of one lock path's inode, as decimal strings from a bigint `stat`.\n * ext4 hands a removed directory's inode to the next one at once (two\n * directories created 1.4 ms apart got the same inode on drew-gtr-pro), so dev\n * and ino alone can match a stale record to a live holder's new lock; the\n * nanosecond birthtime tells them apart.\n */\nexport interface LockIdentity {\n readonly dev: string\n readonly ino: string\n readonly birthtimeNs: string\n}\n\n/** Who holds a lock: the process and the facts that tell it from a later holder of its pid. */\nexport interface LockHolderIdentity {\n readonly pid: number\n readonly host: string\n /** OS start token of `pid`: Linux `/proc/<pid>/stat` starttime, elsewhere `ps` lstart. */\n readonly processStart?: string\n readonly bootId?: string\n readonly pidNamespace?: string\n}\n\n/** A holder record as a lock owner writes it: the holder and the lock it was written for. */\nexport interface LockHolderRecord extends LockHolderIdentity {\n readonly lock?: LockIdentity\n}\n\nexport type LockHolderDeathReason = 'pid gone' | 'pid reused' | 'host rebooted'\n\nexport type LockHolderUnknownReason =\n | 'unreadable record'\n | 'other host'\n | 'incomplete record'\n | 'lock changed'\n | 'other pid namespace'\n | 'boot id unavailable'\n | 'start token unavailable'\n\nexport type LockHolderVerdict =\n | { readonly liveness: 'dead'; readonly reason: LockHolderDeathReason }\n | { readonly liveness: 'alive' }\n | { readonly liveness: 'unknown'; readonly reason: LockHolderUnknownReason }\n\n/** Stat fields `lockIdentity` reads; pass `statSync(path, { bigint: true })` or its fstat/lstat. */\nexport interface LockIdentityStats {\n readonly dev: bigint\n readonly ino: bigint\n readonly birthtimeNs: bigint\n}\n\nexport function lockIdentity(stats: LockIdentityStats): LockIdentity {\n return {\n dev: stats.dev.toString(),\n ino: stats.ino.toString(),\n birthtimeNs: stats.birthtimeNs.toString(),\n }\n}\n\n/**\n * The identity to record for `pid` on this host. The start token is read for\n * `pid` itself, so a lock taken on behalf of another live process records that\n * process. Fields the host cannot report are omitted, which leaves a later\n * verdict on the record `unknown` rather than wrong.\n */\nexport function readLockHolderIdentity(pid: number = process.pid): LockHolderIdentity {\n const processStart = readProcessStart(pid)\n const { bootId, pidNamespace } = ownHostIdentity()\n return {\n pid,\n host: hostname(),\n ...(processStart ? { processStart } : {}),\n ...(bootId ? { bootId } : {}),\n ...(pidNamespace ? { pidNamespace } : {}),\n }\n}\n\n/**\n * Decide whether `record`'s holder is dead, alive, or unknown.\n *\n * `currentLock` is the identity of the lock as it is now. `dead` needs a record\n * with a start token and a lock identity, written for this very lock (equal dev,\n * ino and a nonzero birthtime), on this host and pid namespace, and then a\n * rebooted host, a gone pid, or a pid whose start token changed. `alive` needs\n * the pid present with the recorded start token. Everything else is `unknown`,\n * so a live holder's lock is never taken.\n */\nexport function lockHolderVerdict(\n record: LockHolderRecord | undefined,\n currentLock: LockIdentity | undefined,\n): LockHolderVerdict {\n if (!record || !Number.isSafeInteger(record.pid) || record.pid <= 0) {\n return unknown('unreadable record')\n }\n if (record.host !== hostname()) return unknown('other host')\n if (!record.processStart || !record.lock) return unknown('incomplete record')\n if (\n !currentLock ||\n currentLock.birthtimeNs === '0' ||\n currentLock.dev !== record.lock.dev ||\n currentLock.ino !== record.lock.ino ||\n currentLock.birthtimeNs !== record.lock.birthtimeNs\n ) {\n return unknown('lock changed')\n }\n const own = ownHostIdentity()\n if (record.pidNamespace !== own.pidNamespace) return unknown('other pid namespace')\n if ((record.bootId === undefined) !== (own.bootId === undefined)) {\n return unknown('boot id unavailable')\n }\n if (record.bootId !== own.bootId) return { liveness: 'dead', reason: 'host rebooted' }\n if (pidIsGone(record.pid)) return { liveness: 'dead', reason: 'pid gone' }\n const start = readProcessStart(record.pid)\n if (start === undefined) return unknown('start token unavailable')\n if (start !== record.processStart) return { liveness: 'dead', reason: 'pid reused' }\n return { liveness: 'alive' }\n}\n\n/**\n * Read a holder record from parsed JSON. The required fields are `pid` and\n * `host`; an identity field that is missing or malformed is dropped, which\n * leaves the holder named but never provably dead.\n */\nexport function parseLockHolderRecord(value: unknown): LockHolderRecord | undefined {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) return undefined\n const record = value as Record<string, unknown>\n if (!Number.isSafeInteger(record.pid) || (record.pid as number) <= 0) return undefined\n if (typeof record.host !== 'string' || record.host.length === 0) return undefined\n const processStart = text(record.processStart)\n const bootId = text(record.bootId)\n const pidNamespace = text(record.pidNamespace)\n const lock = parseLockIdentity(record.lock)\n return {\n pid: record.pid as number,\n host: record.host,\n ...(processStart ? { processStart } : {}),\n ...(bootId ? { bootId } : {}),\n ...(pidNamespace ? { pidNamespace } : {}),\n ...(lock ? { lock } : {}),\n }\n}\n\nfunction parseLockIdentity(value: unknown): LockIdentity | undefined {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) return undefined\n const lock = value as Record<string, unknown>\n if (!decimal(lock.dev) || !decimal(lock.ino) || !decimal(lock.birthtimeNs)) return undefined\n return { dev: lock.dev, ino: lock.ino, birthtimeNs: lock.birthtimeNs }\n}\n\nfunction unknown(reason: LockHolderUnknownReason): LockHolderVerdict {\n return { liveness: 'unknown', reason }\n}\n\nfunction text(field: unknown): string | undefined {\n return typeof field === 'string' && field.length > 0 ? field : undefined\n}\n\nfunction decimal(field: unknown): field is string {\n return typeof field === 'string' && /^\\d+$/u.test(field)\n}\n\n/** Only ESRCH proves a pid gone; EPERM means it exists under another user. */\nfunction pidIsGone(pid: number): boolean {\n try {\n process.kill(pid, 0)\n return false\n } catch (error) {\n return error instanceof Error && 'code' in error && error.code === 'ESRCH'\n }\n}\n\ninterface HostIdentity {\n readonly bootId?: string\n readonly pidNamespace?: string\n}\n\nlet hostIdentity: HostIdentity | undefined\n\nfunction ownHostIdentity(): HostIdentity {\n if (hostIdentity) return hostIdentity\n const bootId = readOptional(() => readFileSync('/proc/sys/kernel/random/boot_id', 'utf8').trim())\n const pidNamespace = readOptional(() => readlinkSync('/proc/self/ns/pid'))\n hostIdentity = {\n ...(bootId ? { bootId } : {}),\n ...(pidNamespace ? { pidNamespace } : {}),\n }\n return hostIdentity\n}\n\n/**\n * The OS start token of a live pid: the same for a process's whole life and\n * different for every later holder of its pid. `undefined` when the host cannot\n * report one.\n */\nfunction readProcessStart(pid: number): string | undefined {\n if (!Number.isSafeInteger(pid) || pid <= 0 || process.platform === 'win32') return undefined\n if (process.platform === 'linux') {\n const stat = readOptional(() => readFileSync(`/proc/${pid}/stat`, 'utf8'))\n if (stat === undefined) return undefined\n // The comm field is parenthesized and may hold spaces, so fields are counted after its close.\n const startTime = stat\n .slice(stat.lastIndexOf(')') + 1)\n .trim()\n .split(/\\s+/u)[19]\n return startTime !== undefined && /^\\d+$/u.test(startTime) ? startTime : undefined\n }\n // `ps` lstart has 1 s resolution, so a pid reused within the same second reads\n // as alive and keeps the lock: the safe direction. child_process is resolved\n // on use so bundles that import this module never load it at startup.\n const childProcess = process.getBuiltinModule?.('node:child_process') as\n | typeof import('node:child_process')\n | undefined\n if (!childProcess) return undefined\n return readOptional(() =>\n childProcess\n .execFileSync('ps', ['-o', 'lstart=', '-p', String(pid)], {\n encoding: 'utf8',\n stdio: ['ignore', 'pipe', 'ignore'],\n })\n .trim(),\n )\n}\n\nfunction readOptional(read: () => string): string | undefined {\n try {\n return read() || undefined\n } catch {\n return undefined\n }\n}\n"],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { s as ValidationError } from "./errors-
|
|
2
|
-
import { t as LEDGER_HASH_PATTERN } from "./canonical-
|
|
3
|
-
import "./journal-
|
|
1
|
+
import { s as ValidationError } from "./errors-BcOs5MKW.js";
|
|
2
|
+
import { t as LEDGER_HASH_PATTERN } from "./canonical-Dq2hOQ8L.js";
|
|
3
|
+
import "./journal-C7om8Gum.js";
|
|
4
4
|
import { sha256Bytes } from "@tangle-network/agent-interface";
|
|
5
5
|
//#region src/ledger-core/merkle.ts
|
|
6
6
|
/**
|
|
@@ -61,21 +61,6 @@ function merkleInclusionProof(leaves, leafIndex) {
|
|
|
61
61
|
path: path.map(toLedgerHash)
|
|
62
62
|
};
|
|
63
63
|
}
|
|
64
|
-
/**
|
|
65
|
-
* Consistency proof that the first `oldSize` leaves are the tree of that size
|
|
66
|
-
* (RFC 9162 §2.1.4.1). Sizes 0 and `leaves.length` need no path.
|
|
67
|
-
*/
|
|
68
|
-
function merkleConsistencyProof(leaves, oldSize) {
|
|
69
|
-
const nodes = decodeLeaves(leaves);
|
|
70
|
-
if (!Number.isSafeInteger(oldSize) || oldSize < 0 || oldSize > nodes.length) throw new ValidationError(`merkle old size ${oldSize} is outside a tree of ${nodes.length} leaves`);
|
|
71
|
-
const path = [];
|
|
72
|
-
if (oldSize > 0 && oldSize < nodes.length) subproof(nodes, oldSize, 0, nodes.length, true, path);
|
|
73
|
-
return {
|
|
74
|
-
oldSize,
|
|
75
|
-
newSize: nodes.length,
|
|
76
|
-
path: path.map(toLedgerHash)
|
|
77
|
-
};
|
|
78
|
-
}
|
|
79
64
|
/** Check that `leaf` is in the tree with `root` at the proof's index (RFC 9162 §2.1.3.2). */
|
|
80
65
|
function verifyMerkleInclusion(leaf, proof, root) {
|
|
81
66
|
const { leafIndex, treeSize } = proof;
|
|
@@ -105,50 +90,6 @@ function verifyMerkleInclusion(leaf, proof, root) {
|
|
|
105
90
|
if (sn !== 0) return refused("proof path is shorter than the tree is deep");
|
|
106
91
|
return equal(r, rootBytes) ? { verified: true } : refused("leaf does not hash to the root");
|
|
107
92
|
}
|
|
108
|
-
/** Check that the tree with `newRoot` extends the tree with `oldRoot` (RFC 9162 §2.1.4.2). */
|
|
109
|
-
function verifyMerkleConsistency(proof, oldRoot, newRoot) {
|
|
110
|
-
const { oldSize, newSize } = proof;
|
|
111
|
-
if (!isSize(oldSize) || !isSize(newSize) || oldSize > newSize) return refused(`old size ${oldSize} does not precede new size ${newSize}`);
|
|
112
|
-
const decoded = decodeAll([
|
|
113
|
-
oldRoot,
|
|
114
|
-
newRoot,
|
|
115
|
-
...proof.path
|
|
116
|
-
]);
|
|
117
|
-
if (decoded === void 0) return refused("proof carries a malformed hash");
|
|
118
|
-
const [oldBytes, newBytes, ...given] = decoded;
|
|
119
|
-
if (oldSize === 0 || oldSize === newSize) {
|
|
120
|
-
if (given.length !== 0) return refused("a trivial consistency proof must be empty");
|
|
121
|
-
if (oldSize === 0) return oldRoot === MERKLE_EMPTY_ROOT ? { verified: true } : refused("the empty tree has a different root");
|
|
122
|
-
return equal(oldBytes, newBytes) ? { verified: true } : refused("equal sizes with different roots");
|
|
123
|
-
}
|
|
124
|
-
const path = isPowerOfTwo(oldSize) ? [oldBytes, ...given] : given;
|
|
125
|
-
if (path.length === 0) return refused("consistency proof is empty");
|
|
126
|
-
let fn = oldSize - 1;
|
|
127
|
-
let sn = newSize - 1;
|
|
128
|
-
while (fn % 2 === 1) {
|
|
129
|
-
fn = Math.floor(fn / 2);
|
|
130
|
-
sn = Math.floor(sn / 2);
|
|
131
|
-
}
|
|
132
|
-
let fr = path[0];
|
|
133
|
-
let sr = fr;
|
|
134
|
-
for (const c of path.slice(1)) {
|
|
135
|
-
if (sn === 0) return refused("proof path is longer than the tree is deep");
|
|
136
|
-
if (fn % 2 === 1 || fn === sn) {
|
|
137
|
-
fr = node(c, fr);
|
|
138
|
-
sr = node(c, sr);
|
|
139
|
-
if (fn % 2 === 0) while (fn % 2 === 0 && fn !== 0) {
|
|
140
|
-
fn = Math.floor(fn / 2);
|
|
141
|
-
sn = Math.floor(sn / 2);
|
|
142
|
-
}
|
|
143
|
-
} else sr = node(sr, c);
|
|
144
|
-
fn = Math.floor(fn / 2);
|
|
145
|
-
sn = Math.floor(sn / 2);
|
|
146
|
-
}
|
|
147
|
-
if (sn !== 0) return refused("proof path is shorter than the tree is deep");
|
|
148
|
-
if (!equal(fr, oldBytes)) return refused("proof does not rebuild the old root");
|
|
149
|
-
if (!equal(sr, newBytes)) return refused("proof does not rebuild the new root");
|
|
150
|
-
return { verified: true };
|
|
151
|
-
}
|
|
152
93
|
function subtreeRoot(nodes, start, end) {
|
|
153
94
|
if (end - start === 1) return nodes[start];
|
|
154
95
|
const k = largestPowerOfTwoBelow(end - start);
|
|
@@ -165,20 +106,6 @@ function inclusionPath(nodes, index, start, end, path) {
|
|
|
165
106
|
path.push(subtreeRoot(nodes, start, start + k));
|
|
166
107
|
}
|
|
167
108
|
}
|
|
168
|
-
function subproof(nodes, oldSize, start, end, complete, path) {
|
|
169
|
-
if (end - start === oldSize) {
|
|
170
|
-
if (!complete) path.push(subtreeRoot(nodes, start, end));
|
|
171
|
-
return;
|
|
172
|
-
}
|
|
173
|
-
const k = largestPowerOfTwoBelow(end - start);
|
|
174
|
-
if (oldSize <= k) {
|
|
175
|
-
subproof(nodes, oldSize, start, start + k, complete, path);
|
|
176
|
-
path.push(subtreeRoot(nodes, start + k, end));
|
|
177
|
-
} else {
|
|
178
|
-
subproof(nodes, oldSize - k, start + k, end, false, path);
|
|
179
|
-
path.push(subtreeRoot(nodes, start, start + k));
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
109
|
function node(left, right) {
|
|
183
110
|
return fromHex(digest(NODE_PREFIX, left, right).slice(7));
|
|
184
111
|
}
|
|
@@ -214,12 +141,6 @@ function largestPowerOfTwoBelow(n) {
|
|
|
214
141
|
while (k * 2 < n) k *= 2;
|
|
215
142
|
return k;
|
|
216
143
|
}
|
|
217
|
-
function isPowerOfTwo(n) {
|
|
218
|
-
if (n < 1) return false;
|
|
219
|
-
let m = n;
|
|
220
|
-
while (m % 2 === 0) m /= 2;
|
|
221
|
-
return m === 1;
|
|
222
|
-
}
|
|
223
144
|
function isSize(n) {
|
|
224
145
|
return Number.isSafeInteger(n) && n >= 0;
|
|
225
146
|
}
|
|
@@ -243,6 +164,6 @@ function fromHex(hex) {
|
|
|
243
164
|
return bytes;
|
|
244
165
|
}
|
|
245
166
|
//#endregion
|
|
246
|
-
export {
|
|
167
|
+
export { verifyMerkleInclusion as a, merkleSalt as i, merkleLeafHash as n, merkleRoot as r, merkleInclusionProof as t };
|
|
247
168
|
|
|
248
|
-
//# sourceMappingURL=ledger-core-
|
|
169
|
+
//# sourceMappingURL=ledger-core-CAxUdDk0.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ledger-core-CAxUdDk0.js","names":[],"sources":["../src/ledger-core/merkle.ts"],"sourcesContent":["/**\n * Merkle proofs over an append-only list of leaves (RFC 9162 §2.1, the\n * Certificate Transparency tree).\n *\n * A hash chain proves a whole log against its head, but proving one entry means\n * replaying everything before it. This tree proves any one leaf against a root\n * with ⌈log₂ n⌉ hashes (inclusion), and proves that a larger tree only appended\n * to a smaller one (consistency). A verifier holding a root can therefore check\n * a single event, or that a later checkpoint extends an earlier one, without\n * reading the rest of the log.\n *\n * Leaves and interior nodes are domain-separated (0x00 and 0x01 prefixes), so a\n * leaf can never be presented as an interior node. Content that may later be\n * redacted takes a random 32-byte salt: a verifier then needs only the leaf's\n * hash, and short content cannot be guessed back from that hash. The salt must\n * be stored apart from anything that is shared after redaction.\n *\n * Builders refuse malformed input by throwing; verifiers never throw and return\n * a typed outcome, because a proof is external evidence and a bad one is a\n * finding, not a crash.\n */\nimport { sha256Bytes } from '@tangle-network/agent-interface'\nimport { ValidationError } from '../errors'\nimport { LEDGER_HASH_PATTERN, type LedgerHash } from './canonical'\n\n/** Proof that one leaf is at `leafIndex` in a tree of `treeSize` leaves. */\nexport interface MerkleInclusionProof {\n readonly leafIndex: number\n readonly treeSize: number\n readonly path: readonly LedgerHash[]\n}\n\n/** Proof that the first `oldSize` leaves of a `newSize` tree are unchanged. */\nexport interface MerkleConsistencyProof {\n readonly oldSize: number\n readonly newSize: number\n readonly path: readonly LedgerHash[]\n}\n\nexport type MerkleVerification =\n | { readonly verified: true }\n | { readonly verified: false; readonly reason: string }\n\nconst SALT_PATTERN = /^[a-f0-9]{64}$/\nconst LEAF_PREFIX = 0x00\nconst NODE_PREFIX = 0x01\nconst encoder = new TextEncoder()\n\n/** Root of the empty tree: SHA-256 of no bytes. */\nconst MERKLE_EMPTY_ROOT: LedgerHash = sha256Bytes(new Uint8Array(0)) as LedgerHash\n\n/** A fresh random salt for {@link merkleLeafHash}: 32 bytes as 64 lowercase hex characters. */\nexport function merkleSalt(): string {\n return toHex(globalThis.crypto.getRandomValues(new Uint8Array(32)))\n}\n\n/**\n * Leaf hash of `content`: SHA-256(0x00 ‖ salt ‖ content). Without a salt this is\n * exactly the RFC 9162 leaf hash. Strings are hashed as UTF-8.\n */\nexport function merkleLeafHash(content: Uint8Array | string, salt?: string): LedgerHash {\n const bytes = typeof content === 'string' ? encoder.encode(content) : content\n if (salt === undefined) return digest(LEAF_PREFIX, bytes)\n if (!SALT_PATTERN.test(salt)) {\n throw new ValidationError('merkle salt must be 32 bytes as 64 lowercase hex characters')\n }\n return digest(LEAF_PREFIX, fromHex(salt), bytes)\n}\n\n/** Root over leaf hashes, in order. The empty list has {@link MERKLE_EMPTY_ROOT}. */\nexport function merkleRoot(leaves: readonly LedgerHash[]): LedgerHash {\n const nodes = decodeLeaves(leaves)\n return nodes.length === 0 ? MERKLE_EMPTY_ROOT : toLedgerHash(subtreeRoot(nodes, 0, nodes.length))\n}\n\n/** Inclusion proof for the leaf at `leafIndex` (RFC 9162 §2.1.3.1). */\nexport function merkleInclusionProof(\n leaves: readonly LedgerHash[],\n leafIndex: number,\n): MerkleInclusionProof {\n const nodes = decodeLeaves(leaves)\n if (!Number.isSafeInteger(leafIndex) || leafIndex < 0 || leafIndex >= nodes.length) {\n throw new ValidationError(\n `merkle leaf index ${leafIndex} is outside a tree of ${nodes.length} leaves`,\n )\n }\n const path: Uint8Array[] = []\n inclusionPath(nodes, leafIndex, 0, nodes.length, path)\n return { leafIndex, treeSize: nodes.length, path: path.map(toLedgerHash) }\n}\n\n\n\n/** Check that `leaf` is in the tree with `root` at the proof's index (RFC 9162 §2.1.3.2). */\nexport function verifyMerkleInclusion(\n leaf: LedgerHash,\n proof: MerkleInclusionProof,\n root: LedgerHash,\n): MerkleVerification {\n const { leafIndex, treeSize } = proof\n if (!isSize(treeSize) || !isSize(leafIndex) || leafIndex >= treeSize) {\n return refused(`leaf index ${leafIndex} is outside a tree of ${treeSize} leaves`)\n }\n const decoded = decodeAll([leaf, root, ...proof.path])\n if (decoded === undefined) return refused('proof carries a malformed hash')\n const [leafBytes, rootBytes, ...path] = decoded as [Uint8Array, Uint8Array, ...Uint8Array[]]\n let fn = leafIndex\n let sn = treeSize - 1\n let r = leafBytes\n for (const p of path) {\n if (sn === 0) return refused('proof path is longer than the tree is deep')\n if (fn % 2 === 1 || fn === sn) {\n r = node(p, r)\n if (fn % 2 === 0) {\n while (fn % 2 === 0 && fn !== 0) {\n fn = Math.floor(fn / 2)\n sn = Math.floor(sn / 2)\n }\n }\n } else {\n r = node(r, p)\n }\n fn = Math.floor(fn / 2)\n sn = Math.floor(sn / 2)\n }\n if (sn !== 0) return refused('proof path is shorter than the tree is deep')\n return equal(r, rootBytes) ? { verified: true } : refused('leaf does not hash to the root')\n}\n\n\n\nfunction subtreeRoot(nodes: readonly Uint8Array[], start: number, end: number): Uint8Array {\n if (end - start === 1) return nodes[start] as Uint8Array\n const k = largestPowerOfTwoBelow(end - start)\n return node(subtreeRoot(nodes, start, start + k), subtreeRoot(nodes, start + k, end))\n}\n\nfunction inclusionPath(\n nodes: readonly Uint8Array[],\n index: number,\n start: number,\n end: number,\n path: Uint8Array[],\n): void {\n if (end - start === 1) return\n const k = largestPowerOfTwoBelow(end - start)\n if (index < start + k) {\n inclusionPath(nodes, index, start, start + k, path)\n path.push(subtreeRoot(nodes, start + k, end))\n } else {\n inclusionPath(nodes, index, start + k, end, path)\n path.push(subtreeRoot(nodes, start, start + k))\n }\n}\n\n\n\nfunction node(left: Uint8Array, right: Uint8Array): Uint8Array {\n return fromHex(digest(NODE_PREFIX, left, right).slice('sha256:'.length))\n}\n\nfunction digest(prefix: number, ...parts: Uint8Array[]): LedgerHash {\n const length = parts.reduce((total, part) => total + part.length, 1)\n const bytes = new Uint8Array(length)\n bytes[0] = prefix\n let offset = 1\n for (const part of parts) {\n bytes.set(part, offset)\n offset += part.length\n }\n return sha256Bytes(bytes) as LedgerHash\n}\n\nfunction decodeLeaves(leaves: readonly LedgerHash[]): Uint8Array[] {\n const decoded = decodeAll(leaves)\n if (decoded === undefined) {\n throw new ValidationError('merkle leaves must be sha256:<64 lowercase hex> hashes')\n }\n return decoded\n}\n\nfunction decodeAll(hashes: readonly string[]): Uint8Array[] | undefined {\n const out: Uint8Array[] = []\n for (const hash of hashes) {\n if (typeof hash !== 'string' || !LEDGER_HASH_PATTERN.test(hash)) return undefined\n out.push(fromHex(hash.slice('sha256:'.length)))\n }\n return out\n}\n\nfunction toLedgerHash(bytes: Uint8Array): LedgerHash {\n return `sha256:${toHex(bytes)}`\n}\n\nfunction largestPowerOfTwoBelow(n: number): number {\n let k = 1\n while (k * 2 < n) k *= 2\n return k\n}\n\n\n\nfunction isSize(n: number): boolean {\n return Number.isSafeInteger(n) && n >= 0\n}\n\nfunction equal(a: Uint8Array, b: Uint8Array): boolean {\n if (a.length !== b.length) return false\n for (let i = 0; i < a.length; i++) if (a[i] !== b[i]) return false\n return true\n}\n\nfunction refused(reason: string): MerkleVerification {\n return { verified: false, reason }\n}\n\nfunction toHex(bytes: Uint8Array): string {\n return Array.from(bytes, (byte) => byte.toString(16).padStart(2, '0')).join('')\n}\n\nfunction fromHex(hex: string): Uint8Array {\n const bytes = new Uint8Array(hex.length / 2)\n for (let i = 0; i < bytes.length; i++) bytes[i] = Number.parseInt(hex.slice(i * 2, i * 2 + 2), 16)\n return bytes\n}\n"],"mappings":"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"}
|