From 7764863142074df93c8fe2d1554afc231f605fd1 Mon Sep 17 00:00:00 2001 From: AskaEth Date: Thu, 5 Nov 2026 18:04:37 +0800 Subject: [PATCH 1/3] tower: snapshot of uncommitted base checkout changes (worktree wt-133) --- .../__pycache__/make_artifacts.cpython-312.pyc | Bin 0 -> 18459 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 packaging/__pycache__/make_artifacts.cpython-312.pyc diff --git a/packaging/__pycache__/make_artifacts.cpython-312.pyc b/packaging/__pycache__/make_artifacts.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b89a25068a0428b6bc4edeb9f5e34bec7c24c849 GIT binary patch literal 18459 zcmbt+32++W~{?|<+8ck918oi+|v&(i92eZGoh;wbDe*^mdWVbKEDL@7s%^a zDy|VLp5!~0iEG8hxGxuLM7LP^q_IN~*NIigSs|_$m*8G4ZV;E^zEZ3em*KujtP_{x zzFOQU3b?NkZxL7EzE<2MR^whHZWdSK?iRO*t8icEUoWmcTElUY6Z6=B-#QIiZAMS% zh7Inm;VV{-+Zzt_i-OYY7vw;&r{7=O9q9K9lE2^YmHmQOQUcvxpCSw0A&J%Ug(b-! zRD{8PuY$aRI-Bk8OyvQuA_a~MHL~9?bPjrbN4-7ha^u}idm3At>ITHlY$x5}{(iw1 z3Mvx%cJH*=1YGw9f?{Y$7LIS*O0PmV*dO*C9j@*7hJ(IdzvS6{%rDh@hSX{vRIBqJ z_p_=(O_x{l3wYfi1Vch3FzCLiORqG*I{k_+Sv9TGye@rGNS156fGI`owc~nYR9su^ZCNos1}kvU(i}Z@K>}Z1m}(H z2lj^rxj&?+D8~|JR%Exf7wSE`y^^oD{sF?_Luxgas<>=uX%@NyL9aB-R*9+xj`>xL zda)t$ul56bHs89f{YYzjopM~U+1k7V*h_*G#^$UE%YJFCEcno9gRuFQ&D&}>ZK}QH zR`*V!b9c}?;0GK4Rt|)Mc$yDf=LYO75yifc#%(S1B3nk z0c>)wf-VHnuXqFfLLkWYKRX^Y$hvjH|BRhsd0tueD?*SkB*@-jSs3aK_^Y9sGae^BU_LIdj2^h!M;fku;Y`f#8_f>%(yJwQ}21Dz-Zx)s4Yq=0&UP5I zB(t`(MiO=nkr(Y4XSM(cNLUtHnj4zh+M9%pLffIkc*aAPTx`goF(BK9dcBI;Nx

|d1S#WA0-^^$`TN{H!!GTlu?CF+Krt;%{&^1rSHc9?GXk;fuQ1M%g?G{ z#W0oxA|{4>VcG{61JuQW5^hb zO*)|L%15t_c2L0oI_BwAsJ1BAqDg9$t+J6M3oi^-hMhLL3s!? zA+soK1;bsw(7*st!@A9)9G%hp{a|0B4Lip#fkFBiEx_b5)6SeyS}SB?O%+Twc$7d9 zdL-{4=z|O#f=6Oo0fK(O)=s3AR)QFfD2M^c?^8lJJ+%2k=urxY-Y(ET4VPZ^aH{n| z57~SORsA5V*h98XY@Qy!vT--~GDuqe#td8UWW&%3s6+LJaGYyE@7)AHO_0ho-Y?WJ zJ_736&}<_Tff2fZQFTAi{#F^kx{atM&YLf+Fj#y2UeH?VR>Bj`0A|eSQU>`TO*WNq zVyn@i8N^0o^qG)M7$I6qNF2hBB+wWermY8*9g)2~{+*1iVw-^Ysq?9=)#R7j+WwI5 zs9$7N28Wg2P;d*#oF3+9hMF_~8mLQW72*D6@h{63iK-AWPX=WN^7+Cg8f)@ndL=F=A3c9o=5w=Qk>27yDBaJJ!{zY|mkcS~F7Zod+if|0WM zGEyxLsTe7opPe?~fVmB6bB2VcO)3SCShEB?;<}lOM_d_bGpj?bGtj0D*nMdO@a8s1 zkV?6|gsUK+rdOSl=B`V4RK#;n5Olv^I zOijnPZ}Z@8&MX{*+HFEh{h&V}K1H2KWoQx*f5bX8`1`xB*0au~a@?-|f<32=MAJh7 zXkR+CSWGQ2lFpY=UGUCvJbngbUO$Y7vz(GG6LnGUd)$k9MNie}>Z7{zu5 z$*6f8CmLSM^z($y&9_C&pid!br$C#E*w9rfr3nv8Ad+c=JS?Y8vI1ftrETrQB>FTR z4=AW^9`MU_j%8{g+_=4Q=Yw}jp*|452OC17|G^`{0Dh`2(2~&w9{iFsjPW6_Nh{Ht zh@ZRyNsOE0t)u(n`{O&3wxusOymH4&cYMfioU@h2?>bSNCC*2QcF`_mSUU;0 z&T`f~y!B=ArB#Mf3>Ei>IwgxgQP2JiB7e^KS_W%fbmCC-OKWXK;5q`v=lxRIf`D}aJQ7E#~B8B!S zyF|M}dyHMVdbA_7HaafK_bt-u!l zMRhlic0VVYM|6+sPM%QjL%JdExZ!?oNauqQ!KWWF3~_EpOn4Uk0q zB2FLGXL;-xrTIQN6a*25M2T+t{Xw)1Nzj_ohQZJvaA%ObLqxuP(k1|i+@n2dO9l>E zHX@H0mmpPBX;Bt@k2bBn$PeHr{|ZTryT&_=b#tzYQ^B!d+OdDGaB-@*JXN(kRaEv- z*^*SrlFy2)1-8$NIeXFAnrkJT)$v&cS6F%~G8Rd!Jn>i}GF`APcHke@ZJsIE@@mca zmbf9_{H$xDCUziMuw~9{8{PiRk%aDodGVaZku2Euvtv`eGq>$eZaa{4HqTn_NZCtH z?H=2GqCUwl{@2f(oU`;y$HlVE(`B2J_AP(lbbyW8tr?fc{YmGBi@K2@$AbdA#_+6sd*lx=4lX{ zF)mh^cbM|)qAFcM-5A$Lc%64?2lE*&s*9B>=vBQIB0XB&pf0K#(dUkFA2Ho|S5*IH zqiN&rI*p}_@Jg2G^<{~c)`H8nXyhIO+j|h07%@JG zS&f)R%p;blDQfQ4NBO9sTTd1*S$DEDY9vz84z8CYZlYlfj85dEdZb3tv=B+l!J*9t zq{*Z`>$qW^+Z=hP)jP<9<2=C`Y7(hd%=Sfc8{|^j>w8H=2JOkyAOk_-YD_MM3`~;p zfOl|^bWqaJnXcuRd;ytsEtuQ90u#)KND(E`mvu{;WDT^4J$JXFwW`lSZ}hvF)-()j zMYlKH&lFM`08)29Xo6p^W3Ai%L@?Mwfdt(%+N<{dEOP( zX?Ov~E28?p)ScDoxRXnHZkYSAVMyoJk#K2)f+Hz1X`2uP^mVtSO@orZJ8(R0==Khz z&9G3Ba4!?j1j1q}b+GR4@k6B^lp2tTq$Sz&!}Tcu_UA+^ysc92q!)-_LZ zecA+c1^S26JfR|OrqmOX(^mGtYUn&N$t#^eBfB!F%;Haa2&IqVCr=>(x~@4mVQu2E zlk%zPGttTY7hQX&U3+I-jj{cynvD|$XKF4MS5FsL&lazmx;J)k&R%)ZzHHjQEb)zt z%Ws)pe#^}A%`^5bvBo)P(M<8-AFoG}yr*Nv`9N&noV)Jzs#mLivUJ+AdX%4btsWgp zSjRV|93}DlllJA~`z9L4>u2nnQYDL?Ie5*;t-I|r3um+@?bYMAjk_l{O*}BsI<@4y z|NXvq`)2RDXJ+5M$)@{~*84x?JETL)9v`p;2B2TV(BnvHW5 zW_k)=urEnDiccLJJNSa(2d?K_0Q!X?s|6F=-yO8 zQM@|7Y4liP@r8owxkW3^K6?7maphe5>kq&B@YLR^N6r^b?LU9tOl@0o&7qk^cYa=? z4p_>SR(xKD=h5ZY%Cmzf7p=QsU#Ee6+qs6<+g@#(+In7he#O*|^Sv`04kfGaoGH2M z^Tlc}Xu1CLMR>kei9SBB(w=U}%Ynb|>?vu|8{XZxXB%$sZPZb^<5r}9t2Z{;%{R&S zS&I4rLw-)OkLnl=WGN)@EDeojm44z{u>yq_lwIIVOp?8sGez}GwJ*=rW3`Noi!miz zG?VQ6qFJLnH<@xQpz*XF=Uw1{R@Q@!)O69F-+EXNHM|9yA}q}$XJ*W~ByRQ(lesr* zre(z>sgMyD1>P>QrmDUL;(G8rbi;^V$Ie(=ghXL7^U{IHh{&pts|*h^r&weyc&)!X z%os1aA)_(u**MEkCIj68bf^LoF|px_~5-E0)7m1r^hfum7&uMiI$k>N8$UAP zo@|`lHdU0g?fQ`4Ev>@n3vbWA21&@b4=!Zq%HLwzW)gKh`PQz?W+kS-klJ}%CsRO( z38f2cI;}JUD6#qV3t5sNG>|20TTa;&X$xl+O*GA1Yzr^g2TE)Z2#d6uxw|G1-mLyX zv@{&kNgMvGG41TY{6F=dv)GA_FPw{$_3L`ks9_$=u)tjyX(jIz`~n$sN~bUohDQfx zDd;%t5M?bcnsG>|=?Qx!^22$1HfEX$%scF^y8**jChM@|24bXjNU-5+>A8-Qjg;Ji zB+W_0_0qb|NJ%~be%N+#5+nMZLS#vPff!O9avF3I8*`?xGZ=B@YO=#(d# zvUWmzJ@jfQSz8YtTJrwlcNf1`b>5kDw#`}&rOd9lZ<<-E@|$d%9GVPFN#|F-?|#?) z-um-Plg>l4mOItcFP}Yr`gpu=+%+*Y5ts}oZD0G4uUF4~Mrg;ZIF3XVraa*|a!(t+ z>f~$Z0^}g=nZ2IOg*3vx;|o!^R8%CWQR$ijECi2WPh4? z&BSW^yheD{;3J##%>pCF`O^9saguM7y3r5GR@sYKGGNtRUxSD5>c}+r*NZrpx}13PCw*^!pbN%W){7*eewxR@lhUT}AZ*xBDSQ3L#Q>ZuN`_&rrVQeoVmuOX^C@ABs1gZ9d(c@XwU48ds)E*H8AG zS7L`|`4(n*__se8Ip+Z#1Lf?BJ=Oe8mL1amfi2y2BK06mNYyK0|ui7TVOxb)`Bzkh2q7ku{nx5j?|*7KPz;@`e}FT|V^-&*fkK^zx}m&z0~0{L1&A>=Z6dowz*uosZvm=kn-NSAOz0zkloGrKvOP z)?J$V_T~S4_VUwjeEb)aLMOT3J8dLVe)7(9AOF>xmw)noPLuA z6Ry1U6oA3huDtU0rMJI*^~_H&sZPx=4lj2n=EVlT^yas(BwqjI$>(V*YDYlPQ_o%b z>30G5C-Jv0k4|3s%cn2B`E$(r%GsY^Iq}q$(YT=XMNyD6;g>N_!X(W{dJqc<^4Lx{ z6Jy+rOEa08S-_-wQIs}%jw0q$rt?qDG}+q5Ha82RlU_#IEPgV%pJLo+F0M*|5p4Z5 zzbLkEv@yOqymt(${L9XY8M?3w)-aVkk1%% zu5z+9YUdf$BfoW~my9J67D?E)7!`oM2M$$6t&BMaxsVtfHAIbh49~a_jmf#-K~Id> z?|h`SA%q|nQphNTi4?6&2-?j7XhIDMj9(tU+3Bv6JeY~}O(a+U1qTUhM0ie{(YI%B za~t?hxSP!R;6Gs{&<~b^(Ki!k83>7}{US9dxl3KqQF>xD%c#<&`73IL0S9&plGc8V zy8n!yd=Lo}z|Qm}h9>wKd+pSgcXs}A=Lh8%b{+bw^5l_wr|tK_%n9?dIMx<}{$qQ( zV089{OklCAz<9Rb(2sU%nsE(6^>0}cR79Itu7L70J84Q-FWg*9$n03Oz z)NECV`m?LAQhUnXqgK%*nnlYw>uZ?4joX~BZ zo>HxnXgRLKdv-POoSl>CVrAKQ4U|=A?G_#@w_}*GS1%TTR28CK7RzXt?N93q;!Ke? z6X45*dEc5V)1IQvs7sp#^!;M`%e|j`o=Nuea_85Y|DLzcEZR7^J4j~sv_vg`st25$ zRVDrT`oYQFUyy(M7vwi)G=`E$16-Vl>{ml-VOEA=Yp}K-p}qYSzzGL#KgD`5ikvZ# zt;dHC2rv(LgFY5vEY}^TASi^PQ>1aEFt3z_^G57s#>#k_BIZm;ep)}&b(N%1rhY@m zHB;qKS6`Y3?e(Xf)Qto|kHLa4F(m*8lWqv22A-S_Vy+Ok3hqh6chB->ks~=HbLBpZe zJK+#*YiRN`9%^WpXp2all+Yo`C@VeqRwHfMk8~g4Pn&^G<`*L&7hW=`G9<^^;7~j zBO~=Qje1ZGIe8N3Rhe3Fyk|mYuGB0COPL){M<0(q`RJU*b;>#B1S7L7NvVu1!N(5H z@=G-)SCP2&<@)KWO|$&we=b-yYM3jkOtha~K58OM{-a}$&K4}6a}*{^R*vr*-#)P` zS#;a1V>@;07<0gacx1f&xd%S9xUX5c!sYM?7nC#Sp*dMmGwrH@E7)3iYRTA=xHxOA zO2{uazS8=9S8qD$hN7Va3;;GoHT{`OT@K^0SqvD-(^g zMJvYd0c2MAFIuZUE9Z>%r&}Lyjjx{N zE1=%Q+MtfI$~QhQK*gkU;|*5%8iy7)&?ITCx*;FI%Dq=udBARXZ(YUyuN!}@-&?VN zi}^Q|CHvRfe^YCt=j|30yw6!s>HW3F{kIgnzrl?B_qQ1L@3z0c-AtulHy*H9Kj6)% z^MT!Xpw#R`$JqsrGkZ9;k!bvk_*BpywF(W z;mP=Kij*v?70a0CrJQ+fvLT!h0<(-cI|m;9E+7i2hV&>ji5q9+vlbv@(ZPBdg3GBF(uWJ>e4&YxOwP}L&i1VxP zHR8%!VORbND|_;K1)LBRGn8zkKxxP;b4Ck#vREI1U>Ysx)_t zJ=wP}m#006%NT}>^Y+AY^m0He&)tDBAzCc1_#Q7-D+jgwXjbgS-pZ;aFjF@p+Az1z zRz?dK?lV8IdU%z4HATtUMZfHWvx2@gl%BvyktRgHA)*296U{MG;}!5dE|VnJ9$QQD zAoFh^)&XIEd0*(sLIXuRv+w!PH39?r2O~!I{Ysjr4_G2AU=u(va^BZPHJOOPo$L#j zjc$rg%4A7oQi+(<&ru@V@?so!X>o?^D>1S+kn9T=48)wwhhmh;zI#D`^ofGcFRT68 z^S)n+Y=n4+xzcA&H_6KMt!?gurW}mY2!Ui{k=e{;Ls5qKkkf;2CH;|V`6!&hH1d3h z7^_P$T9}>*9~~32X?AJdF*T<8CP$d|S>sN4sU8W#cuuaY;thG&&G?TkEJ73O5pm)3 zr_6^$v_6rNoLh^4qOg>j!;rpTr$H@Dc=m*jvhQ0|Gs|DFiD`XcNa;roI-10 zuK-Us`3k-Uj~T4Fs?%DP{@0`}SaxU-vOn$GlLDn`jZORZ9BDc1*?Xk9rP0&ae0Lh3d7&}YmZiM_Lp9>iVN+%Ihv?~kO6b^1 zT}aY)gtU3PwFiv@x^-B5yYX%hsp{xXgXP`?i zL0(P?$Udps06%~aXQfY3#SHmh{xz5h`Blm;I#*3QSN&|!taAr^E4=L@zX*2Aggv?L z5qz04%S*XD^F(=a+x;xJBbRGAx9VK@we`u}3M&ccN}RJBZ%;NK{|q}xcTj(gLlkoh z-CFdmbUUDH)1wKBjfeEPR*s1WledekFMrBjbkV+K+P-9lTmY9`%V%6Gpc%lK8GRy} zTD$(0=u6RyYwM@i)=$Z^Ya8NQ&+b0Gdt5iJpDtPXLFwNu`7cXGEr_R&4_&Y?W4g$e z$pe!+lV3ZOyz|}$+?ZUKOn6+2Wl`b8(PM5kzt#busXZpvRCyvb&Y>OS3;|t=J z#Hv|-IowYc$I~NEj3oGR)AO#>iq)?y{o&HnOD21#5cz*Tm^^ZS@^D9T>jR^vIg2w{ zsH#hwlCIhhEp?YHWoNoyxOY4-Sw2&~eQNEjW$z_dG3L4b^!5`$pu!H%7RAQS+J(8| zszlFp@#;}?if1YYRHf2b>nvaQk=Z^Peqtn5xaftBbFL}#`O=xC`;trcpI4HVEz^Z9 zqee|FyDt&`(6ahc;nGA8f}`%8?42q6`l#`et?tKQnPg zTQ0UFX{(;)SElR^W>QUCJP2A21U(-38A(!PdODpV`l?WZE<<0mUDpcWBW;6$xEb#^ zK)@v-Do{`!i-4A}9l5-!7WHg@i*kw5s5FP2T$aZ=B|4;qUlwE__f)x^L$_#<_YiS)^JOC4zDZI=6eWJGL4QXilXDj!mzXE5bMpX>Z) zIM{#)a$xpy*5N`mb3o>1oZsgCEa#Njv~-#PF{u-ANJ^UpYrQ< z{2x0If4cH_T)}TS`)@fHOY!XdEm!ng&W4)dR@hJTZyjnvkflY1G?+gysq%Ns{qL=i|%XJ%U!y!U#~XmmR&Do z1s2`L>*Z!$(e=_QUCH&`n|01>2zlTgqmc`S#s6R{J$?9DP@yGBe#tch$5%4^{a?PS BA>RN1 literal 0 HcmV?d00001 From 969d5ea4505284ccf662688e8439227249b67744 Mon Sep 17 00:00:00 2001 From: AskaEth Date: Thu, 5 Nov 2026 18:05:44 +0800 Subject: [PATCH 2/3] =?UTF-8?q?chore(git):=20=E4=BB=8E=E5=88=86=E6=94=AF?= =?UTF-8?q?=E6=91=98=E6=8E=89=E8=AF=AF=E5=85=A5=E5=BA=93=E7=9A=84=20.pyc?= =?UTF-8?q?=20=E5=BF=AB=E7=85=A7=EF=BC=8C=E5=B9=B6=E6=8A=8A=20=5F=5Fpycach?= =?UTF-8?q?e=5F=5F/=20=E4=B8=8E=20*.pyc=20=E5=8A=A0=E8=BF=9B=20.gitignore?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 03a5de9(TowerSpawn 的 WIP 快照)把主检出里未跟踪的 packaging/__pycache__/make_artifacts.cpython-312.pyc(18459 字节二进制)一并提交了。 这里用 git rm --cached + 忽略规则把它挡在主线之外:跑过 make_artifacts.py 就会再长 一次,不堵根因的话每次 spawn 都会重新污染主检出并触发 WIP 快照。 --- .gitignore | 4 ++++ .../__pycache__/make_artifacts.cpython-312.pyc | Bin 18459 -> 0 bytes 2 files changed, 4 insertions(+) delete mode 100644 packaging/__pycache__/make_artifacts.cpython-312.pyc diff --git a/.gitignore b/.gitignore index 7143e9e..7568856 100644 --- a/.gitignore +++ b/.gitignore @@ -18,6 +18,10 @@ dist/ out/ target/ +# Python bytecode (packaging/*.py 本地跑过就会生成;提交它会让每次 spawn 都打 WIP 快照) +__pycache__/ +*.pyc + # IDE .idea/ .vscode/ diff --git a/packaging/__pycache__/make_artifacts.cpython-312.pyc b/packaging/__pycache__/make_artifacts.cpython-312.pyc deleted file mode 100644 index b89a25068a0428b6bc4edeb9f5e34bec7c24c849..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18459 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 BA>RN1 From e0e1f90aed75f347e5bc231da0c04dfcf6c3ed91 Mon Sep 17 00:00:00 2001 From: AskaEth Date: Thu, 5 Nov 2026 18:11:26 +0800 Subject: [PATCH 3/3] =?UTF-8?q?ci(workflows):=20=E8=AE=A9=E6=97=A5?= =?UTF-8?q?=E5=B8=B8=E7=BA=BF=20dev=20=E4=B9=9F=E8=B7=91=E3=80=8C=E5=BF=AB?= =?UTF-8?q?=E4=B8=94=E4=BC=9A=E9=9D=99=E9=BB=98=E8=85=90=E5=8C=96=E3=80=8D?= =?UTF-8?q?=E7=9A=84=E5=AE=88=E9=97=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 本仓日常开发线是 dev,日常合并不走 PR;而 ci.yml / guards.yml 只挂在 `push: branches: [main]` + `pull_request` 上 ⇒ fmt / clippy / 文件行数≤400 / 三条零依赖守门在日常线上一次都没跑过。可见后果:packaging/README.md 涨到 401 行 超全仓红线,直到文档普查才被发现(M131 才修回 398)。 做法(新增 dev-guards.yml,不改 main/PR 判据): - guards 作业用 `uses: ./.github/workflows/guards.yml` 复用**同一份**六道守门脚本 (guards.yml 只加了 `workflow_call:` 触发,其余一字未动),避免两份 unsafe 词法器 各自演进造成「dev 绿、main 红」的双真相; - fmt / clippy 各写一份,命令与 ci.yml 逐字一致(ci.yml 整份复用会把 build/test/ runtime-smoke 矩阵也拖上 dev); - 刻意不上 dev:全量 cargo test(--all-targets 的 clippy 已覆盖「测试代码编译不过」 这类腐化,「断言暂时红」在施工中间态是常态)、build release、runtime-smoke。 成本控制:workflow 级 concurrency 取消同 ref 旧运行;clippy 在「本次推送只碰文档」 (*.md / LICENSE / NOTICE / .gitignore 白名单)时跳过编译,判据保守——非 push、 before 全 0、base 不可解析、diff 为空、出现任何白名单外路径一律照跑。 --- .github/workflows/dev-guards.yml | 125 +++++++++++++++++++++++++++++++ .github/workflows/guards.yml | 6 ++ 2 files changed, 131 insertions(+) create mode 100644 .github/workflows/dev-guards.yml diff --git a/.github/workflows/dev-guards.yml b/.github/workflows/dev-guards.yml new file mode 100644 index 0000000..33a22ec --- /dev/null +++ b/.github/workflows/dev-guards.yml @@ -0,0 +1,125 @@ +name: Dev Guards + +# 日常线门禁(M133)。 +# +# 为什么需要这个文件:本仓日常开发线是 `dev`,日常合并**不走 PR**(见 DevDocs/AGENTS.md §8 双仓纪律: +# Gitea `dev` = 日常线)。而 ci.yml 与 guards.yml 只挂在 `push: branches: [main]` + `pull_request` 上 +# ⇒ fmt / clippy / 文件行数≤400 / 三条零依赖守门在**日常线上一次都没跑过**。第一个可见后果: +# `packaging/README.md` 涨到 401 行、超全仓红线无人拦,直到文档普查才被发现(M131 才修回 398)。 +# 「门禁存在但日常线上永不运行」= 空跑的门禁,长期等于没有。 +# +# 口径:**只补「快、且坏了会静默腐化」的那几道**,且不复制守门脚本: +# - `guards` 作业直接 `uses: ./.github/workflows/guards.yml` —— 六道守门(core-no-ui / +# presenter-no-ui / design-zero-dep / unsafe-scope / file-size / licenses)跑的是与 main 同一份脚本, +# dev 与 main 的判据永远同源。main / PR / dispatch 的触发与作业一个字没动。 +# - `fmt` / `clippy` 在本文件里各写一份:ci.yml 的作业背后挂着 build / test / runtime-smoke 整条矩阵, +# 整份复用等于把 dev 的成本翻倍;这两条命令与 ci.yml 逐字一致,方便对照与同步。 +# +# 刻意**不上** dev 的(判断依据见 M133 报告,这里只记结论): +# - 全量 `cargo test`:`clippy --all-targets` 已经把测试**代码**类型检查过一遍(「测试编译不过了」 +# 这类静默腐化会被它抓到),而「断言暂时红了」在施工中间态是常态、不是腐化;test 是 2 个 OS × +# 全量编译+运行,留给 main 与发布前的最终门更划算。 +# - build release / runtime-smoke:它们是「能不能发」的门,dev 每次 push 跑一遍换不到新信息。 +# +# 成本控制(dev push 很频繁,这是硬要求): +# 1. `concurrency` 取消**同一个 ref** 上的旧运行:连推三次只留最后一次,被取消的旧运行基本不计费。 +# 2. clippy 只在「这次推送碰过 Rust 侧文件」时跑:只改文档(*.md / LICENSE / NOTICE / .gitignore) +# 的推送跳过编译。判据**保守**——非 push、base 不可解析(force-push / 首次推送)、diff 取不到、 +# 出现任何不在白名单里的路径,一律照跑:宁可多跑一次,不许假绿。 +# 刻意**不**用 `on.push.paths` 过滤整个工作流:file-size 正是要在「只改文档」的推送里跑的那道门 +# (README 401 行就是这么漏的),整条过滤掉等于自废武功。 + +on: + push: + branches: [dev] + workflow_dispatch: + +env: + CARGO_TERM_COLOR: always + RUST_BACKTRACE: 1 + +concurrency: + group: dev-guards-${{ github.ref }} + cancel-in-progress: true + +jobs: + # 六道守门原样来自 guards.yml(那边加了 `workflow_call:` 触发,纯新增)。本文件不重写它们的脚本: + # unsafe-scope 的词法器一旦有第二份副本,就会出现「dev 绿、main 红」的双真相。 + guards: + name: 架构与合规守门(同 main 口径) + uses: ./.github/workflows/guards.yml + + fmt: + name: fmt (rustfmt --check) + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@stable + with: + components: rustfmt + - run: cargo fmt --all --check + + # 只跑 ubuntu:clippy 的判据是类型层 lint,跨平台差异极少(Windows 专属行为由 main/PR 上的 + # windows-latest 槽位与 test 里的像素守门兜);两个 OS 都上会把 dev 的编译成本直接翻倍。 + clippy: + name: clippy (ubuntu) + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + # 要 diff 出「这次推了哪些文件」就得有 base commit;浅 clone 会让下面的判据退化成 + # 「一律照跑」(保守,但不再省成本),所以这里取全历史。 + fetch-depth: 0 + - name: 本次推送是否碰过 Rust 侧文件(只碰文档则跳过编译) + id: scope + env: + EVENT: ${{ github.event_name }} + BEFORE: ${{ github.event.before }} + SHA: ${{ github.sha }} + run: | + set -uo pipefail + run=yes + note="照跑:默认(未进入可判定的 push 分支)" + if [ "$EVENT" != "push" ]; then + note="照跑:非 push 事件(手动 dispatch)没有可信 diff" + elif [ -z "${BEFORE:-}" ] || [ "$BEFORE" = "0000000000000000000000000000000000000000" ]; then + note="照跑:base 为首次推送(before 全 0)" + elif ! git rev-parse --verify -q "${BEFORE}^{commit}" >/dev/null 2>&1; then + note="照跑:base commit 不可解析(force-push / 历史被改写)" + else + changed=$(git diff --name-only "$BEFORE" "$SHA" 2>/dev/null || true) + if [ -z "$changed" ]; then + note="照跑:diff 为空(可能是增量不可得)" + else + # 白名单判定:只有「全部改动都落在这些非 Rust 路径上」才跳过编译。 + # 反向写法(黑名单 .rs)更省事,但漏一个路径就等于漏一次编译检查。 + others=$(printf '%s\n' "$changed" \ + | grep -vE '\.md$' \ + | grep -vxE 'LICENSE|NOTICE|\.gitignore' || true) + if [ -z "$others" ]; then + run=no + note="跳过:本次只碰文档类路径 —— $(printf '%s ' $changed)" + else + note="照跑:本次改动了非文档路径 —— $(printf '%s ' $others)" + fi + fi + fi + echo "$note" + echo "run=$run" >> "$GITHUB_OUTPUT" + - name: Linux 图形栈构建依赖(winit / wgpu 编译期需要) + if: steps.scope.outputs.run == 'yes' + run: | + sudo apt-get update + sudo apt-get install -y --no-install-recommends \ + libxkbcommon-dev libfontconfig1-dev libgl1-mesa-dev libegl1-mesa-dev \ + libwayland-dev libxcb1-dev + - uses: dtolnay/rust-toolchain@stable + if: steps.scope.outputs.run == 'yes' + with: + components: clippy + - uses: Swatinem/rust-cache@v2 + if: steps.scope.outputs.run == 'yes' + # 与 ci.yml 的 clippy 作业逐字一致(`--workspace` 不含已退役的 `unlucky-app`,见 M118)。 + - name: cargo clippy --workspace --all-targets -D warnings + if: steps.scope.outputs.run == 'yes' + run: cargo clippy --workspace --all-targets -- -D warnings diff --git a/.github/workflows/guards.yml b/.github/workflows/guards.yml index 767f8be..807bf0d 100644 --- a/.github/workflows/guards.yml +++ b/.github/workflows/guards.yml @@ -23,6 +23,12 @@ on: branches: [main] pull_request: workflow_dispatch: + # M133:日常线 `dev` 复用**同一份**守门脚本(`.github/workflows/dev-guards.yml` 里 + # `uses: ./.github/workflows/guards.yml`)。这是**纯新增的触发方式**:上面三条与下面全部作业 + # 一字未动,main / PR / dispatch 的触发与判据与加这行之前逐字相同。 + # 为什么复用而不是复制:判据只能有一份。两份 unsafe 词法器(110 行状态机)各自演进,迟早出现 + # 「dev 绿、main 红」的双真相,那时 dev 门禁就变成了装饰品。 + workflow_call: env: CARGO_TERM_COLOR: always