refactor(files): make tunnel frame decoding host-testable (VAPP-83) #94
Loading…
Reference in a new issue
No description provided.
Delete branch "feat/VAPP-83-files-auto-refresh"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
This does not fix VAPP-83. It is the instrumentation step, because the ticket's premise turned out to be wrong and the fix as specified would have been a guess. VAPP-83 stays open.
What the investigation found
Auto-refresh after a mutating op is already implemented on both sides, and has been since the file browser landed in
cfc1942(2026-06-12), a month before the ticket was filed:{action:"refresh"}rather than echoing the op (build_mkdir_replyand friends,vervain-agent::host::tunnel:1508,1537,1576,1600,1648,1683), and upload completion asuploaddone.lsof the current directory (files.rs:734,files.rs:758before this change).So the ACs describe behavior the code already intends. Bolting a second refresh mechanism on top of a correct one would mask the real cause rather than find it, so this change makes the existing one observable instead.
Why the bug could hide here
The entire session driver is
#[cfg(target_arch = "wasm32")].cargo testand the host clippy pass never compile it, so the protocol had zero tests and was only ever type-checked bycargo check --target wasm32-unknown-unknown.live.rsdeliberately keeps its control-channel decoding pure and wasm-free so it is testable; the file browser skipped that.What this does
decode_files_frame -> FilesFrame(no wasm types, no signals), unit-testable on the server build, gatedany(target_arch = "wasm32", test)so the server binary carries no dead code. Same split aslive.rs.handle_textbecomes a thin applier; behavior is unchanged.refreshasks for a re-listing, anduploaddonedoes too.localStorage.setItem("vc-files-debug", "1"), then reopen the tab. A runtime switch, not a build flag, so a reporter can capture frames on a normal deployment. Silent by default.The useful result
The tests pass. That is the finding: the decision mapping is correct, so the stale listing is not a decode bug. The fault is either upstream (the
refreshframe never arrives) or downstream (the re-lsreply never reaches the view). The console log now tells us which, in one repro.The refactor also surfaced a latent gap: the exhaustiveness check caught a missing arm that the old catch-all had silently absorbed, and it only fired on the wasm target, which is exactly the blind spot described above.
To finish VAPP-83
Reproduce once with
vc-files-debugon and grab the console:-> {"action":"mkdir",...}then no<- {"action":"refresh"}means the agent side is at fault, and the ticket's "not agent-side" scoping is wrong.<- {"action":"refresh"}then-> {"action":"ls",...}then<- {"action":"ls",...}with the new entry present means the frames are fine and the fault is in the view (a signal write from a JS callback not re-rendering).Unrelated bug found
On the desktop build (
dioxus-desktop, not wasm),attachreturns a no-opFilesHandlestub (files.rs:452):mkdir_prompt,upload_from_inputandnavigateall do nothing and no WebSocket is ever opened, so the file browser is inert.terminal.rsanddesktop.rshave the same shape, so it looks deliberate for the SSR build and merely inherited by desktop. Not touched here; happy to file it if it is not already known.