Linux implementation and macOS parity

Linux uses the same FileSystem, Entry, capability interfaces, and technique layer as macOS. The Linux backend reads ext4 metadata. The macOS backend reads APFS metadata.

Native operations use each platform’s file APIs. Explicit slack reads run the image parser on a verified device.

Implemented changes

Area Linux behavior
Xattr capacity New attributes keep existing inode-body values. An external fallback or a rejection leaves unrelated values intact
Directory images Linear and validated HTree directories, including index nodes and 64 KiB record-length decoding
Recursive scans Unsupported slack layouts and children are skipped, and child warnings go to stderr. Permission, I/O, and corruption errors stay fatal
Live timestamps Access and modify writes keep the other field atomically. Reads cover ctime and optional statx birth time
Live slack Explicit detection and extraction use verified, read-only backing-device access. Mounted writes are refused
Backups Opened-file identity, ext4 UUID, and a per-hide nonce guard against cross-image and stale-frame restores
CLI capabilities nemo features --mode live explains partial, read-only, and unavailable capabilities on the host
Acceptance Image and native extraction, preserved sources, permission denial, and skipped-child scans are checked

HTree checks

HTree traversal validates the root and index records, counts, limits, referenced blocks, hash order, and duplicate names. Integration fixtures use mke2fs, debugfs, and e2fsck -D to build real indexed 1 KiB and 4 KiB ext4 directories with 700 files.

Raw slack discovery

Linux checks the opened target’s mount ID and device number against mountinfo. It handles bind roots and escaped paths. It also verifies the opened device’s major and minor numbers, and the raw inode must match the mounted target.

These reads can see stale or changing mounted data. They are not a snapshot.

Validation

Run the regular checks and a native ext4 acceptance pass:

go test ./...
go vet ./...
python3 scripts/linux-acceptance.py --work-parent <ext4-directory> --require-live

The native pass creates disposable files and an ext4 image in the directory you give it. It checks:

The Linux CI workflow requires native coverage instead of letting it skip silently. Pure and injected fixtures test mount parsing, read-only wrapping, descriptor identity, and cleanup without touching a host raw device.

Windows amd64 and macOS amd64/arm64 builds are also checked. Cross-building does not run native Windows or macOS operations.

The final integrated version passed all of these checks on 2026-10-12. That run included native ext4 permission-denial and symlink/FIFO traversal checks, 10 independently verified custody records, and builds for Linux amd64, Windows amd64, and macOS amd64/arm64. The backup replacement and repeated-hide reproductions now fail before changing image bytes. Regression tests cover legacy frame reads.

Remaining boundaries