@maycombhq/atticus 2.0.0-beta.2 → 2.0.0-beta.21
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/dist/bin.js +8 -4
- package/dist/chunk-265LWMOA.js +91 -0
- package/dist/chunk-26WBY34Y.js +37 -0
- package/dist/{chunk-UBBC2XSG.js → chunk-26Z7OGQW.js} +518 -93
- package/dist/chunk-2D7PWSOK.js +172 -0
- package/dist/{chunk-JCZIKA4C.js → chunk-2HH3UCZM.js} +4 -4
- package/dist/{chunk-GDLULHTC.js → chunk-2HTEMYTB.js} +12 -26
- package/dist/chunk-2UCRFXFZ.js +130 -0
- package/dist/{chunk-MVZVGYXH.js → chunk-2V2ZPQQU.js} +81 -13
- package/dist/{chunk-BOHJZTEQ.js → chunk-36RY7ZXM.js} +130 -71
- package/dist/{chunk-I3E7CX4H.js → chunk-37WE3LS2.js} +3 -3
- package/dist/{chunk-IPKHE5D6.js → chunk-3AQ2R5NL.js} +1520 -871
- package/dist/chunk-3G6S7LAA.js +43 -0
- package/dist/chunk-3J5I7ZOU.js +58 -0
- package/dist/{chunk-65NYPGRC.js → chunk-3LZ6P5EP.js} +1 -1
- package/dist/chunk-3SSTNB4E.js +191 -0
- package/dist/chunk-3TD6S4TC.js +49 -0
- package/dist/{chunk-3C7EYRFZ.js → chunk-3UTYPHN3.js} +1 -1
- package/dist/{chunk-G2B4ZQGH.js → chunk-3WON4G3M.js} +2 -2
- package/dist/{chunk-S3QNRWYR.js → chunk-42EPP7OB.js} +12 -12
- package/dist/chunk-455SYIIE.js +113 -0
- package/dist/{chunk-YISXLPHN.js → chunk-4B6BT75O.js} +166 -23
- package/dist/{chunk-C6EKFH7J.js → chunk-4CLK2RJO.js} +7 -7
- package/dist/chunk-4CYTJ5TZ.js +38 -0
- package/dist/{chunk-EYWIDJFU.js → chunk-4D62IZII.js} +5 -5
- package/dist/chunk-4FOAYLI4.js +328 -0
- package/dist/{chunk-7JUKDRSZ.js → chunk-4KNOJC6J.js} +294 -215
- package/dist/{chunk-YMZ3TNYB.js → chunk-4PYC2UGC.js} +2 -2
- package/dist/{chunk-27NKUS3X.js → chunk-4SLBCEPD.js} +2104 -726
- package/dist/chunk-4TKVU2I2.js +122 -0
- package/dist/{chunk-RUVFXE2L.js → chunk-4WXRPQDE.js} +448 -47
- package/dist/{chunk-7ZUIMTOU.js → chunk-5CMPVC3N.js} +24 -24
- package/dist/chunk-5G7ILBUG.js +66 -0
- package/dist/{chunk-HFQCFSJR.js → chunk-5PV7S2ZP.js} +3 -3
- package/dist/{chunk-FITWGOJ2.js → chunk-5QUOPNLN.js} +4 -4
- package/dist/{chunk-Z6LF7HQN.js → chunk-5TDRBOAV.js} +5 -5
- package/dist/{chunk-T6AIP7H5.js → chunk-5WERBKLE.js} +199 -63
- package/dist/{chunk-XPCM366L.js → chunk-62DLJSLV.js} +8 -8
- package/dist/{chunk-L24C55VN.js → chunk-64AADMTW.js} +99 -25
- package/dist/{chunk-K65BJIMT.js → chunk-67BP7HXL.js} +17 -17
- package/dist/chunk-6DQYZU2W.js +379 -0
- package/dist/{chunk-EDS2L2LD.js → chunk-6EXDI5GI.js} +52 -26
- package/dist/chunk-6FNAKCET.js +38 -0
- package/dist/{chunk-6IU67AEK.js → chunk-75ASLHBT.js} +21 -15
- package/dist/{chunk-A3GY6SOA.js → chunk-75ZOZFGH.js} +18 -18
- package/dist/{chunk-MGYZM27B.js → chunk-77O633L5.js} +49 -23
- package/dist/{chunk-GQ4N4WKF.js → chunk-7AB6OWTV.js} +3 -3
- package/dist/{chunk-M766ZJ6W.js → chunk-7CZHUZBL.js} +25 -25
- package/dist/{chunk-A7UPUQFY.js → chunk-7FHNFCHK.js} +643 -124
- package/dist/chunk-7FUIVIBG.js +415 -0
- package/dist/{chunk-6QSERWXH.js → chunk-7QPCGTPS.js} +21 -21
- package/dist/{chunk-LR3R6Z2A.js → chunk-A2G72UI4.js} +7 -7
- package/dist/{chunk-I4JRCD6M.js → chunk-AE4P57KK.js} +23 -17
- package/dist/{chunk-AVJDSJ2F.js → chunk-AHW3RY3X.js} +7 -7
- package/dist/chunk-AM6FP6JW.js +43 -0
- package/dist/{chunk-CSZ4C5N6.js → chunk-AOCWFA7T.js} +93 -10
- package/dist/{chunk-EPTBZ3GP.js → chunk-API5TOUB.js} +1 -1
- package/dist/{chunk-652QWTLZ.js → chunk-AZDITBCT.js} +3 -3
- package/dist/{chunk-DPUYDDQG.js → chunk-BA2HUMDN.js} +25 -3
- package/dist/chunk-BA3U7ALS.js +99 -0
- package/dist/{chunk-HVUPKCGJ.js → chunk-BC6KKZ67.js} +5 -5
- package/dist/{chunk-CKSITVS4.js → chunk-BEPCKDCP.js} +2554 -722
- package/dist/{chunk-3ALD2W2A.js → chunk-BPPU3PW7.js} +4 -4
- package/dist/{chunk-QRAOANID.js → chunk-BVWWPBKD.js} +21 -21
- package/dist/{chunk-ZDPAS56H.js → chunk-BXBCMGIQ.js} +7 -1
- package/dist/chunk-BXZ4PKIT.js +233 -0
- package/dist/chunk-C7CEK3KW.js +247 -0
- package/dist/chunk-CFH3QH26.js +29 -0
- package/dist/chunk-CG6CULP6.js +170 -0
- package/dist/chunk-CLD4RVTA.js +45 -0
- package/dist/{chunk-DKJA76CJ.js → chunk-CNPY4NTZ.js} +13 -13
- package/dist/chunk-CNU5Q2D5.js +575 -0
- package/dist/{chunk-T2UYZSCQ.js → chunk-COYN3UAN.js} +126 -23
- package/dist/{chunk-23W7VWKR.js → chunk-CPK7QSBG.js} +1360 -113
- package/dist/{chunk-4AK7IBVP.js → chunk-D2WSW4GU.js} +1 -1
- package/dist/{chunk-ABWHYWNI.js → chunk-D57MFJPP.js} +3 -3
- package/dist/chunk-D5KV5PSK.js +45 -0
- package/dist/chunk-D5MASS4I.js +48 -0
- package/dist/{chunk-7EOBHUMC.js → chunk-DCWN3HFV.js} +2 -2
- package/dist/{chunk-QSXK2RGH.js → chunk-DDJPM5YX.js} +2 -2
- package/dist/chunk-DN4A2Q2O.js +57 -0
- package/dist/{chunk-IHMLFRVV.js → chunk-DUPZPDCJ.js} +58 -16
- package/dist/{chunk-PRPPGYZG.js → chunk-E2VXBSIR.js} +4 -4
- package/dist/chunk-E57AOFYN.js +32 -0
- package/dist/{chunk-UGLN7QHV.js → chunk-ECLXZWAG.js} +12 -12
- package/dist/{chunk-5WG5YP4T.js → chunk-EDZ45WIR.js} +14 -14
- package/dist/chunk-EFCQSMXB.js +37 -0
- package/dist/{chunk-2ANOROX3.js → chunk-EZIN5E5B.js} +8 -8
- package/dist/{chunk-BWZ77RQT.js → chunk-F6H2RJ3N.js} +1 -1
- package/dist/{chunk-OLQJTJJU.js → chunk-FAJDKNSD.js} +7 -3
- package/dist/chunk-FGAGWYZB.js +47 -0
- package/dist/{chunk-4WBVUHXN.js → chunk-FLVZFTLQ.js} +18 -18
- package/dist/chunk-FQ6WH6PB.js +140 -0
- package/dist/{chunk-T6XQL73F.js → chunk-FRHD22WM.js} +61 -23
- package/dist/{chunk-XAKWMCXI.js → chunk-FVMPFCDS.js} +4 -4
- package/dist/{chunk-B2WLAWNJ.js → chunk-FY3QIRTL.js} +3 -3
- package/dist/{chunk-CPA6HPVR.js → chunk-FYBF5MB2.js} +15 -11
- package/dist/{chunk-V2YTAIQO.js → chunk-G5YJBNDZ.js} +21 -6
- package/dist/chunk-G6IQYM25.js +339 -0
- package/dist/chunk-G6X4YL4D.js +161 -0
- package/dist/{chunk-SJRGMG6A.js → chunk-GC2VK3JT.js} +25 -25
- package/dist/{chunk-SP2I63OO.js → chunk-GCS3FZOB.js} +77 -3
- package/dist/{chunk-6TACQN3N.js → chunk-GDZB57IU.js} +5 -5
- package/dist/chunk-GIFMBCTW.js +221 -0
- package/dist/{chunk-YY6ZQQBP.js → chunk-GK4PYVEC.js} +18 -8
- package/dist/{chunk-TDD55CJH.js → chunk-GNWAOVFQ.js} +6 -5
- package/dist/chunk-GS76RXQE.js +226 -0
- package/dist/{chunk-YYQN46FY.js → chunk-GSGIZ2OO.js} +23 -23
- package/dist/chunk-GUYL7RMK.js +60 -0
- package/dist/chunk-GX74YWR7.js +321 -0
- package/dist/chunk-HE3HRDNZ.js +122 -0
- package/dist/{chunk-AIOQPLA5.js → chunk-HGHRSF3E.js} +30 -12
- package/dist/{chunk-2RMYG36Q.js → chunk-HK3VOHIE.js} +198 -336
- package/dist/{chunk-QZSX3F7C.js → chunk-HS4BGB4G.js} +24 -22
- package/dist/{chunk-XY3P7JW7.js → chunk-HSZMPH5T.js} +834 -149
- package/dist/{chunk-L6SGQIR3.js → chunk-HWD4JPU7.js} +4 -2
- package/dist/{chunk-PCVDV3UZ.js → chunk-HXXP2NTE.js} +6 -6
- package/dist/{chunk-AA6YULYB.js → chunk-I2A3Z5AK.js} +7 -7
- package/dist/{chunk-N7IXEHK3.js → chunk-ICHDSWEY.js} +7 -7
- package/dist/chunk-IFFRGC3N.js +31 -0
- package/dist/{chunk-4BN53TG3.js → chunk-IFHDV6KQ.js} +31 -23
- package/dist/chunk-J2O4LFVI.js +80 -0
- package/dist/chunk-J5AAZ6OJ.js +161 -0
- package/dist/{chunk-ZMFPW66A.js → chunk-JAABT3DA.js} +3 -3
- package/dist/chunk-JITJP64K.js +34 -0
- package/dist/chunk-JKIGL3XQ.js +162 -0
- package/dist/chunk-JRVNXLZP.js +615 -0
- package/dist/chunk-JRXHON4E.js +41 -0
- package/dist/{chunk-DHPACDG7.js → chunk-JS6WMC3J.js} +8 -8
- package/dist/chunk-JU4QNJSR.js +62 -0
- package/dist/{chunk-PAMPPUR6.js → chunk-JYMIB5XY.js} +1697 -172
- package/dist/{chunk-RRTKKSLQ.js → chunk-JYTIHTIK.js} +8 -6
- package/dist/{chunk-3HI6Z55Y.js → chunk-K332XW7K.js} +324 -39
- package/dist/{chunk-GLUX4EEP.js → chunk-K6JB6XTX.js} +9 -9
- package/dist/chunk-KDAHXQIE.js +294 -0
- package/dist/chunk-KYZMRSPS.js +93 -0
- package/dist/chunk-L4CESDPB.js +22 -0
- package/dist/{chunk-NXFPS2LR.js → chunk-LEBR5NHW.js} +14 -14
- package/dist/chunk-LIJJCBQI.js +223 -0
- package/dist/{chunk-DE76JROX.js → chunk-LIRVU3HW.js} +16 -16
- package/dist/{chunk-JMSCMUCA.js → chunk-LN77DXBM.js} +145 -21
- package/dist/{chunk-JIITQXFB.js → chunk-LNWEWYCM.js} +2969 -788
- package/dist/{chunk-TANFV3MZ.js → chunk-LO3BLMVG.js} +3 -3
- package/dist/chunk-LPV6T362.js +250 -0
- package/dist/{chunk-2VHF7OXM.js → chunk-LQH4P45K.js} +1 -1
- package/dist/chunk-LU4MQVAL.js +41 -0
- package/dist/chunk-LWDNKE4X.js +273 -0
- package/dist/chunk-M4H2UG4R.js +218 -0
- package/dist/{chunk-6BVONWJ7.js → chunk-M6D2U3YM.js} +3 -3
- package/dist/chunk-MD7KUEJ3.js +514 -0
- package/dist/{chunk-66YVAGGM.js → chunk-MMZUN7ZO.js} +20 -20
- package/dist/chunk-MZGRDONP.js +916 -0
- package/dist/chunk-N3RUGTGV.js +39 -0
- package/dist/{chunk-JGZCG5VM.js → chunk-NCB6656Z.js} +7 -7
- package/dist/{chunk-4NDAAFQT.js → chunk-NRQ65LTQ.js} +7 -5
- package/dist/{chunk-UNM6ZOKP.js → chunk-NTAVOWYD.js} +145 -18
- package/dist/{chunk-3USYZGRF.js → chunk-NYOABJNK.js} +36 -27
- package/dist/{chunk-WVPJSRRJ.js → chunk-O4IKAIZ2.js} +24 -20
- package/dist/{chunk-D3PO4DOZ.js → chunk-ODMBPDDV.js} +51 -14
- package/dist/chunk-OKUB6RJA.js +533 -0
- package/dist/chunk-OMPENNWY.js +39 -0
- package/dist/chunk-OPQZISG3.js +25 -0
- package/dist/{chunk-5GGOLAKC.js → chunk-OV57AHCG.js} +26 -26
- package/dist/chunk-OZJ3JLYI.js +58 -0
- package/dist/{chunk-KEM4SDDP.js → chunk-P2VBXX7N.js} +11 -10
- package/dist/{chunk-S2A7YC3Q.js → chunk-PAINMSID.js} +10150 -1720
- package/dist/chunk-PKJAV25S.js +43 -0
- package/dist/{chunk-EBEW3XXQ.js → chunk-PNQLCRSS.js} +4 -4
- package/dist/{chunk-WY6PP6AA.js → chunk-PQH56YF6.js} +37 -5
- package/dist/chunk-PRTBPXYA.js +50 -0
- package/dist/{chunk-YEDDOYSC.js → chunk-PRW3HXM3.js} +2 -2
- package/dist/chunk-PRZ7KMWL.js +42 -0
- package/dist/{chunk-6M5NK3K3.js → chunk-PTQ3ZALZ.js} +42 -4
- package/dist/{chunk-5GDRCDQB.js → chunk-PUEWDYGP.js} +2 -2
- package/dist/chunk-Q26LDIUV.js +236 -0
- package/dist/{chunk-CR3MTH32.js → chunk-Q46QDDMF.js} +77 -7
- package/dist/chunk-QBNWF5ZU.js +19 -0
- package/dist/chunk-QE527XRY.js +342 -0
- package/dist/{chunk-CNUKCS2T.js → chunk-QHJJMZLX.js} +1518 -54
- package/dist/chunk-QJCJOMW3.js +425 -0
- package/dist/{chunk-VYDBJ73M.js → chunk-QKMRFNMA.js} +15 -15
- package/dist/chunk-QOOEYDNJ.js +317 -0
- package/dist/chunk-QSIDVFB7.js +45 -0
- package/dist/{chunk-R77KLRB3.js → chunk-RA33EYS4.js} +19 -18
- package/dist/{chunk-DFBCSHVT.js → chunk-RALY3E5U.js} +4 -4
- package/dist/{chunk-ZCJDOK2S.js → chunk-S2RY3BOD.js} +35 -21
- package/dist/chunk-S5LSDXV4.js +40 -0
- package/dist/chunk-SB5GRUFM.js +54 -0
- package/dist/chunk-SH27FYPF.js +150 -0
- package/dist/chunk-T74WQQGS.js +40 -0
- package/dist/{chunk-O3WI5KWW.js → chunk-TGVVUKTG.js} +2 -2
- package/dist/chunk-THN26IEF.js +48 -0
- package/dist/chunk-TJH2EUAZ.js +47 -0
- package/dist/{chunk-ZNCEKR4J.js → chunk-TQ4TG57V.js} +12 -8
- package/dist/{chunk-7FBGJFEE.js → chunk-TQTRWENN.js} +12 -12
- package/dist/{chunk-TYAID7B7.js → chunk-TSM6T6GQ.js} +23 -23
- package/dist/{chunk-DPZHZQKE.js → chunk-TW3KOSQK.js} +43 -10
- package/dist/{chunk-MC3H7736.js → chunk-TWQRPM76.js} +37 -4
- package/dist/chunk-TYD6I4CZ.js +109 -0
- package/dist/chunk-U3NBK4EU.js +420 -0
- package/dist/{chunk-6JCPI55B.js → chunk-UDXWIPCB.js} +47 -7
- package/dist/{chunk-MMOSZPWJ.js → chunk-UEVZZZU2.js} +4 -4
- package/dist/{chunk-JBTK5OP2.js → chunk-UF4UHCIG.js} +2 -2
- package/dist/{chunk-6JUBZBMW.js → chunk-UFE36WJH.js} +4 -4
- package/dist/{chunk-ONLS5QA5.js → chunk-URIKUID7.js} +12 -12
- package/dist/chunk-UYLBRRFK.js +1106 -0
- package/dist/chunk-UZACEG2C.js +515 -0
- package/dist/{chunk-7SW2QWLU.js → chunk-VAMHOHUU.js} +12 -12
- package/dist/{chunk-RZPYKDWS.js → chunk-VUVGX5L2.js} +1 -1
- package/dist/{chunk-Q4D5X7QB.js → chunk-VYOCPTUB.js} +44 -24
- package/dist/{chunk-CAQZUNOH.js → chunk-WAZEXEJH.js} +567 -3
- package/dist/chunk-WCEF7H6L.js +221 -0
- package/dist/{chunk-2DIQQJCB.js → chunk-WEOMJHPV.js} +12 -12
- package/dist/{chunk-FHH4I4ZV.js → chunk-WFU77T3A.js} +12 -6
- package/dist/chunk-WIWTJMMR.js +292 -0
- package/dist/{chunk-2BFCZ3RK.js → chunk-WNTIOBOG.js} +18 -18
- package/dist/{chunk-7WD63HU2.js → chunk-X2CUXTWU.js} +6 -6
- package/dist/chunk-X7EMBM5X.js +34 -0
- package/dist/chunk-XEQCQO66.js +33 -0
- package/dist/{chunk-F7HYOUFF.js → chunk-XG4WJHLQ.js} +20 -4
- package/dist/{chunk-EFHQ3TWP.js → chunk-XOL3GFW2.js} +171 -31
- package/dist/{chunk-NE2W3OO7.js → chunk-XQ3YZ4QW.js} +22 -22
- package/dist/{chunk-CEXSU4S6.js → chunk-Y6K3CJBU.js} +723 -85
- package/dist/{chunk-4RS5KZQD.js → chunk-YAH5IQAL.js} +5 -5
- package/dist/{chunk-64EQYWCA.js → chunk-YBOVNMHC.js} +51 -14
- package/dist/chunk-YF5DZCPN.js +1212 -0
- package/dist/chunk-YIGBJNH4.js +37 -0
- package/dist/{chunk-BKVWTZ6A.js → chunk-YJ3TBOTK.js} +25 -25
- package/dist/{chunk-Q5AMFEWD.js → chunk-YKTE2RU3.js} +2 -2
- package/dist/{chunk-7EKXJZ2Y.js → chunk-YO2PKTXT.js} +296 -37
- package/dist/{chunk-6J5OKA4Y.js → chunk-YTTNTQOX.js} +15 -15
- package/dist/{chunk-OT2O76OS.js → chunk-YWAKDNMH.js} +183 -33
- package/dist/{chunk-R6XF6UR3.js → chunk-YZDZOEV4.js} +4 -4
- package/dist/chunk-Z3QFH7YG.js +17 -0
- package/dist/{chunk-W5BVQF44.js → chunk-Z6VLC5X4.js} +17 -17
- package/dist/{chunk-HLJAXMM4.js → chunk-ZFQMMU5Y.js} +2 -2
- package/dist/{chunk-W3BQAZ3Q.js → chunk-ZKYRDV7A.js} +12 -12
- package/dist/{chunk-ZMAINWBW.js → chunk-ZLS6PU2O.js} +3 -3
- package/dist/{chunk-ZVM6AKKM.js → chunk-ZOSD4FXV.js} +3 -3
- package/dist/chunk-ZPDDEVQX.js +47 -0
- package/dist/{chunk-TXLH6WHQ.js → chunk-ZQLRCA2V.js} +11 -11
- package/dist/{chunk-HITVBIJS.js → chunk-ZX7235KR.js} +128 -54
- package/dist/{chunk-GT4I4ZWM.js → chunk-ZZFHLRQW.js} +18 -16
- package/dist/files.json +636 -364
- package/dist/packages/naysayer/constitution/constitution.yaml +19 -0
- package/dist/packages/sdk/npm/index.js +5614 -2343
- package/dist/packages/ui/dist/assets/{elk-api-tma0MCuh.js → elk-api-CowTnhEJ.js} +2 -2
- package/dist/packages/ui/dist/assets/index-Dw20IRhQ.css +1 -0
- package/dist/packages/ui/dist/assets/index-z2wv0d5d.js +47 -0
- package/dist/packages/ui/dist/index.html +2 -2
- package/package.json +4 -4
- package/dist/chunk-2BF2EYJV.js +0 -174
- package/dist/chunk-42EVSKME.js +0 -37
- package/dist/chunk-4BKGMUIK.js +0 -53
- package/dist/chunk-5KLGBXG5.js +0 -48
- package/dist/chunk-6BNC6EQ4.js +0 -41
- package/dist/chunk-6D2CQ5II.js +0 -41
- package/dist/chunk-7AVHLZGD.js +0 -45
- package/dist/chunk-D46WUV3T.js +0 -33
- package/dist/chunk-E36QOJMD.js +0 -47
- package/dist/chunk-FQXYPF7E.js +0 -147
- package/dist/chunk-GBRFVT63.js +0 -45
- package/dist/chunk-ICY36XCH.js +0 -34
- package/dist/chunk-J4K3KVLD.js +0 -131
- package/dist/chunk-JZU3H6UQ.js +0 -54
- package/dist/chunk-NN2ZQEB4.js +0 -38
- package/dist/chunk-PCOCACY3.js +0 -385
- package/dist/chunk-RTEYOSJY.js +0 -29
- package/dist/chunk-RVH5SUW5.js +0 -69
- package/dist/chunk-VN3DP4LQ.js +0 -43
- package/dist/chunk-XPTOBS2D.js +0 -48
- package/dist/packages/ui/dist/assets/index-B54fm9FQ.js +0 -29
- package/dist/packages/ui/dist/assets/index-DD_hufQz.css +0 -1
|
@@ -12,14 +12,16 @@ import {
|
|
|
12
12
|
changeTypeOf,
|
|
13
13
|
checkFindings,
|
|
14
14
|
loadChangeContext,
|
|
15
|
+
outsideKindOf,
|
|
16
|
+
outsideSystemsOf,
|
|
15
17
|
phaseGates,
|
|
16
18
|
statePhase
|
|
17
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-HSZMPH5T.js";
|
|
18
20
|
import {
|
|
19
21
|
daysBetween,
|
|
20
22
|
knowledgeGaps,
|
|
21
23
|
newestEvidence
|
|
22
|
-
} from "./chunk-
|
|
24
|
+
} from "./chunk-64AADMTW.js";
|
|
23
25
|
import {
|
|
24
26
|
BREAKING_SPEC,
|
|
25
27
|
INSTRUCTION_RULES,
|
|
@@ -31,45 +33,59 @@ import {
|
|
|
31
33
|
screenText,
|
|
32
34
|
settle,
|
|
33
35
|
toRunSummary
|
|
34
|
-
} from "./chunk-
|
|
36
|
+
} from "./chunk-QHJJMZLX.js";
|
|
35
37
|
import {
|
|
38
|
+
ASKED_GAP_STEP,
|
|
36
39
|
AgentDefinition,
|
|
37
40
|
ChecklistPack,
|
|
38
41
|
ChecklistRule,
|
|
39
42
|
CriticQuestion,
|
|
40
43
|
Finding,
|
|
41
44
|
FindingAction,
|
|
45
|
+
HOSTS_STEP,
|
|
42
46
|
IsoDateTime,
|
|
47
|
+
JOINED_BY_AI,
|
|
43
48
|
LEGACY_LENSES,
|
|
44
49
|
Lens,
|
|
45
50
|
PHASES,
|
|
51
|
+
QUESTION_SCHEMA_VERSION,
|
|
52
|
+
Question,
|
|
46
53
|
RECORD_KINDS,
|
|
47
54
|
RecordId,
|
|
55
|
+
answerByWords,
|
|
48
56
|
answerWords,
|
|
57
|
+
askedGapQuestionId,
|
|
49
58
|
assistantActor,
|
|
59
|
+
callsOfQuestion,
|
|
50
60
|
changesDirOf,
|
|
51
61
|
changesRelOf,
|
|
52
62
|
external_exports,
|
|
53
63
|
fileJudgments,
|
|
54
64
|
findingPath,
|
|
55
65
|
gateRoundLimit,
|
|
66
|
+
hostOfQuestion,
|
|
56
67
|
isAssistantResolution,
|
|
57
68
|
isCriticQuestion,
|
|
69
|
+
isLinkQuestion,
|
|
58
70
|
judgmentKey,
|
|
59
71
|
lensCovers,
|
|
60
72
|
listQuestions,
|
|
61
73
|
orgPackDirOf,
|
|
62
74
|
orgPackRelOf,
|
|
63
75
|
questionOfLens,
|
|
76
|
+
questionsRelOf,
|
|
64
77
|
quotedIn,
|
|
78
|
+
readQuestion,
|
|
79
|
+
repoReadOf,
|
|
65
80
|
require_dist,
|
|
66
81
|
runsDirOf,
|
|
67
82
|
stateDirOf,
|
|
68
|
-
toCanonicalYaml
|
|
69
|
-
|
|
83
|
+
toCanonicalYaml,
|
|
84
|
+
writeQuestion
|
|
85
|
+
} from "./chunk-PAINMSID.js";
|
|
70
86
|
import {
|
|
71
87
|
writeFileAtomic
|
|
72
|
-
} from "./chunk-
|
|
88
|
+
} from "./chunk-ODMBPDDV.js";
|
|
73
89
|
import {
|
|
74
90
|
__toESM
|
|
75
91
|
} from "./chunk-TV45EUGM.js";
|
|
@@ -610,7 +626,8 @@ function catalogEvidence(ctx, id) {
|
|
|
610
626
|
recordEvidence(id),
|
|
611
627
|
...file ? [
|
|
612
628
|
{
|
|
613
|
-
|
|
629
|
+
// ADR 0181: an AI evidence cites the call's own code line; a finding names it as code.
|
|
630
|
+
source: file.source === "ai" ? "code" : file.source,
|
|
614
631
|
path: file.path,
|
|
615
632
|
...file.repo ? { repo: file.repo } : {},
|
|
616
633
|
...file.line ? { line: file.line } : {}
|
|
@@ -637,7 +654,7 @@ var observabilityPresent = {
|
|
|
637
654
|
const design = docOf(ctx.files, "design.md");
|
|
638
655
|
for (const id of ctx.footprint.components) {
|
|
639
656
|
const c = ctx.get("Component", id);
|
|
640
|
-
if (!c || ctx.
|
|
657
|
+
if (!c || ctx.outsideOf(c.system) === "vendor")
|
|
641
658
|
continue;
|
|
642
659
|
const assets = ctx.records.filter((r) => r.kind === "ObservabilityAsset" && r.component === id && kinds.includes(r.assetKind));
|
|
643
660
|
const planned = design && contentLines(design).some((l) => l.text.toLowerCase().includes(id) && kinds.some((k) => l.text.toLowerCase().includes(k)));
|
|
@@ -720,7 +737,7 @@ var knowledgeCheck = {
|
|
|
720
737
|
}
|
|
721
738
|
const subjects = [...fp.components, ...fp.systems].filter((id) => {
|
|
722
739
|
const sys = ctx.systemOf(id);
|
|
723
|
-
return !sys || ctx.
|
|
740
|
+
return !sys || ctx.outsideOf(sys) !== "vendor";
|
|
724
741
|
});
|
|
725
742
|
return { hits, subjects };
|
|
726
743
|
}
|
|
@@ -803,7 +820,7 @@ var factKnown = {
|
|
|
803
820
|
var vendorOperationKnown = {
|
|
804
821
|
id: "vendor-operation-known",
|
|
805
822
|
question: "true",
|
|
806
|
-
description: "Each new or changed call to a vendor uses an operation in
|
|
823
|
+
description: "Each new or changed call to a vendor, or to another team's system, uses an operation in its published spec (as read into the catalog).",
|
|
807
824
|
params: external_exports.strictObject({}),
|
|
808
825
|
run(ctx) {
|
|
809
826
|
const doc = docOf(ctx.files, "interfaces.md");
|
|
@@ -811,15 +828,20 @@ var vendorOperationKnown = {
|
|
|
811
828
|
const subjects = /* @__PURE__ */ new Set();
|
|
812
829
|
if (!doc)
|
|
813
830
|
return { hits, subjects: [] };
|
|
831
|
+
const ofSystem = (component, sys) => ctx.systemOf(component) === sys || component === sys;
|
|
814
832
|
for (const h of ctx.hops) {
|
|
815
833
|
if (h.status !== "planned-new" && h.status !== "planned-modify")
|
|
816
834
|
continue;
|
|
817
835
|
const sys = ctx.systemOf(h.callee);
|
|
818
|
-
|
|
836
|
+
const outside = sys ? ctx.outsideOf(sys) : void 0;
|
|
837
|
+
if (!sys || !outside || !h.method || !h.path)
|
|
838
|
+
continue;
|
|
839
|
+
const vendor = outside === "vendor";
|
|
840
|
+
if (!vendor && !ctx.records.some((r) => r.kind === "Endpoint" && ofSystem(r.component, sys)))
|
|
819
841
|
continue;
|
|
820
842
|
subjects.add(sys);
|
|
821
843
|
const want = normalizePath(h.path);
|
|
822
|
-
const found = ctx.records.some((r) => r.kind === "Endpoint" && (r.component === h.callee ||
|
|
844
|
+
const found = ctx.records.some((r) => r.kind === "Endpoint" && (r.component === h.callee || ofSystem(r.component, sys)) && (r.method ?? "").toUpperCase() === h.method && normalizePath(r.normalizedPath ?? r.pathOrTopic) === want);
|
|
823
845
|
if (found)
|
|
824
846
|
continue;
|
|
825
847
|
const name = ctx.get("System", sys)?.name ?? sys;
|
|
@@ -828,9 +850,9 @@ var vendorOperationKnown = {
|
|
|
828
850
|
artifact: "interfaces.md",
|
|
829
851
|
locator: { line: h.line, record: sys },
|
|
830
852
|
summary: sentence(`${name}'s published spec has no ${h.method} ${h.path}.`),
|
|
831
|
-
why: "The change plans a call to a vendor operation the catalog has never seen in the vendor's spec, so its contract, limits and errors are unknown.",
|
|
853
|
+
why: vendor ? "The change plans a call to a vendor operation the catalog has never seen in the vendor's spec, so its contract, limits and errors are unknown." : "The change plans a call to an operation of another team's system that the catalog has never seen in that team's published spec, so its contract, limits and errors are unknown.",
|
|
832
854
|
fix: {
|
|
833
|
-
text: `Get the operation's spec from ${name} and add it to inputs/partner-specs, or correct the operation.`
|
|
855
|
+
text: vendor ? `Get the operation's spec from ${name} and add it to inputs/partner-specs, or correct the operation.` : `Get the operation's spec from the team that owns ${name} and add it to inputs/partner-specs, or correct the operation.`
|
|
834
856
|
},
|
|
835
857
|
evidence: [lineEvidence(doc, h.line), ...subjectEvidence(ctx, sys)],
|
|
836
858
|
question: {
|
|
@@ -1277,6 +1299,8 @@ function patternProblems(ctx, o) {
|
|
|
1277
1299
|
const doc = docOf(ctx.files, IFACES);
|
|
1278
1300
|
if (!doc)
|
|
1279
1301
|
return [];
|
|
1302
|
+
if (ctx.patterns.size === 0)
|
|
1303
|
+
return [];
|
|
1280
1304
|
const hits = [];
|
|
1281
1305
|
const codes = [...ctx.patterns.keys()].sort();
|
|
1282
1306
|
for (const h of ctx.hops) {
|
|
@@ -1668,7 +1692,8 @@ var interfaceViaMatchesPattern = {
|
|
|
1668
1692
|
evidence: [
|
|
1669
1693
|
recordEvidence(rec.id),
|
|
1670
1694
|
...rec.evidence.filter((e) => e.path).slice(0, 1).map((e) => ({
|
|
1671
|
-
source: e.source,
|
|
1695
|
+
source: e.source === "ai" ? "code" : e.source,
|
|
1696
|
+
// ADR 0181: the call's own line
|
|
1672
1697
|
path: e.path,
|
|
1673
1698
|
...e.repo ? { repo: e.repo } : {},
|
|
1674
1699
|
...e.line ? { line: e.line } : {}
|
|
@@ -1681,8 +1706,178 @@ var interfaceViaMatchesPattern = {
|
|
|
1681
1706
|
}
|
|
1682
1707
|
};
|
|
1683
1708
|
|
|
1684
|
-
// packages/naysayer/dist/checks/
|
|
1709
|
+
// packages/naysayer/dist/checks/links.js
|
|
1685
1710
|
var IFACES2 = "interfaces.md";
|
|
1711
|
+
var GUESSES = {
|
|
1712
|
+
"joined-by-path": "by path",
|
|
1713
|
+
"joined-by-label": "by a host's first label",
|
|
1714
|
+
"joined-by-platform-setting": "by a platform-wide setting nobody set for it",
|
|
1715
|
+
"joined-by-folder-name": "by the folder name of the setting that gives its host",
|
|
1716
|
+
"joined-despite-conflict": "by a host or base path an open conflict disputes",
|
|
1717
|
+
"joined-by-service-name": "by a Kubernetes Service's short name, from a namespace not shown to be its"
|
|
1718
|
+
};
|
|
1719
|
+
var guessOf = (f) => Object.hasOwn(GUESSES, f);
|
|
1720
|
+
function reposOf(ctx) {
|
|
1721
|
+
const out = new Set(ctx.footprint.repos);
|
|
1722
|
+
for (const c of calls(ctx))
|
|
1723
|
+
for (const id of [c.caller, c.callee]) {
|
|
1724
|
+
const repo = ctx.get("Component", id)?.repo;
|
|
1725
|
+
if (repo)
|
|
1726
|
+
out.add(repo);
|
|
1727
|
+
}
|
|
1728
|
+
return [...out].sort();
|
|
1729
|
+
}
|
|
1730
|
+
async function loadEstateReads(root, ctx) {
|
|
1731
|
+
const reads = /* @__PURE__ */ new Map();
|
|
1732
|
+
for (const r of reposOf(ctx))
|
|
1733
|
+
reads.set(r, await repoReadOf(root, r));
|
|
1734
|
+
const facts = new Map([...reads].map(([k, v]) => [k, v.facts]));
|
|
1735
|
+
const open = await listQuestions(root, { state: "open" }).then((l) => l.questions, () => []);
|
|
1736
|
+
return {
|
|
1737
|
+
reads,
|
|
1738
|
+
questions: open.filter((q) => isLinkQuestion(q) && reads.has(q.repo)).map((q) => ({
|
|
1739
|
+
question: q,
|
|
1740
|
+
calls: callsOfQuestion(q, facts),
|
|
1741
|
+
file: `${questionsRelOf(root)}/${q.id}.yaml`
|
|
1742
|
+
}))
|
|
1743
|
+
};
|
|
1744
|
+
}
|
|
1745
|
+
var pathOf = (p) => normalizePath(p.split(/[?#]/)[0].trim()).toLowerCase();
|
|
1746
|
+
function sameCall(f, c) {
|
|
1747
|
+
if (c.record?.evidence.some((e) => e.repo === f.repo && e.path === f.cite.file && e.line === f.cite.line))
|
|
1748
|
+
return true;
|
|
1749
|
+
const path = c.hop?.path ?? c.record?.normalizedPath;
|
|
1750
|
+
const method = c.hop?.method ?? c.record?.method;
|
|
1751
|
+
if (!path)
|
|
1752
|
+
return false;
|
|
1753
|
+
if (method && f.method && method.toUpperCase() !== f.method.toUpperCase())
|
|
1754
|
+
return false;
|
|
1755
|
+
return pathOf(path) === pathOf(f.path);
|
|
1756
|
+
}
|
|
1757
|
+
function placeOf(ctx, c) {
|
|
1758
|
+
const ifaces = docOf(ctx.files, IFACES2);
|
|
1759
|
+
if (c.hop && ifaces)
|
|
1760
|
+
return {
|
|
1761
|
+
artifact: IFACES2,
|
|
1762
|
+
locator: rowLocator2(ifaces, c.hop.line),
|
|
1763
|
+
evidence: [lineEvidence(ifaces, c.hop.line)]
|
|
1764
|
+
};
|
|
1765
|
+
return {
|
|
1766
|
+
artifact: "catalog",
|
|
1767
|
+
locator: { record: c.record?.id ?? c.caller },
|
|
1768
|
+
evidence: c.record ? [recordEvidence(c.record.id)] : []
|
|
1769
|
+
};
|
|
1770
|
+
}
|
|
1771
|
+
var plainWhat = (step, q) => step === HOSTS_STEP ? `which repo answers on ${hostOfQuestion(q) ?? "its host"}` : "which repo or system answers it";
|
|
1772
|
+
var changeLinksKnown = {
|
|
1773
|
+
id: "change-links-known",
|
|
1774
|
+
question: "true",
|
|
1775
|
+
description: "Every call the change plans rests on a link read from code: not one the join guessed (by path, by a host's first label, by a platform-wide setting or a setting's folder name, or despite an open conflict), not one a link question still asks about, and not in a repo whose read is stale or incomplete.",
|
|
1776
|
+
params: external_exports.strictObject({}),
|
|
1777
|
+
run(ctx) {
|
|
1778
|
+
const hits = [];
|
|
1779
|
+
const all = calls(ctx);
|
|
1780
|
+
for (const c of all) {
|
|
1781
|
+
const rec = c.record;
|
|
1782
|
+
const place = placeOf(ctx, c);
|
|
1783
|
+
const flag = rec?.confidence === "inferred" ? rec.flags?.find(guessOf) : void 0;
|
|
1784
|
+
if (rec && flag)
|
|
1785
|
+
hits.push({
|
|
1786
|
+
kind: "knowledge-gap",
|
|
1787
|
+
...place,
|
|
1788
|
+
summary: sentence(`The change rests on a guessed link: the map joined ${c.caller} to ${c.callee} (${c.operation}) ${GUESSES[flag]}, not from code that names ${c.callee}.`),
|
|
1789
|
+
why: `Nobody named ${c.callee} as the target of this call: the join found it ${GUESSES[flag]} (the Interface is inferred, flagged ${flag}). If the guess is wrong, the design is built on a call that goes somewhere else.`,
|
|
1790
|
+
fix: {
|
|
1791
|
+
text: `Confirm the target: name it on the call (the call's target in its facts, or Map \u203A Why is this linked? \u203A This link is wrong), then atticus verify ${ctx.get("Component", c.caller)?.repo ?? c.caller} --write.`
|
|
1792
|
+
},
|
|
1793
|
+
evidence: [
|
|
1794
|
+
...place.evidence.filter((e) => e.source !== "catalog"),
|
|
1795
|
+
recordEvidence(rec.id)
|
|
1796
|
+
],
|
|
1797
|
+
question: {
|
|
1798
|
+
text: `Does ${c.caller}'s ${c.operation} go to ${c.callee}? The map joined them ${GUESSES[flag]}: nothing in ${c.caller}'s code names ${c.callee}.`,
|
|
1799
|
+
owner: questionOwner(ctx, c.caller)
|
|
1800
|
+
},
|
|
1801
|
+
subject: c.caller,
|
|
1802
|
+
key: `link-guess|${rec.id}`
|
|
1803
|
+
});
|
|
1804
|
+
if (rec && !flag && rec.flags?.includes(JOINED_BY_AI)) {
|
|
1805
|
+
const run = rec.evidence.find((e) => e.source === "ai")?.run;
|
|
1806
|
+
hits.push({
|
|
1807
|
+
kind: "knowledge-gap",
|
|
1808
|
+
...place,
|
|
1809
|
+
summary: sentence(`The change rests on a link the AI decided: ${c.caller} to ${c.callee} (${c.operation}), detected by AI${run ? ` (run ${run})` : ""} and not confirmed by a person.`),
|
|
1810
|
+
why: `The AI paired this call with ${c.callee}, and Atticus applied it because its lines checked and its shape agreed; nobody has said it is right. If it is wrong, the design is built on a call that goes somewhere else.`,
|
|
1811
|
+
fix: {
|
|
1812
|
+
text: `Confirm or correct it: atticus questions decisions lists it; atticus questions correct (or Correct on the "Detected by AI" chip) makes it a person's word, then atticus verify ${ctx.get("Component", c.caller)?.repo ?? c.caller} --write.`
|
|
1813
|
+
},
|
|
1814
|
+
evidence: [
|
|
1815
|
+
...place.evidence.filter((e) => e.source !== "catalog"),
|
|
1816
|
+
recordEvidence(rec.id)
|
|
1817
|
+
],
|
|
1818
|
+
question: {
|
|
1819
|
+
text: `Does ${c.caller}'s ${c.operation} go to ${c.callee}? The AI decided so; nobody has confirmed it.`,
|
|
1820
|
+
owner: questionOwner(ctx, c.caller)
|
|
1821
|
+
},
|
|
1822
|
+
subject: c.caller,
|
|
1823
|
+
key: `link-ai|${rec.id}`
|
|
1824
|
+
});
|
|
1825
|
+
}
|
|
1826
|
+
const repo = ctx.get("Component", c.caller)?.repo;
|
|
1827
|
+
for (const q of ctx.estate?.questions ?? []) {
|
|
1828
|
+
if (!repo || q.question.repo !== repo || !q.calls.some((f) => sameCall(f, c)))
|
|
1829
|
+
continue;
|
|
1830
|
+
const id = q.question.id;
|
|
1831
|
+
hits.push({
|
|
1832
|
+
kind: "knowledge-gap",
|
|
1833
|
+
...place,
|
|
1834
|
+
summary: sentence(`The call from ${c.caller} to ${c.callee} (${c.operation}) rests on an open question, ${id}: ${plainWhat(q.question.askedBy.step, q.question)}.`),
|
|
1835
|
+
why: `The map doesn't know yet where this call goes: ${id} asks "${q.question.question}" and nobody has answered. Until it is answered, the link the design draws is a guess.`,
|
|
1836
|
+
fix: {
|
|
1837
|
+
text: `Answer it: atticus questions answer ${id} --option <n> (or on the app's Questions page), then ${q.question.rerun}.`
|
|
1838
|
+
},
|
|
1839
|
+
evidence: [
|
|
1840
|
+
...place.evidence,
|
|
1841
|
+
...rec && place.artifact !== "catalog" ? [recordEvidence(rec.id)] : [],
|
|
1842
|
+
{ source: "manual", path: q.file }
|
|
1843
|
+
],
|
|
1844
|
+
question: { text: q.question.question, owner: questionOwner(ctx, c.caller) },
|
|
1845
|
+
subject: c.caller,
|
|
1846
|
+
key: `link-question|${id}|${c.hop?.line ?? rec?.id}`
|
|
1847
|
+
});
|
|
1848
|
+
}
|
|
1849
|
+
}
|
|
1850
|
+
for (const [repo, r] of ctx.estate?.reads ?? []) {
|
|
1851
|
+
if (r.state !== "stale" && r.state !== "incomplete")
|
|
1852
|
+
continue;
|
|
1853
|
+
const c = all.find((x) => [x.caller, x.callee].some((id) => ctx.get("Component", id)?.repo === repo));
|
|
1854
|
+
const component = ctx.records.find((x) => x.kind === "Component" && x.repo === repo);
|
|
1855
|
+
const place = c ? placeOf(ctx, c) : {
|
|
1856
|
+
artifact: "catalog",
|
|
1857
|
+
locator: { record: component?.id ?? repo },
|
|
1858
|
+
evidence: []
|
|
1859
|
+
};
|
|
1860
|
+
const evidence = [...place.evidence, ...component ? [recordEvidence(component.id)] : []];
|
|
1861
|
+
if (!evidence.length)
|
|
1862
|
+
continue;
|
|
1863
|
+
hits.push({
|
|
1864
|
+
kind: "issue",
|
|
1865
|
+
...place,
|
|
1866
|
+
summary: sentence(`The change rests on ${repo}, whose read is ${r.state}: ${r.why.join("; ")}.`),
|
|
1867
|
+
why: `What the catalog says of ${repo} comes from ${r.state === "stale" ? "an older commit than its checkout" : "a read that is not whole"}, so a link or entry the design relies on may have moved or be missing.`,
|
|
1868
|
+
fix: {
|
|
1869
|
+
text: `Read it again before relying on it: ${r.next ?? `atticus map ${repo}`}${r.next?.startsWith("atticus map") ? `, then atticus verify ${repo} --write` : ""}, and run the critic again.`
|
|
1870
|
+
},
|
|
1871
|
+
evidence,
|
|
1872
|
+
key: `read|${repo}`
|
|
1873
|
+
});
|
|
1874
|
+
}
|
|
1875
|
+
return { hits, subjects: [] };
|
|
1876
|
+
}
|
|
1877
|
+
};
|
|
1878
|
+
|
|
1879
|
+
// packages/naysayer/dist/checks/questions.js
|
|
1880
|
+
var IFACES3 = "interfaces.md";
|
|
1686
1881
|
var ASYNC_ROUTES = /* @__PURE__ */ new Set(["event-bus", "pubsub", "mq", "sftp"]);
|
|
1687
1882
|
function waits(c) {
|
|
1688
1883
|
if (c.record?.sync === "async")
|
|
@@ -1691,11 +1886,11 @@ function waits(c) {
|
|
|
1691
1886
|
return false;
|
|
1692
1887
|
return !(c.via && ASYNC_ROUTES.has(c.via));
|
|
1693
1888
|
}
|
|
1694
|
-
function
|
|
1695
|
-
const ifaces = docOf(ctx.files,
|
|
1889
|
+
function placeOf2(ctx, c) {
|
|
1890
|
+
const ifaces = docOf(ctx.files, IFACES3);
|
|
1696
1891
|
if (c.hop && ifaces)
|
|
1697
1892
|
return {
|
|
1698
|
-
artifact:
|
|
1893
|
+
artifact: IFACES3,
|
|
1699
1894
|
locator: rowLocator2(ifaces, c.hop.line),
|
|
1700
1895
|
evidence: [lineEvidence(ifaces, c.hop.line)]
|
|
1701
1896
|
};
|
|
@@ -1720,7 +1915,7 @@ var callTimeoutStated = {
|
|
|
1720
1915
|
const lines = callLines(ctx, c);
|
|
1721
1916
|
if (setting || lines.some((l) => KIND_WORDS.timeout.test(l.text)))
|
|
1722
1917
|
continue;
|
|
1723
|
-
const place =
|
|
1918
|
+
const place = placeOf2(ctx, c);
|
|
1724
1919
|
if (place.evidence.length === 0)
|
|
1725
1920
|
continue;
|
|
1726
1921
|
hits.push({
|
|
@@ -1783,7 +1978,7 @@ var publicEntryAuth = {
|
|
|
1783
1978
|
description: "Every entry point the change adds or changes that another system or the gateway calls has an auth fact: the Endpoint's or the Interface's auth, or a gateway route that checks scopes. And the scopes hold up (A-gateway2): a route through the gateway that demands none, a caller whose own token can't hold the scope a hop downstream demands, and a scope a story's criteria name that no route demands.",
|
|
1784
1979
|
params: external_exports.strictObject({}),
|
|
1785
1980
|
run(ctx) {
|
|
1786
|
-
const doc = docOf(ctx.files,
|
|
1981
|
+
const doc = docOf(ctx.files, IFACES3);
|
|
1787
1982
|
if (!doc)
|
|
1788
1983
|
return { hits: [], subjects: [] };
|
|
1789
1984
|
const hits = [];
|
|
@@ -1820,7 +2015,7 @@ var publicEntryAuth = {
|
|
|
1820
2015
|
if (h.status !== "planned-new" && h.status !== "planned-modify")
|
|
1821
2016
|
continue;
|
|
1822
2017
|
const calleeSystem = ctx.systemOf(h.callee);
|
|
1823
|
-
if (!calleeSystem || ctx.
|
|
2018
|
+
if (!calleeSystem || ctx.outsideOf(calleeSystem) === "vendor")
|
|
1824
2019
|
continue;
|
|
1825
2020
|
const callerSystem = ctx.systemOf(h.caller);
|
|
1826
2021
|
const rec = interfaceOf(ctx, h);
|
|
@@ -1845,7 +2040,7 @@ var publicEntryAuth = {
|
|
|
1845
2040
|
if (!checked.length)
|
|
1846
2041
|
hits.push({
|
|
1847
2042
|
kind: "issue",
|
|
1848
|
-
artifact:
|
|
2043
|
+
artifact: IFACES3,
|
|
1849
2044
|
locator: { ...rowLocator2(doc, h.line), field: "notes" },
|
|
1850
2045
|
summary: sentence(`The gateway route ${routes.map((r) => r.id).join(", ")} that carries ${op} demands no scope.`),
|
|
1851
2046
|
why: `The route checks who the caller is and nothing about what they may do, so any token the gateway accepts reaches ${h.callee}: ${h.caller} and every other client of ${routes[0].proxy} are let through alike.`,
|
|
@@ -1861,7 +2056,7 @@ var publicEntryAuth = {
|
|
|
1861
2056
|
if (held.length && !wants.some((s) => held.includes(s)))
|
|
1862
2057
|
hits.push({
|
|
1863
2058
|
kind: "knowledge-gap",
|
|
1864
|
-
artifact:
|
|
2059
|
+
artifact: IFACES3,
|
|
1865
2060
|
locator: { ...rowLocator2(doc, h.line), field: "notes" },
|
|
1866
2061
|
summary: sentence(`${op} demands ${wants.join(", ")}, and the token ${h.caller} is itself called with holds ${held.join(", ")}.`),
|
|
1867
2062
|
why: `The routes into ${h.caller} demand ${held.join(", ")}, so a token passed straight through would be refused at ${routes.map((r) => r.id).join(", ")}. Nothing in the catalog says ${h.caller} gets a token that holds ${wants.join(", ")}.`,
|
|
@@ -1883,7 +2078,7 @@ var publicEntryAuth = {
|
|
|
1883
2078
|
if (facts.length) {
|
|
1884
2079
|
hits.push({
|
|
1885
2080
|
kind: "issue",
|
|
1886
|
-
artifact:
|
|
2081
|
+
artifact: IFACES3,
|
|
1887
2082
|
locator: { ...rowLocator2(doc, h.line), field: "notes" },
|
|
1888
2083
|
summary: sentence(`${h.callee} takes ${op} from ${h.caller}, ${crosses ? "in another system" : "through the gateway"}, with no authentication.`),
|
|
1889
2084
|
why: `The catalog records the entry's auth as none, and ${h.caller} calls it ${from}: anyone who can reach it can call it.`,
|
|
@@ -1897,7 +2092,7 @@ var publicEntryAuth = {
|
|
|
1897
2092
|
}
|
|
1898
2093
|
hits.push({
|
|
1899
2094
|
kind: "knowledge-gap",
|
|
1900
|
-
artifact:
|
|
2095
|
+
artifact: IFACES3,
|
|
1901
2096
|
locator: { ...rowLocator2(doc, h.line), field: "notes" },
|
|
1902
2097
|
summary: sentence(`Nothing says how ${h.callee} authenticates callers of ${op}, which ${h.caller} calls ${from}.`),
|
|
1903
2098
|
why: `No Endpoint or Interface in the catalog records the entry's auth, and no gateway route the hop names checks scopes, so nobody can say who may call it.`,
|
|
@@ -2063,7 +2258,7 @@ var breakingDeltaConsumers = {
|
|
|
2063
2258
|
params: external_exports.strictObject({}),
|
|
2064
2259
|
run(ctx) {
|
|
2065
2260
|
const hits = [];
|
|
2066
|
-
const ifaces = docOf(ctx.files,
|
|
2261
|
+
const ifaces = docOf(ctx.files, IFACES3);
|
|
2067
2262
|
const index = callersIndex(ctx);
|
|
2068
2263
|
for (const d of deltas(ctx)) {
|
|
2069
2264
|
const via = routeCallersOf(ctx, d, index);
|
|
@@ -2084,7 +2279,7 @@ var breakingDeltaConsumers = {
|
|
|
2084
2279
|
...via.evidence
|
|
2085
2280
|
];
|
|
2086
2281
|
const through = via.labels.length ? ` They reach it through ${and(via.routes)}${via.declared.length ? `; ${and(via.declared)} ${via.declared.length === 1 ? "is" : "are"} a person's word in the org pack's profile, not read from code` : ""}.` : "";
|
|
2087
|
-
const place = d.hop && ifaces ? { artifact:
|
|
2282
|
+
const place = d.hop && ifaces ? { artifact: IFACES3, locator: rowLocator2(ifaces, d.hop.line) } : { artifact: "catalog", locator: { record: d.record.id } };
|
|
2088
2283
|
const key = `breaking|${d.hop?.line ?? d.record?.id}`;
|
|
2089
2284
|
const repos = [
|
|
2090
2285
|
...new Set(scanned.map((w) => ctx.get("Component", w)?.repo).filter((r) => r !== void 0))
|
|
@@ -2129,7 +2324,7 @@ var routeCallersKnown = {
|
|
|
2129
2324
|
params: external_exports.strictObject({}),
|
|
2130
2325
|
run(ctx) {
|
|
2131
2326
|
const hits = [];
|
|
2132
|
-
const ifaces = docOf(ctx.files,
|
|
2327
|
+
const ifaces = docOf(ctx.files, IFACES3);
|
|
2133
2328
|
const index = callersIndex(ctx);
|
|
2134
2329
|
const asked = /* @__PURE__ */ new Set();
|
|
2135
2330
|
for (const d of deltas(ctx))
|
|
@@ -2141,7 +2336,7 @@ var routeCallersKnown = {
|
|
|
2141
2336
|
if (asked.has(key))
|
|
2142
2337
|
continue;
|
|
2143
2338
|
asked.add(key);
|
|
2144
|
-
const place = d.hop && ifaces ? { artifact:
|
|
2339
|
+
const place = d.hop && ifaces ? { artifact: IFACES3, locator: rowLocator2(ifaces, d.hop.line) } : { artifact: "catalog", locator: { record: r.id } };
|
|
2145
2340
|
hits.push({
|
|
2146
2341
|
kind: "knowledge-gap",
|
|
2147
2342
|
...place,
|
|
@@ -2538,7 +2733,9 @@ var BUILT_IN_CHECKS = [
|
|
|
2538
2733
|
// Who a gateway route lets in (ADR 0124 addendum A-callers).
|
|
2539
2734
|
routeCallersKnown,
|
|
2540
2735
|
// ADR 0113 addendum (2026-10-26): a criterion an attached note gives quotes the note's line.
|
|
2541
|
-
noteCitesOnLine
|
|
2736
|
+
noteCitesOnLine,
|
|
2737
|
+
// ADR 0140: a change that rests on a guessed link, an open link question or a stale read.
|
|
2738
|
+
changeLinksKnown
|
|
2542
2739
|
];
|
|
2543
2740
|
function checkRegistry(extra = []) {
|
|
2544
2741
|
const m = /* @__PURE__ */ new Map();
|
|
@@ -2823,6 +3020,7 @@ function buildContext(o) {
|
|
|
2823
3020
|
return r?.kind === kind ? r : void 0;
|
|
2824
3021
|
};
|
|
2825
3022
|
const profileSystems = new Map(lifecycle.orgPack.profiles.flatMap((p) => p.profile?.systems ?? []).map((s) => [s.id, s]));
|
|
3023
|
+
const outside = outsideSystemsOf(lifecycle.orgPack);
|
|
2826
3024
|
const endpointOwners = new Set(records.filter((r) => r.kind === "Endpoint").map((r) => r.component));
|
|
2827
3025
|
const systemOf = (id) => {
|
|
2828
3026
|
const c = get("Component", id);
|
|
@@ -2866,6 +3064,7 @@ function buildContext(o) {
|
|
|
2866
3064
|
get,
|
|
2867
3065
|
systemOf,
|
|
2868
3066
|
boundaryOf: (s) => get("System", s)?.boundary ?? profileSystems.get(s)?.boundary,
|
|
3067
|
+
outsideOf: (s) => outsideKindOf(outside, s, get("System", s)?.boundary ?? profileSystems.get(s)?.boundary),
|
|
2869
3068
|
ownerOf: (s) => profileSystems.get(s)?.owner ?? get("System", s)?.owner,
|
|
2870
3069
|
isKnown: (id) => get("Component", id) !== void 0 || get("System", id) !== void 0 || profileSystems.has(id) || endpointOwners.has(id),
|
|
2871
3070
|
namesOf: (id) => {
|
|
@@ -3066,7 +3265,8 @@ async function changeAnswers(root, change) {
|
|
|
3066
3265
|
id: q.id,
|
|
3067
3266
|
question: q.question.trim(),
|
|
3068
3267
|
answer: (answerWords(q) ?? "").trim(),
|
|
3069
|
-
|
|
3268
|
+
// ADR 0181: an AI answer reads as the AI's, never a person's word.
|
|
3269
|
+
by: answerByWords(q.answer.by),
|
|
3070
3270
|
at: q.answer.at
|
|
3071
3271
|
})).filter((a) => a.answer.length > 0);
|
|
3072
3272
|
}
|
|
@@ -4040,6 +4240,33 @@ async function sinceReview(root, o) {
|
|
|
4040
4240
|
}
|
|
4041
4241
|
|
|
4042
4242
|
// packages/naysayer/dist/ai.js
|
|
4243
|
+
var LENS_BATCH_AGENT = "critic-lenses";
|
|
4244
|
+
var batchingOf = (rt) => typeof rt.prepareBatch === "function" && typeof rt.canBatch === "function" ? rt : void 0;
|
|
4245
|
+
async function batchLenses(ctx, runtime, runs) {
|
|
4246
|
+
const batching = batchingOf(runtime);
|
|
4247
|
+
const waiting = runs.filter((r) => r.state === "waiting" && r.runId);
|
|
4248
|
+
if (!batching || waiting.length < 2)
|
|
4249
|
+
return void 0;
|
|
4250
|
+
const tokens = waiting.reduce((n, r) => n + (r.context?.tokens ?? 0), 0);
|
|
4251
|
+
if (!batching.canBatch(waiting.length, tokens))
|
|
4252
|
+
return void 0;
|
|
4253
|
+
const first = lensAgent(ctx, waiting[0].lens);
|
|
4254
|
+
const batch = await batching.prepareBatch({
|
|
4255
|
+
change: ctx.change.id,
|
|
4256
|
+
agent: {
|
|
4257
|
+
...first,
|
|
4258
|
+
id: LENS_BATCH_AGENT,
|
|
4259
|
+
description: `The critic's ${waiting.map((r) => r.lens).join(", ")} lenses on change ${ctx.change.id}, asked in one prompt: each lens is its own review, answered in its own section.`,
|
|
4260
|
+
allowedRuntimes: ["hand-off"]
|
|
4261
|
+
},
|
|
4262
|
+
parts: waiting.map((r) => ({ name: r.lens, runId: r.runId })),
|
|
4263
|
+
stepClass: "critic"
|
|
4264
|
+
});
|
|
4265
|
+
const run = await runtime.run(batch.runId);
|
|
4266
|
+
for (const r of waiting)
|
|
4267
|
+
r.batch = run.runId;
|
|
4268
|
+
return run.runId;
|
|
4269
|
+
}
|
|
4043
4270
|
var ALL_INPUTS = [
|
|
4044
4271
|
"brief",
|
|
4045
4272
|
"proposal",
|
|
@@ -4784,7 +5011,8 @@ async function runLenses(ctx, rules, o) {
|
|
|
4784
5011
|
runs.push({ ...base, state: "failed", reason: e.message });
|
|
4785
5012
|
}
|
|
4786
5013
|
}
|
|
4787
|
-
|
|
5014
|
+
const batch = o.runtime && o.batch ? await batchLenses(ctx, o.runtime, runs).catch(() => void 0) : void 0;
|
|
5015
|
+
return { hits, runs, discarded, skipped, reviewed, ...batch ? { batch } : {} };
|
|
4788
5016
|
}
|
|
4789
5017
|
|
|
4790
5018
|
// packages/naysayer/dist/gates.js
|
|
@@ -4807,7 +5035,9 @@ async function gateStatusOf(root, lifecycle, change, gate) {
|
|
|
4807
5035
|
return p && f.finding.state === "open" ? { ...f, proposal: p } : f;
|
|
4808
5036
|
});
|
|
4809
5037
|
const open = findings.filter((f) => f.finding.state === "open");
|
|
4810
|
-
const
|
|
5038
|
+
const checked = await checkFindings(root, change, [gate]);
|
|
5039
|
+
const blocking = checked.map((r) => r.message);
|
|
5040
|
+
const onlyGaps = checked.length > 0 && checked.every((r) => r.code === "open-gap");
|
|
4811
5041
|
const waiting = round ? ((await readRoundMeta(root, change.id, gate, round))?.lenses ?? []).filter((l) => l.state === "waiting" && l.runId).map((l) => ({ lens: l.lens, runId: l.runId })) : [];
|
|
4812
5042
|
const proposed = findings.filter((f) => f.proposal && f.finding.severity === "blocking");
|
|
4813
5043
|
const reasons = [
|
|
@@ -4829,7 +5059,7 @@ async function gateStatusOf(root, lifecycle, change, gate) {
|
|
|
4829
5059
|
total: count(findings),
|
|
4830
5060
|
mayProceed: reasons.length === 0,
|
|
4831
5061
|
// An open gap with nothing blocking waits on its owner, not on a person's decision.
|
|
4832
|
-
humanDecides: blocking.length > 0 && usedUp && !(count(open).blocking === 0 &&
|
|
5062
|
+
humanDecides: blocking.length > 0 && usedUp && !(count(open).blocking === 0 && onlyGaps && waiting.length === 0),
|
|
4833
5063
|
checkRound: usedUp && (await checkRoundDue(root, change.id, gate)).length > 0,
|
|
4834
5064
|
checkRoundsRun,
|
|
4835
5065
|
waiting,
|
|
@@ -4946,6 +5176,7 @@ async function prepareLayers(root, g, now, teamPacks, checks = []) {
|
|
|
4946
5176
|
const ctx = buildContext({ root, change, type, lifecycle, footprint, files, gate, now });
|
|
4947
5177
|
ctx.answers = await changeAnswers(root, change.id);
|
|
4948
5178
|
ctx.recorded = await recordedFacts(root, change.id);
|
|
5179
|
+
ctx.estate = await loadEstateReads(root, ctx);
|
|
4949
5180
|
const { sources, problems } = await ruleSources(ctx, teamPacks);
|
|
4950
5181
|
const layered = layerRules(sources);
|
|
4951
5182
|
problems.push(...layered.problems);
|
|
@@ -5149,6 +5380,7 @@ async function runCritic(root, changeId, opts = {}) {
|
|
|
5149
5380
|
}) : void 0;
|
|
5150
5381
|
const ai = await runLenses(ctx, applicable, {
|
|
5151
5382
|
...opts.runtime ? { runtime: opts.runtime } : {},
|
|
5383
|
+
...opts.batchLenses ? { batch: true } : {},
|
|
5152
5384
|
lenses,
|
|
5153
5385
|
failed,
|
|
5154
5386
|
...opts.maxClassification ? { maxClassification: opts.maxClassification } : {},
|
|
@@ -5243,6 +5475,8 @@ async function runCritic(root, changeId, opts = {}) {
|
|
|
5243
5475
|
artifacts: r.artifacts,
|
|
5244
5476
|
...r.promptSha256 ? { promptSha256: r.promptSha256 } : {},
|
|
5245
5477
|
...r.runId ? { runId: r.runId } : {},
|
|
5478
|
+
// ADR 0185: the one prompt it was asked in with the round's other waiting lenses.
|
|
5479
|
+
...r.batch ? { batch: r.batch } : {},
|
|
5246
5480
|
// What the lens was sent (ADR 0115 addendum, 2026-10-25): its size, what was cut to
|
|
5247
5481
|
// need, and in a redraft the round it was diffed against and what wasn't sent.
|
|
5248
5482
|
...r.context ? { context: r.context } : {}
|
|
@@ -5262,6 +5496,7 @@ async function runCritic(root, changeId, opts = {}) {
|
|
|
5262
5496
|
refused: layered.refused,
|
|
5263
5497
|
problems,
|
|
5264
5498
|
lenses: ai.runs,
|
|
5499
|
+
...ai.batch ? { batch: ai.batch } : {},
|
|
5265
5500
|
discarded: ai.discarded,
|
|
5266
5501
|
failedLayer1: [...failed].sort(),
|
|
5267
5502
|
model,
|
|
@@ -5404,6 +5639,19 @@ async function completeLensRun(root, run, opts = {}) {
|
|
|
5404
5639
|
status: await gateStatusOf(root, lifecycle, change, gateId)
|
|
5405
5640
|
};
|
|
5406
5641
|
}
|
|
5642
|
+
async function completeLensBatch(root, batch, result, opts = {}) {
|
|
5643
|
+
const out = [];
|
|
5644
|
+
for (const p of batch.parts ?? []) {
|
|
5645
|
+
const run = await result(p.runId).catch(() => void 0);
|
|
5646
|
+
if (run?.state !== "validated" || !lensRunOf(run.request))
|
|
5647
|
+
continue;
|
|
5648
|
+
const found = await roundOf(root, run.request.change, run.runId);
|
|
5649
|
+
if (found?.entry.state !== "waiting")
|
|
5650
|
+
continue;
|
|
5651
|
+
out.push(await completeLensRun(root, run, opts));
|
|
5652
|
+
}
|
|
5653
|
+
return out;
|
|
5654
|
+
}
|
|
5407
5655
|
async function failLens(root, change, gate, round, runId, reason) {
|
|
5408
5656
|
const meta = await readRoundMeta(root, change, gate, round);
|
|
5409
5657
|
if (!meta || !meta.lenses.some((l) => l.runId === runId && l.state === "waiting"))
|
|
@@ -5417,6 +5665,29 @@ import { createHash } from "node:crypto";
|
|
|
5417
5665
|
import { readdir as readdir7, readFile as readFile8 } from "node:fs/promises";
|
|
5418
5666
|
import { join as join12, normalize, sep as sep2 } from "node:path";
|
|
5419
5667
|
var import_yaml8 = __toESM(require_dist(), 1);
|
|
5668
|
+
async function raiseAskedQuestion(root, f, askedOf, at) {
|
|
5669
|
+
const id = askedGapQuestionId(f.change, f);
|
|
5670
|
+
if (await readQuestion(root, id).catch(() => void 0))
|
|
5671
|
+
return id;
|
|
5672
|
+
const rel = `${changesRelOf(root)}/${f.change}`;
|
|
5673
|
+
const file = f.artifact === "catalog" ? "change.yaml" : f.artifact;
|
|
5674
|
+
const rerun = `atticus critic ${f.change} --gate ${f.gate}`;
|
|
5675
|
+
await writeQuestion(root, Question.parse({
|
|
5676
|
+
schemaVersion: QUESTION_SCHEMA_VERSION,
|
|
5677
|
+
id,
|
|
5678
|
+
askedBy: { step: ASKED_GAP_STEP, command: `atticus finding ${f.change} ${f.id} ask`, at },
|
|
5679
|
+
repo: f.change,
|
|
5680
|
+
question: f.question?.text ?? f.summary,
|
|
5681
|
+
options: [],
|
|
5682
|
+
evidence: [`${rel}/${file}:${f.artifact === "catalog" ? 1 : f.locator.line ?? 1}`],
|
|
5683
|
+
scope: { level: "repo", id: f.change },
|
|
5684
|
+
askedOf,
|
|
5685
|
+
finding: { change: f.change, gate: f.gate, round: f.round, id: f.id },
|
|
5686
|
+
state: "open",
|
|
5687
|
+
rerun
|
|
5688
|
+
}));
|
|
5689
|
+
return id;
|
|
5690
|
+
}
|
|
5420
5691
|
async function locate(lifecycle, root, change, id, gate) {
|
|
5421
5692
|
const gates = gate ? [gate] : await reviewedGates(root, change);
|
|
5422
5693
|
const order = lifecycle.orgPack.gates.gates.map((g) => g.id);
|
|
@@ -5561,7 +5832,7 @@ async function act(root, changeId, findingId, action, o) {
|
|
|
5561
5832
|
const said = o.reason?.trim().replace(/[.!?]+$/, "");
|
|
5562
5833
|
message = edited.length ? `Recorded your edit to ${edited.join(", ")}.` : said ? `Recorded what you did: ${said}.` : `Recorded your edit to ${f.artifact}.`;
|
|
5563
5834
|
} else if (act2 === "ask")
|
|
5564
|
-
message = `Asked ${askedOf}
|
|
5835
|
+
message = `Asked ${askedOf}.`;
|
|
5565
5836
|
else if (act2 === "waive")
|
|
5566
5837
|
message = `Waived ${f.id}. The waiver, its reason and your name are recorded on the finding; it reaches main with the ${f.gate} hand-off PR, where reviewers see it.`;
|
|
5567
5838
|
else
|
|
@@ -5590,6 +5861,11 @@ async function act(root, changeId, findingId, action, o) {
|
|
|
5590
5861
|
};
|
|
5591
5862
|
}
|
|
5592
5863
|
await writeFinding(root, next.data);
|
|
5864
|
+
let question;
|
|
5865
|
+
if (act2 === "ask" && gap) {
|
|
5866
|
+
question = await raiseAskedQuestion(root, next.data, askedOf, next.data.resolution.at);
|
|
5867
|
+
message = `Asked ${askedOf}: owner question ${question} is in Questions, Owner questions. The ${f.gate} gate waits for its answer.`;
|
|
5868
|
+
}
|
|
5593
5869
|
if (waiting)
|
|
5594
5870
|
await writeProposals(root, change.id, f.gate, f.round, proposals.filter((p) => p.finding !== f.id));
|
|
5595
5871
|
const after = act2 === "ask" ? void 0 : await afterLimit(lifecycle, root, change.id, next.data);
|
|
@@ -5597,7 +5873,13 @@ async function act(root, changeId, findingId, action, o) {
|
|
|
5597
5873
|
message = `${message} ${after}`;
|
|
5598
5874
|
else if (act2 === "apply" || act2 === "edit-and-apply")
|
|
5599
5875
|
message = patched || act2 === "edit-and-apply" ? `${message.replace(/\.$/, "")}; the next critic round checks it.` : `${message} The next critic round checks the fix.`;
|
|
5600
|
-
return {
|
|
5876
|
+
return {
|
|
5877
|
+
finding: next.data,
|
|
5878
|
+
path: found.path,
|
|
5879
|
+
...patched ? { patched } : {},
|
|
5880
|
+
...question ? { question } : {},
|
|
5881
|
+
message
|
|
5882
|
+
};
|
|
5601
5883
|
}
|
|
5602
5884
|
async function afterLimit(ctx, root, change, f) {
|
|
5603
5885
|
const max = gateRoundLimit(ctx.orgPack.gates, f.gate);
|
|
@@ -5649,8 +5931,8 @@ async function editedByPerson(folder) {
|
|
|
5649
5931
|
if (!written || typeof written !== "object")
|
|
5650
5932
|
continue;
|
|
5651
5933
|
for (const [file, hash] of Object.entries(written)) {
|
|
5652
|
-
const now = await readFile8(join12(folder, ...file.split("/"))).catch(() => void 0);
|
|
5653
|
-
const h = now ? createHash("sha256").update(now).digest("hex") : void 0;
|
|
5934
|
+
const now = await readFile8(join12(folder, ...file.split("/")), "utf8").catch(() => void 0);
|
|
5935
|
+
const h = now !== void 0 ? createHash("sha256").update(now.replace(/\r\n?/g, "\n"), "utf8").digest("hex") : void 0;
|
|
5654
5936
|
if (h !== hash)
|
|
5655
5937
|
out.add(file);
|
|
5656
5938
|
}
|
|
@@ -5920,6 +6202,7 @@ export {
|
|
|
5920
6202
|
focusTerms,
|
|
5921
6203
|
trimSources,
|
|
5922
6204
|
sinceReview,
|
|
6205
|
+
LENS_BATCH_AGENT,
|
|
5923
6206
|
lensAgent,
|
|
5924
6207
|
catalogSlice,
|
|
5925
6208
|
lensAnswerProblem,
|
|
@@ -5943,7 +6226,9 @@ export {
|
|
|
5943
6226
|
lensRunOf,
|
|
5944
6227
|
waitingLenses,
|
|
5945
6228
|
completeLensRun,
|
|
6229
|
+
completeLensBatch,
|
|
5946
6230
|
failLens,
|
|
5947
6231
|
act,
|
|
6232
|
+
editedByPerson,
|
|
5948
6233
|
overrideStats
|
|
5949
6234
|
};
|