@iowarp/clio-coder 0.4.8 → 0.4.9
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 +82 -0
- package/README.md +7 -6
- package/dist/{acp-JWPQZM2D.js → acp-ZWZCPS2A.js} +13 -13
- package/dist/{agents-4GCDIRVX.js → agents-LYSOWZUE.js} +53 -52
- package/dist/assets/codewiki.json +1 -1
- package/dist/{auth-SYAKTDQE.js → auth-WBQGKWQ5.js} +27 -27
- package/dist/{background-OW67WMYR.js → background-BUMOBAQN.js} +4 -4
- package/dist/{builtins-TKS63VNV.js → builtins-ODRJOEDI.js} +7 -7
- package/dist/{chunk-JLBVCROW.js → chunk-2DRRZ57Q.js} +33 -24
- package/dist/chunk-2JBZYUPY.js +105 -0
- package/dist/chunk-2KUBKL63.js +336 -0
- package/dist/{chunk-K45LHSCI.js → chunk-2VBWFXYE.js} +7 -3
- package/dist/{chunk-XTLJDC2X.js → chunk-2X2R3UTH.js} +23 -18
- package/dist/{chunk-5HULHKT2.js → chunk-37LW32LZ.js} +5 -5
- package/dist/{chunk-W7KNI3F5.js → chunk-3AND2EFU.js} +5 -5
- package/dist/{chunk-36XSBPXL.js → chunk-3RDHGNU7.js} +95 -27
- package/dist/{chunk-BIY22UUK.js → chunk-3SUDBGEI.js} +11 -10
- package/dist/{chunk-3IQOZRQ6.js → chunk-3TQN67I2.js} +7 -7
- package/dist/{chunk-KWJXCL2X.js → chunk-3U4BL2EV.js} +3 -3
- package/dist/{chunk-RBES4TCZ.js → chunk-3UQADNG2.js} +3 -3
- package/dist/{chunk-V4ZKOKRB.js → chunk-434LRQ6Z.js} +61 -53
- package/dist/{chunk-MWMW53WW.js → chunk-4ATBOFRP.js} +649 -193
- package/dist/{chunk-QGIC5SX5.js → chunk-4DNL43EZ.js} +3 -3
- package/dist/{chunk-GVU4CXPJ.js → chunk-4HFJKRGZ.js} +113 -54
- package/dist/{chunk-5A6XR3RJ.js → chunk-555E2WVV.js} +16 -2
- package/dist/{chunk-LZDLYSUN.js → chunk-5RTEFNBP.js} +3 -3
- package/dist/{chunk-HMGAKB7E.js → chunk-64XJW7NT.js} +15 -15
- package/dist/{chunk-EXKUF426.js → chunk-7FBCRWVT.js} +280 -280
- package/dist/{chunk-K3W6BF5C.js → chunk-7JSOSVLP.js} +2 -2
- package/dist/{chunk-WFTSK7N3.js → chunk-7N3OLLSL.js} +4 -4
- package/dist/{chunk-JRA6OBHY.js → chunk-A6DULIMH.js} +17 -5
- package/dist/{chunk-R5NRX5N4.js → chunk-AB3QXXBC.js} +2 -2
- package/dist/chunk-ACCECAH4.js +49 -0
- package/dist/{chunk-GJBJHJNY.js → chunk-AM6CEP2K.js} +5 -5
- package/dist/{chunk-MUXNDNMZ.js → chunk-AY4XE6GN.js} +19 -13
- package/dist/{chunk-MATCRH3M.js → chunk-BBA2TAWV.js} +9 -9
- package/dist/{chunk-PMUUAABD.js → chunk-BMNVVKEW.js} +9 -9
- package/dist/{chunk-TOPICHGR.js → chunk-CTGZCEI6.js} +2 -2
- package/dist/{chunk-L75H5B3B.js → chunk-DIAJYJYG.js} +2 -2
- package/dist/{chunk-JIMWEYWO.js → chunk-EHZRAB4U.js} +2 -2
- package/dist/{chunk-YXANQGCX.js → chunk-EM2DIQAJ.js} +6 -6
- package/dist/{chunk-JCVIL6TY.js → chunk-ETF4ROKH.js} +4 -4
- package/dist/{chunk-5W4FRA5Q.js → chunk-F2YM3JY4.js} +483 -253
- package/dist/{chunk-YGIV24MF.js → chunk-FEBQWHJT.js} +21 -16
- package/dist/{chunk-PGEFOTJB.js → chunk-FPS4R2RN.js} +5 -4
- package/dist/{chunk-XC5POIL4.js → chunk-G5R53COU.js} +1 -1
- package/dist/chunk-GHXGMFQ5.js +40 -0
- package/dist/{chunk-QLKCCC2J.js → chunk-GJDRMBDI.js} +14 -14
- package/dist/{chunk-2ZWLMA3T.js → chunk-GREYLTZ5.js} +7 -7
- package/dist/{chunk-YXFKLMX2.js → chunk-H2WSCZZT.js} +22 -6
- package/dist/{chunk-FNVPQQYT.js → chunk-H6IUCY6Q.js} +2 -2
- package/dist/{chunk-5C2OQHLR.js → chunk-H72DCH3E.js} +92 -203
- package/dist/{chunk-JYKUMHCQ.js → chunk-H7TXJR23.js} +21 -21
- package/dist/chunk-HBJQQTKM.js +40 -0
- package/dist/chunk-HCVKSGNZ.js +990 -0
- package/dist/{chunk-ARRUMZ7X.js → chunk-I47EJPYL.js} +3 -3
- package/dist/{chunk-YKIIWURD.js → chunk-IALGWTLO.js} +3 -3
- package/dist/{chunk-FB3KTE2J.js → chunk-IALZJE37.js} +4 -4
- package/dist/{chunk-RAUOKUZV.js → chunk-IC7JXLOM.js} +15 -10
- package/dist/{chunk-LLCGGVSW.js → chunk-IOSVTTCD.js} +7 -7
- package/dist/{chunk-DBREN25X.js → chunk-IPTPMLA6.js} +8 -3
- package/dist/{chunk-V552WL53.js → chunk-IZZI3SKQ.js} +3 -67
- package/dist/{chunk-UDAK6GR2.js → chunk-JIYWMQZ5.js} +2 -2
- package/dist/{chunk-O3HSB2YL.js → chunk-JKU34ACI.js} +2 -2
- package/dist/{chunk-6X7VOCDY.js → chunk-JTR3VSV3.js} +3 -3
- package/dist/{chunk-O2QJDRWP.js → chunk-JU6MAMRJ.js} +4 -4
- package/dist/chunk-JURMQWVJ.js +15 -0
- package/dist/{chunk-STC6CWUZ.js → chunk-K3XN4LZ4.js} +5 -5
- package/dist/{chunk-ATB3Q7YO.js → chunk-KIVFXGBM.js} +27 -2
- package/dist/{chunk-WJWNZXRM.js → chunk-KOAHT3N2.js} +2 -2
- package/dist/chunk-KP5BPXR3.js +73 -0
- package/dist/{chunk-K53E2PTW.js → chunk-KRJQG47M.js} +3 -3
- package/dist/{chunk-IILXVWJY.js → chunk-KW6OJ7IY.js} +19 -21
- package/dist/{chunk-A46ILRS2.js → chunk-L3NBWLSN.js} +4 -4
- package/dist/{chunk-2U2U5POA.js → chunk-L4RUTLRL.js} +5 -5
- package/dist/{chunk-QYSAZMSH.js → chunk-LGTVWPRN.js} +2 -2
- package/dist/{chunk-KGP3UQGJ.js → chunk-LSQW6KZO.js} +5 -5
- package/dist/{chunk-P4JS3MH5.js → chunk-LWJYOHT3.js} +8 -8
- package/dist/{chunk-U3TPUXOQ.js → chunk-M6YLF66Z.js} +74 -40
- package/dist/{chunk-5D2FNBMG.js → chunk-MJ4QEJVT.js} +2 -2
- package/dist/{chunk-RM3XJX7P.js → chunk-MO65K5CH.js} +5 -5
- package/dist/{chunk-H5DPSUBB.js → chunk-MTOZEQHL.js} +3 -3
- package/dist/{chunk-6R5MBXBJ.js → chunk-NBPA5QM6.js} +2 -2
- package/dist/{chunk-H77XBUBM.js → chunk-NMBEW4PP.js} +3 -3
- package/dist/{chunk-QWUSS2QP.js → chunk-NPLLK3HO.js} +67 -87
- package/dist/{chunk-K5UJD6MM.js → chunk-NSYGPIVW.js} +5 -5
- package/dist/{context-EZZPT2ZV.js → chunk-NXTV5OI5.js} +30 -84
- package/dist/{chunk-F7Y6QTPL.js → chunk-NYDG4QP4.js} +4 -4
- package/dist/{chunk-PFZJMXIY.js → chunk-OA2GDACN.js} +2 -2
- package/dist/{chunk-Q32C6AWI.js → chunk-PJI57EC6.js} +4 -4
- package/dist/{chunk-EFXMQYI6.js → chunk-PJJBUGMR.js} +52 -52
- package/dist/{chunk-ICYIUNO4.js → chunk-PNJE7JPS.js} +18 -3
- package/dist/chunk-PP23PZEV.js +1347 -0
- package/dist/chunk-PPIFDSBK.js +409 -0
- package/dist/{chunk-RFULVPBX.js → chunk-PTFISXQO.js} +6 -5
- package/dist/{chunk-JV25I7ID.js → chunk-QB33Z5S7.js} +5 -5
- package/dist/{chunk-D55WO5J7.js → chunk-QGNII5VC.js} +8 -8
- package/dist/{chunk-RKFNU5UA.js → chunk-QI72X67S.js} +104 -27
- package/dist/chunk-QKHZZFKH.js +98 -0
- package/dist/{chunk-5UG6EZI3.js → chunk-RDKX2PME.js} +4 -4
- package/dist/{chunk-B5ZTR6KZ.js → chunk-RL7LJYN4.js} +1 -1
- package/dist/{chunk-BE4I3UJ2.js → chunk-RQROVOV3.js} +15 -13
- package/dist/{chunk-TEHVMHOK.js → chunk-S34A7BSP.js} +3 -3
- package/dist/{chunk-4P6M2TTE.js → chunk-SJETVJHX.js} +2 -2
- package/dist/{chunk-OPC4DQD6.js → chunk-SJMNU4ZS.js} +2 -2
- package/dist/{chunk-2JSCCEKO.js → chunk-SLLG2G44.js} +2 -2
- package/dist/{chunk-EPYATQMG.js → chunk-SQAZN2V3.js} +42 -16
- package/dist/{chunk-E2NSPYLC.js → chunk-SQBT46OF.js} +5 -5
- package/dist/{chunk-WTZVSMQZ.js → chunk-TCUOGIL2.js} +5 -5
- package/dist/{chunk-RRZFRIJP.js → chunk-TIWPKCVO.js} +5 -5
- package/dist/{chunk-QLAGXTTV.js → chunk-UIU7MGZ3.js} +5 -1
- package/dist/{chunk-WLHX3MM5.js → chunk-V4XJWDHR.js} +21 -11
- package/dist/{chunk-PJ5H5B7A.js → chunk-VPWGADBG.js} +18 -18
- package/dist/{chunk-GEYX2NZ5.js → chunk-VWFCAK34.js} +6 -6
- package/dist/{chunk-44U2OUSM.js → chunk-W72LLZAV.js} +2 -2
- package/dist/{chunk-ORRNGQDV.js → chunk-WGRDABW7.js} +4 -4
- package/dist/{chunk-RNLAPBJL.js → chunk-XFLSL7BT.js} +2 -2
- package/dist/{chunk-2SXGG2IV.js → chunk-XJZEDCNT.js} +6 -6
- package/dist/{chunk-UB33F3YW.js → chunk-XLLEL3K7.js} +5 -5
- package/dist/{chunk-2GPGAE5W.js → chunk-XNIZBOFV.js} +15 -1
- package/dist/{chunk-WS4FOGLY.js → chunk-XNZWWDC3.js} +2 -2
- package/dist/{chunk-P7GTE4FX.js → chunk-XRECG65F.js} +2 -2
- package/dist/chunk-XTQ7MEJG.js +457 -0
- package/dist/{chunk-GEVQNST4.js → chunk-XZWSP67B.js} +2 -2
- package/dist/{chunk-OEMFEL26.js → chunk-Y3M2T5RO.js} +3 -3
- package/dist/{chunk-HP7KJ5O2.js → chunk-YPQOPFP7.js} +6 -6
- package/dist/{chunk-MEHBW2SP.js → chunk-YQYINEJI.js} +6 -6
- package/dist/{chunk-RXI7K4J5.js → chunk-ZF6CV4WZ.js} +1338 -217
- package/dist/{chunk-3XE4NRLF.js → chunk-ZKJU55MX.js} +4 -2
- package/dist/{chunk-526ABLHD.js → chunk-ZKQ63XZ5.js} +12 -35
- package/dist/{chunk-PAQVETLA.js → chunk-ZKVMDNAN.js} +5 -5
- package/dist/cli/index.js +47 -37
- package/dist/{clio-BPBAPZGA.js → clio-JUDCLNHC.js} +7 -7
- package/dist/clio-context-tools-FT672MNZ.js +136 -0
- package/dist/{code-nav-KBQ3RIFK.js → code-nav-7OVCTP2Z.js} +28 -26
- package/dist/{components-6DKAXWFN.js → components-OZXZMDWU.js} +5 -5
- package/dist/{config-FWL5JK2H.js → config-P3ZQVF63.js} +80 -75
- package/dist/{config-graph-ACDB26L2.js → config-graph-GKAOBAS5.js} +74 -70
- package/dist/{configure-ZIZ4YV62.js → configure-25LRYZJG.js} +45 -44
- package/dist/context-72VQV7JX.js +73 -0
- package/dist/{context-VIL5MFRH.js → context-COWRWXP3.js} +74 -70
- package/dist/{context-Z3GOBHDK.js → context-WB3D474G.js} +12 -12
- package/dist/{context-clear-ZPB3L7MN.js → context-clear-Y4LYMWC6.js} +70 -66
- package/dist/{context-working-set-2GLBVF7L.js → context-working-set-TMZYVC7A.js} +15 -14
- package/dist/data-tool-KMBWKKWR.js +2987 -0
- package/dist/{detail-VSBWYSGZ.js → detail-4GLROGY5.js} +71 -67
- package/dist/{dispatch-runner-EEEHGKX4.js → dispatch-runner-TR3LBP5P.js} +92 -88
- package/dist/{docs-VMMWFVHL.js → docs-ZK777W2G.js} +3 -3
- package/dist/{doctor-V5L4IQGP.js → doctor-WC4OV2OB.js} +61 -59
- package/dist/{eval-VJYJ2BV3.js → eval-FUNWJNUJ.js} +45 -45
- package/dist/{evals-J2H5V6DD.js → evals-L73EBHSU.js} +4 -4
- package/dist/{evidence-Y35YSXH6.js → evidence-AVJ2RTHX.js} +80 -76
- package/dist/{evidence-POWAEBEW.js → evidence-P4NZOAK7.js} +70 -66
- package/dist/{evidence-XCCCLS36.js → evidence-Y55WKYHH.js} +79 -75
- package/dist/{evolve-GPG72VB6.js → evolve-MAWKRYWF.js} +75 -71
- package/dist/{extensions-YIZ7W3DA.js → extensions-PYQH3H47.js} +8 -8
- package/dist/{fleet-2MDCQ2VK.js → fleet-M4H2QBWT.js} +84 -80
- package/dist/{fleet-W2AF3TOJ.js → fleet-ULBXXRDR.js} +123 -119
- package/dist/{fleet-commands-WS56G26H.js → fleet-commands-7NNC4JZU.js} +17 -16
- package/dist/{fleet-decisions-MYGZ3JW7.js → fleet-decisions-EHEY7KPU.js} +9 -9
- package/dist/{fleet-graph-ELTBXBAV.js → fleet-graph-LQ2AHZT3.js} +15 -15
- package/dist/{fleet-inspect-45IK73L4.js → fleet-inspect-5IGBIIYZ.js} +76 -72
- package/dist/{fleet-preflight-T5NCZKHE.js → fleet-preflight-UTTNOKMG.js} +7 -2
- package/dist/{fleet-validate-VG4JBLA4.js → fleet-validate-YGILJKA6.js} +20 -20
- package/dist/{fleet-verify-VTSABAYO.js → fleet-verify-AUWTCDKR.js} +70 -66
- package/dist/{fleet-view-XC7WMKSS.js → fleet-view-TGUFCY5A.js} +73 -69
- package/dist/{init-VTJNNTIP.js → init-GFN2Z7NF.js} +94 -90
- package/dist/{interop-IU6BNA7C.js → interop-EF5JUWWK.js} +21 -21
- package/dist/{inventory-QPQUTUUZ.js → inventory-I6VJDDYF.js} +73 -69
- package/dist/{library-Q3NWL5CM.js → library-3J5IO2OJ.js} +13 -13
- package/dist/{library-LF7DLU6S.js → library-IJTOFTDS.js} +16 -15
- package/dist/{library-HUTAS57T.js → library-Z3KZSHPE.js} +27 -27
- package/dist/{library-import-PPW4YUC5.js → library-import-IMKFLDHX.js} +21 -21
- package/dist/{library-inventory-DIRVFRZU.js → library-inventory-CQP5D6GU.js} +13 -13
- package/dist/{library-validation-XHUZ3INE.js → library-validation-33UTX7AI.js} +11 -11
- package/dist/mcp-5FWZKUS6.js +26 -0
- package/dist/{memory-Z2LSKNV6.js → memory-36CWN67Y.js} +75 -71
- package/dist/{models-3FTREYPY.js → models-KQ6PQJJQ.js} +49 -49
- package/dist/{monitor-HF2MQRB3.js → monitor-XX6ZD6KC.js} +83 -79
- package/dist/{orchestrator-UYPA6W4S.js → orchestrator-SK6HDAOP.js} +1337 -772
- package/dist/{panes-736XB73K.js → panes-L27QRXUH.js} +12 -12
- package/dist/{panes-C4P3PIWT.js → panes-LXZIWNOZ.js} +4 -4
- package/dist/{paths-JQ4QYIYB.js → paths-7DJDU4P4.js} +5 -5
- package/dist/{preload-XSLRYH3Y.js → preload-K2TDYI4Y.js} +70 -66
- package/dist/{reset-V7QSPZYE.js → reset-73VU3XNT.js} +10 -10
- package/dist/{resources-OJGDFHYT.js → resources-3BYJYVYL.js} +16 -16
- package/dist/{run-T354SMDW.js → run-AR7PY6GW.js} +132 -128
- package/dist/run-script-H2KUDIII.js +41 -0
- package/dist/{settings-MWZXO6RV.js → settings-3VMBMWID.js} +4 -4
- package/dist/{share-Y5ZKJPND.js → share-HVWH4FPF.js} +21 -21
- package/dist/{skills-4GLZC4LN.js → skills-5TYEY75Q.js} +22 -22
- package/dist/{skills-eval-L5T7GODM.js → skills-eval-CK3MD63Z.js} +96 -87
- package/dist/{skills-inventory-LASKXEZI.js → skills-inventory-KSFYG3I6.js} +16 -16
- package/dist/{slash-commands-OIMRU36D.js → slash-commands-DMVHML7P.js} +47 -44
- package/dist/{steer-KMAM2Y2C.js → steer-XCD6V3EW.js} +4 -4
- package/dist/{support-AWC3XKPX.js → support-JAZL6VBR.js} +7 -7
- package/dist/{system-CD75NYBU.js → system-3TDQRMZZ.js} +26 -26
- package/dist/{targets-VSZX2J2S.js → targets-EZKHAYRN.js} +66 -65
- package/dist/{tasks-AN567LYH.js → tasks-SNEFHWYW.js} +12 -12
- package/dist/{terminal-lease-6KTWNHVY.js → terminal-lease-BNLFA4OF.js} +8 -7
- package/dist/{tools-AGRK3V5J.js → tools-7IM6BDCE.js} +12 -12
- package/dist/{trace-P4MQZD33.js → trace-C3MBGD4S.js} +8 -8
- package/dist/{tui-primitives-A6MUW32V.js → tui-primitives-36BY2774.js} +2 -2
- package/dist/{uninstall-BRUTEPIC.js → uninstall-WWLOSZ42.js} +10 -10
- package/dist/{upgrade-SBCGHQGJ.js → upgrade-ETK2JNSJ.js} +37 -47
- package/dist/{usage-BIDVTO6V.js → usage-S2HOB7BZ.js} +93 -89
- package/dist/{verifiers-LTGCAMXS.js → verifiers-QDTEVH7R.js} +24 -22
- package/dist/{verify-OZU4LLNP.js → verify-SUKUK6XM.js} +15 -14
- package/dist/web/client/assets/{abnfDiagram-VCTEODGH-C5wfoHm3.js → abnfDiagram-VCTEODGH-BznNOe_I.js} +1 -1
- package/dist/web/client/assets/{arc-oH91sfLl.js → arc-Pry-7G1_.js} +1 -1
- package/dist/web/client/assets/architecture-7GRP2DOG-BQO9DL_y.js +1 -0
- package/dist/web/client/assets/architectureDiagram-5GKGNRK7-CKPbdvyx.js +36 -0
- package/dist/web/client/assets/{blockDiagram-I7D4REHJ-wi0_CYHL.js → blockDiagram-I7D4REHJ-prINbpbM.js} +1 -1
- package/dist/web/client/assets/{c4Diagram-7LVT6UL2-DV7NYc2W.js → c4Diagram-7LVT6UL2-DkVRKtyU.js} +1 -1
- package/dist/web/client/assets/channel-c4EeUUqA.js +1 -0
- package/dist/web/client/assets/{chunk-4HAMMTFA-Bhsegh3F.js → chunk-4HAMMTFA-CV0Z1ApC.js} +1 -1
- package/dist/web/client/assets/{chunk-75Z2AOVW-RQCckcQG.js → chunk-75Z2AOVW-D34Nohxq.js} +1 -1
- package/dist/web/client/assets/chunk-DU6HZSFF-Das_cS-O.js +125 -0
- package/dist/web/client/assets/{chunk-F27PBJKO-BcNqv2x1.js → chunk-F27PBJKO-CmRojxkG.js} +1 -1
- package/dist/web/client/assets/{chunk-GMAD6QVW-Bq8JWiZT.js → chunk-GMAD6QVW-ClYZmc73.js} +1 -1
- package/dist/web/client/assets/{chunk-GVQU2GXP-DbchrAeJ.js → chunk-GVQU2GXP-B2BiHFt-.js} +1 -1
- package/dist/web/client/assets/{chunk-IMKFNOWR-DrpvjocK.js → chunk-IMKFNOWR-BGApZ8nP.js} +1 -1
- package/dist/web/client/assets/{chunk-L3NEJ4N5-DHLmTnCe.js → chunk-L3NEJ4N5-DIzCgpkY.js} +1 -1
- package/dist/web/client/assets/{chunk-OSK3NFVY-CsRbtN9n.js → chunk-OSK3NFVY-BPT-yePv.js} +1 -1
- package/dist/web/client/assets/{chunk-P2QGCYS3-aqPbxoMh.js → chunk-P2QGCYS3-BC1WTc2t.js} +1 -1
- package/dist/web/client/assets/{chunk-POPQ4Y6H-Dl5vw0h0.js → chunk-POPQ4Y6H-BSjzBmZU.js} +1 -1
- package/dist/web/client/assets/{chunk-PWAF6VOD-D7OBRSdO.js → chunk-PWAF6VOD-BIjLs86Z.js} +1 -1
- package/dist/web/client/assets/{chunk-SHT3W25Y-CdKCIwuB.js → chunk-SHT3W25Y-CduDz2cm.js} +1 -1
- package/dist/web/client/assets/{chunk-SVP7TREG-B94Nu_1-.js → chunk-SVP7TREG-XUn4pPAP.js} +1 -1
- package/dist/web/client/assets/{chunk-TICWLB2K-jjRQI_hk.js → chunk-TICWLB2K-DcBy2DKy.js} +1 -1
- package/dist/web/client/assets/{chunk-XXDRQBXY-azkbKE37.js → chunk-XXDRQBXY-DqAYeljN.js} +1 -1
- package/dist/web/client/assets/classDiagram-ZZMXUADV-C0HR7YKN.js +1 -0
- package/dist/web/client/assets/classDiagram-v2-VYDZK3BY-C0HR7YKN.js +1 -0
- package/dist/web/client/assets/cose-bilkent-JH36ORCC-CVh1icwb.js +1 -0
- package/dist/web/client/assets/{cynefin-OW5HDTMX--i9RDU5f.js → cynefin-OW5HDTMX-BecPbyM6.js} +1 -1
- package/dist/web/client/assets/{cynefinDiagram-5FMLGOSQ-cRcvyBdp.js → cynefinDiagram-5FMLGOSQ-BzMzFwyT.js} +1 -1
- package/dist/web/client/assets/{dagre-GXQ25YYZ-C9mZmAPe.js → dagre-GXQ25YYZ-CAWJmRMG.js} +1 -1
- package/dist/web/client/assets/{diagram-S7CK7UJ4-Oj_zlLDY.js → diagram-S7CK7UJ4--lp0ALmn.js} +1 -1
- package/dist/web/client/assets/{diagram-UQ7AKVKN-BWKbbfcR.js → diagram-UQ7AKVKN-gKUnsjcj.js} +1 -1
- package/dist/web/client/assets/{diagram-VSXAHHWV-C3N3f7DO.js → diagram-VSXAHHWV-BoN5D1Gh.js} +1 -1
- package/dist/web/client/assets/{diagram-VX7I27RA-CtDKDAWe.js → diagram-VX7I27RA-BMtuswQ6.js} +1 -1
- package/dist/web/client/assets/{diagram-Z3DM3KII-B8bkBRCz.js → diagram-Z3DM3KII-DtU8LXrA.js} +1 -1
- package/dist/web/client/assets/dist-v5Q1xZ2K.js +1 -0
- package/dist/web/client/assets/{ebnfDiagram-PWID7BFC-CskW-Whx.js → ebnfDiagram-PWID7BFC-DDcnv9BH.js} +1 -1
- package/dist/web/client/assets/{erDiagram-RLTQ6QDP-C-83cgCW.js → erDiagram-RLTQ6QDP-DvRb4iDL.js} +1 -1
- package/dist/web/client/assets/eventmodeling-NTZA5JFV-01h4SbTc.js +1 -0
- package/dist/web/client/assets/flowDiagram-HODETNUW-Bll_YZ6T.js +1 -0
- package/dist/web/client/assets/framework-YGoR34M4.js +9 -0
- package/dist/web/client/assets/ganttDiagram-EL5Y4UJY-DdFZ9hvH.js +292 -0
- package/dist/web/client/assets/{gitGraph-4MIJSDKK-B40cQtBE.js → gitGraph-4MIJSDKK-DjD_AAMj.js} +1 -1
- package/dist/web/client/assets/{gitGraphDiagram-WWUBYQGX-CH-7P7Di.js → gitGraphDiagram-WWUBYQGX-CDyN9n2u.js} +1 -1
- package/dist/web/client/assets/index-CVcy0FAn.js +75 -0
- package/dist/web/client/assets/{info-A6RAGUB7-eCCE9D_Q.js → info-A6RAGUB7-C_XK8Hq0.js} +1 -1
- package/dist/web/client/assets/{infoDiagram-27XIBGKW-DRnvqMjM.js → infoDiagram-27XIBGKW-DIe4tJ1i.js} +1 -1
- package/dist/web/client/assets/{ishikawaDiagram-5VMMS53U-DBA_55wp.js → ishikawaDiagram-5VMMS53U-CVl5unKI.js} +1 -1
- package/dist/web/client/assets/{journeyDiagram-3NMN7TZE-C-ewpNl7.js → journeyDiagram-3NMN7TZE-CPEB1Vt8.js} +1 -1
- package/dist/web/client/assets/{kanban-definition-UXKFOSKX-B1taGsu0.js → kanban-definition-UXKFOSKX-j-9WXjYQ.js} +1 -1
- package/dist/web/client/assets/{line-lZ0kyxDI.js → line-BIDAcEtX.js} +1 -1
- package/dist/web/client/assets/{linear-DIc8FgZj.js → linear-SzVmGSw4.js} +1 -1
- package/dist/web/client/assets/{mermaid-parser.core-SXolxpXw.js → mermaid-parser.core-Ux4vssh0.js} +3 -3
- package/dist/web/client/assets/{mermaid.core-DXgQtkNg.js → mermaid.core-CDuwVKeh.js} +4 -4
- package/dist/web/client/assets/{mindmap-definition-YA3MSWOX-DXJas9K7.js → mindmap-definition-YA3MSWOX-5MlQEeQ6.js} +1 -1
- package/dist/web/client/assets/{packet-AYTQ26CC-OqVl_07o.js → packet-AYTQ26CC-DRO66c9Q.js} +1 -1
- package/dist/web/client/assets/{pegDiagram-XKGWAZYB-CPE_zdfN.js → pegDiagram-XKGWAZYB-BakZnSjM.js} +1 -1
- package/dist/web/client/assets/{pie-WAS4IAKB-DAxnMBLe.js → pie-WAS4IAKB-BEzcmhz8.js} +1 -1
- package/dist/web/client/assets/{pieDiagram-E7YTZNPT-Uwjpufxv.js → pieDiagram-E7YTZNPT-DpmqgoPt.js} +1 -1
- package/dist/web/client/assets/prism-core-BtsZdCS6.js +1 -0
- package/dist/web/client/assets/{quadrantDiagram-AXDQQJYC-Bjs4yjgs.js → quadrantDiagram-AXDQQJYC-DuMPwwV2.js} +1 -1
- package/dist/web/client/assets/{radar-RG4KPBEZ-CuCKjHM3.js → radar-RG4KPBEZ-Djm3oXl5.js} +1 -1
- package/dist/web/client/assets/{railroad-74A4TZTK-CnQK-Cc1.js → railroad-74A4TZTK-Cpvkwsao.js} +1 -1
- package/dist/web/client/assets/railroad-abnf-HS5TGJTU-CpRQ3ruG.js +1 -0
- package/dist/web/client/assets/railroad-ebnf-LZEXJU2U-1Rm5a5eJ.js +1 -0
- package/dist/web/client/assets/railroad-peg-WCYAUIDC-C8344cTh.js +1 -0
- package/dist/web/client/assets/{railroadDiagram-O6MQD6OU-BDDIPNLL.js → railroadDiagram-O6MQD6OU-CgMS4B6R.js} +1 -1
- package/dist/web/client/assets/{requirementDiagram-BXWQKSXE-B5Ydyxc1.js → requirementDiagram-BXWQKSXE-CX5eoNdN.js} +1 -1
- package/dist/web/client/assets/rolldown-runtime-hePW80VL.js +1 -0
- package/dist/web/client/assets/{sankeyDiagram-P5KCCOFB-Bw2Qym75.js → sankeyDiagram-P5KCCOFB-CODBX2N3.js} +1 -1
- package/dist/web/client/assets/{sequenceDiagram-WJ2MYXX4-BZf36nO0.js → sequenceDiagram-WJ2MYXX4-eUhhF8OR.js} +1 -1
- package/dist/web/client/assets/src-B6xuSHsQ.js +1 -0
- package/dist/web/client/assets/{stateDiagram-D77RDMKH-DnH6JRkp.js → stateDiagram-D77RDMKH-vR6l0NC2.js} +1 -1
- package/dist/web/client/assets/stateDiagram-v2-MP3YSRHH-BYUm8jLY.js +1 -0
- package/dist/web/client/assets/{swimlanes-42K2YHIH-D9PZmtZg.js → swimlanes-42K2YHIH-v9Tw_zX7.js} +1 -1
- package/dist/web/client/assets/swimlanesDiagram-VR7AAH4N-B2jdCvhD.js +8 -0
- package/dist/web/client/assets/{timeline-definition-24CTP7MA-CrkZZBo7.js → timeline-definition-24CTP7MA-DxianbhU.js} +1 -1
- package/dist/web/client/assets/{treeView-Q6P3EWNA-C9zDShoC.js → treeView-Q6P3EWNA-DLxnZb9R.js} +1 -1
- package/dist/web/client/assets/{treemap-WGGIJYW6-B-plj9yK.js → treemap-WGGIJYW6-I7UnZ6xJ.js} +1 -1
- package/dist/web/client/assets/{vennDiagram-4TSXK5OY-VeOdaphN.js → vennDiagram-4TSXK5OY-Ar7M8Mrj.js} +1 -1
- package/dist/web/client/assets/{wardley-WFR3VGLG-Wl1P_m6L.js → wardley-WFR3VGLG-B8ZSHeDu.js} +1 -1
- package/dist/web/client/assets/{wardleyDiagram-VM6X3IG4-B85-R9t2.js → wardleyDiagram-VM6X3IG4-Qks2FmIn.js} +1 -1
- package/dist/web/client/assets/{xychartDiagram-S5SC5T6Z-BrD8OW8m.js → xychartDiagram-S5SC5T6Z-BBBjRtiE.js} +1 -1
- package/dist/web/client/index.html +3 -1
- package/dist/web/reads-worker.js +17 -17
- package/dist/web/server.js +25 -25
- package/dist/{web-EU6ATJWA.js → web-EMGUGGEI.js} +3 -3
- package/dist/{web-fetch-U22Q7HV4.js → web-fetch-6BRRVQON.js} +22 -5
- package/dist/{wiki-generate-LZRLFG6I.js → wiki-generate-XHSJTDOP.js} +104 -100
- package/dist/{with-panes-X5CZOGML.js → with-panes-Z6BTEHMZ.js} +11 -11
- package/dist/worker/entry.js +101 -87
- package/docs/README.md +1 -1
- package/docs/architecture/artifact-placement.md +12 -1
- package/docs/architecture/library.md +1 -1
- package/docs/architecture/prompt-envelope-and-tools.md +37 -27
- package/docs/architecture/safety-model.md +19 -6
- package/docs/architecture/session-lifecycle.md +10 -4
- package/docs/architecture/tui-design.md +37 -14
- package/docs/guide/commands-and-modes.md +39 -19
- package/docs/guide/configuration-and-targets.md +7 -5
- package/docs/guide/configuration-reference.md +116 -13
- package/docs/guide/environment-variables.md +2 -5
- package/docs/guide/fleet-dispatch.md +3 -2
- package/docs/guide/glossary.md +1 -1
- package/docs/guide/installation-and-lifecycle.md +2 -2
- package/docs/guide/resource-library.md +1 -1
- package/docs/guide/tool-usage.md +166 -64
- package/docs/guide/troubleshooting.md +1 -1
- package/docs/process/documentation-guide.md +1 -0
- package/docs/process/fleet-demo-runbook.md +6 -6
- package/docs/process/scientific-validation.md +22 -2
- package/docs/process/tool-audit-v0.4.9.md +357 -0
- package/package.json +1 -1
- package/src/cli/argv.ts +31 -0
- package/src/cli/clio.ts +17 -13
- package/src/cli/config.ts +4 -0
- package/src/cli/doctor-panes.ts +1 -1
- package/src/cli/doctor.ts +3 -1
- package/src/cli/index.ts +14 -1
- package/src/cli/mcp.ts +106 -0
- package/src/cli/skills-eval.ts +8 -2
- package/src/cli/upgrade.ts +34 -38
- package/src/cli/verifiers.ts +1 -1
- package/src/core/bash-exec.ts +27 -4
- package/src/core/config.ts +2 -1
- package/src/core/defaults.ts +10 -1
- package/src/core/event-bus.ts +1 -1
- package/src/core/run-records.ts +438 -0
- package/src/core/safe-exec.ts +506 -56
- package/src/core/skill-activation.ts +5 -3
- package/src/core/termination.ts +3 -3
- package/src/core/tool-names.ts +33 -12
- package/src/domains/context/clio-md.ts +1 -1
- package/src/domains/context/worker/pressure.ts +6 -2
- package/src/domains/context/working-set/path-index.ts +7 -2
- package/src/domains/dispatch/code-step.ts +7 -2
- package/src/domains/dispatch/contract.ts +7 -0
- package/src/domains/dispatch/execution-role.ts +3 -3
- package/src/domains/dispatch/execution-scheduler.ts +204 -79
- package/src/domains/dispatch/extension.ts +131 -14
- package/src/domains/dispatch/fleet-preflight.ts +18 -3
- package/src/domains/dispatch/fleet-run.ts +1 -0
- package/src/domains/dispatch/gate-decisions.ts +3 -3
- package/src/domains/dispatch/heartbeat.ts +1 -1
- package/src/domains/dispatch/host-verification.ts +16 -14
- package/src/domains/dispatch/receipt-findings.ts +3 -4
- package/src/domains/dispatch/reservation-store.ts +7 -9
- package/src/domains/dispatch/route-facts.ts +1 -1
- package/src/domains/dispatch/state.ts +3 -3
- package/src/domains/dispatch/types.ts +1 -1
- package/src/domains/evidence/build.ts +35 -7
- package/src/domains/gateway/mcp/client.ts +923 -0
- package/src/domains/gateway/mcp/config.ts +456 -0
- package/src/domains/gateway/mcp/index.ts +88 -0
- package/src/domains/gateway/mcp/protocol.ts +273 -0
- package/src/domains/gateway/mcp/trust.ts +263 -0
- package/src/domains/lifecycle/doctor.ts +17 -3
- package/src/domains/mux/contract.ts +5 -9
- package/src/domains/mux/detect.ts +1 -1
- package/src/domains/mux/extension.ts +1 -1
- package/src/domains/mux/protocol.ts +5 -7
- package/src/domains/mux/socket-client.ts +3 -3
- package/src/domains/observability/accountability.ts +2 -2
- package/src/domains/observability/contract.ts +7 -3
- package/src/domains/observability/evidence-index.ts +2 -2
- package/src/domains/observability/projection.ts +10 -0
- package/src/domains/prompts/compiler.ts +41 -23
- package/src/domains/prompts/fragments/identity/docs-routing.md +2 -2
- package/src/domains/prompts/fragments/operating/skills.md +12 -10
- package/src/domains/providers/index.ts +5 -1
- package/src/domains/providers/models/local-models/clio-coder-local-coding-targets.yaml +42 -10
- package/src/domains/providers/probe/http.ts +44 -59
- package/src/domains/providers/probe/reasoning.ts +2 -0
- package/src/domains/providers/runtimes/local-native/llamacpp-embed.ts +20 -31
- package/src/domains/providers/runtimes/local-native/llamacpp-rerank.ts +9 -4
- package/src/domains/safety/action-classifier.ts +17 -1
- package/src/domains/safety/call-target.ts +14 -0
- package/src/domains/safety/contract.ts +1 -1
- package/src/domains/safety/finish-contract.ts +9 -3
- package/src/domains/safety/loop-detector.ts +1 -1
- package/src/domains/safety/policy-engine.ts +7 -0
- package/src/domains/safety/protected-artifacts.ts +3 -4
- package/src/domains/safety/rejection-feedback.ts +1 -1
- package/src/domains/safety/scope.ts +2 -3
- package/src/domains/safety/validation-contract.ts +3 -2
- package/src/domains/scheduling/budget.ts +5 -3
- package/src/domains/scheduling/contract.ts +2 -1
- package/src/domains/scheduling/extension.ts +3 -3
- package/src/domains/session/compaction/branch-summary.ts +1 -1
- package/src/domains/session/compaction/compact.ts +25 -2
- package/src/domains/session/compaction/cut-point.ts +1 -1
- package/src/domains/session/compaction/tokens.ts +5 -10
- package/src/domains/session/contract.ts +1 -1
- package/src/domains/session/cwd-fallback.ts +2 -2
- package/src/domains/session/handoff.ts +5 -1
- package/src/domains/session/history.ts +6 -0
- package/src/domains/session/manager.ts +14 -7
- package/src/domains/session/retry.ts +2 -1
- package/src/domains/session/session-artifacts.ts +12 -7
- package/src/domains/session/task-board.ts +2 -3
- package/src/engine/apis/openai-completions.ts +8 -0
- package/src/engine/loop-guard.ts +7 -0
- package/src/engine/provider-error-body.ts +65 -0
- package/src/engine/session.ts +118 -29
- package/src/engine/worker-runtime.ts +3 -0
- package/src/entry/boot-options.ts +2 -0
- package/src/entry/orchestrator.ts +18 -2
- package/src/interactive/chat-loop-policy.ts +1 -0
- package/src/interactive/chat-loop.ts +8 -4
- package/src/interactive/chat-panel.ts +23 -9
- package/src/interactive/chat-renderer.ts +33 -11
- package/src/interactive/clio-editor.ts +13 -5
- package/src/interactive/dispatch-board.ts +70 -30
- package/src/interactive/editor-submit.ts +30 -25
- package/src/interactive/footer/widgets.ts +12 -9
- package/src/interactive/interactive-presentation.ts +2 -3
- package/src/interactive/mux-bridge.ts +3 -7
- package/src/interactive/overlay-general-openers.ts +14 -7
- package/src/interactive/overlays/cwd-fallback.ts +1 -1
- package/src/interactive/overlays/library-model.ts +114 -35
- package/src/interactive/overlays/library.ts +52 -5
- package/src/interactive/overlays/list-overlay.ts +4 -1
- package/src/interactive/overlays/session-selector.ts +28 -23
- package/src/interactive/overlays/settings.ts +20 -1
- package/src/interactive/overlays/tree-selector.ts +47 -10
- package/src/interactive/panes-runtime.ts +1 -1
- package/src/interactive/renderers/compaction-summary.ts +1 -1
- package/src/interactive/renderers/provider-error.ts +118 -0
- package/src/interactive/renderers/retry-status.ts +59 -23
- package/src/interactive/renderers/tool-execution.ts +67 -7
- package/src/interactive/renderers/worker-answer.ts +198 -0
- package/src/interactive/renderers/worker-entry.ts +57 -163
- package/src/interactive/slash-commands.ts +26 -1
- package/src/interactive/slash-spec.ts +2 -2
- package/src/interactive/theme/labels.ts +66 -30
- package/src/interactive/turn-persistence.ts +6 -1
- package/src/interactive/turn-recovery.ts +2 -1
- package/src/interactive/turn-runtime.ts +22 -5
- package/src/interactive/view/artifacts.ts +3 -2
- package/src/interactive/view/view-overlay.ts +96 -20
- package/src/tools/agent-tools.ts +21 -7
- package/src/tools/artifact.ts +16 -8
- package/src/tools/bash.ts +90 -11
- package/src/tools/bootstrap.ts +42 -4
- package/src/tools/builtin-tool-catalog.ts +72 -7
- package/src/tools/context/index.ts +27 -31
- package/src/tools/context/library.ts +3 -1
- package/src/tools/context/surface.ts +12 -26
- package/src/tools/core-bootstrap.ts +72 -1
- package/src/tools/data/csv.ts +1189 -0
- package/src/tools/data/index.ts +308 -0
- package/src/tools/data/json.ts +1799 -0
- package/src/tools/data/jsonl.ts +561 -0
- package/src/tools/data/shared.ts +452 -0
- package/src/tools/edit-diff.ts +0 -7
- package/src/tools/edit.ts +115 -18
- package/src/tools/file-mutation-queue.ts +114 -4
- package/src/tools/find.ts +108 -29
- package/src/tools/gateway/caps.ts +11 -0
- package/src/tools/gateway/clio-context-surface.ts +41 -0
- package/src/tools/gateway/clio-context-tools.ts +77 -0
- package/src/tools/gateway/data-surface.ts +138 -0
- package/src/tools/gateway/data-tool.ts +201 -0
- package/src/tools/gateway/index.ts +342 -0
- package/src/tools/gateway/mcp-capabilities.ts +469 -0
- package/src/tools/grep.ts +88 -33
- package/src/tools/harness-extensions.ts +3 -0
- package/src/tools/ignore-policy.ts +7 -5
- package/src/tools/ls.ts +111 -20
- package/src/tools/policy.ts +35 -13
- package/src/tools/presentation.ts +6 -0
- package/src/tools/read.ts +634 -156
- package/src/tools/registry.ts +94 -6
- package/src/tools/run-script.ts +997 -0
- package/src/tools/spawn-hygiene.ts +157 -5
- package/src/tools/surface.ts +163 -0
- package/src/tools/verify/authoring.ts +8 -3
- package/src/tools/verify/catalog.ts +14 -1
- package/src/tools/verify/numeric.ts +367 -59
- package/src/tools/verify/perf.ts +171 -9
- package/src/tools/verify/scripts.ts +178 -26
- package/src/tools/web-fetch-surface.ts +22 -0
- package/src/tools/web-fetch.ts +26 -1
- package/src/tools/write.ts +45 -19
- package/dist/chunk-B6UM3OZC.js +0 -15
- package/dist/chunk-GJ24ODAX.js +0 -196
- package/dist/chunk-LZCCBLRC.js +0 -57
- package/dist/web/client/assets/architecture-7GRP2DOG-EGozsYEO.js +0 -1
- package/dist/web/client/assets/architectureDiagram-5GKGNRK7-z9FokbJl.js +0 -36
- package/dist/web/client/assets/channel-CiUWbHN9.js +0 -1
- package/dist/web/client/assets/chunk-DU6HZSFF-C5USiOAy.js +0 -125
- package/dist/web/client/assets/classDiagram-ZZMXUADV-CMODalmo.js +0 -1
- package/dist/web/client/assets/classDiagram-v2-VYDZK3BY-CMODalmo.js +0 -1
- package/dist/web/client/assets/cose-bilkent-JH36ORCC-RbQL23qS.js +0 -1
- package/dist/web/client/assets/dist-D0_q-A2b.js +0 -1
- package/dist/web/client/assets/eventmodeling-NTZA5JFV-DjVq8wKU.js +0 -1
- package/dist/web/client/assets/flowDiagram-HODETNUW-BUiCBGXt.js +0 -1
- package/dist/web/client/assets/ganttDiagram-EL5Y4UJY-B2lb8lvF.js +0 -292
- package/dist/web/client/assets/index-FSIC94pi.js +0 -83
- package/dist/web/client/assets/prism-core-BngLtbUd.js +0 -1
- package/dist/web/client/assets/railroad-abnf-HS5TGJTU-BcW01NZG.js +0 -1
- package/dist/web/client/assets/railroad-ebnf-LZEXJU2U-B7YCEDDd.js +0 -1
- package/dist/web/client/assets/railroad-peg-WCYAUIDC-DjNZbSTZ.js +0 -1
- package/dist/web/client/assets/src-yeptRXpt.js +0 -1
- package/dist/web/client/assets/stateDiagram-v2-MP3YSRHH-C7QtHeK4.js +0 -1
- package/dist/web/client/assets/swimlanesDiagram-VR7AAH4N-CBZlPFky.js +0 -8
|
@@ -4,17 +4,54 @@
|
|
|
4
4
|
* names a reference file of the same shape and a tolerance. This module
|
|
5
5
|
* decides pass or fail and writes the structured report; it reads no file and
|
|
6
6
|
* runs nothing.
|
|
7
|
+
*
|
|
8
|
+
* The verdict is a statement about the declared tolerance only. A payload
|
|
9
|
+
* that passes agrees with the reference within the named bounds; whether the
|
|
10
|
+
* reference itself is scientifically right is not established by this module.
|
|
7
11
|
*/
|
|
8
12
|
|
|
9
13
|
export type NumericToleranceKind = "relative" | "absolute" | "ulp";
|
|
10
14
|
|
|
15
|
+
/**
|
|
16
|
+
* How the named bounds combine. `all` (the default) requires every named
|
|
17
|
+
* bound to hold, which is the strict conjunction; `any` passes when at least
|
|
18
|
+
* one named bound holds, which is the common `|a-e| <= abs OR |a-e| <= rel*|e|`
|
|
19
|
+
* formula when both are named. The two rules are not interchangeable, so the
|
|
20
|
+
* report always states which one judged the payload.
|
|
21
|
+
*/
|
|
22
|
+
export type NumericToleranceCombine = "all" | "any";
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* How a pair with a NaN or an infinity on either side is judged. `fail` (the
|
|
26
|
+
* default) rejects every such pair as not finite. `match` accepts NaN against
|
|
27
|
+
* NaN and an infinity against the same-signed infinity, and rejects every
|
|
28
|
+
* other pairing.
|
|
29
|
+
*/
|
|
30
|
+
export type NumericNonFinitePolicy = "fail" | "match";
|
|
31
|
+
|
|
32
|
+
export const DEFAULT_NUMERIC_COMBINE: NumericToleranceCombine = "all";
|
|
33
|
+
export const DEFAULT_NUMERIC_NON_FINITE: NumericNonFinitePolicy = "fail";
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* The largest admissible `ulp` bound. `ulpDistance` reports a distance past
|
|
37
|
+
* the safe-integer range as Infinity, so a bound within the range judges
|
|
38
|
+
* exactly: Infinity exceeds it only when the true distance does. A larger
|
|
39
|
+
* bound would turn that sentinel into a spurious failure, so the normalizer
|
|
40
|
+
* refuses it.
|
|
41
|
+
*/
|
|
42
|
+
export const MAX_ULP_TOLERANCE = Number.MAX_SAFE_INTEGER;
|
|
43
|
+
|
|
11
44
|
export interface NumericTolerance {
|
|
12
45
|
/** |actual - expected| / |expected| must not exceed this. Zero expected passes only on exact equality. */
|
|
13
46
|
relative?: number;
|
|
14
47
|
/** |actual - expected| must not exceed this. */
|
|
15
48
|
absolute?: number;
|
|
16
|
-
/** Distance in representable doubles between actual and expected must not exceed this integer. */
|
|
49
|
+
/** Distance in representable doubles between actual and expected must not exceed this integer, at most MAX_ULP_TOLERANCE. */
|
|
17
50
|
ulp?: number;
|
|
51
|
+
/** Combination rule for the named bounds; absent means `all`. */
|
|
52
|
+
combine?: NumericToleranceCombine;
|
|
53
|
+
/** Non-finite pairing policy; absent means `fail`. */
|
|
54
|
+
nonFinite?: NumericNonFinitePolicy;
|
|
18
55
|
}
|
|
19
56
|
|
|
20
57
|
export type NumericValue = number | number[];
|
|
@@ -28,37 +65,110 @@ export type NumericFailureReason =
|
|
|
28
65
|
| "not-finite"
|
|
29
66
|
| NumericToleranceKind;
|
|
30
67
|
|
|
68
|
+
/**
|
|
69
|
+
* A number as the report writes it. JSON has no spelling for NaN or the
|
|
70
|
+
* infinities: `JSON.stringify` writes each as null, and null already means
|
|
71
|
+
* "undefined" in a deviation (a relative deviation against zero, a ulp
|
|
72
|
+
* distance to a non-finite value). So a non-finite value is written by name,
|
|
73
|
+
* the protobuf JSON convention, and a serialized report reads back with every
|
|
74
|
+
* distinction intact. `reportedNumberValue` restores the number.
|
|
75
|
+
*/
|
|
76
|
+
export type ReportedNumber = number | "NaN" | "Infinity" | "-Infinity";
|
|
77
|
+
|
|
78
|
+
function reportedNumber(value: number): ReportedNumber {
|
|
79
|
+
if (Number.isNaN(value)) return "NaN";
|
|
80
|
+
if (value === Number.POSITIVE_INFINITY) return "Infinity";
|
|
81
|
+
if (value === Number.NEGATIVE_INFINITY) return "-Infinity";
|
|
82
|
+
return value;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/** The number a `ReportedNumber` names. */
|
|
86
|
+
export function reportedNumberValue(value: ReportedNumber): number {
|
|
87
|
+
return typeof value === "number" ? value : Number(value);
|
|
88
|
+
}
|
|
89
|
+
|
|
31
90
|
export interface NumericDeviation {
|
|
32
91
|
/** Array index of the worst element; absent for a scalar. */
|
|
33
92
|
index?: number;
|
|
34
|
-
actual:
|
|
35
|
-
expected:
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
93
|
+
actual: ReportedNumber;
|
|
94
|
+
expected: ReportedNumber;
|
|
95
|
+
/** |actual - expected|; `"Infinity"` when the difference overflows or the pair is a mismatched non-finite. */
|
|
96
|
+
absolute: ReportedNumber;
|
|
97
|
+
/**
|
|
98
|
+
* Relative deviation; `"Infinity"` when the quotient overflows; null when
|
|
99
|
+
* it is undefined (expected is zero and actual is not, or the pair is a
|
|
100
|
+
* mismatched non-finite).
|
|
101
|
+
*/
|
|
102
|
+
relative: ReportedNumber | null;
|
|
103
|
+
/** Distance in representable doubles; `"Infinity"` past the safe-integer range; null when either side is not finite. */
|
|
104
|
+
ulp: ReportedNumber | null;
|
|
105
|
+
/**
|
|
106
|
+
* Present when either side is not finite. `matched` means the non-finite
|
|
107
|
+
* policy accepted the pair (NaN against NaN, or same-signed infinities);
|
|
108
|
+
* the deviation fields then read zero because the rule, not arithmetic,
|
|
109
|
+
* declared the pair equal. `mismatched` keeps the infinite deviation.
|
|
110
|
+
*/
|
|
111
|
+
nonFinite?: "matched" | "mismatched";
|
|
41
112
|
}
|
|
42
113
|
|
|
43
114
|
export interface NumericKeyReport {
|
|
44
115
|
key: string;
|
|
45
116
|
passed: boolean;
|
|
46
|
-
/**
|
|
117
|
+
/** Why the key failed, in schema order; empty on pass. */
|
|
47
118
|
failed: NumericFailureReason[];
|
|
48
|
-
/**
|
|
119
|
+
/** Named bounds the worst element satisfied; empty when nothing was comparable. */
|
|
120
|
+
held: NumericToleranceKind[];
|
|
121
|
+
/** Named bounds the worst element violated, listed even when `combine: any` let the key pass. */
|
|
122
|
+
violated: NumericToleranceKind[];
|
|
123
|
+
/**
|
|
124
|
+
* Worst deviation for the key, present whenever both sides had a comparable
|
|
125
|
+
* value. A failing element outranks a passing one with a violated bound
|
|
126
|
+
* (possible only under `combine: any`), which outranks a clean one; within
|
|
127
|
+
* a tier the largest absolute deviation is the worst. So a key that passed
|
|
128
|
+
* only by `any` names the element that needed it, not the clean element
|
|
129
|
+
* that happened to deviate most.
|
|
130
|
+
*/
|
|
49
131
|
worst?: NumericDeviation;
|
|
50
132
|
/** One line a reader can act on. */
|
|
51
133
|
detail: string;
|
|
52
134
|
}
|
|
53
135
|
|
|
136
|
+
/** Identity of the reference payload the judgement read. */
|
|
137
|
+
export interface NumericReferenceProvenance {
|
|
138
|
+
/** The caller's label for the reference, for example `reference 'tests/ref.json'`. */
|
|
139
|
+
source: string;
|
|
140
|
+
/** The reference path when the caller supplied one; a sealed host path or a repository-relative catalog path. */
|
|
141
|
+
path?: string;
|
|
142
|
+
/** SHA-256 of the exact reference text. */
|
|
143
|
+
sha256: string;
|
|
144
|
+
bytes: number;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/** Identity of the payload text the judgement extracted from the command's stdout. */
|
|
148
|
+
export interface NumericPayloadProvenance {
|
|
149
|
+
sha256: string;
|
|
150
|
+
bytes: number;
|
|
151
|
+
}
|
|
152
|
+
|
|
54
153
|
export interface NumericCompareReport {
|
|
55
154
|
kind: "numeric-compare";
|
|
56
155
|
passed: boolean;
|
|
156
|
+
/** The tolerance exactly as declared, defaults not filled in. */
|
|
57
157
|
tolerance: NumericTolerance;
|
|
158
|
+
/** The combination rule that judged the payload, default applied. */
|
|
159
|
+
combine: NumericToleranceCombine;
|
|
160
|
+
/** The non-finite policy that judged the payload, default applied. */
|
|
161
|
+
nonFinite: NumericNonFinitePolicy;
|
|
162
|
+
/** The effective rule in words, for example `all of relative<=1e-6, absolute<=1e-9 must hold; non-finite values fail`. */
|
|
163
|
+
rule: string;
|
|
58
164
|
keys: NumericKeyReport[];
|
|
59
165
|
/** The keys that failed, sorted; empty on pass. */
|
|
60
166
|
failedKeys: string[];
|
|
61
167
|
summary: string;
|
|
168
|
+
/** Reference identity, present when the judgement read reference text. */
|
|
169
|
+
reference?: NumericReferenceProvenance;
|
|
170
|
+
/** Actual payload identity, present when the judgement extracted payload text. */
|
|
171
|
+
actual?: NumericPayloadProvenance;
|
|
62
172
|
}
|
|
63
173
|
|
|
64
174
|
export const NUMERIC_PAYLOAD_CAPS = Object.freeze({
|
|
@@ -66,13 +176,16 @@ export const NUMERIC_PAYLOAD_CAPS = Object.freeze({
|
|
|
66
176
|
elements: 1_000_000,
|
|
67
177
|
});
|
|
68
178
|
|
|
69
|
-
|
|
179
|
+
const TOLERANCE_FIELDS = new Set(["relative", "absolute", "ulp", "combine", "nonFinite"]);
|
|
180
|
+
const TOLERANCE_KINDS: ReadonlyArray<NumericToleranceKind> = ["relative", "absolute", "ulp"];
|
|
181
|
+
|
|
182
|
+
/** True when the tolerance names at least one bound and every named field is usable. */
|
|
70
183
|
export function normalizeNumericTolerance(value: unknown): NumericTolerance | Error {
|
|
71
184
|
if (value === null || typeof value !== "object" || Array.isArray(value)) {
|
|
72
185
|
return new Error("tolerance must be an object with relative, absolute, or ulp");
|
|
73
186
|
}
|
|
74
187
|
const record = value as Record<string, unknown>;
|
|
75
|
-
const unknown = Object.keys(record).filter((key) => key
|
|
188
|
+
const unknown = Object.keys(record).filter((key) => !TOLERANCE_FIELDS.has(key));
|
|
76
189
|
if (unknown.length > 0) return new Error(`tolerance has unknown field(s): ${unknown.sort().join(", ")}`);
|
|
77
190
|
const tolerance: NumericTolerance = {};
|
|
78
191
|
for (const kind of ["relative", "absolute"] as const) {
|
|
@@ -88,11 +201,24 @@ export function normalizeNumericTolerance(value: unknown): NumericTolerance | Er
|
|
|
88
201
|
if (typeof bound !== "number" || !Number.isInteger(bound) || bound < 0) {
|
|
89
202
|
return new Error("tolerance.ulp must be a non-negative integer");
|
|
90
203
|
}
|
|
204
|
+
if (bound > MAX_ULP_TOLERANCE) {
|
|
205
|
+
return new Error(`tolerance.ulp must not exceed ${MAX_ULP_TOLERANCE} (Number.MAX_SAFE_INTEGER)`);
|
|
206
|
+
}
|
|
91
207
|
tolerance.ulp = bound;
|
|
92
208
|
}
|
|
93
209
|
if (tolerance.relative === undefined && tolerance.absolute === undefined && tolerance.ulp === undefined) {
|
|
94
210
|
return new Error("tolerance must name at least one of relative, absolute, or ulp");
|
|
95
211
|
}
|
|
212
|
+
if (Object.hasOwn(record, "combine")) {
|
|
213
|
+
const combine = record.combine;
|
|
214
|
+
if (combine !== "all" && combine !== "any") return new Error("tolerance.combine must be all or any");
|
|
215
|
+
tolerance.combine = combine;
|
|
216
|
+
}
|
|
217
|
+
if (Object.hasOwn(record, "nonFinite")) {
|
|
218
|
+
const policy = record.nonFinite;
|
|
219
|
+
if (policy !== "fail" && policy !== "match") return new Error("tolerance.nonFinite must be fail or match");
|
|
220
|
+
tolerance.nonFinite = policy;
|
|
221
|
+
}
|
|
96
222
|
return tolerance;
|
|
97
223
|
}
|
|
98
224
|
|
|
@@ -109,7 +235,9 @@ function orderedBits(value: number): bigint {
|
|
|
109
235
|
* Distance in representable doubles between two finite numbers. Adjacent
|
|
110
236
|
* doubles are 1 apart, +0 and -0 are 0 apart, and a sign crossing counts every
|
|
111
237
|
* double in between. Returns Infinity when the distance exceeds the safe
|
|
112
|
-
* integer range or either side is not finite
|
|
238
|
+
* integer range or either side is not finite; every admissible bound is at
|
|
239
|
+
* most MAX_ULP_TOLERANCE, so that sentinel fails a bound only when the true
|
|
240
|
+
* distance does.
|
|
113
241
|
*/
|
|
114
242
|
export function ulpDistance(actual: number, expected: number): number {
|
|
115
243
|
if (!Number.isFinite(actual) || !Number.isFinite(expected)) return Number.POSITIVE_INFINITY;
|
|
@@ -118,7 +246,16 @@ export function ulpDistance(actual: number, expected: number): number {
|
|
|
118
246
|
return magnitude > BigInt(Number.MAX_SAFE_INTEGER) ? Number.POSITIVE_INFINITY : Number(magnitude);
|
|
119
247
|
}
|
|
120
248
|
|
|
121
|
-
/**
|
|
249
|
+
/**
|
|
250
|
+
* Parse command stdout or a reference file as a numeric payload, naming the
|
|
251
|
+
* fault when it is not one.
|
|
252
|
+
*
|
|
253
|
+
* JSON has no spelling for NaN, so NaN never arrives through this parser. An
|
|
254
|
+
* infinity can: `JSON.parse` turns an overflowing literal such as `1e999` into
|
|
255
|
+
* `Infinity`, and a validator that prints an overflowed measurement produces
|
|
256
|
+
* exactly that. The payload keeps it, and the tolerance's `nonFinite` policy
|
|
257
|
+
* decides how it is judged.
|
|
258
|
+
*/
|
|
122
259
|
export function parseNumericPayload(text: string, label: string): NumericPayload | Error {
|
|
123
260
|
let parsed: unknown;
|
|
124
261
|
try {
|
|
@@ -153,11 +290,69 @@ export function parseNumericPayload(text: string, label: string): NumericPayload
|
|
|
153
290
|
return Object.fromEntries(entries);
|
|
154
291
|
}
|
|
155
292
|
|
|
156
|
-
function
|
|
293
|
+
function effectiveNumericCombine(tolerance: NumericTolerance): NumericToleranceCombine {
|
|
294
|
+
return tolerance.combine ?? DEFAULT_NUMERIC_COMBINE;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
function effectiveNumericNonFinite(tolerance: NumericTolerance): NumericNonFinitePolicy {
|
|
298
|
+
return tolerance.nonFinite ?? DEFAULT_NUMERIC_NON_FINITE;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
/** The named bounds, in schema order. */
|
|
302
|
+
function namedKinds(tolerance: NumericTolerance): NumericToleranceKind[] {
|
|
303
|
+
return TOLERANCE_KINDS.filter((kind) => tolerance[kind] !== undefined);
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
/** NaN pairs with NaN; an infinity pairs with the same-signed infinity; nothing else pairs. */
|
|
307
|
+
function nonFinitePairMatches(actual: number, expected: number): boolean {
|
|
308
|
+
if (Number.isNaN(actual) && Number.isNaN(expected)) return true;
|
|
309
|
+
return actual === expected && !Number.isFinite(actual);
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
/** A deviation as arithmetic produced it, before the report encodes its non-finite values by name. */
|
|
313
|
+
interface Deviation {
|
|
314
|
+
index?: number;
|
|
315
|
+
actual: number;
|
|
316
|
+
expected: number;
|
|
317
|
+
absolute: number;
|
|
318
|
+
relative: number | null;
|
|
319
|
+
ulp: number | null;
|
|
320
|
+
nonFinite?: "matched" | "mismatched";
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
function reportDeviation(item: Deviation): NumericDeviation {
|
|
324
|
+
return {
|
|
325
|
+
...item,
|
|
326
|
+
actual: reportedNumber(item.actual),
|
|
327
|
+
expected: reportedNumber(item.expected),
|
|
328
|
+
absolute: reportedNumber(item.absolute),
|
|
329
|
+
relative: item.relative === null ? null : reportedNumber(item.relative),
|
|
330
|
+
ulp: item.ulp === null ? null : reportedNumber(item.ulp),
|
|
331
|
+
};
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
function deviation(
|
|
335
|
+
actual: number,
|
|
336
|
+
expected: number,
|
|
337
|
+
index: number | undefined,
|
|
338
|
+
nonFinite: NumericNonFinitePolicy,
|
|
339
|
+
): Deviation {
|
|
157
340
|
const finite = Number.isFinite(actual) && Number.isFinite(expected);
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
341
|
+
if (!finite) {
|
|
342
|
+
const matched = nonFinite === "match" && nonFinitePairMatches(actual, expected);
|
|
343
|
+
return {
|
|
344
|
+
...(index !== undefined ? { index } : {}),
|
|
345
|
+
actual,
|
|
346
|
+
expected,
|
|
347
|
+
absolute: matched ? 0 : Number.POSITIVE_INFINITY,
|
|
348
|
+
relative: matched ? 0 : null,
|
|
349
|
+
ulp: matched ? 0 : null,
|
|
350
|
+
nonFinite: matched ? "matched" : "mismatched",
|
|
351
|
+
};
|
|
352
|
+
}
|
|
353
|
+
const absolute = Math.abs(actual - expected);
|
|
354
|
+
let relative = expected === 0 ? (absolute === 0 ? 0 : null) : absolute / Math.abs(expected);
|
|
355
|
+
if (!Number.isFinite(absolute)) {
|
|
161
356
|
// Finite subtraction overflows only across signs, where division first
|
|
162
357
|
// is safe. Keep subtraction first for nearby values to preserve precision.
|
|
163
358
|
relative = Math.abs(actual / expected - 1);
|
|
@@ -168,12 +363,12 @@ function deviation(actual: number, expected: number, index?: number): NumericDev
|
|
|
168
363
|
expected,
|
|
169
364
|
absolute,
|
|
170
365
|
relative,
|
|
171
|
-
ulp:
|
|
366
|
+
ulp: ulpDistance(actual, expected),
|
|
172
367
|
};
|
|
173
368
|
}
|
|
174
369
|
|
|
175
|
-
/**
|
|
176
|
-
function violatedTolerances(item:
|
|
370
|
+
/** Named bounds the deviation violates, in schema order. */
|
|
371
|
+
function violatedTolerances(item: Deviation, tolerance: NumericTolerance): NumericToleranceKind[] {
|
|
177
372
|
const failed: NumericToleranceKind[] = [];
|
|
178
373
|
if (tolerance.relative !== undefined && (item.relative === null || item.relative > tolerance.relative)) {
|
|
179
374
|
failed.push("relative");
|
|
@@ -183,15 +378,104 @@ function violatedTolerances(item: NumericDeviation, tolerance: NumericTolerance)
|
|
|
183
378
|
return failed;
|
|
184
379
|
}
|
|
185
380
|
|
|
381
|
+
interface ElementJudgement {
|
|
382
|
+
failed: NumericFailureReason[];
|
|
383
|
+
held: NumericToleranceKind[];
|
|
384
|
+
violated: NumericToleranceKind[];
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
/**
|
|
388
|
+
* Judge one deviation under the combination rule. A mismatched non-finite
|
|
389
|
+
* pair fails as not finite before any bound is consulted; a matched pair
|
|
390
|
+
* passes by policy with no bound consulted at all.
|
|
391
|
+
*/
|
|
392
|
+
function judgeDeviation(
|
|
393
|
+
item: Deviation,
|
|
394
|
+
tolerance: NumericTolerance,
|
|
395
|
+
combine: NumericToleranceCombine,
|
|
396
|
+
): ElementJudgement {
|
|
397
|
+
if (item.nonFinite === "mismatched") return { failed: ["not-finite"], held: [], violated: [] };
|
|
398
|
+
if (item.nonFinite === "matched") return { failed: [], held: [], violated: [] };
|
|
399
|
+
const violated = violatedTolerances(item, tolerance);
|
|
400
|
+
const held = namedKinds(tolerance).filter((kind) => !violated.includes(kind));
|
|
401
|
+
const passed = combine === "all" ? violated.length === 0 : held.length > 0;
|
|
402
|
+
return { failed: passed ? [] : violated, held, violated };
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
/**
|
|
406
|
+
* Worst-first rank of an element's judgement: failing, then passing with a
|
|
407
|
+
* violated bound (which only `combine: any` allows), then clean. Ties inside
|
|
408
|
+
* a tier go to the larger absolute deviation.
|
|
409
|
+
*/
|
|
410
|
+
function severity(judgement: ElementJudgement): 0 | 1 | 2 {
|
|
411
|
+
if (judgement.failed.length > 0) return 2;
|
|
412
|
+
return judgement.violated.length > 0 ? 1 : 0;
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
/**
|
|
416
|
+
* Six significant digits with trailing fraction zeros dropped: `1.00000` reads
|
|
417
|
+
* `1`, `1.50000e-9` reads `1.5e-9`. An integer keeps every digit, so `500000`
|
|
418
|
+
* never collapses to `5`.
|
|
419
|
+
*/
|
|
186
420
|
function formatNumber(value: number): string {
|
|
187
|
-
|
|
421
|
+
if (!Number.isFinite(value)) return String(value);
|
|
422
|
+
const [mantissa = "", exponent] = value.toPrecision(6).split("e");
|
|
423
|
+
const trimmed = mantissa.includes(".") ? mantissa.replace(/\.?0+$/u, "") : mantissa;
|
|
424
|
+
return exponent === undefined ? trimmed : `${trimmed}e${exponent}`;
|
|
188
425
|
}
|
|
189
426
|
|
|
190
|
-
function describeDeviation(item:
|
|
427
|
+
function describeDeviation(item: Deviation): string {
|
|
191
428
|
const where = item.index === undefined ? "" : `[${item.index}]`;
|
|
429
|
+
if (item.nonFinite === "matched") {
|
|
430
|
+
return `${where} actual=${String(item.actual)} expected=${String(item.expected)} (non-finite values match by policy)`;
|
|
431
|
+
}
|
|
192
432
|
const relative = item.relative === null ? "undefined" : formatNumber(item.relative);
|
|
193
433
|
const ulp = item.ulp === null ? "undefined" : String(item.ulp);
|
|
194
|
-
|
|
434
|
+
const zeroReference =
|
|
435
|
+
item.nonFinite === undefined && item.expected === 0 && item.actual !== 0
|
|
436
|
+
? "; relative undefined: reference is zero"
|
|
437
|
+
: "";
|
|
438
|
+
return `${where} actual=${formatNumber(item.actual)} expected=${formatNumber(item.expected)} abs=${formatNumber(item.absolute)} rel=${relative} ulp=${ulp}${zeroReference}`;
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
/**
|
|
442
|
+
* A declared bound, printed exactly. The shortest round-trip spelling keeps
|
|
443
|
+
* every digit the catalog wrote; exponent form below 1e-3 and from 1e6 up
|
|
444
|
+
* keeps `1e-6` readable instead of `0.000001`.
|
|
445
|
+
*/
|
|
446
|
+
function formatBound(value: number): string {
|
|
447
|
+
if (value === 0) return "0";
|
|
448
|
+
const magnitude = Math.abs(value);
|
|
449
|
+
return magnitude < 1e-3 || magnitude >= 1e6 ? value.toExponential() : String(value);
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
function describeBound(kind: NumericToleranceKind, tolerance: NumericTolerance): string {
|
|
453
|
+
return `${kind}<=${formatBound(tolerance[kind] ?? 0)}`;
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
/** The effective judgement rule in words, so a reader never has to infer the conjunction from the tolerance object. */
|
|
457
|
+
export function describeNumericRule(tolerance: NumericTolerance): string {
|
|
458
|
+
const bounds = namedKinds(tolerance).map((kind) => describeBound(kind, tolerance));
|
|
459
|
+
const combine = effectiveNumericCombine(tolerance);
|
|
460
|
+
const clause =
|
|
461
|
+
bounds.length === 1
|
|
462
|
+
? `${bounds[0]} must hold`
|
|
463
|
+
: combine === "all"
|
|
464
|
+
? `all of ${bounds.join(", ")} must hold`
|
|
465
|
+
: `any of ${bounds.join(", ")} may hold`;
|
|
466
|
+
const nonFinite =
|
|
467
|
+
effectiveNumericNonFinite(tolerance) === "match"
|
|
468
|
+
? "NaN matches NaN and same-signed infinities match"
|
|
469
|
+
: "non-finite values fail";
|
|
470
|
+
return `${clause}; ${nonFinite}`;
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
function passedDetail(key: string, judgement: ElementJudgement, worst: Deviation): string {
|
|
474
|
+
if (worst.nonFinite === "matched")
|
|
475
|
+
return `${key}: non-finite values match by policy, worst${describeDeviation(worst)}`;
|
|
476
|
+
const partial =
|
|
477
|
+
judgement.violated.length > 0 ? ` by ${judgement.held.join(", ")} (${judgement.violated.join(", ")} violated)` : "";
|
|
478
|
+
return `${key}: within tolerance${partial}, worst${describeDeviation(worst)}`;
|
|
195
479
|
}
|
|
196
480
|
|
|
197
481
|
function compareElements(
|
|
@@ -199,87 +483,100 @@ function compareElements(
|
|
|
199
483
|
actual: number[],
|
|
200
484
|
expected: number[],
|
|
201
485
|
tolerance: NumericTolerance,
|
|
486
|
+
combine: NumericToleranceCombine,
|
|
487
|
+
nonFinite: NumericNonFinitePolicy,
|
|
202
488
|
): NumericKeyReport {
|
|
203
|
-
let worst:
|
|
204
|
-
let
|
|
489
|
+
let worst: Deviation | undefined;
|
|
490
|
+
let worstJudgement: ElementJudgement = { failed: [], held: [], violated: [] };
|
|
205
491
|
for (let index = 0; index < expected.length; index += 1) {
|
|
206
492
|
const item = deviation(
|
|
207
493
|
actual[index] as number,
|
|
208
494
|
expected[index] as number,
|
|
209
495
|
expected.length === 1 && actual.length === 1 ? undefined : index,
|
|
496
|
+
nonFinite,
|
|
210
497
|
);
|
|
211
|
-
const
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
const worse =
|
|
216
|
-
worst === undefined ||
|
|
217
|
-
(failed.length > 0 && worstFailed.length === 0) ||
|
|
218
|
-
(failed.length > 0 === worstFailed.length > 0 && item.absolute > worst.absolute);
|
|
498
|
+
const judgement = judgeDeviation(item, tolerance, combine);
|
|
499
|
+
const rank = severity(judgement);
|
|
500
|
+
const worstRank = severity(worstJudgement);
|
|
501
|
+
const worse = worst === undefined || rank > worstRank || (rank === worstRank && item.absolute > worst.absolute);
|
|
219
502
|
if (worse) {
|
|
220
503
|
worst = item;
|
|
221
|
-
|
|
504
|
+
worstJudgement = judgement;
|
|
222
505
|
}
|
|
223
506
|
}
|
|
224
|
-
if (worst === undefined)
|
|
225
|
-
|
|
507
|
+
if (worst === undefined) {
|
|
508
|
+
return { key, passed: true, failed: [], held: [], violated: [], detail: `${key}: empty array matches` };
|
|
509
|
+
}
|
|
510
|
+
const passed = worstJudgement.failed.length === 0;
|
|
226
511
|
return {
|
|
227
512
|
key,
|
|
228
513
|
passed,
|
|
229
|
-
failed:
|
|
230
|
-
|
|
514
|
+
failed: worstJudgement.failed,
|
|
515
|
+
held: worstJudgement.held,
|
|
516
|
+
violated: worstJudgement.violated,
|
|
517
|
+
worst: reportDeviation(worst),
|
|
231
518
|
detail: passed
|
|
232
|
-
?
|
|
233
|
-
: `${key}: failed ${
|
|
519
|
+
? passedDetail(key, worstJudgement, worst)
|
|
520
|
+
: `${key}: failed ${worstJudgement.failed.join(", ")} at worst${describeDeviation(worst)}`,
|
|
234
521
|
};
|
|
235
522
|
}
|
|
236
523
|
|
|
524
|
+
function structuralFailure(key: string, reason: NumericFailureReason, detail: string): NumericKeyReport {
|
|
525
|
+
return { key, passed: false, failed: [reason], held: [], violated: [], detail };
|
|
526
|
+
}
|
|
527
|
+
|
|
237
528
|
/**
|
|
238
529
|
* Compare a command's payload against the reference. Every key on either side
|
|
239
530
|
* is judged: a key missing on one side fails and names the side, a scalar
|
|
240
531
|
* against an array fails, arrays compare elementwise and fail on length
|
|
241
|
-
* mismatch, and
|
|
242
|
-
*
|
|
532
|
+
* mismatch, and a NaN or infinity fails as not finite unless the tolerance's
|
|
533
|
+
* `nonFinite` policy matches the pair. A comparable value passes when the
|
|
534
|
+
* named bounds hold under the tolerance's `combine` rule: every bound under
|
|
535
|
+
* `all` (the default), at least one under `any`.
|
|
243
536
|
*/
|
|
244
537
|
export function compareNumeric(
|
|
245
538
|
actual: NumericPayload,
|
|
246
539
|
reference: NumericPayload,
|
|
247
540
|
tolerance: NumericTolerance,
|
|
248
541
|
): NumericCompareReport {
|
|
542
|
+
const combine = effectiveNumericCombine(tolerance);
|
|
543
|
+
const nonFinite = effectiveNumericNonFinite(tolerance);
|
|
249
544
|
const keys = [...new Set([...Object.keys(reference), ...Object.keys(actual)])].sort();
|
|
250
545
|
const reports: NumericKeyReport[] = [];
|
|
251
546
|
for (const key of keys) {
|
|
252
547
|
const got = actual[key];
|
|
253
548
|
const want = reference[key];
|
|
254
549
|
if (got === undefined) {
|
|
255
|
-
reports.push(
|
|
550
|
+
reports.push(structuralFailure(key, "missing-actual", `${key}: missing from the command output`));
|
|
256
551
|
continue;
|
|
257
552
|
}
|
|
258
553
|
if (want === undefined) {
|
|
259
|
-
reports.push(
|
|
554
|
+
reports.push(structuralFailure(key, "missing-reference", `${key}: missing from the reference`));
|
|
260
555
|
continue;
|
|
261
556
|
}
|
|
262
557
|
if (Array.isArray(got) !== Array.isArray(want)) {
|
|
263
|
-
reports.push(
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
558
|
+
reports.push(
|
|
559
|
+
structuralFailure(
|
|
560
|
+
key,
|
|
561
|
+
"shape-mismatch",
|
|
562
|
+
`${key}: ${Array.isArray(got) ? "array" : "scalar"} in the command output but ${Array.isArray(want) ? "array" : "scalar"} in the reference`,
|
|
563
|
+
),
|
|
564
|
+
);
|
|
269
565
|
continue;
|
|
270
566
|
}
|
|
271
567
|
const gotList = Array.isArray(got) ? got : [got];
|
|
272
568
|
const wantList = Array.isArray(want) ? want : [want];
|
|
273
569
|
if (gotList.length !== wantList.length) {
|
|
274
|
-
reports.push(
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
570
|
+
reports.push(
|
|
571
|
+
structuralFailure(
|
|
572
|
+
key,
|
|
573
|
+
"length-mismatch",
|
|
574
|
+
`${key}: ${gotList.length} element(s) in the command output but ${wantList.length} in the reference`,
|
|
575
|
+
),
|
|
576
|
+
);
|
|
280
577
|
continue;
|
|
281
578
|
}
|
|
282
|
-
reports.push(compareElements(key, gotList, wantList, tolerance));
|
|
579
|
+
reports.push(compareElements(key, gotList, wantList, tolerance, combine, nonFinite));
|
|
283
580
|
}
|
|
284
581
|
const failedKeys = reports.filter((report) => !report.passed).map((report) => report.key);
|
|
285
582
|
const passed = failedKeys.length === 0;
|
|
@@ -287,6 +584,9 @@ export function compareNumeric(
|
|
|
287
584
|
kind: "numeric-compare",
|
|
288
585
|
passed,
|
|
289
586
|
tolerance: { ...tolerance },
|
|
587
|
+
combine,
|
|
588
|
+
nonFinite,
|
|
589
|
+
rule: describeNumericRule(tolerance),
|
|
290
590
|
keys: reports,
|
|
291
591
|
failedKeys,
|
|
292
592
|
summary: passed
|
|
@@ -297,7 +597,15 @@ export function compareNumeric(
|
|
|
297
597
|
|
|
298
598
|
/** The report as lines for a tool result or a receipt tail. */
|
|
299
599
|
export function renderNumericReport(report: NumericCompareReport): string {
|
|
300
|
-
const lines = [report.summary, `tolerance: ${JSON.stringify(report.tolerance)}`];
|
|
600
|
+
const lines = [report.summary, `rule: ${report.rule}`, `tolerance: ${JSON.stringify(report.tolerance)}`];
|
|
601
|
+
if (report.reference !== undefined) {
|
|
602
|
+
lines.push(
|
|
603
|
+
`reference: ${report.reference.path ?? report.reference.source} sha256=${report.reference.sha256.slice(0, 12)} (${report.reference.bytes}B)`,
|
|
604
|
+
);
|
|
605
|
+
}
|
|
606
|
+
if (report.actual !== undefined) {
|
|
607
|
+
lines.push(`actual: sha256=${report.actual.sha256.slice(0, 12)} (${report.actual.bytes}B)`);
|
|
608
|
+
}
|
|
301
609
|
for (const key of report.keys) lines.push(`- ${key.detail}`);
|
|
302
610
|
return lines.join("\n");
|
|
303
611
|
}
|