Skip to content

Pick an entry's handle in one place, so HFS+ folders can be opened, searched and tagged - #181

Merged
switch-nz merged 1 commit into
mainfrom
claude/hfsplus-node-handles
Oct 2, 2026
Merged

switch-nz merged 1 commit into
mainfrom
claude/hfsplus-node-handles

Conversation

@switch-nz

Copy link
Copy Markdown
Owner

Found while starting the cross-check harness: its walker could not descend into HFS+ folders, and the cause was a rule copied around the code base.

What changes for examiners

Each filesystem reader names its entries by its own key: MFT record (NTFS), inode (ext), object ID (APFS, logical evidence), first cluster (FAT/exFAT), and catalog node ID cnid (HFS+). About twenty places chose among those keys, and nearly all of them left cnid out. On an HFS+ volume that meant:

  • Expanding a folder in the tree listed the volume's top level again (and again inside that). Checked in a browser on a synthetic volume: Top expanded to Top, root.txt on main; it now expands to Inner, a.txt.
  • Search, file-type checks, hashing, indexing, triage and the timeline never went below the top folder, with nothing said.
  • An HFS+ file had no key to tag or hash it under (it was stored as the text "None").
  • Exporting tagged items could not have worked for HFS+: the export route rebuilt an entry from the bare key, and an HFS+ entry needs its catalog record (extents) to be read.

The change

  • New engine/nodes.py with node_of / node_key; the Python copies (filesearch, hashing, artifacts, recyclebin, filetype, textindex, casedb ×2, server ×4, timeline) now call it. The hit dicts built by search and the store entries built by the mail sweep carry cnid too.
  • web/app.js: one nodeValue() replaces ten copies.
  • HfsPlus.entry_by_node() looks an entry up again from its key, and _entry_from_body uses it, so a tagged HFS+ file exports its content, not an empty file.
  • tests/test_nodes.py (12 tests): the rule, HFS+ walking and keying through the real walker, lookup by key, the server's rebuild, and a source check that fails if a copy of the chain is written out again (Python or JS) or the two key lists drift apart. 7 of its tests fail on the old code.

Verification

  • Full suite 1375 tests OK (14 skipped), smoke passes.
  • Browser before/after as above.
  • Nothing about an HFS+ volume's own on-disk layout changed; this is about how entries are referred to.

Does not fix the empty root listing seen on one real volume (that is a different problem, being chased separately).

🤖 Generated with Claude Code

https://claude.ai/code/session_017DPjyZZHvaivtvJ3N4hZhz


Generated by Claude Code

…earched and tagged

HFS+ names its entries by catalog node ID (cnid); about twenty copies of the
rule looked only for the other readers' keys. Expanding an HFS+ folder listed
the volume root again, and search, hashing, indexing and tagging never went
below the top folder. One helper (engine/nodes.py) replaces the copies in the
engine and web/app.js; a test fails if one is written out again. HfsPlus can
look an entry up by handle, so a tagged file can be exported.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017DPjyZZHvaivtvJ3N4hZhz
@switch-nz
switch-nz merged commit 5557398 into main Oct 2, 2026
32 checks passed
@switch-nz
switch-nz deleted the claude/hfsplus-node-handles branch October 2, 2026 20:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants