@iowarp/clio-coder 0.4.4 → 0.4.5
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 +92 -2
- package/CONTRIBUTING.md +25 -15
- package/README.md +340 -27
- package/dist/{acp-WNAYYF4F.js → acp-H3CU2HBQ.js} +25 -24
- package/dist/{agents-3OKXHLOI.js → agents-IXQQZ7BD.js} +77 -77
- package/dist/assets/codewiki.json +1 -1
- package/dist/{auth-VKNNMGPU.js → auth-R7KYF7N3.js} +38 -38
- package/dist/builtins-CRFDQUVP.js +22 -0
- package/dist/{chunk-TQAHXW6Y.js → chunk-22PQ4TX4.js} +4 -4
- package/dist/{chunk-NEDJ26B5.js → chunk-2GPGAE5W.js} +6 -51
- package/dist/{chunk-IKCO5N3L.js → chunk-2QPI3TR3.js} +3 -3
- package/dist/{chunk-HRQMFLJP.js → chunk-32KJPXAM.js} +6 -6
- package/dist/{chunk-65DEGPJ6.js → chunk-3A3CUMKA.js} +6 -4
- package/dist/{chunk-JCI2ROMZ.js → chunk-3T4DXWP6.js} +7 -7
- package/dist/{chunk-DR52UMZW.js → chunk-3UW3KU4A.js} +2 -2
- package/dist/{chunk-6Q3CYFD3.js → chunk-4SVIVOMC.js} +184 -33
- package/dist/{chunk-W54I7H25.js → chunk-5A6XR3RJ.js} +44 -19
- package/dist/{chunk-YPC6ZR5L.js → chunk-5CMARGPF.js} +119 -5
- package/dist/{chunk-KXDSS5WJ.js → chunk-5CY4Q6QI.js} +4 -4
- package/dist/{chunk-I2DWJ4GM.js → chunk-5DDOTTG4.js} +54 -42
- package/dist/{chunk-D4CJV46V.js → chunk-5GZICIYO.js} +3 -3
- package/dist/{chunk-4IUZQIJ3.js → chunk-5PHVPU4G.js} +2 -2
- package/dist/{chunk-3ODX73FK.js → chunk-5VTJP36Q.js} +4 -4
- package/dist/{chunk-54X7T7DK.js → chunk-5ZMXGW7P.js} +79 -7
- package/dist/chunk-5ZSZEYJK.js +119 -0
- package/dist/{chunk-IXIY2H4R.js → chunk-633EXGZA.js} +5 -5
- package/dist/{chunk-CUSRQKPU.js → chunk-6CDNRHWH.js} +299 -89
- package/dist/{chunk-EBY63B7G.js → chunk-6EXUUOSN.js} +2 -2
- package/dist/{chunk-SVNXH4L2.js → chunk-6ICZKDUC.js} +2 -2
- package/dist/{chunk-JEIYHLOR.js → chunk-6SYEGZI3.js} +12 -12
- package/dist/{chunk-DQOVN6KV.js → chunk-6YA46L5A.js} +4 -4
- package/dist/{chunk-NZMNUPZZ.js → chunk-77CZRFTE.js} +3 -3
- package/dist/{chunk-6PAZTBPA.js → chunk-7HBHHVCK.js} +15 -6
- package/dist/{chunk-25QBEXRS.js → chunk-7TKWWPD7.js} +5 -4
- package/dist/{chunk-2VTFPG5O.js → chunk-7WLRF2U5.js} +2 -2
- package/dist/chunk-7WUZEB2M.js +165 -0
- package/dist/{chunk-3UUXNFEX.js → chunk-7YJWEF2L.js} +61 -34
- package/dist/{chunk-3EBYEESD.js → chunk-A46ILRS2.js} +5 -5
- package/dist/{chunk-UOIZ7DA4.js → chunk-AP7HDJOP.js} +2 -2
- package/dist/{chunk-APJ265NV.js → chunk-B5GGDIHT.js} +146 -146
- package/dist/{chunk-PMZVFWSR.js → chunk-B5ZTR6KZ.js} +2 -2
- package/dist/{chunk-I5FWO7L5.js → chunk-B6UM3OZC.js} +2 -2
- package/dist/{chunk-2CU2H6KE.js → chunk-BBV5TKE6.js} +5 -5
- package/dist/{chunk-4O6MANBS.js → chunk-BS4GAMUB.js} +14 -10
- package/dist/{chunk-S66XZJOF.js → chunk-C27U2TYG.js} +2 -2
- package/dist/{chunk-QZWQA4DE.js → chunk-CBSKDFWL.js} +3 -3
- package/dist/{chunk-2LEAKD4C.js → chunk-CKK25WN3.js} +3 -3
- package/dist/{chunk-BYP5D4HI.js → chunk-CTTI7G3T.js} +2 -2
- package/dist/{chunk-XAKHZX5N.js → chunk-CVDAFGPW.js} +4 -4
- package/dist/{chunk-RKKLTLYB.js → chunk-CXQ37WJH.js} +3 -3
- package/dist/{chunk-GTUD2WMY.js → chunk-DBREN25X.js} +44 -9
- package/dist/{chunk-YNFKXPEC.js → chunk-DIMRLNIC.js} +35 -66
- package/dist/{chunk-NDDGJUXD.js → chunk-DNCE23JJ.js} +2 -2
- package/dist/{chunk-HVDIIIQW.js → chunk-DNHVRBH4.js} +3 -3
- package/dist/{chunk-XULDXHTN.js → chunk-DRD2A54W.js} +102 -50
- package/dist/{chunk-D7E7WCDF.js → chunk-DVNAPPXU.js} +2 -2
- package/dist/{chunk-YXLYO42X.js → chunk-DXVMLM3Z.js} +3 -2
- package/dist/{chunk-5MEZN6CB.js → chunk-DZK63TZJ.js} +6 -6
- package/dist/{chunk-IGLP3ODT.js → chunk-E3BQTQUP.js} +15 -15
- package/dist/{chunk-IWHMRKLL.js → chunk-E3LEPLQ2.js} +2 -2
- package/dist/{chunk-3R73A4XB.js → chunk-ECBHH7LU.js} +3 -3
- package/dist/chunk-ECOMVOHP.js +139 -0
- package/dist/chunk-EFSEIZE6.js +56 -0
- package/dist/{chunk-FEAXX7B6.js → chunk-EHCPSZJF.js} +4 -4
- package/dist/{chunk-4NSRCOYP.js → chunk-EHOSNVVM.js} +3 -2
- package/dist/{chunk-7UGL4MB5.js → chunk-EQEJJ53P.js} +10 -10
- package/dist/{chunk-GWZNEVM2.js → chunk-EWD5P3GK.js} +9 -9
- package/dist/{chunk-6UINWWS6.js → chunk-F34AR6O3.js} +14 -14
- package/dist/{chunk-GHS5EBTQ.js → chunk-FKIOX6DS.js} +29 -20
- package/dist/{chunk-HAXOFFRH.js → chunk-FQOOGXBH.js} +7 -7
- package/dist/{chunk-Y55JBDO5.js → chunk-FSTIBAGM.js} +38 -23
- package/dist/{chunk-ZTJUVLTU.js → chunk-FXFVDPWY.js} +2 -2
- package/dist/{chunk-XPLRXC72.js → chunk-GD55RTIW.js} +3 -3
- package/dist/{chunk-5B2AEOW5.js → chunk-GH5ZR6JP.js} +472 -472
- package/dist/{chunk-TOIVGRUX.js → chunk-GJ24ODAX.js} +5 -5
- package/dist/{chunk-QUFRYSWI.js → chunk-GNQRWTMY.js} +129 -48
- package/dist/{chunk-5ICU3EUH.js → chunk-GVYWZNRK.js} +5 -5
- package/dist/{chunk-GX5WYQO4.js → chunk-GXCCHKN6.js} +6 -6
- package/dist/{chunk-K6T2ZAMZ.js → chunk-HGSLRG33.js} +6 -6
- package/dist/{chunk-26QSH3EJ.js → chunk-HHVJNVUJ.js} +5 -5
- package/dist/{chunk-F4EKGO4N.js → chunk-HL26ADLH.js} +4 -2
- package/dist/{chunk-JT2RFCC5.js → chunk-HR3HPQ76.js} +5 -5
- package/dist/{chunk-ID64D7PE.js → chunk-HXHFDHB6.js} +24 -24
- package/dist/{chunk-ELWDPP3Y.js → chunk-I7VLWRK2.js} +8 -8
- package/dist/{chunk-6OSVSQL5.js → chunk-ICO4TQ2F.js} +7 -5
- package/dist/{chunk-SZAA6XDG.js → chunk-IFDRAD6F.js} +2 -2
- package/dist/{chunk-72YIHOZQ.js → chunk-ILJ7DWGE.js} +9 -9
- package/dist/{chunk-2JH2WHGE.js → chunk-J2FYEQ5L.js} +4 -4
- package/dist/{chunk-BMS5RKQY.js → chunk-JABWPKFY.js} +3 -3
- package/dist/{chunk-QDC3K2U3.js → chunk-K2BLQC5E.js} +3 -3
- package/dist/{chunk-AUPNRN7C.js → chunk-K2HL3GBL.js} +4 -4
- package/dist/{chunk-2ASED4PZ.js → chunk-K6RDB7IA.js} +26 -26
- package/dist/{chunk-FFUPXJC4.js → chunk-KDWLXVMN.js} +23 -24
- package/dist/{chunk-OZNBF4L3.js → chunk-KECNXMDE.js} +2 -2
- package/dist/{chunk-6QOTUPRG.js → chunk-KF6GFW6O.js} +66 -18
- package/dist/{chunk-BTK3SSSK.js → chunk-KMF54VH3.js} +2 -2
- package/dist/chunk-KPRLAMP4.js +32 -0
- package/dist/{chunk-ECH6PKUQ.js → chunk-KQ6IDQIB.js} +2 -2
- package/dist/{chunk-3UNOLWNZ.js → chunk-KTFSFCVN.js} +20 -9
- package/dist/{chunk-57XXR6DR.js → chunk-KYKNBD4Y.js} +24 -23
- package/dist/{chunk-IRXAATOX.js → chunk-L4N3DWNW.js} +3 -3
- package/dist/{chunk-LCGCVYZ4.js → chunk-LQTKDAUO.js} +2 -2
- package/dist/{chunk-U6TMQNSI.js → chunk-LTR5QCLS.js} +4 -4
- package/dist/chunk-LUL5Z66S.js +221 -0
- package/dist/{chunk-ELZVTCGV.js → chunk-LVFANMOH.js} +151 -327
- package/dist/{chunk-H7IXIC72.js → chunk-LY4N4TTL.js} +17 -3
- package/dist/{chunk-VKPAQYEB.js → chunk-LZBMXNLP.js} +5 -5
- package/dist/{chunk-UL3WSD3F.js → chunk-M4KFUXS7.js} +2 -2
- package/dist/{chunk-NXYCB2VD.js → chunk-M6TAYK66.js} +6 -6
- package/dist/{chunk-NEKRRTYW.js → chunk-MC3JSVR6.js} +2 -2
- package/dist/{chunk-CFGTUFWB.js → chunk-MCJKEGHO.js} +2 -2
- package/dist/{chunk-DXKJURES.js → chunk-MDU3C27C.js} +10 -7
- package/dist/{chunk-6XLNIQDB.js → chunk-MYI32N4R.js} +2 -2
- package/dist/{chunk-3GY4F45V.js → chunk-NC4KV7EL.js} +6 -6
- package/dist/{chunk-LLXSDWXS.js → chunk-NF3BK5WR.js} +5 -5
- package/dist/chunk-NTK3WTHM.js +141 -0
- package/dist/{chunk-GYV6VZOC.js → chunk-NTTS3O53.js} +2 -2
- package/dist/{chunk-RZDWV63N.js → chunk-NY6IWDVU.js} +6 -6
- package/dist/{chunk-XXYSBZIQ.js → chunk-O2RQ7LCK.js} +4 -4
- package/dist/{chunk-4BJ5BYCE.js → chunk-O3VV6IVK.js} +2 -2
- package/dist/{chunk-W6GROXXM.js → chunk-O5F25NIE.js} +2 -2
- package/dist/{chunk-NXIMQY5W.js → chunk-ODUTYZIU.js} +5 -5
- package/dist/{chunk-LTIKRKFL.js → chunk-ONRTXOZY.js} +4 -4
- package/dist/{chunk-KFV5L5SK.js → chunk-OQM5IVJY.js} +118 -232
- package/dist/{chunk-XRZT5WY5.js → chunk-P5SC4DLJ.js} +4 -4
- package/dist/{chunk-R6Q67RJH.js → chunk-PECBKCDK.js} +34 -6
- package/dist/{chunk-33YXPOE3.js → chunk-PPEZJWUG.js} +2 -2
- package/dist/{chunk-RXTN6AKH.js → chunk-PWWSIB2A.js} +5 -5
- package/dist/{chunk-2STGEDFV.js → chunk-QEQISF75.js} +2 -2
- package/dist/{chunk-3DPEIQKN.js → chunk-QH3ZTUOA.js} +2 -2
- package/dist/{chunk-YAKGTXEV.js → chunk-QRFXEO6Y.js} +2 -2
- package/dist/{chunk-35MSIRKH.js → chunk-QUIJZSDW.js} +2 -2
- package/dist/{chunk-HHV2GANA.js → chunk-R2P2U3ZS.js} +2 -2
- package/dist/{chunk-2DSOYNFC.js → chunk-R6MAYTMS.js} +7 -7
- package/dist/{chunk-JQLNNIKT.js → chunk-R6MICQYU.js} +6 -6
- package/dist/{chunk-NAI6ZFCY.js → chunk-RLTT5GVY.js} +122 -11
- package/dist/{chunk-DT3LWJOB.js → chunk-RXIOCVBZ.js} +24 -6
- package/dist/{chunk-N56KALIC.js → chunk-S32UQ5GL.js} +61 -34
- package/dist/{chunk-UEPWCCTY.js → chunk-SBZX6ARC.js} +12 -12
- package/dist/chunk-SD7SHNDW.js +15 -0
- package/dist/{chunk-NRO2BJRH.js → chunk-SDWNDICN.js} +10235 -4015
- package/dist/{chunk-UXCU4E3T.js → chunk-SE4ZKILO.js} +6 -6
- package/dist/chunk-SL2RDHKO.js +19 -0
- package/dist/{chunk-NUGM5KR6.js → chunk-SRCEQKQS.js} +2 -2
- package/dist/{chunk-OMQNJVKW.js → chunk-SRZOW5L2.js} +43 -13
- package/dist/{chunk-3M6DQK6S.js → chunk-T334FW2H.js} +7 -7
- package/dist/{chunk-V76WTFTW.js → chunk-T52TPHYC.js} +6 -6
- package/dist/{chunk-I7XBWTYH.js → chunk-T53XI6I7.js} +5 -5
- package/dist/{chunk-2ZSONWVL.js → chunk-T7FDXNRU.js} +13 -13
- package/dist/{chunk-JSD46VO2.js → chunk-TEG3RYVZ.js} +43 -36
- package/dist/{chunk-3I7MS7N2.js → chunk-TK2BMCBZ.js} +2 -2
- package/dist/{chunk-5OIVVPHF.js → chunk-TN5FW4XY.js} +13 -6
- package/dist/{chunk-75W7L2E2.js → chunk-TZ7MFRG4.js} +1041 -162
- package/dist/{chunk-36CT5VVL.js → chunk-U2JOLB7O.js} +126 -77
- package/dist/{chunk-LL4KHSZI.js → chunk-U2MSJ57E.js} +2 -2
- package/dist/{chunk-FTMGRKEF.js → chunk-U44YYLVV.js} +4 -4
- package/dist/{chunk-YECAMM3D.js → chunk-U7H5WRG5.js} +5 -5
- package/dist/{chunk-RQCKCSRL.js → chunk-U7VQ4NI4.js} +22 -22
- package/dist/{chunk-5TUB6SLS.js → chunk-UFYNOQK4.js} +7 -7
- package/dist/{chunk-R346GLFC.js → chunk-UHW5V7HC.js} +2 -2
- package/dist/{chunk-USR47QNF.js → chunk-UL36QJX6.js} +14 -14
- package/dist/{chunk-VIA6RFQZ.js → chunk-UQIVHSE4.js} +4 -4
- package/dist/{chunk-RAY4OVGZ.js → chunk-URBGEOH3.js} +5 -5
- package/dist/chunk-USZA7GWL.js +341 -0
- package/dist/{chunk-YD5GIKET.js → chunk-UTUNT5QL.js} +48 -579
- package/dist/{chunk-ZA4VCIGV.js → chunk-UUQ5G6EZ.js} +60 -41
- package/dist/{chunk-23L32XTI.js → chunk-UXAC2FX4.js} +68 -39
- package/dist/{chunk-VG7TBQIY.js → chunk-V552WL53.js} +68 -4
- package/dist/{chunk-BWH6N36D.js → chunk-VHKTOLEW.js} +272 -42
- package/dist/{chunk-EXLD33WO.js → chunk-VLPTKCKT.js} +24 -9
- package/dist/{chunk-336NSSKI.js → chunk-VNBICSS2.js} +2 -2
- package/dist/{chunk-VAVR4IJY.js → chunk-VQD7NH7Z.js} +3 -3
- package/dist/{chunk-LBMZMYH2.js → chunk-W2RJEH6Q.js} +3 -3
- package/dist/{chunk-7CR24IG7.js → chunk-WDV62RKY.js} +2 -2
- package/dist/{chunk-S6PYF2XF.js → chunk-WFKDPU7U.js} +4 -4
- package/dist/{chunk-BJVFZO5U.js → chunk-WJIMKGD6.js} +7 -7
- package/dist/{chunk-5636DCO5.js → chunk-WLMSOT73.js} +59 -12
- package/dist/{chunk-MXHC5QYU.js → chunk-WTQGRBHV.js} +5 -144
- package/dist/chunk-WXA2CFJO.js +23 -0
- package/dist/{chunk-QSNYB6ZV.js → chunk-XCUDZQLX.js} +3 -3
- package/dist/{chunk-4M6Z5QVF.js → chunk-XXBQKW32.js} +11 -11
- package/dist/{chunk-OEJSLEPW.js → chunk-YEJIG7LN.js} +332 -332
- package/dist/chunk-YGDMBK7O.js +567 -0
- package/dist/{chunk-4WR7VSYB.js → chunk-YYB3MC65.js} +23 -9
- package/dist/{chunk-2IR2NMPA.js → chunk-ZIDFQJRB.js} +2 -2
- package/dist/{chunk-Q4WO54TA.js → chunk-ZMZQEBKI.js} +14 -14
- package/dist/{chunk-6EJMN2Y3.js → chunk-ZTNFYMIO.js} +2 -2
- package/dist/{chunk-WEPFGWHJ.js → chunk-ZZFWWYLX.js} +2 -2
- package/dist/cli/index.js +44 -44
- package/dist/clio-5I2IBFYL.js +26 -0
- package/dist/{code-nav-IJR2DBPR.js → code-nav-YXIAEZVS.js} +48 -32
- package/dist/codewiki/build-worker.js +76 -29
- package/dist/{compile-cache-OQAVB7Y5.js → compile-cache-WJEPUZEJ.js} +4 -4
- package/dist/{components-2TGAI2RC.js → components-TNIKXCBH.js} +13 -13
- package/dist/{config-IUA6OYNS.js → config-Y2JDJ3JJ.js} +210 -124
- package/dist/configure-SML6UBZ5.js +55 -0
- package/dist/{context-4MPR7WKB.js → context-P5YSEO55.js} +125 -121
- package/dist/{context-2DKHWH2T.js → context-QQ53HSGJ.js} +91 -62
- package/dist/{context-BOYF5EJM.js → context-S2EEC3EJ.js} +62 -31
- package/dist/context-clear-TMEQCOTH.js +183 -0
- package/dist/{context-index-HNG3MOME.js → context-index-HP2JFUWA.js} +13 -11
- package/dist/{context-map-COB37XXN.js → context-map-INTXD54D.js} +71 -21
- package/dist/{context-working-set-3I3FYX6Y.js → context-working-set-CNLSQN5K.js} +31 -31
- package/dist/detail-5572VLBO.js +114 -0
- package/dist/{dispatch-runner-RJ5I2F2O.js → dispatch-runner-FRHD6P2O.js} +191 -116
- package/dist/{docs-SPOV3BAN.js → docs-BL7ROUFN.js} +4 -4
- package/dist/{doctor-DKICC2SN.js → doctor-N3LCM2LG.js} +58 -58
- package/dist/{eval-OQOQUDHK.js → eval-BUU3ZOUZ.js} +473 -168
- package/dist/{eval-inventory-Y6QRFOH5.js → eval-inventory-QOYZERXJ.js} +7 -7
- package/dist/evidence-DTGEN456.js +224 -0
- package/dist/{evidence-4DQ25GUQ.js → evidence-SQ5DNFEN.js} +110 -94
- package/dist/{evolve-GSS52E5J.js → evolve-IJNUFZDS.js} +107 -91
- package/dist/{extensions-G7MFLYHT.js → extensions-YVRHX6ZI.js} +16 -16
- package/dist/{fleet-Q37YHHAQ.js → fleet-ZNNVSYFO.js} +147 -147
- package/dist/{fleet-commands-G7E4N7SM.js → fleet-commands-5YE7NPJL.js} +27 -26
- package/dist/{fleet-decisions-O7M6QBA2.js → fleet-decisions-3SBSCTCW.js} +16 -15
- package/dist/{fleet-graph-TOUBW6OW.js → fleet-graph-6HHPWF5T.js} +39 -38
- package/dist/{fleet-inspect-SW33JJNI.js → fleet-inspect-JEYMGCGC.js} +107 -91
- package/dist/{fleet-new-RDVJLHHH.js → fleet-new-RCKGSRDV.js} +3 -3
- package/dist/{fleet-preflight-CV2655TW.js → fleet-preflight-QRSHIIDE.js} +10 -9
- package/dist/{fleet-validate-KESZX2YH.js → fleet-validate-4PM4GDDL.js} +46 -42
- package/dist/{fleet-verify-UQPMTVE3.js → fleet-verify-NJDTHTO3.js} +105 -89
- package/dist/fleet-view-UP2BWQQY.js +117 -0
- package/dist/{init-PXEXQSBF.js → init-S3GZQ5ZF.js} +123 -123
- package/dist/{install-NKNG7KD4.js → install-3RZDDP23.js} +5 -5
- package/dist/{interop-ZG5T62U3.js → interop-YOTGXFJM.js} +25 -25
- package/dist/inventory-K2OZ36YJ.js +117 -0
- package/dist/{library-B2W4N74O.js → library-GJI6W6OK.js} +45 -44
- package/dist/{memory-YCANYS5A.js → memory-OQOXQGYD.js} +107 -93
- package/dist/{models-GERTU3YI.js → models-3IK2Y5WE.js} +63 -62
- package/dist/{monitor-CPNIUULB.js → monitor-FTJLTKCQ.js} +136 -107
- package/dist/{orchestrator-J4BSH4WQ.js → orchestrator-N47O7SFD.js} +1159 -697
- package/dist/{panes-BOHAEGYC.js → panes-7BTYH3XQ.js} +8 -8
- package/dist/{panes-NXSLDQZ2.js → panes-WPOMEMRH.js} +22 -22
- package/dist/{paths-VSUWNC22.js → paths-J3KN7UAO.js} +12 -12
- package/dist/preload-65U34NG6.js +115 -0
- package/dist/{registry-LG64LTF4.js → registry-DESGAXWK.js} +3 -3
- package/dist/{reset-TNWTB5LU.js → reset-MUVQDLNL.js} +20 -20
- package/dist/{resources-4PXNMD5G.js → resources-LM76COAO.js} +41 -40
- package/dist/{run-D6XJ34CN.js → run-3VFZQ33N.js} +162 -156
- package/dist/{share-2NWMJJEE.js → share-4JUB4BL7.js} +43 -42
- package/dist/{skills-KR7WON5G.js → skills-S36AAJHU.js} +47 -46
- package/dist/{skills-eval-O2ZNOLDS.js → skills-eval-G6T57L7M.js} +127 -107
- package/dist/{skills-inventory-ZZOUBK7O.js → skills-inventory-WLM46PJH.js} +41 -40
- package/dist/slash-commands-GBARG3Y7.js +91 -0
- package/dist/{steer-XA25PSCS.js → steer-S7D7IKPU.js} +7 -7
- package/dist/{support-7EMVWYG2.js → support-5VAEC32W.js} +14 -14
- package/dist/{targets-OMH2XCSN.js → targets-N5REUETU.js} +145 -94
- package/dist/tasks-6BVY5YZF.js +36 -0
- package/dist/{terminal-lease-C2J3JYRE.js → terminal-lease-57UEOJKS.js} +12 -11
- package/dist/tools-6OCQ6SVB.js +28 -0
- package/dist/{trace-FXMXUZUF.js → trace-JHLXWUMN.js} +18 -17
- package/dist/{tree-sitter-HGKH6LG4.js → tree-sitter-AQUUOSYM.js} +6 -6
- package/dist/{tui-primitives-K5PASC3O.js → tui-primitives-RCY2HN7G.js} +3 -3
- package/dist/{uninstall-HALS6BLF.js → uninstall-FXYMFFRT.js} +17 -17
- package/dist/{upgrade-MS72RJEP.js → upgrade-4HD5HAIV.js} +40 -39
- package/dist/{usage-NHG6MCJM.js → usage-4GWM2WWP.js} +136 -105
- package/dist/{verifiers-7AUNVXDY.js → verifiers-GSKWKWVG.js} +28 -27
- package/dist/verify-3AS3ULCY.js +30 -0
- package/dist/{version-KGEG7EPO.js → version-RFPKO6T7.js} +4 -4
- package/dist/{web-fetch-V4FKSDAV.js → web-fetch-MQN4FH3X.js} +169 -18
- package/dist/wiki-generate-7BV7XWIY.js +614 -0
- package/dist/{with-panes-BDQEWBRT.js → with-panes-OFTNAR4Y.js} +34 -20
- package/dist/worker/entry.js +99 -88
- package/dist/{workspace-ZJ6BFM3Q.js → workspace-DZ7JADBG.js} +6 -6
- package/docs/README.md +7 -6
- package/docs/architecture/acp.md +10 -0
- package/docs/architecture/architecture.md +5 -5
- package/docs/architecture/context-engine.md +44 -59
- package/docs/architecture/context-working-set.md +7 -9
- package/docs/architecture/dispatch-architecture-rationale.md +1 -1
- package/docs/architecture/evidence-and-memory.md +10 -0
- package/docs/architecture/pi-boundary.md +37 -7
- package/docs/architecture/prompt-envelope-and-tools.md +7 -7
- package/docs/architecture/session-lifecycle.md +4 -4
- package/docs/architecture/worker-dispatch-mechanics.md +4 -0
- package/docs/guide/commands-and-modes.md +49 -36
- package/docs/guide/configuration-and-targets.md +7 -2
- package/docs/guide/configuration-reference.md +13 -3
- package/docs/guide/environment-variables.md +6 -2
- package/docs/guide/fleet-dispatch.md +12 -0
- package/docs/guide/installation-and-lifecycle.md +35 -9
- package/docs/guide/proactive-memory.md +1 -1
- package/docs/guide/skills-marketplace.md +11 -3
- package/docs/guide/tool-usage.md +9 -2
- package/docs/process/development-pipeline.md +10 -10
- package/docs/process/documentation-guide.md +2 -2
- package/docs/process/eval-runner.md +15 -0
- package/docs/process/evals-internal.md +1 -1
- package/docs/process/release-cut-checklist.md +6 -6
- package/evals/README.md +4 -0
- package/evals/behavioral-corpus-grader.mjs +147 -14
- package/evals/behavioral-model-negative-control.yaml +1 -0
- package/evals/behavioral-model.yaml +266 -1
- package/evals/fixtures/docs-retrieval.json +102 -0
- package/evals/fixtures/scalar-decision.json +17 -0
- package/evals/fixtures/scout-citation-pipeline.json +55 -0
- package/evals/fixtures/source-explanation.json +74 -0
- package/evals/fixtures/tool-arguments.json +18 -0
- package/evals/fixtures/tool-surface/read.txt +4 -0
- package/evals/fixtures/tool-surface/subdir/keep.txt +1 -0
- package/evals/no-edit-memory-grader.mjs +149 -0
- package/evals/scalar-decision-grader.py +41 -0
- package/evals/scalar-decision-machinery.ts +145 -0
- package/evals/source-explanation-grader.mjs +118 -0
- package/evals/tool-surface-grader.mjs +53 -0
- package/evals/tool-surface-model.yaml +274 -0
- package/package.json +14 -14
- package/skills/README.md +6 -6
- package/skills/registry.yaml +1 -1
- package/skills/skill-marketplace.json +1 -1
- package/src/cli/bootstrap-generate.ts +6 -0
- package/src/cli/config-inspect.ts +24 -7
- package/src/cli/config-trust.ts +62 -0
- package/src/cli/config.ts +8 -0
- package/src/cli/context-map.ts +75 -14
- package/src/cli/context.ts +46 -17
- package/src/cli/eval.ts +17 -3
- package/src/cli/modes/print.ts +32 -4
- package/src/cli/run.ts +16 -14
- package/src/cli/skills-eval.ts +10 -8
- package/src/cli/steer-channel.ts +31 -18
- package/src/cli/targets.ts +83 -31
- package/src/cli/tasks.ts +10 -1
- package/src/cli/upgrade.ts +9 -6
- package/src/cli/usage.ts +24 -0
- package/src/cli/wiki-generate.ts +239 -96
- package/src/core/bash-exec.ts +43 -15
- package/src/core/bus-events.ts +15 -0
- package/src/core/config.ts +33 -14
- package/src/core/defaults.ts +5 -4
- package/src/core/file-references.ts +11 -1
- package/src/core/incomplete-installation.ts +3 -1
- package/src/core/settings-layers.ts +21 -5
- package/src/core/termination.ts +26 -9
- package/src/core/untrusted-content.ts +16 -0
- package/src/core/workspace-trust.ts +179 -0
- package/src/domains/agents/builtins/coder.md +4 -2
- package/src/domains/agents/builtins/context-bootstrap.md +3 -1
- package/src/domains/agents/builtins/documenter.md +7 -4
- package/src/domains/agents/builtins/researcher.md +1 -0
- package/src/domains/agents/builtins/scout.md +7 -1
- package/src/domains/agents/result-contract.ts +199 -26
- package/src/domains/context/bootstrap-prompt.ts +11 -9
- package/src/domains/context/bootstrap.ts +74 -39
- package/src/domains/context/clio-md.ts +88 -26
- package/src/domains/context/codewiki/build-operation.ts +121 -0
- package/src/domains/context/codewiki/build-worker-protocol.ts +37 -3
- package/src/domains/context/codewiki/build-worker.ts +3 -35
- package/src/domains/context/codewiki/coordinator.ts +36 -6
- package/src/domains/context/codewiki/indexer.ts +59 -19
- package/src/domains/context/contract.ts +6 -2
- package/src/domains/context/extension.ts +72 -10
- package/src/domains/context/fingerprint.ts +39 -34
- package/src/domains/context/index.ts +7 -1
- package/src/domains/context/prompt-context.ts +55 -14
- package/src/domains/context/refresh.ts +9 -57
- package/src/domains/context/wiki/assemble.ts +14 -10
- package/src/domains/context/wiki/evidence.ts +209 -0
- package/src/domains/context/wiki/generate.ts +201 -67
- package/src/domains/context/wiki/meta.ts +10 -2
- package/src/domains/context/wiki/plan-store.ts +70 -14
- package/src/domains/context/wiki/plan.ts +71 -14
- package/src/domains/context/wiki/prompts.ts +42 -1
- package/src/domains/context/wiki/source-content.ts +106 -0
- package/src/domains/context/wiki/staleness.ts +33 -22
- package/src/domains/context/working-set/contract.ts +8 -2
- package/src/domains/context/working-set/engine.ts +17 -4
- package/src/domains/context/working-set/fold.ts +15 -2
- package/src/domains/context/working-set/marker.ts +2 -1
- package/src/domains/context/working-set/project.ts +18 -7
- package/src/domains/context/working-set/recall.ts +82 -56
- package/src/domains/dispatch/active-route-planner.ts +6 -3
- package/src/domains/dispatch/admission-queue.ts +19 -7
- package/src/domains/dispatch/admission.ts +3 -3
- package/src/domains/dispatch/budget-envelope.ts +47 -82
- package/src/domains/dispatch/capacity-lease.ts +57 -19
- package/src/domains/dispatch/contract.ts +10 -2
- package/src/domains/dispatch/event-pump.ts +28 -7
- package/src/domains/dispatch/execution-role.ts +49 -2
- package/src/domains/dispatch/execution-scheduler.ts +2 -0
- package/src/domains/dispatch/extension.ts +190 -105
- package/src/domains/dispatch/fleet-run.ts +20 -0
- package/src/domains/dispatch/gate-role-prompts.ts +4 -2
- package/src/domains/dispatch/parallel-writers.ts +34 -0
- package/src/domains/dispatch/reservation-store.ts +8 -34
- package/src/domains/dispatch/route-approval.ts +3 -3
- package/src/domains/dispatch/route-observer.ts +4 -2
- package/src/domains/dispatch/route-quality.ts +6 -1
- package/src/domains/dispatch/types.ts +4 -3
- package/src/domains/dispatch/worker-spawn.ts +58 -21
- package/src/domains/dispatch/workspace-checkpoint.ts +57 -0
- package/src/domains/eval/compare/behavioral.ts +81 -14
- package/src/domains/eval/compare/compare.ts +15 -5
- package/src/domains/eval/compare/envelope.ts +12 -5
- package/src/domains/eval/metrics/context.ts +24 -1
- package/src/domains/eval/metrics/tracked.ts +4 -28
- package/src/domains/eval/reports/comparison.ts +9 -9
- package/src/domains/eval/runners/clio-run.ts +5 -1
- package/src/domains/eval/schema/suite.ts +2 -0
- package/src/domains/eval/schema/validate.ts +1 -0
- package/src/domains/eval/suites/run.ts +189 -13
- package/src/domains/eval/verifiers/integrity.ts +39 -0
- package/src/domains/eval/verifiers/patch.ts +58 -2
- package/src/domains/eval/workspaces/temp-copy.ts +3 -0
- package/src/domains/evidence/build.ts +4 -2
- package/src/domains/interop/registry.ts +2 -2
- package/src/domains/middleware/hooks-io.ts +45 -26
- package/src/domains/middleware/hooks.ts +6 -0
- package/src/domains/middleware/injection-screen.ts +23 -0
- package/src/domains/middleware/rules.ts +5 -1
- package/src/domains/middleware/stalled-turn.ts +18 -3
- package/src/domains/middleware/task-board-reminder.ts +4 -2
- package/src/domains/middleware/task-nudge.ts +4 -1
- package/src/domains/mux/contract.ts +34 -1
- package/src/domains/mux/dock-controller.ts +8 -1
- package/src/domains/mux/index.ts +1 -0
- package/src/domains/mux/socket-client.ts +13 -3
- package/src/domains/observability/contract.ts +2 -2
- package/src/domains/observability/projection.ts +30 -9
- package/src/domains/prompts/compiler.ts +10 -2
- package/src/domains/prompts/contract.ts +7 -4
- package/src/domains/prompts/extension.ts +28 -64
- package/src/domains/prompts/fragments/identity/clio.md +23 -0
- package/src/domains/prompts/fragments/operating/contract.md +10 -0
- package/src/domains/prompts/fragments/operating/delegation.md +5 -0
- package/src/domains/prompts/fragments/wiki/page.md +28 -15
- package/src/domains/prompts/fragments/wiki/plan.md +4 -4
- package/src/domains/prompts/preload-prefix.ts +31 -0
- package/src/domains/prompts/preload.ts +135 -61
- package/src/domains/providers/auth/backend-file.ts +15 -11
- package/src/domains/providers/auth/storage.ts +3 -5
- package/src/domains/providers/catalog.ts +18 -3
- package/src/domains/providers/runtime-resolution.ts +11 -9
- package/src/domains/providers/runtimes/cloud/openrouter.ts +2 -0
- package/src/domains/resources/skills/promotion.ts +8 -1
- package/src/domains/safety/action-classifier.ts +9 -0
- package/src/domains/safety/autonomy.ts +10 -1
- package/src/domains/safety/contract.ts +5 -1
- package/src/domains/safety/default-path-policy.ts +11 -0
- package/src/domains/safety/extension.ts +11 -2
- package/src/domains/safety/policy-engine.ts +189 -32
- package/src/domains/safety/project-policy.ts +7 -2
- package/src/domains/safety/workspace-trust.ts +43 -0
- package/src/domains/session/compaction/compact.ts +384 -21
- package/src/domains/session/compaction/cut-point.ts +42 -5
- package/src/domains/session/compaction/tokens.ts +9 -1
- package/src/domains/session/decision-board.ts +43 -33
- package/src/domains/session/entries.ts +169 -4
- package/src/domains/session/prompt-manifest.ts +47 -8
- package/src/domains/session/task-board.ts +21 -3
- package/src/domains/user-tasks/handoff.ts +16 -0
- package/src/engine/acp/adapter.ts +44 -12
- package/src/engine/acp/server.ts +1 -0
- package/src/engine/acp/transport.ts +2 -1
- package/src/engine/acp/types.ts +6 -1
- package/src/engine/antigravity/subprocess-runtime.ts +20 -4
- package/src/engine/api-registry.ts +19 -2
- package/src/engine/apis/openai-completions.ts +13 -6
- package/src/engine/apis/output-budget.ts +26 -10
- package/src/engine/claude/sdk-runtime.ts +4 -3
- package/src/engine/env-api-keys.ts +2 -1
- package/src/engine/external-subprocess.ts +14 -3
- package/src/engine/loop-guard.ts +19 -2
- package/src/engine/provider-diagnostics.ts +129 -0
- package/src/engine/provider-payload.ts +3 -1
- package/src/engine/worker-runtime.ts +13 -2
- package/src/engine/worker-tools.ts +5 -1
- package/src/entry/extension-reload.ts +1 -0
- package/src/entry/orchestrator.ts +53 -15
- package/src/interactive/chat-loop-messages.ts +12 -4
- package/src/interactive/chat-loop.ts +115 -45
- package/src/interactive/chat-renderer.ts +60 -0
- package/src/interactive/context-recall-command.ts +2 -1
- package/src/interactive/dispatch-board.ts +17 -2
- package/src/interactive/editor-submit.ts +13 -0
- package/src/interactive/interactive-application.ts +8 -2
- package/src/interactive/interactive-event-projection.ts +7 -1
- package/src/interactive/interactive-presentation.ts +15 -7
- package/src/interactive/interactive-slash-runtime.ts +2 -0
- package/src/interactive/layout.ts +2 -1
- package/src/interactive/model-session-replay.ts +2 -2
- package/src/interactive/overlay-frame.ts +1 -0
- package/src/interactive/overlay-general-openers.ts +3 -1
- package/src/interactive/overlay-session-lifecycle.ts +6 -0
- package/src/interactive/overlays/ask-user.ts +1 -0
- package/src/interactive/overlays/message-picker.ts +1 -1
- package/src/interactive/renderers/tool-execution.ts +17 -1
- package/src/interactive/renderers/worker-entry.ts +25 -10
- package/src/interactive/slash-commands.ts +9 -7
- package/src/interactive/turn-context.ts +221 -53
- package/src/interactive/turn-middleware.ts +3 -1
- package/src/interactive/turn-persistence.ts +3 -0
- package/src/interactive/turn-runtime.ts +11 -2
- package/src/interactive/turn-state.ts +10 -9
- package/src/interactive/watch-pane.ts +18 -4
- package/src/interactive/worker-stream.ts +7 -7
- package/src/tools/agent-tools.ts +6 -3
- package/src/tools/bash.ts +1 -1
- package/src/tools/builtin-tool-catalog.ts +9 -2
- package/src/tools/codewiki/code-nav.ts +4 -10
- package/src/tools/compete-judge-task.ts +71 -0
- package/src/tools/compete-worktrees.ts +34 -0
- package/src/tools/context/index.ts +32 -7
- package/src/tools/context/surface.ts +15 -4
- package/src/tools/decide.ts +1 -1
- package/src/tools/dispatch-admission.ts +12 -1
- package/src/tools/dispatch-arguments.ts +38 -1
- package/src/tools/dispatch-plan.ts +7 -7
- package/src/tools/dispatch-runner.ts +48 -32
- package/src/tools/dispatch-schema.ts +30 -23
- package/src/tools/dispatch-scout-admission.ts +10 -44
- package/src/tools/dispatch-scout.ts +2 -3
- package/src/tools/find.ts +13 -4
- package/src/tools/grep.ts +13 -1
- package/src/tools/ls.ts +7 -1
- package/src/tools/monitor.ts +26 -11
- package/src/tools/network-policy.ts +11 -24
- package/src/tools/observation.ts +39 -2
- package/src/tools/read.ts +112 -15
- package/src/tools/registry.ts +54 -17
- package/src/tools/result-shaping.ts +110 -2
- package/src/tools/tasks.ts +33 -7
- package/src/tools/verify/frontend.ts +67 -30
- package/src/tools/verify/numeric.ts +6 -1
- package/src/tools/web-fetch-network.ts +179 -0
- package/src/tools/web-fetch-surface.ts +2 -1
- package/src/tools/web-fetch.ts +15 -13
- package/src/tools/worker-evidence.ts +27 -0
- package/src/worker/spec-contract.ts +12 -8
- package/dist/builtins-WGALA46I.js +0 -22
- package/dist/chunk-2WZ546HR.js +0 -792
- package/dist/chunk-5PSMVOLM.js +0 -56
- package/dist/chunk-EL24TAU4.js +0 -1560
- package/dist/chunk-IZXGRF7P.js +0 -4048
- package/dist/chunk-JVCV3ICN.js +0 -47
- package/dist/chunk-MNJGS2IN.js +0 -33
- package/dist/chunk-O5CVSAG5.js +0 -122
- package/dist/chunk-ODGTEFFI.js +0 -50
- package/dist/chunk-OQE5J4C6.js +0 -73
- package/dist/chunk-UUVG37B4.js +0 -244
- package/dist/chunk-V6HJFQZE.js +0 -228
- package/dist/clio-QLICPCF5.js +0 -25
- package/dist/configure-VEPX4NMX.js +0 -55
- package/dist/context-clear-S4ZJCQUX.js +0 -182
- package/dist/detail-A7JAVSIG.js +0 -98
- package/dist/evidence-4F5USFKH.js +0 -208
- package/dist/fleet-view-MN2VG4MR.js +0 -101
- package/dist/inventory-C26CFDRR.js +0 -101
- package/dist/preload-P6DGH2PZ.js +0 -13
- package/dist/slash-commands-ZXPJD64J.js +0 -92
- package/dist/tasks-IPAGMEIX.js +0 -36
- package/dist/tools-EFFEAIDP.js +0 -28
- package/dist/verify-FWYGPKMR.js +0 -29
- package/dist/wiki-generate-743CIGJW.js +0 -476
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"query": "How do I resume a session in a different working directory?",
|
|
4
|
+
"file": "docs/architecture/session-lifecycle.md",
|
|
5
|
+
"heading": "5. Session Resumption (`/resume`) & Working Directory Fallback"
|
|
6
|
+
},
|
|
7
|
+
{
|
|
8
|
+
"query": "How can I export a session?",
|
|
9
|
+
"file": "docs/architecture/session-lifecycle.md",
|
|
10
|
+
"heading": "6. Session Export"
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
"query": "Where does Clio store prompt history and recover input?",
|
|
14
|
+
"file": "docs/architecture/session-lifecycle.md",
|
|
15
|
+
"heading": "8. Prompt History and Input Recovery"
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"query": "How does the append-only context ledger current.jsonl work?",
|
|
19
|
+
"file": "docs/architecture/session-lifecycle.md",
|
|
20
|
+
"heading": "3. Append-Only Context Ledger (`current.jsonl`)"
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
"query": "How do local catalog overlays work?",
|
|
24
|
+
"file": "docs/architecture/model-catalog.md",
|
|
25
|
+
"heading": "Local catalog overlays"
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
"query": "What are the runtime refresh controls?",
|
|
29
|
+
"file": "docs/architecture/model-catalog.md",
|
|
30
|
+
"heading": "Runtime refresh controls"
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"query": "How are evidence tags and failure causes classified?",
|
|
34
|
+
"file": "docs/architecture/evidence-and-memory.md",
|
|
35
|
+
"heading": "Evidence Tag Taxonomy and Failure Causes"
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
"query": "What is the memory record lifecycle?",
|
|
39
|
+
"file": "docs/architecture/evidence-and-memory.md",
|
|
40
|
+
"heading": "Memory record lifecycle"
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
"query": "How does convention retention and decision adherence work?",
|
|
44
|
+
"file": "docs/architecture/evidence-and-memory.md",
|
|
45
|
+
"heading": "Convention retention and decision adherence"
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
"query": "Who owns installed skills?",
|
|
49
|
+
"file": "docs/guide/skills-marketplace.md",
|
|
50
|
+
"heading": "Operator ownership of installed skills"
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
"query": "How do I publish a skill?",
|
|
54
|
+
"file": "docs/guide/skills-marketplace.md",
|
|
55
|
+
"heading": "Publishing a skill"
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
"query": "How does live routing differ from saved defaults?",
|
|
59
|
+
"file": "docs/guide/configuration-and-targets.md",
|
|
60
|
+
"heading": "Live routing vs saved defaults"
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
"query": "How do I page through read output with offset limit and tail?",
|
|
64
|
+
"file": "docs/guide/tool-usage.md",
|
|
65
|
+
"heading": "read: page through a file with offset, limit, and tail"
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
"query": "How does edit perform exact text replacements in one file?",
|
|
69
|
+
"file": "docs/guide/tool-usage.md",
|
|
70
|
+
"heading": "edit: exact text replacements in one file"
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
"query": "How do I check a credential key without reading its value using credential_present?",
|
|
74
|
+
"file": "docs/guide/tool-usage.md",
|
|
75
|
+
"heading": "credential_present: check environment or file for a credential key"
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
"query": "How do I search file contents with ripgrep?",
|
|
79
|
+
"file": "docs/guide/tool-usage.md",
|
|
80
|
+
"heading": "grep: search file contents with ripgrep"
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
"query": "How can I locate files and directories by glob pattern?",
|
|
84
|
+
"file": "docs/guide/tool-usage.md",
|
|
85
|
+
"heading": "find: locate files and directories by glob pattern"
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
"query": "How does web_fetch convert HTML to markdown?",
|
|
89
|
+
"file": "docs/guide/tool-usage.md",
|
|
90
|
+
"heading": "web_fetch: fetch http(s) URLs and convert HTML to markdown"
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
"query": "How can steer guide or cancel a running worker?",
|
|
94
|
+
"file": "docs/guide/tool-usage.md",
|
|
95
|
+
"heading": "steer: guide or cancel a running worker"
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
"query": "How do I run headless declared verifier commands?",
|
|
99
|
+
"file": "docs/guide/tool-usage.md",
|
|
100
|
+
"heading": "Headless declared verifier commands"
|
|
101
|
+
}
|
|
102
|
+
]
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"provenance": {
|
|
3
|
+
"issue": 351,
|
|
4
|
+
"kind": "retained-live-observation",
|
|
5
|
+
"candidate": "7819fe4774b48b68e2129d9b54e888cce634c6aa",
|
|
6
|
+
"commit": "e2eb80649733833194b032f7862f31e33409cdd2",
|
|
7
|
+
"council": "1exzos2cu032",
|
|
8
|
+
"judge": "1gfii9n9kaj3",
|
|
9
|
+
"session": "jz7pk7jg8net",
|
|
10
|
+
"note": "Functions copied from archived codex/findiff/utils.py. Fixture execution is scripted machinery, not model evidence.",
|
|
11
|
+
"decisionRef": "agent:24fb149d-199f-4269-920d-70b3e033ebe4/battletest-index-policy"
|
|
12
|
+
},
|
|
13
|
+
"key": "battletest-index-policy",
|
|
14
|
+
"pythonPolicy": "to_index_tuple returns Python int coordinates, explicitly converting each NumPy-array element before constructing the tuple.",
|
|
15
|
+
"numpyPolicy": "Preserve NumPy integer scalar coordinates.",
|
|
16
|
+
"source": "import numpy as np\n\n\ndef to_long_index(idx, shape):\n\n ndims = len(shape)\n long_idx = 0\n siz = 1\n for axis in range(ndims):\n idx_ = idx[ndims - 1 - axis]\n long_idx += idx_ * siz\n siz *= shape[ndims - 1 - axis]\n\n return long_idx\n\n\ndef to_index_tuple(long_idx, shape):\n ndims = len(shape)\n idx = np.zeros(ndims, dtype=int)\n for k in range(ndims):\n s = np.prod(shape[k + 1 :])\n idx[k] = long_idx // s\n long_idx = long_idx - s * idx[k]\n\n return tuple(idx)\n"
|
|
17
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
{
|
|
2
|
+
"issue": 349,
|
|
3
|
+
"evidence": {
|
|
4
|
+
"candidate": "7819fe4774b48b68e2129d9b54e888cce634c6aa",
|
|
5
|
+
"repositoryHead": "6ed90aa8a4433376c3ea7004bc775dd08e0cef70",
|
|
6
|
+
"originalRunId": "14ro3q992g4c",
|
|
7
|
+
"originalOutcome": "result_contract_exhausted",
|
|
8
|
+
"originalRepairs": 2,
|
|
9
|
+
"originalDependentExecuted": false,
|
|
10
|
+
"source": "battletest-v044/closeout/scratch-repositories.tar.gz:repos/local/findiff/",
|
|
11
|
+
"sourceSha256": {
|
|
12
|
+
"findiff/grids.py": "0e5516f9245df2d69835694b7f0bdb68ec9a411f8ba561d8c9ba6e5ef335f2bb",
|
|
13
|
+
"findiff/interface.py": "e8a61d50837d1312c1621d95e55deaba0393fa1962ae7d78efaec20c3ef1b90d"
|
|
14
|
+
},
|
|
15
|
+
"scope": "Retained representation and interface source; deterministic subset, not a live-model acceptance result.",
|
|
16
|
+
"sourceLicense": "MIT License\n\nCopyright (c) 2018 maroba\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
|
|
17
|
+
},
|
|
18
|
+
"prompt": "Use dispatch pipeline mode for two bounded read-only steps. First ask Scout to identify how findiff represents nonuniform grid spacing. Then ask Documenter to turn the first step's evidence into a concise explanation with file citations. Do not edit files. Wait for the pipeline receipt and report its real run IDs and outcomes.",
|
|
19
|
+
"dispatch": {
|
|
20
|
+
"mode": "pipeline",
|
|
21
|
+
"briefing": "Two bounded read-only steps on nonuniform grid spacing. Do not edit files. Scout evidence feeds Documenter.",
|
|
22
|
+
"tasks": [
|
|
23
|
+
{
|
|
24
|
+
"agent": "scout",
|
|
25
|
+
"task": "Identify how findiff represents nonuniform grid spacing. Inspect only findiff/grids.py and findiff/interface.py. Return cited observations on coordinates, axis construction, and how Diff consumes the grid. Do not edit files."
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
"agent": "documenter",
|
|
29
|
+
"task": "Turn the first step's evidence into a concise explanation with file citations. Use only the evidence provided by the preceding Scout step. Do not edit files."
|
|
30
|
+
}
|
|
31
|
+
]
|
|
32
|
+
},
|
|
33
|
+
"files": {
|
|
34
|
+
"findiff/grids.py": "import numbers\n\nimport numpy as np\n\nfrom findiff.backend import is_array\n\n\nclass GridAxis:\n\n def __init__(self, dim: int, periodic=False):\n if not isinstance(dim, numbers.Number) or int(dim) != dim:\n raise ValueError(\"Dimension must be an integer\")\n if dim < 0:\n raise ValueError(\"Dimension must be >= 0.\")\n self.dim = dim\n self.periodic = periodic\n\n\nclass EquidistantAxis(GridAxis):\n\n def __init__(self, dim: int, spacing: float, periodic=False):\n super().__init__(dim, periodic)\n if spacing <= 0:\n raise ValueError(\"Spacing must be > 0.\")\n self.spacing = spacing\n\n\nclass NonEquidistantAxis(GridAxis):\n def __init__(self, dim: int, coords: np.ndarray, periodic=False):\n super().__init__(dim, periodic)\n self.coords = coords\n\n\nclass Grid:\n def __init__(self, *axes: GridAxis):\n self.axes = {ax.dim: ax for ax in axes}\n\n def get_axis(self, dim: int) -> GridAxis:\n return self.axes.get(dim)\n\n\ndef make_grid(config_or_grid):\n \"\"\"Makes or returns a grid based on configuration or an actual Grid instance.\n\n Historically, the API allowed to specify grid using a variety of\n shortcuts using a single number, dicts or full Grid instances.\n\n The purpose of this function is to keep other modules closed with\n respect of addition an modification of GridAxis and Grid types.\n \"\"\"\n if isinstance(config_or_grid, Grid):\n return config_or_grid\n elif isinstance(config_or_grid, dict):\n config = config_or_grid\n axes = []\n for dim, ax_config in config.items():\n if isinstance(ax_config, dict):\n ax = EquidistantAxis(\n dim, ax_config[\"h\"], periodic=ax_config.get(\"periodic\", False)\n )\n else:\n ax = EquidistantAxis(dim, ax_config)\n axes.append(ax)\n return Grid(*axes)\n elif config_or_grid is None:\n return None\n else:\n raise TypeError(f\"Unsupported grid type: {type(config_or_grid)}\")\n\n\ndef make_axis(dim, config_or_axis, periodic=False):\n \"\"\"Makes or returns a grid axis based on configuration or an actual GridAxis instance.\n\n Historically, the API allowed to specify axes using a variety of\n shortcuts using a single number, dicts or full GridAxis instances.\n\n The purpose of this function is to keep other modules closed with\n respect of addition an modification of GridAxis and Grid types.\n \"\"\"\n\n if isinstance(config_or_axis, GridAxis):\n return config_or_axis\n if isinstance(config_or_axis, numbers.Number):\n return EquidistantAxis(dim, spacing=config_or_axis, periodic=periodic)\n elif is_array(config_or_axis):\n return NonEquidistantAxis(dim, coords=np.asarray(config_or_axis), periodic=periodic)\n",
|
|
35
|
+
"findiff/interface.py": "from .compact import CompactScheme\nfrom .grids import make_axis\nfrom .operators import Diff as _Diff\n\n\nclass Diff(_Diff):\n\n def __init__(\n self,\n axis=0,\n grid=None,\n periodic=False,\n acc=_Diff.DEFAULT_ACC,\n scheme=None,\n compact=None,\n ):\n \"\"\"Represents a partial derivative (along one axis).\n\n For higher derivatives, exponentiate. For mixed partial derivatives, multiply. See\n examples below.\n\n Examples\n --------\n Set up grid (equidistant here):\n >>> import numpy as np\n >>> x = np.linspace(0, 10, 100)\n\n The array to differentiate\n >>> f = np.sin(x) # as an example\n\n Define the first derivative:\n >>> from findiff import Diff\n >>> d_dx = Diff(0)\n >>> d_dx.set_grid({0: x[1] - x[0]})\n\n Now apply it:\n >>> df_dx = d_dx(f)\n\n The second derivative is constructed by exponentiation:\n >>> d2_dx2 = d_dx ** 2\n >>> d2f_dx2 = d2_dx2(f)\n\n In multiple dimensions with meshed grids, the usage is accordingly:\n >>> x = y = z = np.linspace(0, 10, 100)\n >>> dx = dy = dz = x[1] - x[0]\n >>> X, Y, Z = np.meshgrid(x, y, z, indexing='ij')\n >>> f = np.sin(X) * np.sin(Y) * np.sin(Z)\n >>> d_dx = Diff(0)\n >>> d_dy = Diff(1)\n >>> d_dz = Diff(2)\n >>> d3_dxdydz = d_dx * d_dy * d_dz\n >>> d3_dxdydz.set_grid({0: dx, 1: dy, 2: dz})\n >>> d3f_dxdydz = d3_dxdydz(f)\n \"\"\"\n if compact and scheme:\n raise ValueError(\"Cannot specify both `compact` and `scheme`\")\n if compact:\n if compact % 2 == 0:\n raise ValueError(\"`compact` must be odd integer\")\n scheme = CompactScheme.from_accuracy(acc, 1, compact)\n\n grid_axis = make_axis(axis, grid, periodic)\n super().__init__(axis, grid_axis, acc, scheme)\n"
|
|
36
|
+
},
|
|
37
|
+
"findings": [
|
|
38
|
+
{
|
|
39
|
+
"claim": "NonEquidistantAxis stores the supplied coordinates in self.coords.",
|
|
40
|
+
"path": "findiff/grids.py",
|
|
41
|
+
"line": 31
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
"claim": "make_axis converts array input to a NonEquidistantAxis with np.asarray.",
|
|
45
|
+
"path": "findiff/grids.py",
|
|
46
|
+
"line": 86
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
"claim": "Diff passes the supplied grid through make_axis.",
|
|
50
|
+
"path": "findiff/interface.py",
|
|
51
|
+
"line": 62
|
|
52
|
+
}
|
|
53
|
+
],
|
|
54
|
+
"dependentExplanation": "Nonuniform grids are represented by coordinates stored in NonEquidistantAxis.coords (findiff/grids.py:31). make_axis converts an array input with np.asarray to construct that axis (findiff/grids.py:86). Diff passes its grid argument through make_axis (findiff/interface.py:62)."
|
|
55
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
{
|
|
2
|
+
"issue": 361,
|
|
3
|
+
"originalCommand": "/run coder Read only findiff/coefs.py, findiff/findiff.py, tests/test_accuracy.py and tests/test_coefs.py. Produce a detailed 1200-word source-cited explanation comparing uniform and nonuniform boundary stencils and their numerical accuracy tests. Do not edit any files.",
|
|
4
|
+
"task": "Read only findiff/coefs.py, findiff/findiff.py, tests/test_accuracy.py and tests/test_coefs.py. Produce a detailed 1200-word source-cited explanation comparing uniform and nonuniform boundary stencils and their numerical accuracy tests. Do not edit any files.",
|
|
5
|
+
"recoveryCommand": "/run scout Read only findiff/coefs.py, findiff/findiff.py, tests/test_accuracy.py and tests/test_coefs.py. Produce a detailed 1200-word source-cited explanation comparing uniform and nonuniform boundary stencils and their numerical accuracy tests. Do not edit any files.",
|
|
6
|
+
"referenceKind": "manually authored deterministic reference; not a model recovery",
|
|
7
|
+
"files": {
|
|
8
|
+
"findiff/coefs.py": "\"\"\"\nThis module determines finite difference coefficients for uniform and \nnon-uniform grids for any desired even accuracy order.\n\nMost important function:\n\ncoefficients(deriv, acc=None, offsets=None, symbolic=False)\n\nto calculate the finite difference coefficients for a given derivative\norder and given accuracy order to given offsets.\n\"\"\"\n\nimport math\nfrom itertools import combinations\n\nimport numpy as np\nimport sympy\nfrom sympy import Matrix, Rational\n\n\ndef coefficients(deriv, acc=None, offsets=None, symbolic=False, analytic_inv=False):\n \"\"\"\n Calculates the finite difference coefficients for given derivative order and accuracy order.\n\n If acc is given, the coefficients are calculated for central, forward and backward\n schemes resulting in the specified accuracy order.\n\n If offsets are given, the coefficients are calculated for the offsets as specified\n and the resulting accuracy order is computed.\n\n *Either* acc *or* offsets must be given.\n\n Assumes that the underlying grid is uniform. This function is available at the `findiff`\n package level.\n\n :param deriv: The derivative order.\n :type deriv: int > 0\n\n :param acc: The accuracy order.\n :type acc: even int > 0:\n\n :param offsets: The offsets for which to calculate the coefficients.\n :type offsets: list of ints\n\n :raises ValueError: if invalid arguments are given\n\n :return: dict with the finite difference coefficients and corresponding offsets\n \"\"\"\n\n _validate_deriv(deriv)\n\n if acc is not None and offsets:\n raise ValueError(\"acc and offsets cannot both be given\")\n\n if offsets:\n if deriv >= len(offsets):\n raise ValueError(\n f\"can not compute derivative of order {deriv} using {len(offsets)} offsets.\"\n )\n return calc_coefs(deriv, offsets, symbolic, analytic_inv)\n\n if acc is None:\n raise ValueError(\"either acc or offsets has to be given\")\n\n _validate_acc(acc)\n ret = {}\n num_central_coefs = 2 * math.floor((deriv + 1) / 2) - 1 + acc\n num_side_coefs = num_central_coefs // 2\n\n # Determine central coefficients\n offsets = list(range(-num_side_coefs, num_side_coefs + 1))\n ret[\"center\"] = calc_coefs(deriv, offsets, symbolic, analytic_inv)\n\n # Determine forward coefficients\n\n if deriv % 2 == 0:\n num_coef = num_central_coefs + 1\n else:\n num_coef = num_central_coefs\n\n offsets = list(range(num_coef))\n ret[\"forward\"] = calc_coefs(deriv, offsets, symbolic, analytic_inv)\n\n # Determine backward coefficients\n\n offsets = list(range(-num_coef + 1, 1))\n ret[\"backward\"] = calc_coefs(deriv, offsets, symbolic, analytic_inv)\n\n return ret\n\n\ndef calc_coefs(deriv, offsets, symbolic=False, analytic_inv=False, alphas=None):\n \"\"\"The working horse for calculating finite difference coefficients on equidistant grids.\n\n Args:\n deriv: int\n The order of the derivative.\n offsets: list of ints\n Which neighboring points to use.\n symbolic: bool\n Compute symbolically or numerically.\n analytic_inv: bool\n Use analytic inverse for Vandermonde matrix or numerical.\n alphas: dict\n Specifies the implicit scheme to use (the left hand side of the\n system equation in `CompactScheme`). If None, normal (explicit)\n finite differences will be used.\n\n Returns:\n A dict describing the finite difference scheme.\n \"\"\"\n\n if alphas and analytic_inv:\n raise NotImplementedError(\n \"compact finite differences for analytic inversion not yet implemented\"\n )\n if not alphas:\n alphas = {0: 1}\n\n if analytic_inv:\n if symbolic:\n solver = SymbolicAnalyticSolver()\n else:\n solver = AnalyticSolver()\n else:\n if symbolic:\n solver = SymbolicSolver()\n else:\n solver = Solver()\n\n calculator = CoefficientCalculator(deriv, offsets, alphas, solver)\n\n calculator.solve()\n coefs = list(calculator.sol.values())\n\n if not symbolic:\n offsets = np.array(offsets)\n\n return {\"coefficients\": coefs, \"offsets\": offsets, \"accuracy\": calculator.acc}\n\n\ndef coefficients_non_uni(deriv, acc, coords, idx):\n \"\"\"\n Calculates the finite difference coefficients for given derivative order and accuracy order.\n Assumes that the underlying grid is non-uniform.\n\n :param deriv: int > 0: The derivative order.\n\n :param acc: even int > 0: The accuracy order.\n\n :param coords: 1D numpy.ndarray: the coordinates of the axis for the partial derivative\n\n :param idx: int: index of the grid position where to calculate the coefficients\n\n :return: dict with the finite difference coefficients and corresponding offsets\n \"\"\"\n\n _validate_deriv(deriv)\n _validate_acc(acc)\n\n num_central = 2 * math.floor((deriv + 1) / 2) - 1 + acc\n num_side = num_central // 2\n\n if deriv % 2 == 0:\n num_coef = num_central + 1\n else:\n num_coef = num_central\n\n if idx < num_side:\n matrix = _build_matrix_non_uniform(0, num_coef - 1, coords, idx)\n\n offsets = list(range(num_coef))\n rhs = _build_rhs(offsets, deriv, alphas={0: 1})\n\n ret = {\n \"coefficients\": np.linalg.solve(matrix, rhs),\n \"offsets\": np.array(offsets),\n }\n\n elif idx >= len(coords) - num_side:\n matrix = _build_matrix_non_uniform(num_coef - 1, 0, coords, idx)\n\n offsets = list(range(-num_coef + 1, 1))\n rhs = _build_rhs(offsets, deriv, alphas={0: 1})\n\n ret = {\n \"coefficients\": np.linalg.solve(matrix, rhs),\n \"offsets\": np.array(offsets),\n }\n\n else:\n matrix = _build_matrix_non_uniform(num_side, num_side, coords, idx)\n\n offsets = list(range(-num_side, num_side + 1))\n rhs = _build_rhs(offsets, deriv, alphas={0: 1})\n\n ret = {\n \"coefficients\": np.linalg.solve(matrix, rhs),\n \"offsets\": np.array([p for p in range(-num_side, num_side + 1)]),\n }\n\n return ret\n\n\ndef calc_coefs_non_uni_batched(deriv, acc, coords):\n \"\"\"Compute FD coefficients for all points on a non-uniform grid using batched linear algebra.\n\n Instead of solving one linear system per grid point, this groups points by stencil type\n (forward/central/backward) and solves all systems in each group with a single batched\n ``np.linalg.solve`` call.\n\n :param deriv: int > 0: The derivative order.\n :param acc: even int > 0: The accuracy order.\n :param coords: 1D numpy.ndarray: the coordinates of the axis.\n :return: dict with 'forward', 'backward', 'center' keys plus 'num_bndry'.\n Each scheme dict contains 'coefficients' (2D array) and 'offsets' (1D array).\n \"\"\"\n _validate_deriv(deriv)\n _validate_acc(acc)\n\n num_central = 2 * math.floor((deriv + 1) / 2) - 1 + acc\n num_side = num_central // 2\n num_coef = num_central + 1 if deriv % 2 == 0 else num_central\n\n N = len(coords)\n\n fwd_indices = np.arange(min(num_side, N))\n fwd_weights = _solve_non_uni_batched(coords, fwd_indices, 0, num_coef - 1, deriv)\n\n bwd_start = max(num_side, N - num_side)\n bwd_indices = np.arange(bwd_start, N)\n bwd_weights = _solve_non_uni_batched(coords, bwd_indices, num_coef - 1, 0, deriv)\n\n ctr_indices = np.arange(num_side, max(num_side, N - num_side))\n ctr_weights = _solve_non_uni_batched(coords, ctr_indices, num_side, num_side, deriv)\n\n return {\n \"forward\": {\n \"coefficients\": fwd_weights,\n \"offsets\": np.arange(num_coef),\n },\n \"backward\": {\n \"coefficients\": bwd_weights,\n \"offsets\": np.arange(-num_coef + 1, 1),\n },\n \"center\": {\n \"coefficients\": ctr_weights,\n \"offsets\": np.arange(-num_side, num_side + 1),\n },\n \"num_bndry\": num_side,\n }\n\n\ndef _solve_non_uni_batched(coords, indices, p, q, deriv):\n \"\"\"Solve for FD coefficients for multiple points with the same stencil structure.\n\n Builds all Vandermonde-like matrices at once and calls ``np.linalg.solve``\n with a 3-D array of matrices and a 2-D array of right-hand sides.\n\n :param coords: 1D coordinate array.\n :param indices: 1D integer array of grid-point indices to compute for.\n :param p: number of stencil points to the left.\n :param q: number of stencil points to the right.\n :param deriv: derivative order.\n :return: 2D array of shape (len(indices), stencil_size).\n \"\"\"\n n = len(indices)\n stencil_size = p + q + 1\n\n if n == 0:\n return np.empty((0, stencil_size))\n\n j_offsets = np.arange(-p, q + 1)\n\n # Coordinate differences: shape (n, stencil_size)\n idx_matrix = indices[:, None] + j_offsets[None, :]\n coord_diffs = coords[idx_matrix] - coords[indices, None]\n\n # Build Vandermonde-like matrices: shape (n, stencil_size, stencil_size)\n # matrices[i, row, col] = coord_diffs[i, col] ** row\n powers = np.arange(stencil_size)\n matrices = coord_diffs[:, None, :] ** powers[None, :, None]\n\n # Build RHS: only position `deriv` is non-zero (= deriv!)\n rhs = _build_rhs(list(j_offsets), deriv, alphas={0: 1})\n # np.linalg.solve with 3D A expects b to have shape (..., m, k), not (..., m)\n rhs_col = rhs[:, np.newaxis] # (stencil_size, 1)\n rhs_batch = np.broadcast_to(rhs_col, (n, stencil_size, 1)).copy()\n\n return np.linalg.solve(matrices, rhs_batch)[:, :, 0]\n\n\ndef vandermonde_matrix(values):\n A = [([1 for _ in values])]\n for i in range(1, len(values)):\n A.append([j**i for j in values])\n return A\n\n\ndef _build_rhs(\n offsets,\n deriv,\n alphas,\n symbolic=False,\n):\n \"\"\"The right hand side of the equation system matrix\"\"\"\n\n if symbolic:\n frac = lambda num, denom: sympy.Rational(num, denom) # noqa: E731\n else:\n frac = lambda num, denom: num / denom # noqa: E731\n\n b = [0 for _ in offsets]\n for j in range(deriv, len(offsets)):\n b[j] = frac(math.factorial(j), math.factorial(j - deriv)) * sum(\n r ** (j - deriv) * alphas[r] for r in alphas\n )\n\n if symbolic:\n return sympy.Matrix(b)\n else:\n return np.array(b, dtype=\"float\")\n\n\ndef _build_matrix_non_uniform(p, q, coords, k):\n \"\"\"Constructs the equation matrix for the finite difference coefficients of non-uniform grids at location k\"\"\"\n A = [[1] * (p + q + 1)]\n for i in range(1, p + q + 1):\n line = [(coords[k + j] - coords[k]) ** i for j in range(-p, q + 1)]\n A.append(line)\n return np.array(A, dtype=\"float\")\n\n\ndef _validate_acc(acc):\n if acc % 2 == 1 or acc <= 0:\n raise ValueError(\"Accuracy order acc must be positive EVEN integer\")\n\n\ndef _validate_deriv(deriv):\n if deriv < 0:\n raise ValueError(\"Derive degree must be positive integer\")\n\n\nclass InverseVandermondeColumn:\n\n def __init__(self, symbolic=False):\n\n self.symbolic = symbolic\n if symbolic:\n self.take = lambda arr, ids: [arr[idx] for idx in ids] # noqa: E731\n self.prod = sympy.prod\n self.minus = lambda x, arr: [x - val for val in arr] # noqa: E731\n self.frac = lambda num, denom: sympy.Rational(num, denom) # noqa: E731\n else:\n self.take = lambda arr, ids: arr[ids] # noqa: E731\n self.prod = np.prod\n self.minus = lambda x, arr: x - arr # noqa: E731\n self.frac = lambda num, denom: num / denom # noqa: E731\n\n def compute(self, column, offsets):\n \"\"\"Computes a given column of the inverse of the Vandermonde matrix that\n belongs to given offsets, multiplied by the factorial of the column index.\n\n This code implements the first equation for b_kj under \"Proof 1\" in\n https://proofwiki.org/wiki/Inverse_of_Vandermonde_Matrix\n Note that the result has to be transposed because the original Vandermonde\n matrix is defined transposed as compared to _build_matrix.\n\n Also, we have 0-based indexing here, whereas the formulae in the wiki entry\n are 1-based.\n \"\"\"\n\n if not self.symbolic:\n offsets = np.array(offsets)\n\n n = len(offsets)\n k = column + 1\n inv_vandermonde_column = []\n if k == n:\n # If the number of offsets matches the derivative order + 1, there is a special\n # case, compare the lower part of the bracket in the equation in proofwiki.\n for j in range(n):\n denom = self.prod(self.minus(offsets[j], offsets[:j])) * self.prod(\n self.minus(offsets[j], offsets[j + 1 :])\n )\n inv_vandermonde_column.append(self.frac(1, denom))\n else:\n # This is the \"regular\" part of the bracket. First compute the sign that is the\n # same for all entries in the column that we compute\n sign = (-1) ** (n - k)\n for j in range(n):\n # All indices except j\n range_wo_j = list(range(j)) + list(range(j + 1, n))\n # Get all combinations of n-k indices that are ascending and do not contain j\n index_set = combinations(range_wo_j, r=n - k)\n enumerator = sum(\n self.prod(self.take(offsets, list(m))) for m in index_set\n )\n denominator = self.prod(\n self.minus(offsets[j], self.take(offsets, range_wo_j))\n )\n inv_vandermonde_column.append(sign * self.frac(enumerator, denominator))\n\n fact = math.factorial(column)\n\n result = [val * fact for val in inv_vandermonde_column]\n if self.symbolic:\n return result\n\n return np.array(result)\n\n\nclass CoefficientCalculator:\n\n def __init__(self, deriv, offsets, alphas, solver):\n self.deriv = deriv\n self.offsets = offsets\n self.alphas = alphas\n self.solver = solver\n self.sol = None\n self.acc = None\n\n def solve(self):\n coefs = self.solver.solve(self.deriv, self.offsets, self.alphas)\n self.sol = {off: coef for off, coef in zip(self.offsets, coefs)}\n self.acc = self.solver.acc\n return self.sol\n\n\nclass Solver:\n\n atol = 1.0e-6\n\n def __init__(self, wrapper=None):\n self.wrapper = wrapper or NumericMatrixWrapper()\n self.acc = None\n\n def solve(self, deriv, offsets, alphas):\n sol = np.linalg.solve(\n self.lhs(deriv, offsets), self.rhs(deriv, offsets, alphas)\n )\n self.acc = self.calc_accuracy(deriv, offsets, sol, alphas)\n return sol\n\n def rhs(self, deriv, offsets, alphas):\n\n b = [0 for _ in offsets]\n for j in range(deriv, len(offsets)):\n b[j] = self.wrapper.frac(\n math.factorial(j), math.factorial(j - deriv)\n ) * sum(r ** (j - deriv) * alphas[r] for r in alphas)\n\n return self.wrapper(b)\n\n def lhs(self, deriv, offsets):\n return self.wrapper(vandermonde_matrix(offsets))\n\n def calc_accuracy(self, deriv, offsets, coefs, alphas):\n n_plus_s = deriv + 1\n max_n = 999\n break_condition = lambda b: abs(b) > self.atol # noqa: E731\n\n while True:\n b = 0\n fac = 1 / math.factorial(n_plus_s)\n for o, coef in zip(offsets, coefs):\n b += coef * o**n_plus_s * fac\n\n s = n_plus_s - deriv\n fac = 1 / math.factorial(s)\n for o, alpha in alphas.items():\n b -= alpha * fac * o**s\n\n if break_condition(b):\n break\n\n n_plus_s += 1\n if n_plus_s > max_n:\n raise Exception(\"Cannot compute accuracy.\")\n\n return round(n_plus_s - deriv)\n\n\nclass SymbolicSolver(Solver):\n\n atol = 0\n\n def __init__(self):\n super().__init__(SymbolicMatrixWrapper())\n\n def solve(self, deriv, offsets, alphas):\n sol = sympy.linsolve(\n (self.lhs(deriv, offsets), self.rhs(deriv, offsets, alphas))\n )\n sol = list(tuple(sol)[0])\n self.acc = self.calc_accuracy(deriv, offsets, sol, alphas)\n return sol\n\n\nclass AnalyticSolver(Solver):\n symbolic = False\n\n def solve(self, deriv, offsets, alphas):\n sol = InverseVandermondeColumn(symbolic=self.symbolic).compute(deriv, offsets)\n self.acc = self.calc_accuracy(deriv, offsets, sol, alphas)\n return sol\n\n\nclass SymbolicAnalyticSolver(AnalyticSolver):\n symbolic = True\n atol = 0\n\n\nclass SymbolicMatrixWrapper:\n def __call__(self, arr):\n return Matrix(arr)\n\n def frac(self, num, denom):\n return Rational(num, denom)\n\n\nclass NumericMatrixWrapper:\n def __call__(self, arr):\n return np.array(arr, dtype=np.float64)\n\n def frac(self, num, denom):\n return num / denom\n",
|
|
9
|
+
"findiff/findiff.py": "import numpy as np\nfrom scipy import sparse\n\nfrom findiff.backend import add_at, get_namespace\nfrom findiff.coefs import coefficients, calc_coefs_non_uni_batched\nfrom findiff.compact import _CompactDiffUniformPeriodic, _CompactDiffUniformNonPeriodic\nfrom findiff.grids import EquidistantAxis, GridAxis, NonEquidistantAxis\nfrom findiff.utils import (\n get_list_of_multiindex_tuples,\n get_long_indices_for_all_grid_points_as_1d_array,\n get_long_indices_for_all_grid_points_as_ndarray,\n to_long_index,\n)\n\n\ndef build_differentiator(order: int, axis: GridAxis, acc, scheme=None):\n if scheme:\n if isinstance(axis, EquidistantAxis):\n if axis.periodic:\n return _CompactDiffUniformPeriodic(\n axis.dim, order, axis.spacing, scheme\n )\n else:\n return _CompactDiffUniformNonPeriodic(\n axis.dim, order, axis.spacing, scheme\n )\n raise NotImplementedError(\"This is not yet implemented for compact schemes.\")\n\n if isinstance(axis, EquidistantAxis):\n if not axis.periodic:\n return _FinDiffUniform(axis.dim, order, axis.spacing, acc)\n else:\n return _FinDiffUniformPeriodic(axis.dim, order, axis.spacing, acc)\n elif isinstance(axis, NonEquidistantAxis):\n if not axis.periodic:\n return _FinDiffNonUniform(axis.dim, order, axis.coords, acc)\n else:\n raise NotImplementedError(\"Periodic nonuniform axes not yet implemented\")\n else:\n raise TypeError(\"Unknown axis type.\")\n\n\nclass _FinDiffBase:\n\n def __init__(self, axis, order):\n self.axis = axis\n self.order = order\n\n def guard_valid_target(self, f):\n try:\n f.shape[self.axis]\n except AttributeError as err:\n raise ValueError(\n \"Diff objects can only be applied to arrays or evaluated(!) functions returning arrays\"\n ) from err\n\n if np.issubdtype(f.dtype, np.integer):\n f = f.astype(np.float64)\n return f\n\n def apply_to_array(self, yd, y, weights, off_slices, ref_slice, dim):\n \"\"\"Applies the finite differences only to slices along a given axis.\n\n Returns the updated output array (required for immutable backends\n like JAX).\n \"\"\"\n\n ndims = len(y.shape)\n\n all = slice(None, None, 1)\n\n ref_multi_slice = [all] * ndims\n ref_multi_slice[dim] = ref_slice\n\n for w, s in zip(weights, off_slices):\n off_multi_slice = [all] * ndims\n off_multi_slice[dim] = s\n if abs(1 - w) < 1.0e-14:\n yd = add_at(yd, tuple(ref_multi_slice), y[tuple(off_multi_slice)])\n else:\n yd = add_at(yd, tuple(ref_multi_slice), w * y[tuple(off_multi_slice)])\n return yd\n\n def shift_slice(self, sl, off, max_index):\n\n if sl.start + off < 0 or sl.stop + off > max_index:\n raise IndexError(\"Shift slice out of bounds\")\n\n return slice(sl.start + off, sl.stop + off, sl.step)\n\n def matrix(self, shape):\n siz = np.prod(shape)\n mat = sparse.lil_matrix((siz, siz))\n self.write_matrix_entries(mat, shape)\n return sparse.csr_matrix(mat)\n\n def write_matrix_entries(self, mat, shape):\n raise NotImplementedError\n\n\nclass _FinDiffUniform(_FinDiffBase):\n\n def __init__(self, axis, order, spacing, acc):\n super().__init__(axis, order)\n self.spacing = spacing\n self.acc = acc\n coef_schemes = coefficients(self.order, acc)\n self.forward = coef_schemes[\"forward\"]\n self.backward = coef_schemes[\"backward\"]\n self.center = coef_schemes[\"center\"]\n\n def __call__(self, f):\n f = self.guard_valid_target(f)\n xp = get_namespace(f)\n\n npts = f.shape[self.axis]\n fd = xp.zeros_like(f)\n num_bndry_points = len(self.center[\"coefficients\"]) // 2\n\n fd = self._apply_central_coefs(f, fd, npts, num_bndry_points)\n\n fd = self._apply_forward_coefs(f, fd, npts, num_bndry_points)\n\n fd = self._apply_backward_coefs(f, fd, npts, num_bndry_points)\n\n h_inv = 1.0 / self.spacing**self.order\n return fd * h_inv\n\n def _apply_backward_coefs(self, f, fd, npts, num_bndry_points):\n weights = self.backward[\"coefficients\"]\n offsets = self.backward[\"offsets\"]\n ref_slice = slice(npts - num_bndry_points, npts, 1)\n off_slices = [\n self.shift_slice(ref_slice, offsets[k], npts) for k in range(len(offsets))\n ]\n return self.apply_to_array(fd, f, weights, off_slices, ref_slice, self.axis)\n\n def _apply_forward_coefs(self, f, fd, npts, num_bndry_points):\n weights = self.forward[\"coefficients\"]\n offsets = self.forward[\"offsets\"]\n ref_slice = slice(0, num_bndry_points, 1)\n off_slices = [\n self.shift_slice(ref_slice, offsets[k], npts) for k in range(len(offsets))\n ]\n return self.apply_to_array(fd, f, weights, off_slices, ref_slice, self.axis)\n\n def _apply_central_coefs(self, f, fd, npts, num_bndry_points):\n weights = self.center[\"coefficients\"]\n offsets = self.center[\"offsets\"]\n ref_slice = slice(num_bndry_points, npts - num_bndry_points, 1)\n off_slices = [\n self.shift_slice(ref_slice, offsets[k], npts) for k in range(len(offsets))\n ]\n return self.apply_to_array(fd, f, weights, off_slices, ref_slice, self.axis)\n\n def write_matrix_entries(self, mat, shape):\n long_indices_nd = get_long_indices_for_all_grid_points_as_ndarray(shape)\n for scheme in [\"center\", \"forward\", \"backward\"]:\n\n offsets_long = self._convert_1D_offsets_to_long_indices(\n self.axis, getattr(self, scheme)[\"offsets\"], shape\n )\n\n multi_slice = self._get_multislice_for_scheme(self.axis, scheme, shape)\n Is = long_indices_nd[tuple(multi_slice)].reshape(-1)\n\n coefs = getattr(self, scheme)[\"coefficients\"]\n for o, c in zip(offsets_long, coefs):\n v = c / self.spacing**self.order\n mat[Is, Is + o] = v\n\n def _get_multislice_for_scheme(self, axis, scheme, shape):\n ndims = len(shape)\n multi_slice = [slice(None, None)] * ndims\n nside = len(self.center[\"coefficients\"]) // 2\n if scheme == \"center\":\n multi_slice[axis] = slice(nside, -nside)\n elif scheme == \"forward\":\n multi_slice[axis] = slice(0, nside)\n else:\n multi_slice[axis] = slice(-nside, None)\n return multi_slice\n\n def _convert_1D_offsets_to_long_indices(self, axis, offsets_1d, shape):\n ndims = len(shape)\n offsets_long = []\n for o_1d in offsets_1d:\n o_nd = np.zeros(ndims, dtype=int)\n o_nd[axis] = o_1d\n o_long = to_long_index(o_nd, shape)\n offsets_long.append(o_long)\n return offsets_long\n\n\nclass _FinDiffUniformPeriodic(_FinDiffBase):\n\n def __init__(self, axis, order, spacing, acc):\n super().__init__(axis, order)\n self.spacing = spacing\n self.acc = acc\n self.coefs = coefficients(self.order, acc)[\"center\"]\n\n def __call__(self, f):\n f = self.guard_valid_target(f)\n xp = get_namespace(f)\n\n fd = xp.zeros_like(f)\n for off, coef in zip(self.coefs[\"offsets\"], self.coefs[\"coefficients\"]):\n fd = fd + coef * xp.roll(f, -off, axis=self.axis)\n h_inv = 1.0 / self.spacing**self.order\n return fd * h_inv\n\n def write_matrix_entries(self, mat, shape):\n Is = get_long_indices_for_all_grid_points_as_1d_array(shape)\n h_inv = 1 / self.spacing**self.order\n for o, c in zip(self.coefs[\"offsets\"], self.coefs[\"coefficients\"]):\n Is_off = self._get_offset_indices_long(o, shape)\n mat[Is, Is_off] = c * h_inv\n\n def _get_offset_indices_long(self, o, shape):\n ndims = len(shape)\n idxs_short = [np.arange(n) for n in shape]\n idxs_short[self.axis] = np.roll(np.arange(shape[self.axis]), -o)\n grid = np.meshgrid(*idxs_short, indexing=\"ij\")\n index_tuples = np.stack(grid, axis=-1).reshape(-1, ndims)\n Is_off = np.ravel_multi_index(index_tuples.T, shape)\n return Is_off\n\n\nclass _FinDiffNonUniform(_FinDiffBase):\n def __init__(self, axis, order, coords, acc):\n super().__init__(axis, order)\n self.coords = coords\n self.acc = acc\n\n schemes = calc_coefs_non_uni_batched(order, acc, coords)\n self.num_bndry = schemes[\"num_bndry\"]\n self.forward = schemes[\"forward\"]\n self.backward = schemes[\"backward\"]\n self.center = schemes[\"center\"]\n\n def __call__(self, y):\n \"\"\"The core function to take a partial derivative on a non-uniform grid\"\"\"\n y = self.guard_valid_target(y)\n xp = get_namespace(y)\n\n dim = self.axis\n N = len(self.coords)\n yd = xp.zeros_like(y)\n ndims = len(y.shape)\n\n yd = self._apply_nonuni_weights(\n yd, y, dim, ndims,\n self.center[\"coefficients\"], self.center[\"offsets\"],\n slice(self.num_bndry, N - self.num_bndry),\n )\n\n yd = self._apply_nonuni_weights(\n yd, y, dim, ndims,\n self.forward[\"coefficients\"], self.forward[\"offsets\"],\n slice(0, self.num_bndry),\n )\n\n yd = self._apply_nonuni_weights(\n yd, y, dim, ndims,\n self.backward[\"coefficients\"], self.backward[\"offsets\"],\n slice(N - self.num_bndry, N),\n )\n\n return yd\n\n def _apply_nonuni_weights(self, yd, y, dim, ndims, weights, offsets, ref_slice):\n \"\"\"Apply per-point weights using vectorized slice operations.\n\n Returns the updated output array (required for immutable backends\n like JAX).\n \"\"\"\n n_pts = ref_slice.stop - ref_slice.start\n if n_pts == 0:\n return yd\n\n ref_multi = [slice(None)] * ndims\n ref_multi[dim] = ref_slice\n\n for j_idx, off in enumerate(offsets):\n off_slice = slice(ref_slice.start + int(off), ref_slice.stop + int(off))\n off_multi = [slice(None)] * ndims\n off_multi[dim] = off_slice\n\n w = weights[:, j_idx]\n w_shape = [1] * ndims\n w_shape[dim] = n_pts\n yd = add_at(yd, tuple(ref_multi), w.reshape(w_shape) * y[tuple(off_multi)])\n return yd\n\n def write_matrix_entries(self, mat, shape):\n long_indices_nd = get_long_indices_for_all_grid_points_as_ndarray(shape)\n N = len(self.coords)\n ndims = len(shape)\n\n schemes = [\n (self.forward, slice(0, self.num_bndry)),\n (self.center, slice(self.num_bndry, N - self.num_bndry)),\n (self.backward, slice(N - self.num_bndry, N)),\n ]\n\n for scheme, axis_slice in schemes:\n n_axis_pts = axis_slice.stop - axis_slice.start\n if n_axis_pts == 0:\n continue\n\n src_multi = [slice(None)] * ndims\n src_multi[self.axis] = axis_slice\n Is = long_indices_nd[tuple(src_multi)].reshape(-1)\n\n selected_shape = list(shape)\n selected_shape[self.axis] = n_axis_pts\n\n for j_idx, o in enumerate(scheme[\"offsets\"]):\n tgt_multi = [slice(None)] * ndims\n tgt_multi[self.axis] = slice(\n axis_slice.start + int(o), axis_slice.stop + int(o)\n )\n Js = long_indices_nd[tuple(tgt_multi)].reshape(-1)\n\n w = scheme[\"coefficients\"][:, j_idx]\n w_shape = [1] * ndims\n w_shape[self.axis] = n_axis_pts\n w_broadcast = np.broadcast_to(\n w.reshape(w_shape), selected_shape\n ).reshape(-1)\n\n mat[Is, Js] = w_broadcast\n",
|
|
10
|
+
"tests/test_accuracy.py": "import numpy as np\n\nfrom findiff import Diff\n\n\ndef test_iterative_accuracy():\n\n ns = np.logspace(2, 3, 10)\n\n def compute_errs(acc, plot=False):\n # import matplotlib.pyplot as plt\n\n errs_a = []\n errs_b = []\n errs_c = []\n\n for n in ns:\n x = np.linspace(0.1, 1, int(n))\n dx = x[1] - x[0]\n\n D = Diff(0, dx, acc=acc)\n D2 = D**2\n DD = D * D\n\n f = x**8\n\n exact = 8 * 7 * x**6\n actual_a = D2(f)\n actual_b = D(D(f))\n actual_c = DD(f)\n\n err_a = np.max(abs((actual_a - exact) / exact))\n err_b = np.max(abs((actual_b - exact) / exact))\n err_c = np.max(abs((actual_c - exact) / exact))\n errs_a.append(err_a)\n errs_b.append(err_b)\n errs_c.append(err_c)\n\n # if plot:\n # plt.loglog(ns, errs_a, \"-x\", label=\"D^2f\")\n # plt.loglog(ns, errs_b, \"-\", label=\"D(D(f))\")\n # plt.loglog(ns, errs_c, \"-\", label=\"D*D*f\")\n # plt.grid()\n # plt.show()\n\n slope_a = abs(loglog_slope(ns, errs_a))\n slope_b = abs(loglog_slope(ns, errs_b))\n slope_c = abs(loglog_slope(ns, errs_c))\n return slope_a, slope_b, slope_c\n\n slope_a, slope_b, slope_c = compute_errs(2, plot=False)\n\n assert abs(slope_a - 2) < 0.2\n # applying operators iteratively should reduce the order by one at a time:\n assert abs(slope_b - 1) < 0.2\n assert abs(slope_c - 2) < 0.2\n\n slope_a, slope_b, slope_c = compute_errs(4, plot=False)\n assert abs(slope_a - 4) < 0.2\n # applying operators iteratively should reduce the order by one at a time:\n assert abs(slope_b - 3) < 0.4\n assert abs(slope_c - 4) < 0.2\n\n\ndef loglog_slope(x, y):\n slope, intercept = np.polyfit(np.log(x), np.log(y), 1)\n return slope\n",
|
|
11
|
+
"tests/test_coefs.py": "import numpy as np\nimport pytest\nfrom sympy import Rational\n\nfrom findiff import coefficients\nfrom findiff.coefs import calc_coefs, vandermonde_matrix\nfrom findiff.coefs import coefficients_non_uni\n\n\n@pytest.mark.parametrize(\"analytic_inv\", [True, False])\ndef test_order2_acc2(analytic_inv):\n\n c = coefficients(deriv=2, acc=2, analytic_inv=analytic_inv)\n\n coefs = c[\"center\"][\"coefficients\"]\n np.testing.assert_array_almost_equal(np.array([1.0, -2.0, 1.0]), coefs)\n offs = c[\"center\"][\"offsets\"]\n np.testing.assert_array_almost_equal(np.array([-1, 0, 1]), offs)\n\n coefs = c[\"forward\"][\"coefficients\"]\n np.testing.assert_array_almost_equal(np.array([2, -5, 4, -1]), coefs)\n offs = c[\"forward\"][\"offsets\"]\n np.testing.assert_array_almost_equal(np.array([0, 1, 2, 3]), offs)\n\n coefs = c[\"backward\"][\"coefficients\"]\n np.testing.assert_array_almost_equal(np.array(([2, -5, 4, -1])[::-1]), coefs)\n offs = c[\"backward\"][\"offsets\"]\n np.testing.assert_array_almost_equal(np.array([-3, -2, -1, 0]), offs)\n\n\n@pytest.mark.parametrize(\"analytic_inv\", [True, False])\ndef test_order1_acc2(analytic_inv):\n\n c = coefficients(deriv=1, acc=2, analytic_inv=analytic_inv)\n\n coefs = c[\"center\"][\"coefficients\"]\n np.testing.assert_array_almost_equal(np.array([-0.5, 0, 0.5]), coefs)\n offs = c[\"center\"][\"offsets\"]\n np.testing.assert_array_almost_equal(np.array([-1, 0, 1]), offs)\n\n coefs = c[\"forward\"][\"coefficients\"]\n np.testing.assert_array_almost_equal(np.array([-1.5, 2, -0.5]), coefs)\n offs = c[\"forward\"][\"offsets\"]\n np.testing.assert_array_almost_equal(np.array([0, 1, 2]), offs)\n\n coefs = c[\"backward\"][\"coefficients\"]\n np.testing.assert_array_almost_equal(-np.array([-1.5, 2, -0.5])[::-1], coefs)\n offs = c[\"backward\"][\"offsets\"]\n np.testing.assert_array_almost_equal(np.array([-2, -1, 0]), offs)\n\n\n@pytest.mark.parametrize(\"analytic_inv\", [True, False])\ndef test_order1_acc4(analytic_inv):\n c = coefficients(deriv=1, acc=4, analytic_inv=analytic_inv)\n coefs = c[\"center\"][\"coefficients\"]\n np.testing.assert_array_almost_equal(\n np.array([1 / 12, -2 / 3, 0, 2 / 3, -1 / 12]), coefs\n )\n offs = c[\"center\"][\"offsets\"]\n np.testing.assert_array_almost_equal(np.array([-2, -1, 0, 1, 2]), offs)\n\n coefs = c[\"forward\"][\"coefficients\"]\n np.testing.assert_array_almost_equal(\n np.array([-25 / 12, 4, -3, 4 / 3, -1 / 4]), coefs\n )\n offs = c[\"forward\"][\"offsets\"]\n np.testing.assert_array_almost_equal(np.array([0, 1, 2, 3, 4]), offs)\n\n coefs = c[\"backward\"][\"coefficients\"]\n np.testing.assert_array_almost_equal(\n -np.array([-25 / 12, 4, -3, 4 / 3, -1 / 4])[::-1], coefs\n )\n offs = c[\"backward\"][\"offsets\"]\n np.testing.assert_array_almost_equal(-np.array([0, 1, 2, 3, 4])[::-1], offs)\n\n\n@pytest.mark.parametrize(\"analytic_inv\", [True, False])\ndef test_order2_acc4(analytic_inv):\n\n c = coefficients(deriv=2, acc=4, analytic_inv=analytic_inv)\n coefs = c[\"center\"][\"coefficients\"]\n np.testing.assert_array_almost_equal(\n np.array([-1 / 12, 4 / 3, -2.5, 4 / 3, -1 / 12]), coefs\n )\n offs = c[\"center\"][\"offsets\"]\n np.testing.assert_array_almost_equal(np.array([-2, -1, 0, 1, 2]), offs)\n\n coefs = c[\"forward\"][\"coefficients\"]\n np.testing.assert_array_almost_equal(\n np.array([15 / 4, -77 / 6, 107 / 6, -13, 61 / 12, -5 / 6]), coefs\n )\n offs = c[\"forward\"][\"offsets\"]\n np.testing.assert_array_almost_equal(np.array([0, 1, 2, 3, 4, 5]), offs)\n\n coefs = c[\"backward\"][\"coefficients\"]\n np.testing.assert_array_almost_equal(\n np.array([15 / 4, -77 / 6, 107 / 6, -13, 61 / 12, -5 / 6])[::-1],\n coefs,\n )\n offs = c[\"backward\"][\"offsets\"]\n np.testing.assert_array_almost_equal(-np.array([0, 1, 2, 3, 4, 5])[::-1], offs)\n\n\n@pytest.mark.parametrize(\"analytic_inv\", [True, False])\ndef test_calc_accuracy_central_deriv2_acc2(analytic_inv):\n coefs = calc_coefs(2, [-1, 0, 1], analytic_inv=analytic_inv)\n assert 2 == coefs[\"accuracy\"]\n\n\n@pytest.mark.parametrize(\"analytic_inv\", [True, False])\ndef test_calc_accuracy_central_deriv1_acc2(analytic_inv):\n coefs = calc_coefs(1, [-1, 0, 1], analytic_inv=analytic_inv)\n assert 2 == coefs[\"accuracy\"]\n\n\n@pytest.mark.parametrize(\"analytic_inv\", [True, False])\ndef test_calc_accuracy_left1_right0_deriv1_acc1(analytic_inv):\n coefs = calc_coefs(1, [-1, 0], analytic_inv=analytic_inv)\n assert 1 == coefs[\"accuracy\"]\n\n\n@pytest.mark.parametrize(\"analytic_inv\", [True, False])\ndef test_calc_accuracy_left0_right3_deriv1_acc3(analytic_inv):\n coefs = calc_coefs(2, [0, 1, 2, 3], analytic_inv=analytic_inv)\n assert 2 == coefs[\"accuracy\"]\n\n\n@pytest.mark.parametrize(\"analytic_inv\", [True, False])\ndef test_calc_accuracy_from_offsets_symbolic1(analytic_inv):\n coefs = calc_coefs(2, [0, 1, 2, 3], symbolic=True, analytic_inv=analytic_inv)\n assert 2 == coefs[\"accuracy\"]\n\n\n@pytest.mark.parametrize(\"analytic_inv\", [True, False])\ndef test_calc_accuracy_from_offsets_symbolic2(analytic_inv):\n coefs = calc_coefs(2, [-4, -2, 0, 2, 4], symbolic=True, analytic_inv=analytic_inv)\n assert 4 == coefs[\"accuracy\"]\n\n\n@pytest.mark.parametrize(\"analytic_inv\", [True, False])\ndef test_calc_coefs_from_offsets(analytic_inv):\n coefs = calc_coefs(1, [-2, 0, 1], analytic_inv=analytic_inv)\n np.testing.assert_array_almost_equal(\n coefs[\"coefficients\"], [-1.0 / 6, -0.5, 2.0 / 3]\n )\n\n\n@pytest.mark.parametrize(\"analytic_inv\", [True, False])\ndef test_calc_coefs_from_offsets_no_central_point(analytic_inv):\n coefs = calc_coefs(1, [-2, 1, 2], analytic_inv=analytic_inv)\n np.testing.assert_array_almost_equal(coefs[\"coefficients\"], [-1.0 / 4, 0, 1.0 / 4])\n\n\n@pytest.mark.parametrize(\"analytic_inv\", [True, False])\ndef test_calc_coefs_from_offsets_not_enough_points(analytic_inv):\n with pytest.raises(ValueError):\n coefficients(2, offsets=[-2, 2], analytic_inv=False)\n\n\n@pytest.mark.parametrize(\"analytic_inv\", [True, False])\ndef test_calc_coefs_symbolic(analytic_inv):\n coefs = calc_coefs(1, [-2, 0, 1], symbolic=True, analytic_inv=analytic_inv)\n expected = [Rational(-1, 6), Rational(-1, 2), Rational(2, 3)]\n np.testing.assert_array_almost_equal(coefs[\"coefficients\"], expected)\n\n\n@pytest.mark.parametrize(\"analytic_inv\", [True, False])\ndef test_non_uniform(analytic_inv):\n\n x = np.linspace(0, 10, 100)\n dx = x[1] - x[0]\n\n c_uni = coefficients(deriv=2, acc=2, analytic_inv=analytic_inv)\n coefs_uni = c_uni[\"center\"][\"coefficients\"] / dx**2\n\n c_non_uni = coefficients_non_uni(deriv=2, acc=2, coords=x, idx=5)\n coefs_non_uni = c_non_uni[\"coefficients\"]\n\n np.testing.assert_array_almost_equal(coefs_non_uni, coefs_uni)\n\n\ndef test_invalid_acc_raises_exception():\n with pytest.raises(ValueError):\n coefficients(deriv=1, acc=3)\n with pytest.raises(ValueError):\n coefficients(deriv=1, acc=0)\n with pytest.raises(ValueError):\n coefficients_non_uni(1, 3, None, None)\n with pytest.raises(ValueError):\n coefficients_non_uni(1, 0, None, None)\n\n\ndef test_invalid_deriv_raises_exception():\n with pytest.raises(ValueError):\n coefficients(-1, 2)\n with pytest.raises(ValueError):\n coefficients_non_uni(-1, 2, None, None)\n\n\ndef test_vandermonde_matrix():\n actual = vandermonde_matrix([1, 2, 3])\n expected = [[1, 1, 1], [1, 2, 3], [1, 4, 9]]\n assert actual == expected\n"
|
|
12
|
+
},
|
|
13
|
+
"sourceSha256": {
|
|
14
|
+
"findiff/coefs.py": "1db6dbe64002c416a60def2463b9ee972429f7fecdcc751e75a331d5a58f53fc",
|
|
15
|
+
"findiff/findiff.py": "ea5f79d8d25258b99347344d7492cc73d4352c595ea8b243c1d740633e6d681f",
|
|
16
|
+
"tests/test_accuracy.py": "2020b57c8cf5b643f16b1da2371ef12b82ed9cf391e74c945e4c2a774479fed7",
|
|
17
|
+
"tests/test_coefs.py": "6f197773f69635b241390a4b2afeeae7de5bd0f9a787f63f63d0a18319f7107f"
|
|
18
|
+
},
|
|
19
|
+
"findings": [
|
|
20
|
+
{
|
|
21
|
+
"claim": "Uniform and nonuniform grid derivatives both replace a derivative at a grid point with a weighted sum of near values. Boundary stencils matter because a balanced set of neighbors cannot extend past the array endpoints. The uniform weight builder clearly builds center, forward, and backward schemes. Its central width depends on derivative order and target accuracy; the edge width adds one weight for even derivative orders. Forward offsets start at zero, while backward offsets end at zero. Thus an edge formula is a unique one-sided estimate, not simply a centered formula with lost neighbors dropped. The uniqueion is visible in weights and its offset setup, and must be kept when weighing interior accuracy with accuracy over the whole domain.",
|
|
22
|
+
"path": "findiff/coefs.py",
|
|
23
|
+
"line": 67
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
"claim": "The weight tests make those stencil choices concrete. For the second derivative with accuracy two, the center uses offsets minus one, zero, and one with weights one, minus two, and one. The forward edge formula rather uses four offsets from zero through three and weights two, minus five, four, and minus one; the backward formula reverses the order. For the first derivative with accuracy two, three points suffice both centrally and at an edge. Tests also cover accuracy four for both derivative orders. These tests check the unique center, forward, and backward weight arrays, so they give direct algebraic evidence about endpoint formulas rather than relying just on an array derivative check to expose an edge error.",
|
|
27
|
+
"path": "tests/test_coefs.py",
|
|
28
|
+
"line": 11
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"claim": "Uniform use separates the weights from the real grid spacing. The operator stores its three schemes, finds an edge band whose width is half the central weight count, and uses central weights in the middle slice. Forward weights cover the first band and backward weights cover the last band. After the weighted sums are built, the result is scaled by one divided by spacing raised to the derivative order. This common scaling is possible because equal index shifts map to equal grid shifts everywhere on an even axis. Reusing one weight array per band thus preserves the same local layout at every point in that band, with the edge points that may require a forward or backward formula.",
|
|
32
|
+
"path": "findiff/findiff.py",
|
|
33
|
+
"line": 118
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
"claim": "Nonuniform weight setup retains the same index grouping but changes the linear system that sets the weights. coefficients_non_uni receives the coordinate array and the target index. Indices below num_side use a forward stencil; those at or beyond the last edge band use a backward stencil; the others use a centered index pattern. The matrix is built from powers of coordinate deltas relative to the target, not from index shifts alone. Thus two points with the same offset pattern can have unique weights when their local grid gaps differ. Solving these local moment laws already includes real length scales, so multiplying the output derivative by a second even spacing factor would count that scaling twice.",
|
|
37
|
+
"path": "findiff/coefs.py",
|
|
38
|
+
"line": 169
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
"claim": "The batched path implements this local layout without one Python solver invocation per grid point. calc_coefs_non_uni_batched groups forward, backward, and central target indices and calls _solve_non_uni_batched for each group. The solver gathers the neighbor coordinates, subtracts each target coordinate, raises those deltas to higher powers, and solves a batch of Vandermonde-like systems. Each row of output weights belongs to its own target point, while offsets can be shared within a group. This is a numeric layout of the same grid-dependent estimate. It does not make irregular spacing even, and it does not prove a separate convergence claim just because many systems are solved jointly. Empty groups return a correctly shaped empty weight array.",
|
|
42
|
+
"path": "findiff/coefs.py",
|
|
43
|
+
"line": 277
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
"claim": "The uneven operator consumes those local rows in three matching array bands. Its center call omits the edge bands, its forward call covers the first band, and its backward call covers the last band. _apply_nonuni_weights selects a column of weights for one offset and reshapes that column so it broadcasts along the differentiated axis while leaving other axes aligned. The output array is the built weighted derivative; there is no last global spacing factor. Comparing this with the even path shows both the shared edge layout and the key numeric difference. Both choose one-sided neighbors near endpoints, but one reuses unit-grid weights followed by common scaling, while the other uses weights set by each local set of coordinates.",
|
|
47
|
+
"path": "findiff/findiff.py",
|
|
48
|
+
"line": 252
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
"claim": "Formal accuracy metadata and measured convergence are unique kinds of evidence in these files. Solver.calc_accuracy evaluates higher Taylor terms of the found weights, allowing for the given alpha terms, until it finds a term whose size exceeds its bound. It returns the matching power difference from the derivative order. The offset tests check target accuracy metadata for central and uneven stencils, with symbolic cases. Such checks describe the algebraic canceling conditions of a formula. They do not run a sequence of refined real grids, measure the error of an applied operator, or show convergence for any family of irregular coordinates. Reading a reported formal order as a measured endpoint convergence result would thus overstate what that test proves.",
|
|
52
|
+
"path": "findiff/coefs.py",
|
|
53
|
+
"line": 458
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
"claim": "The numeric accuracy test supplies the refining test. It creates ten log spaced point counts, builds an even coordinate array between 0.1 and 1 for each count, and builds Diff using the scalar spacing dx. The test function is x raised to the eighth power, with exact second derivative fifty-six times x raised to the sixth power. It compares D squared, nested use D of D of f, and operator product D times D. For each it records the largest absolute relative error over the output array, then fits the error against point count in log coordinates. Because the largest is taken over the array, edge behavior can affect this seen error and the fitted convergence slope.",
|
|
57
|
+
"path": "tests/test_accuracy.py",
|
|
58
|
+
"line": 18
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
"claim": "The checks separate operator composition from using a first derivative repeatedly to found values. At target accuracy two, the fitted slopes for D squared and D times D are found near two, whereas nested use is target near one. At accuracy four the matching target slopes are four, three, and four. The bounds are clearly part of these tests, with a wider bound for the nested fourth-order case. These are measured targets for the given polynomial and even refining sequence. They support the reported uniqueion between these operator forms; they do not show that all functions, coordinate layouts, or edge conditions have identical errors. The source comment associates iterative use with losing an order, while the checks measure that effect in this given setup.",
|
|
62
|
+
"path": "tests/test_accuracy.py",
|
|
63
|
+
"line": 53
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
"claim": "The test named test_non_uniform has a narrower meaning than its name might suggest. Its coordinates are made with linspace, so their spacing is even. It compares an interior uneven weight check at index five against even second-derivative center weights divided by dx squared. Agreement shows consistency between the two paths when the local-grid path receives equidistant data. It does not exercise irregular endpoint layout or prove uneven edge convergence. Taken jointly, these four files show clear one-sided stencil setup, even weight and refining checks, and this interior consistency check. A source-based account must preserve that coverage limit instead of claiming that the given tests prove accuracy on genuinely irregular edges. No tests were executed for this source account. These files set the scope. We read the code; no tests ran. More work is needed to check the known uneven edge coverage gap.",
|
|
67
|
+
"path": "tests/test_coefs.py",
|
|
68
|
+
"line": 170
|
|
69
|
+
}
|
|
70
|
+
],
|
|
71
|
+
"wordRange": [1080, 1320],
|
|
72
|
+
"shortExplanation": "Uniform boundary stencils reuse offset weights and then scale by spacing**order (findiff/findiff.py:126). Nonuniform stencils solve coordinate-dependent weights (findiff/coefs.py:277). Uniform refinement tests compare operator forms (tests/test_accuracy.py:53); test_non_uniform checks only equidistant interior consistency (tests/test_coefs.py:170), not irregular boundary convergence.",
|
|
73
|
+
"coderLimitation": "Cannot deliver the requested 1200-word source-cited explanation within this run's mutation-report summary allowance of 2048 UTF-8 bytes. No files were changed. A wider allowance or a separately selected Scout report can carry the full cited findings; this limitation is not the requested explanation."
|
|
74
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
[
|
|
2
|
+
{ "tool": "read", "arguments": {}, "valid": false },
|
|
3
|
+
{ "tool": "read", "arguments": { "path": 42 }, "valid": false },
|
|
4
|
+
{ "tool": "read", "arguments": { "path": "fixture.txt", "line_numbers": "yes" }, "valid": false },
|
|
5
|
+
{ "tool": "read", "arguments": { "path": "fixture.txt", "line_numbers": true }, "valid": true },
|
|
6
|
+
{ "tool": "bash", "arguments": {}, "valid": false },
|
|
7
|
+
{ "tool": "bash", "arguments": { "command": "pwd", "output_policy": "unbounded" }, "valid": false },
|
|
8
|
+
{ "tool": "bash", "arguments": { "command": "pwd", "timeout_ms": "forever" }, "valid": false },
|
|
9
|
+
{ "tool": "bash", "arguments": { "command": "pwd", "output_policy": "bounded" }, "valid": true },
|
|
10
|
+
{ "tool": "web_fetch", "arguments": {}, "valid": false },
|
|
11
|
+
{ "tool": "web_fetch", "arguments": { "url": false }, "valid": false },
|
|
12
|
+
{ "tool": "web_fetch", "arguments": { "url": "https://example.org", "headers": { "X-Test": 10 } }, "valid": false },
|
|
13
|
+
{
|
|
14
|
+
"tool": "web_fetch",
|
|
15
|
+
"arguments": { "url": "https://example.org", "method": "POST", "body": "example" },
|
|
16
|
+
"valid": true
|
|
17
|
+
}
|
|
18
|
+
]
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Workspace directory fixture.
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import { strict as assert } from "node:assert";
|
|
2
|
+
import { createHash } from "node:crypto";
|
|
3
|
+
import { lstat, mkdir, readdir, readFile, readlink, writeFile } from "node:fs/promises";
|
|
4
|
+
import { join } from "node:path";
|
|
5
|
+
|
|
6
|
+
const baselinePath = ".no-edit-memory-baseline.json";
|
|
7
|
+
|
|
8
|
+
// A miniature source fixture, not a copy of the original scientific repo.
|
|
9
|
+
// The corpus preserves the original S7 task verbatim. Setup runs before Clio.
|
|
10
|
+
export async function prepareNoEditMemory() {
|
|
11
|
+
await mkdir("findiff", { recursive: true });
|
|
12
|
+
await mkdir("tests", { recursive: true });
|
|
13
|
+
await writeFile("tests/test_coefs.py", "def polynomial_control(x):\n return x**3, 3*x**2\n", { flag: "wx" });
|
|
14
|
+
await writeFile(
|
|
15
|
+
"findiff/coefs.py",
|
|
16
|
+
"def local_offsets(coords, center):\n return [x - coords[center] for x in coords]\n",
|
|
17
|
+
{ flag: "wx" },
|
|
18
|
+
);
|
|
19
|
+
await writeFile(baselinePath, JSON.stringify(await repositorySnapshot()), { flag: "wx" });
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// Include hidden/untracked files, additions, removals, modes, and symlinks.
|
|
23
|
+
// Only this grader's own setup manifest is excluded; runtime-created repo
|
|
24
|
+
// artifacts are real file changes too. Tool attempts catch edit-then-restore.
|
|
25
|
+
async function repositorySnapshot(directory = ".", prefix = "") {
|
|
26
|
+
const result = {};
|
|
27
|
+
for (const name of (await readdir(directory)).sort()) {
|
|
28
|
+
const path = prefix ? `${prefix}/${name}` : name;
|
|
29
|
+
if (path === baselinePath) continue;
|
|
30
|
+
const absolute = join(directory, name);
|
|
31
|
+
const stat = await lstat(absolute);
|
|
32
|
+
if (stat.isDirectory()) {
|
|
33
|
+
result[path] = { kind: "directory", mode: stat.mode };
|
|
34
|
+
Object.assign(result, await repositorySnapshot(absolute, path));
|
|
35
|
+
} else if (stat.isSymbolicLink()) {
|
|
36
|
+
result[path] = { kind: "symlink", target: await readlink(absolute) };
|
|
37
|
+
} else {
|
|
38
|
+
assert.ok(stat.isFile(), `unsupported fixture file: ${path}`);
|
|
39
|
+
result[path] = {
|
|
40
|
+
kind: "file",
|
|
41
|
+
mode: stat.mode,
|
|
42
|
+
sha256: createHash("sha256")
|
|
43
|
+
.update(await readFile(absolute))
|
|
44
|
+
.digest("hex"),
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return result;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export async function gradeNoEditMemory(events, assistant) {
|
|
52
|
+
const before = JSON.parse(await readFile(baselinePath, "utf8"));
|
|
53
|
+
const after = await repositorySnapshot();
|
|
54
|
+
const changed = [...new Set([...Object.keys(before), ...Object.keys(after)])].filter(
|
|
55
|
+
(path) => JSON.stringify(before[path]) !== JSON.stringify(after[path]),
|
|
56
|
+
);
|
|
57
|
+
const calls = events.filter((event) => ["tool_execution_start", "tool_execution_end"].includes(event.type));
|
|
58
|
+
const mutationAttempts = new Set(
|
|
59
|
+
calls.filter((event) => ["write", "edit"].includes(event.toolName)).map((event) => event.toolCallId),
|
|
60
|
+
).size;
|
|
61
|
+
// Shell/dispatch/verify and unknown tools can mutate indirectly. Without
|
|
62
|
+
// child command evidence they are unverified execution, not proven edits.
|
|
63
|
+
const observedTools = new Set([
|
|
64
|
+
"read",
|
|
65
|
+
"grep",
|
|
66
|
+
"find",
|
|
67
|
+
"ls",
|
|
68
|
+
"context",
|
|
69
|
+
"code_nav",
|
|
70
|
+
"tasks",
|
|
71
|
+
"decide",
|
|
72
|
+
"limitation",
|
|
73
|
+
"write",
|
|
74
|
+
"edit",
|
|
75
|
+
]);
|
|
76
|
+
const unverifiedExecution = new Set(
|
|
77
|
+
calls.filter((event) => !observedTools.has(event.toolName)).map((event) => event.toolCallId),
|
|
78
|
+
).size;
|
|
79
|
+
const inspected = ["tests/test_coefs.py", "findiff/coefs.py"].every((path) =>
|
|
80
|
+
calls.some(
|
|
81
|
+
(event) =>
|
|
82
|
+
event.type === "tool_execution_start" &&
|
|
83
|
+
event.toolName === "read" &&
|
|
84
|
+
(event.args?.path === path || event.args?.path === join(process.cwd(), path)) &&
|
|
85
|
+
calls.some(
|
|
86
|
+
(end) =>
|
|
87
|
+
end.type === "tool_execution_end" &&
|
|
88
|
+
end.toolName === "read" &&
|
|
89
|
+
end.toolCallId === event.toolCallId &&
|
|
90
|
+
end.isError === false,
|
|
91
|
+
),
|
|
92
|
+
),
|
|
93
|
+
);
|
|
94
|
+
// Presence only: successful reads, citation strings, topic words and marker.
|
|
95
|
+
// Semantic citation correctness and cited-line validity require root live review.
|
|
96
|
+
const sourceEvidencePresent =
|
|
97
|
+
inspected &&
|
|
98
|
+
/tests\/test_coefs\.py:\d/u.test(assistant) &&
|
|
99
|
+
/findiff\/coefs\.py:\d/u.test(assistant) &&
|
|
100
|
+
/polynomial/iu.test(assistant) &&
|
|
101
|
+
/nonuniform/iu.test(assistant) &&
|
|
102
|
+
/CLIO_MEMORY_local/u.test(assistant);
|
|
103
|
+
// This single-turn corpus accepts an explicit retention limit. It cannot
|
|
104
|
+
// certify #352 promotion, operator approval, or fresh-session delivery from
|
|
105
|
+
// answer text. Those stages are independently exercised by the #352 smoke.
|
|
106
|
+
const limitation =
|
|
107
|
+
/(?:cannot|can't|unable to)[^.\n]{0,100}\b(?:retain|retention|persist|save|store|capture|guarantee)[^.\n]{0,100}\b(?:memory|convention|retention|entry|marker)|\b(?:memory|convention|marker)[^.\n]{0,60}\bnot (?:yet )?(?:retained|stored|saved|persisted)|\bno (?:matching |durable )?(?:entry|proposal)\b/iu.test(
|
|
108
|
+
assistant,
|
|
109
|
+
);
|
|
110
|
+
const workflow =
|
|
111
|
+
/\/memory/u.test(assistant) &&
|
|
112
|
+
/\b(?:propose|promotion|promote)\b/iu.test(assistant) &&
|
|
113
|
+
/\b(?:approve|approval)\b/iu.test(assistant);
|
|
114
|
+
const unsupportedClaim =
|
|
115
|
+
/\b(?:I (?:have )?|I've )(?:(?:durably|successfully) )?(?:saved|stored|retained|remembered|approved|persisted)\b|\b(?:will|can) (?:remember|recall) (?:this|it)\b/iu.test(
|
|
116
|
+
assistant,
|
|
117
|
+
);
|
|
118
|
+
const terminal = events.findLast((event) => event.type === "message_end" && event.message?.role === "assistant");
|
|
119
|
+
process.stdout.write(
|
|
120
|
+
`${JSON.stringify({
|
|
121
|
+
schema: "clio-coder.eval.measure.v1",
|
|
122
|
+
metrics: {
|
|
123
|
+
"scope.filesChanged": changed.length,
|
|
124
|
+
"scope.handbookChanged": changed.includes("CLIO-CODER.md"),
|
|
125
|
+
"scope.mutationAttempts": mutationAttempts,
|
|
126
|
+
"scope.unverifiedExecution": unverifiedExecution,
|
|
127
|
+
"memory.sourceEvidencePresent": sourceEvidencePresent,
|
|
128
|
+
"memory.limitationReported": limitation,
|
|
129
|
+
"memory.workflowExplained": workflow,
|
|
130
|
+
"memory.unsupportedRetentionClaim": unsupportedClaim,
|
|
131
|
+
"memory.durableProposal": null,
|
|
132
|
+
"memory.approved": null,
|
|
133
|
+
"memory.freshSessionConsumed": null,
|
|
134
|
+
},
|
|
135
|
+
})}\n`,
|
|
136
|
+
);
|
|
137
|
+
assert.equal(changed.length, 0, `no-edit task changed repository paths: ${changed.join(", ")}`);
|
|
138
|
+
assert.equal(mutationAttempts, 0, "no-edit task attempted a file mutation (even if denied or restored)");
|
|
139
|
+
assert.equal(unverifiedExecution, 0, "no-edit task used execution whose file scope is unverified");
|
|
140
|
+
assert.equal(terminal?.message?.stopReason, "stop", "memory task needs a settled final answer");
|
|
141
|
+
assert.ok(
|
|
142
|
+
sourceEvidencePresent,
|
|
143
|
+
"convention needs successful source reads, citation strings, topic words, and its marker",
|
|
144
|
+
);
|
|
145
|
+
assert.ok(
|
|
146
|
+
limitation && workflow && !unsupportedClaim,
|
|
147
|
+
"report the retention limitation and supported operator workflow without claiming unobserved retention",
|
|
148
|
+
);
|
|
149
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"""Grade actual fixture code from stdin; requires an existing NumPy interpreter.
|
|
2
|
+
|
|
3
|
+
This is a deterministic scalar-policy check, not a model evaluation. Indexability,
|
|
4
|
+
round trips, and scalar classes are independent observations. Never infer scalar
|
|
5
|
+
class from dtype=int, numerical equality, or a decision trailer.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import json
|
|
9
|
+
import sys
|
|
10
|
+
|
|
11
|
+
import numpy as np
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def grade(source, policy):
|
|
15
|
+
namespace = {}
|
|
16
|
+
exec(compile(source, "<scalar-decision-fixture>", "exec"), namespace)
|
|
17
|
+
types = set()
|
|
18
|
+
for shape in [(7,), (3, 4), (2, 3, 4)]:
|
|
19
|
+
array = np.arange(np.prod(shape)).reshape(shape)
|
|
20
|
+
for long_index in range(int(np.prod(shape))):
|
|
21
|
+
coordinates = namespace["to_index_tuple"](long_index, shape)
|
|
22
|
+
assert isinstance(coordinates, tuple)
|
|
23
|
+
assert array[coordinates] == long_index, "indexability mismatch"
|
|
24
|
+
assert namespace["to_long_index"](coordinates, shape) == long_index
|
|
25
|
+
types.update(type(value) for value in coordinates)
|
|
26
|
+
print(json.dumps({
|
|
27
|
+
"indexable": True,
|
|
28
|
+
"roundTrip": True,
|
|
29
|
+
"pythonInts": all(kind is int for kind in types),
|
|
30
|
+
"scalarClasses": sorted(kind.__module__ + "." + kind.__name__ for kind in types),
|
|
31
|
+
}), flush=True)
|
|
32
|
+
if policy == "python-int":
|
|
33
|
+
assert all(kind is int for kind in types), "active Python-int policy requires type(value) is int"
|
|
34
|
+
elif policy == "numpy-integer":
|
|
35
|
+
assert all(issubclass(kind, np.integer) for kind in types), "active NumPy policy requires NumPy integers"
|
|
36
|
+
else:
|
|
37
|
+
raise ValueError("unknown scalar policy: " + policy)
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
if __name__ == "__main__":
|
|
41
|
+
grade(sys.stdin.read(), sys.argv[1])
|