From a96f0dd932be5a3b8ad1f8fa262d2114c0c36aaa Mon Sep 17 00:00:00 2001 From: gsxdsm Date: Thu, 20 Aug 2026 21:42:30 -0700 Subject: [PATCH] fix: ship git-lfs in the Docker image MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The repo keeps binary assets as Git LFS objects, but the runner stage installed plain git. Without git-lfs, checkout writes ~130-byte pointer files in place of the real content and reports a clean tree, so an agent reads a text stub where an image should be and any `git lfs` subcommand fails. That is silent corruption of a working checkout, not a visibly missing tool, which is why it goes in beside git rather than with the optional tooling. Confirmed in the running container: screenshots/fn-061-medieval-desktop.png was a `version https://git-lfs.github.com/spec/v1` stub — 129 tracked files in that state — and became a valid 753KB PNG (signature and IEND intact) after installing git-lfs and running `git lfs pull`. The Dockerfile manifest guard now asserts the package so it cannot be dropped. Co-Authored-By: Claude Opus 5 --- .changeset/docker-git-lfs.md | 7 +++++++ Dockerfile | 7 ++++++- screenshots/fn-096-chat-header-new-desktop.png | Bin 7476 -> 129 bytes screenshots/fn-096-chat-header-new-mobile.png | Bin 4881 -> 129 bytes .../fn-099-task-chat-model-menu-desktop.png | Bin 9534 -> 129 bytes .../fn-099-task-chat-model-menu-mobile.png | Bin 7240 -> 129 bytes .../dockerfile-workspace-manifests.test.mjs | 10 ++++++++++ 7 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 .changeset/docker-git-lfs.md diff --git a/.changeset/docker-git-lfs.md b/.changeset/docker-git-lfs.md new file mode 100644 index 0000000000..1b87ec38f3 --- /dev/null +++ b/.changeset/docker-git-lfs.md @@ -0,0 +1,7 @@ +--- +"@runfusion/fusion": patch +--- + +summary: The Docker image now ships git-lfs, so LFS-tracked files check out as real content instead of stubs. +category: fix +dev: The repository stores binary assets (screenshots) as Git LFS objects, but the runner stage installed plain `git`. Without git-lfs, `git checkout`/`clone` writes ~130-byte pointer files in place of the real content AND reports a clean tree — an agent reading one gets a text stub where an image should be, and any `git lfs` subcommand fails outright. Verified in the running container: `screenshots/fn-061-medieval-desktop.png` was a `version https://git-lfs.github.com/spec/v1` stub across 129 tracked files, and became a valid 753KB PNG after installing git-lfs and running `git lfs pull`. Added to the runner apt install alongside git, with the Dockerfile manifest guard extended so it cannot be dropped again. diff --git a/Dockerfile b/Dockerfile index f3d7a9f3da..14f16303c0 100644 --- a/Dockerfile +++ b/Dockerfile @@ -77,8 +77,13 @@ ENV PORT=4040 # FNXC:DockerRun 2026-08-18-06:05: ripgrep ships by default because the coding agents Fusion drives # reach for `rg` as their primary search tool; without it they silently degrade to slower/partial # fallbacks inside the container while working fine on a developer machine that has it installed. +# FNXC:DockerRun 2026-08-20-04:30: git-lfs ships by default because this repository stores binary +# assets (screenshots) as LFS objects. Without it, git silently checks out 130-byte POINTER FILES +# instead of the real content and reports a clean tree — so an agent reads a text stub where an image +# should be, and `git lfs` subcommands in any workflow fail outright. It is a git dependency, not an +# optional extra: the failure is silent corruption of a working checkout, not a missing feature. RUN apt-get update \ - && apt-get install -y --no-install-recommends git ca-certificates ripgrep curl gnupg \ + && apt-get install -y --no-install-recommends git git-lfs ca-certificates ripgrep curl gnupg \ && rm -rf /var/lib/apt/lists/* # FNXC:DockerRun 2026-08-18-06:40: gh, tailscale, and cloudflared ship in the image. diff --git a/screenshots/fn-096-chat-header-new-desktop.png b/screenshots/fn-096-chat-header-new-desktop.png index 473a2af832afb6a7beab9988da1db39b69868e02..ecb46c3979bc5bb8095cac72b756860348544344 100644 GIT binary patch literal 129 zcmWN?%MrpL5CG6SRnUNeg$*p}hR-6*sAL3luzG!$ckz4n@se$=a~?|F`?@{q-2S&u z+VXg+d2&`4h|!CjEt=gO1Qb#U+UV*qx}Z7jB~&6r3*b>#uC5@V(M$=zn9L~zYi+d! NV-&N0S$gzN`~aOVCb9qk literal 7476 zcmeHMeNfZ)8IOH&4rTFdZLyv(wt1T`w*Wgul#nXEmOG%LGKG;j1ggB+b&lrFyyU)kWjQBkPxpZ9B%;+NG522q#6Qw+4KCqKNxPF*4AFzJO1JO z_Pl&PpXd2~`6YQfGpRoX^vJ7Pl_%I=o^3CoA=hU#$PbkCy~xzgHHjyI>k!Y4YxL*_(5H zv#CS=q7T<|`&oa#+Tk5L_E)B-r=Qr(R<--7rn@p`EGo>zc;Ov?rgvICC}ELK!FZDr0D z!Ss-a=tayjICcPs%xZT`)4-|fFnZ_TS?eq7kKWuH6kOM=sOpYN>0!rK)DP<`1?pHq zi=iMbTVC_OyEl$o&gX0HyX6MW|J(UZ3G+U_iml+>*v^^I8Dxe&iK9Q}#k zh_2RmOhyO9&=cjASle<0VL3?>1wn@H1QtIYk~VL><6hAnW%?&zNvM|eks~;jlY>Ud z$4FozBpHk=1 z)-rAxsoh;<$2iiHz_OM@tiIj^77*~Gh|${eh}w8`(=fT*(RFLen{x&JpywJS4kvPq zAOK4W?G->90kyKw8%9u_@^7P?%DvG!OJ3MYtB>8zP_BGXqm6lL5d=lc zaQ3S=HP`v&OheZ>|a?Z)KCsT@YC zybWE}HYtlAa-Vt+d;0H>^k}#AC5jKsljj7Nw~Pq=hf9tYqy)J8WQFOrdNBF%ZnDV2 zY;oV}rgerP&t%u39I&i8`^Q%6>sRZK7MM=AHwPMFw-~nb!84U|O@duw;}tCT^I)!; z?~Qr%kVpq-kU|cJ;dE>**v_tr)iF02>NubjH*DKN1(E_Z(OZzZ6Cij6&mvqll!Jl8 zAgzWvunGu>2#7rw3%P(LYg1NOK#ZHLuYg(t_PKa8T<{nb`a^c1lsZk}QN&8Am@a^5 zqHVvmi9H@=_S4pN`NOCXXw1en4Nj zNKUnpX+4XfE}d?*@Vf&>&|7jR3`70jibrhjpncD8Hx6x2~j>C?2+yU&a}i9Vh*P|a+H!xm5%_#ucCa|EpgV2}h% ztp%i4#`9p^hiN8iqmzEdBjh1jO6}H!MdC7SaTPWnJC#d@1R11!}BLo6$ z(}}Pyq9mqu_b2nva;_6#^HG)(NIW1h@D4<+qEeOtR{Erh7`V^zqSmw~TF@YwumQNl zc?GsaMve;{jfq?l$Vv0Lj7(r8CW*7lja@c&o8nl1nROlDlLBUBB5kDLiL$_y4g1^^ zc@h|WLG5_RF>l1z=0VAzr;|Y{VU-h^Xw4Kg|CNXP2AK;HA5=>yB_lYLmCqGqqnSd@ zz2IVd?zgkJ8#wu5;m?6L2oLovrDiZ8g7{Gcu7AON7v zP$jU0Lu!PHHGp_tqJn}AMJ!^ncwA)e{T4oN{BWPe@98c0MDCddZeQc0^Fk{>sV^ZG zlw449;R;%~f*$?7<3g7#bjd=Od=Ed2f7h>}&eW1!5(eYxKjAMgD)yG$n#*rBGNwlU z)_LZ$T}kIwCzb!}M&k>DLvJqi`04h~nLC~l|LSLZv-1{ZKK3srPvm7KgdfLMik9L> z(}~TT453zV5$E6ZE0M>o0(<1mRlJd+La}$au^VPpg0!N)%1vLew`rRq`L~J+cg*E>4{*F?RD4)wzPSsMQ#y3%3nNaYHmxv<9uGvetWC zV{eNt?W=ei*NXnIfcLz^-N7+U+kSon({kIt4nv6rY3@ytR$oZ_Y21&{G~h2XVW{Oc ztUC!6IIN8` zbf4eAf*^;0(8*ass?&CRHpl#~QfPkxGY=+;98*P>ukbV2xAyOdJyK}5O|lV9Lv!d4 d=*F8~x}yEhuN>SncoVVj+ZDXCbjR=C_z!{Wh)dTMIRpXE&Eyr?@B$!x;-0j|NB`s zoG--(p}IiKQ6=}g@nN?n=&X&0q#**LExwX=6)4BlO7$rl0Pulw$t@(*)&Xf7Tf++I L1&=RDmlB8{hO;Jg literal 4881 zcmeHLdr(tn7QfKKP)A_dRvm?I26rq|)`>zOG+Gn8$fBd-R_M}QdFToVt3b_N1vHIr z+m&6hfTeACWSj0V)otC9UBrbzOtg+9KzPYmhJXYI$aN76CK$L7$e!JHK=8i$DH6Cfa++swD(LcyHUfWj8^%g_kGn_*6BQgK*!r<&C&p zx6xJ78wBygW~7Z>{rhh!Unu8y97r;xy%_dd`YSzKSMjI6`TZA->3)*Vgi~2peGD6{ z16MR2iH$$w{K2pP*WxuZ?|dogxy?UW zMi{>&I$}Id9t|dHV%KFJZUgECzJQM%s?2A(?5JCbyCQIg~#U?0HedK za1JLsKWo2Zat>;(f?0ak2`@?O+&@ioJawYeCKH*@PuY7-!`r8OO>^anN<45X{Q)~O zG>&?hN79cF_L%1E-Rjiu3?uk^N;4KV7a88R>$RpiE-@j#Z*|UXBqnw*GT@82KXzGA zs}()jTGdiQVV<%0(DMJ*4_!_x{`~c9Rt0%+-&qjdY1dZI+~R}MZEwg-s_-rd7|ZFE zgB;E2RrCFq_gMasm&spSZOSCG_-n0^VAa-oDyk4<4ERQ4=Mo6j^EbV;w)N24Ln+$c zG{(bbJoGjw=03d1$aK(C_-n;Arc87^wEszgyyOWVd-5NVA?{elDOHk^mEpJf=e4AoT5 z^m5);Q^WMhTYdCw#0cO&fAcMA22OM1>ci%V!&uha_d$w-ID`Z7mk+6MXAu4KB(ucI zARjd2cjSt^_t_eC^}y3m#*t4-fDhsI2h)OG7cO*|n8CnP!h=*Hn4F9I{Bm2kR?khq z3#LWX2;2m*S)WdcD6LB49^}0b~$FkQnfc$dAL^^gWyx_wn%Q)(F$woP|Ck zooP)arov1oa`aT(Q{G<|9=qrv3b>v>nH;}xqkYn|`G2_u{rmf+O26)qamPy8{+M&E zA0HN&(~Ua>pcP^*g*g(Y!Da+k7qGM9)u2JKp|hqel&h2PsCX3=Dm3%lnU;{CuC(U5 z0AA)fHJ_`)C+*=bC$=KkRDReJ!q}16$*Hd?vlL+7E)`oB{J)f$jkm z4v!%hQD2Lufo(j}cZJXQ7PGYzs3sv!`@{W(f&c_^g@Cx9p3+P$ZSFNWHxV^Y`$S&2 zVjg=~KRa6djsE+)Yy9W0hiAE5zonkB@r;edzO(<&X5(qTh8}qpA;upSn@(^H0yY6QsUD&dnpc)dKLvm& zBm(FnJqEVd>*J9dg4ZjF8Djie1@bq@|Ht%d78S}0CaqO}g^BBkN$+BGb zZ(hoL8QEJgC#X59mY(iDY*2`>t(gqhE&-) NtX|3ZH66Wm>JPmICp!QD literal 9534 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

SiINi|3r+J|Io~z2Q>7EW0DNnEHVgV&Sjhib%m3 zzdy)v&Zw<=uziwXxY^6|m!S90c*&r3KD#erGRU&Oo->eFiagvV3Enl&+e%qJ7Ci?I zx(<|4Y9RSIW1<@<7=ma7VyX;T@wXlj4*dGXvp8uI*h}T*i1)%zXU|8Gw7$hdN2uoE zl;$}&0s$9pv?L+lVL4bZ`<@b(rd;5{PBgh>s-*a;>+IaZfRGDh|TExQ5ZvT_} ze}~UZEqfP^ZhxZ}bVX`uwXW_q)Qv_I;_OJZ%Zm&}F8>uqmHQhqNQuOb`WtlCqeCRe z%rG!AU*1I-ik+5q_}6cADY6oZdx_q0g(@8G>797)lsQv94;D=}gZep_{o@sDzs5%) z^n_x4X)iZh2F~~09?cbWOS{C7OOHHg!%Pb4+8)SFnK&o5*0TpPM*O|thbix?A&C}r z#VAf-K~Tmi8V>jLIR=AGXRRO~Li0@8Fh5LWq)uJEpVZgV=NJNh>Q?rin>;VVSZi4h zASlZyj>rykJH*uv_{+~N1NXR!cEM!Dcw!$}jkx}KAn1@a)e!|K$X7s$B7;UiEb8yt zhpj6iiTArr@`>}0u~`F0Y40&K&1HgfQ_g3MBM-=WbtR%ur_sR+XLX)PN_GUo1H<-+ zPgwN$P-XSvg-tIvGB}C478-f2TC@n1JDc+r-LANDwes%xq_oo6BIfL3;-8JZ>^O;P zD+UoS&J$&Yfj#CsfXNV7mjpQ%g&;S~p0Mhft#0toc!lzqqOhb0QTo%P!AYT8O=vof``Q3{95ktAWo&-&~o*d zr%xd5h$^a*W*echJX~_HvL~i~vryZ4TpiP51SkxiLC7S#JccJoIrKGw& zv0HNOm;$GiZMu*S*^dYkZY8EM8TOxMo<~;I0PZ-W#ok2Ej4J*SykpK+CZ|bGcFI3o z$UoBZ%>w?x9PAa%*5@)kA;0MXl%vPV)%)QRT;9GQA3H`10jIorup_#6_`=G2xNEFZ zi9d-QVPTblh2B$w1x4Goo?G~Gr7#aXEOx}_8pVacR5dt>?c9OeRTSNWeM&P$fXH1iKXT-Cib=Lko{|#Dd}oA&dc?al^kx!r zc`~GeLBQ2D2nhAh=0jWr{0H{vSGPzXtep47xE`^d_d(cSWlO}@1y7BJ+zai{AB&&dhtXzAdU8N;;y0i zFFiW|`@)=XaS_NAb@)=|I0RCl=*1;a{9;|xR9I+^mkY$EfLXW74Auo=b6Ctdik`WhR5*?j66CJGT66427mCb&{)Uldc;_fAK)}YtwG;@>O1I39 zz_MfvVw>4*-H$%x5Z0&w!0@&HTY$!_92(Em$|7L5-Y&v=(95*Dpqh!ap3IwqL{r~^ zs^8avdYW!v^SnMxM-$LHP)}%v&{BM0gT|9E?WN#Di~&v7f@&FHs1r{=oXoAPtUs3_ z&A^x;LDL23Mg8jGr|G7`7-fG#WKf%(3L3E6*E|Tb0&PkSYnhd9K{2bJSUbQL5|@$_qcXbF)2oX`O#{q zGvM_v6N^X!(D<>B1KrD3*4}`B+YAXQX-PUJa))5l1 zwq~Zy32CVJ2)keuy0|l>`c0eDuUAtkIB!eM&hQsn@jBtOTZ^phs>w}fL)HkpfbdiY zo<@8fDL0;Nsj9@g1nR484C!9)qH^Z`bS#7gklEkD)9Wi}9L3}z*N&>vp zrE>LgTsq9skqzBf+fILNV`0XhK1Z(?u-I2xSXLQxon6@V4c2#k6GV=p7)Oe`6&L4+ zPv}4R7Su%(rGO#w2IC5K~7 zPup9q@_G%GXKXus?=lVc;lj;|@&oP4d)v>nq(2y4DSE8Jtl;LFFJo4oa`=i6sjCsl z`wRrI@h)h#h9MIKAYsL`syw*kRLD#Z9+oOF^56L#d^)0!AmG}6^5c~m34ZTi*!=cF cJ|-g?zRSNceJ$byJOQxxL*L!SJHx;H2acqQaR2}S diff --git a/screenshots/fn-099-task-chat-model-menu-mobile.png b/screenshots/fn-099-task-chat-model-menu-mobile.png index 95cdfae257b4c59c7581ba3af8831f4c6c5a09db..97a1b68416036f4097d363c1d60fe23997dd4b2d 100644 GIT binary patch literal 129 zcmWN{K@!3s3_#I6r{Dq>g#_B(CO{BoR62%s;pt`d-{N2VmDWGHj&aCt%(IQ#tH?52 z&$y)iHga$>*F*J|wN$d`_v|4QSMur$A^5;(H+EdWGN8u@w0fEg;s%5+qD>_x;t9tY MvXb^=9W30{AJ2v-)&Kwi literal 7240 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 diff --git a/scripts/__tests__/dockerfile-workspace-manifests.test.mjs b/scripts/__tests__/dockerfile-workspace-manifests.test.mjs index b6c36a5269..abbc882612 100644 --- a/scripts/__tests__/dockerfile-workspace-manifests.test.mjs +++ b/scripts/__tests__/dockerfile-workspace-manifests.test.mjs @@ -131,6 +131,16 @@ test("runner stage installs ca-certificates alongside git", () => { /\bripgrep\b/, "runner stage must install ripgrep — the coding agents Fusion drives use `rg` as their primary search tool", ); + /* + FNXC:DockerRun 2026-08-20-04:30: + Without git-lfs, git checks out 130-byte pointer files in place of LFS-tracked binaries and still + reports a clean tree — silent corruption of a working checkout rather than a visibly missing tool. + */ + assert.match( + aptInstall, + /\bgit-lfs\b/, + "runner stage must install git-lfs — LFS-tracked assets otherwise check out as pointer stubs and git reports the tree clean", + ); }); /*