2026-05-24

Weekly open source: fstool builds a filesystem matrix, univdreams goes cross-arch

Another wide week. A disk-image toolkit appeared on Monday and had a working filesystem matrix by Sunday, the universal decompiler grew three new architectures and a preemptive scheduler, the PHP VM swallowed most of the language it was still delegating, and the media framework picked up optical discs.

fstool: a filesystem toolkit in a week

fstool is new this week — created Monday, v0.0.2v0.4.1 by Sunday. It's a pure-Rust library plus CLI to "build, inspect, modify, and repack disk images and filesystem images": in the spirit of genext2fs, but covering whole disks, many filesystems, and round-tripping between formats from either a TOML spec or the command line.

The filesystem matrix it reached in seven days:

  • Read + write + in-place edits — ext2 / ext3 / ext4, FAT32, exFAT, XFS, HFS+/HFSX, NTFS, F2FS, GRF, qcow2.
  • Read + write (repack-only) — tar, SquashFS, ISO 9660, zip, cpio, ar.
  • Read — dmg (UDIF v4, including encrcdsa v2 encrypted with PBKDF2 unlock), with APFS in-place edits still whole-file-only.

Every writable filesystem implements one Filesystem trait, so the CLI (build, repack, add, rm) and the TOML spec dispatch through a single codepath — pick a target by setting --fs-type or type = "hfsplus". The journaling filesystems go further than "write the bytes": ext3/4 commit through real JBD2 transactions, XFS through XLOG, HFS+ and NTFS through their respective journals — so a crash mid-edit leaves an image the host's own fsck can replay.

The correctness bar is the real tools, not a self-check: ext2 output is byte-exact with genext2fs on the same input, and the writers pass xfs_repair -n, fsck.hfsplus, fsck.f2fs, and unsquashfs round-trips. By the end of the week it had also grown a FUSE adapter (mount any backend as a userspace filesystem), layered repack with OCI-style .wh.* whiteouts, and a lib-level fuzz harness with a crash-injection block device. The Ragnarok Online GRF archive (permutation cipher, CP949 filenames) is in there too — the one format that's pure personal itch.

univdreams: BPF, Solana, WASM, and a scheduler

univdreams — the universal decompiler/compiler that split out of oxideav-vfw last week — spent W21 going wide on architectures and deep on the emulator.

New decompile targets:

  • BPF / eBPF + Solana SBF — a Linux eBPF + Solana SBF decoder with byte-identical round-trip, then a full lift stack: syscall name resolution via .rel.dyn, function discovery, stack-slot naming, branch labels, structural if-then-else / while recovery, argument and return-type inference, .rodata string resolution. ud solana <program-id> fetches a deployed Solana program off chain and decompiles it, with per-handler region banners.
  • WASM — container round-trip, per-function disassembly of the Code section, CLI auto-detect.
  • An arch-agnostic SSA core and an arch-codec trait spine, so x86 and BPF lift through the same registry instead of per-architecture forks.

It also grew a browser playground (wasm-bindgen) with Upload / URL / Solana-chain tabs and a Helius RPC override. And the emulator picked up a real preemptive scheduler over six phases: ThreadState + TLS slots, async CreateThread with real context switches, Event / Mutex / Semaphore + WaitForSingleObject, critical sections, quantum-based preemption with thread priority, a process table with real CreateProcessA, and child-PE load + execute. On the codec side, v0.1.40.1.5 reached 12/12 codecs round-tripping, with MagicYUV and HuffYUV pixel-exact (SSE2 XMM, AVX/YMM, Indeo 3 decode).

goro: lowering PHP into the VM

The W20 work was VM correctness against PHP's edge cases. W21 was about coverage — moving construct after construct out of AST-delegation and into dedicated native opcodes, so the VM stops falling back to the tree-walker.

Lowered natively this week: match(), switch(), enum declarations, foreach over non-by-ref targets, try/finally (with per-handler pending control + chain-on-escape, fixing PHP bug65784), nullsafe property / method / dyn-var reads ($obj?->…), variable-variables ($$name / ${expr}), static property writes (Foo::$bar = v), extended clone(), reference creation (&$expr), list destructuring, isset() / empty() and unset() on simple containers, and static-method calls. Plus a recursion-detection fix in mb_convert_variables for cyclic arrays.

OxideAV: optical discs and container depth

W19 filled the codec matrix; W20 was incremental; W21 grew the container and disc layers.

Optical discsoxideav-dvd is new: a read-only DVD-Video reader, clean-room per ECMA-267/268 and OSTA UDF 1.02 — ISO 9660 + UDF mount, VIDEO_TS walk, IFO parser (VMGI/VTSI, program-chain tables, palette LUT), VOB demuxer over MPEG-PS with the nav-pack substream router, and a convert_dvd_to_mkv mux pipeline. The Blu-ray read-side sibling continues alongside (BDMV walk, CPI EP_map seek), still working toward a disc I can actually test against.

Containers got deep box/atom coverage: mov (QuickTime/ISO-BMFF boxes through round 125), mp4 (sample groups, edit lists, subtitle/timed-text tracks), mkv (RFC 9559 ContentEncodings, header-stripping, CRC-32 validation, fuzz target), and avi (OpenDML super-index, per-stream LANGID, SMPTE timecode).

Framework plumbingscribe (font rasterizer/shaper) wired GSUB substitution lookups + ccmp / calt into shape_text; generator added synth modes (DTMF, ADSR envelope, ring modulation, chirp/FM, video zoneplate); source gained concat://, data: (RFC 2397), and mem:// drivers with a file-scope allow-list; and pipeline got a memory-bounded packet queue with per-track channel budgets.

ClawdWallet: the real-device path

Last week's "next week" was getting ClawdWallet's pairing flow onto a real device. That's where the work went.

TibaneApp moved from build 51 to 55 (libwallet 0.4.380.4.44): per-wallet transaction-history scoping, naming a wallet on creation, token logos on the dashboard, split tokens/activity tabs, pull-to-refresh on screens that read drifting on-chain state, copyable address in the wallet sheet, and a 2FA recovery path for a missing device share on unlock.

clawdwallet reworked its threshold-signing core: eddsatss replaced with FROST(Ed25519) plus DKLs23(secp256k1), share-schema round-trip tests, and coverage CI.

libwallet v0.4.33v0.4.44 carried the supporting work: a stretch of iOS/Dart framework fixes (stop initialising the Go runtime twice under static_framework, expose bridge symbols for dlsym), the swap aggregator switched to the OKX DEX API V6, Solana tx-history backfill, and documented cross-device-import recovery.

Also this week

  • chiefstaker — a Solana staking/rewards program took an audit pass: harden pool init against PDA pre-funding griefing, freeze coins during the unstake cooldown, always close the account and pay all owed SOL on full unstake, exact member_count via a required metadata PDA.
  • origami — the RNA arc continued: CHARMM27 nucleic-acid atom typing + force-field parameters, a NeRF base-ring + hydrogen builder, a monomer-aware RNA topology graph, and build → minimize → dynamics now running end-to-end on RNA chains. Proteins are the output side; nucleic acids are the side that does the building.
  • vpnetd-sgx — the VP.NET SGX enclave got its build + release CI (enclave binaries published on version tags).

Next week

fstool heads toward v0.5 and a stable public API; univdreams keeps pushing the cross-architecture lift and the Win32 scheduler; the DVD reader moves from demux toward playback; goro's VM keeps flipping native lowering on until the default can switch.