[PR #921] [MERGED] fix(artifacts): accept APFS image disks ejected with their container #2347

Closed
opened 2026-10-16 21:17:37 +00:00 by bsakaguchi · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/morluto/rea/pull/921
Author: @kaoru0822-kitauji
Created: 10/7/2026
Status: ✅ Merged
Merged: 10/7/2026
Merged by: @kaoru0822-kitauji

Base: main ← Head: fix/dmg-apfs-detach


📝 Commits (2)

  • b72c079 fix(artifacts): accept APFS image disks ejected with their container
  • 62634e4 fix(artifacts): keep the post-snapshot detach check out of provenance

📊 Changes

2 files changed (+123 additions, -1 deletions)

View changed files

📝 src/artifacts/NativeDmgArtifactReader.ts (+32 -1)
📝 tests/boundary/providers/native/nativeDmgArtifactReader.test.ts (+91 -0)

📄 Description

Summary

inspect_artifact failed on every APFS disk image with DMG detach or mount-root cleanup failed (artifact_operation_failed, reason unavailable). APFS is what hdiutil create produces by default on current macOS, so this affects most freshly made DMGs.

Problem and expected behavior

hdiutil attach reports an APFS image as two whole disks: the image disk and a synthesized APFS container.

/dev/disk4    GUID_partition_scheme
/dev/disk4s1  Apple_APFS
/dev/disk5s1  (mounted volume)
/dev/disk5    (synthesized container)

NativeDmgArtifactReader.close() detaches observed whole disks in reverse order. Detaching disk5 also ejects disk4, so the next hdiutil detach /dev/disk4 fails with No such file or directory. The inventory was fine, but the detach failure turned the whole operation into an error.

Reproduction on macOS 26.6.2 (arm64), with an APFS DMG from hdiutil create -srcfolder dir -format UDZO:

  • main: rea inspect-artifact image.dmg --json returns "detail": "DMG detach or mount-root cleanup failed".
  • This branch: a complete inventory, and hdiutil info lists nothing left attached.

Change and scope

When a detach fails, close() asks hdiutil info -plist whether that device is still attached.

  • A device that is no longer listed has already been detached with its image.
  • A device that is still listed, or whose state cannot be read, remains a cleanup failure, as before.

The query goes through the existing NativeDmgHost seam, and the info command is recorded in provenance with a read effect. Detach order and the whole-disk filtering are unchanged.

Contract and boundary impact

  • CLI and MCP/tool-catalog contract: none.
  • Process execution and cleanup: one extra read-only hdiutil info -plist, run only after a failed detach. Cleanup failures are still reported when a device remains attached.
  • Generated metadata: none.

Evidence and regression coverage

tests/boundary/providers/native/nativeDmgArtifactReader.test.ts has two new cases. Both model the real APFS attach output:

  • Detaching the container ejects the image disk. close() succeeds and records info. This fails on main.
  • The device that rejected detach is still attached. close() still fails.

The existing attach-cleanup failure test now answers info with the device still attached.

Validation performed

  • npm run test:focused -- tests/boundary/providers/native/nativeDmgArtifactReader.test.ts: 5 passed.
  • Real APFS DMG through the built CLI (rea inspect-artifact): complete inventory, no image left attached.
  • npm run check:changed: passed.

Compatibility, safety, and release

  • Breaking changes: none.
  • Real Hopper/Ghidra coverage: not applicable.
  • Real OS coverage: macOS 26.6.2 arm64.

🤖 Generated with Claude Code


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/morluto/rea/pull/921 **Author:** [@kaoru0822-kitauji](https://github.com/kaoru0822-kitauji) **Created:** 10/7/2026 **Status:** ✅ Merged **Merged:** 10/7/2026 **Merged by:** [@kaoru0822-kitauji](https://github.com/kaoru0822-kitauji) **Base:** `main` ← **Head:** `fix/dmg-apfs-detach` --- ### 📝 Commits (2) - [`b72c079`](https://github.com/morluto/rea/commit/b72c079a9a90c374bd6dd30ff8c4387306b8f59b) fix(artifacts): accept APFS image disks ejected with their container - [`62634e4`](https://github.com/morluto/rea/commit/62634e4c0177bde8a08decc356da98fbe25d2000) fix(artifacts): keep the post-snapshot detach check out of provenance ### 📊 Changes **2 files changed** (+123 additions, -1 deletions) <details> <summary>View changed files</summary> 📝 `src/artifacts/NativeDmgArtifactReader.ts` (+32 -1) 📝 `tests/boundary/providers/native/nativeDmgArtifactReader.test.ts` (+91 -0) </details> ### 📄 Description ## Summary `inspect_artifact` failed on every APFS disk image with `DMG detach or mount-root cleanup failed` (`artifact_operation_failed`, reason `unavailable`). APFS is what `hdiutil create` produces by default on current macOS, so this affects most freshly made DMGs. ## Problem and expected behavior `hdiutil attach` reports an APFS image as two whole disks: the image disk and a synthesized APFS container. ``` /dev/disk4 GUID_partition_scheme /dev/disk4s1 Apple_APFS /dev/disk5s1 (mounted volume) /dev/disk5 (synthesized container) ``` `NativeDmgArtifactReader.close()` detaches observed whole disks in reverse order. Detaching `disk5` also ejects `disk4`, so the next `hdiutil detach /dev/disk4` fails with `No such file or directory`. The inventory was fine, but the detach failure turned the whole operation into an error. Reproduction on macOS 26.6.2 (arm64), with an APFS DMG from `hdiutil create -srcfolder dir -format UDZO`: - `main`: `rea inspect-artifact image.dmg --json` returns `"detail": "DMG detach or mount-root cleanup failed"`. - This branch: a complete inventory, and `hdiutil info` lists nothing left attached. ## Change and scope When a detach fails, `close()` asks `hdiutil info -plist` whether that device is still attached. - A device that is no longer listed has already been detached with its image. - A device that is still listed, or whose state cannot be read, remains a cleanup failure, as before. The query goes through the existing `NativeDmgHost` seam, and the `info` command is recorded in provenance with a `read` effect. Detach order and the whole-disk filtering are unchanged. ## Contract and boundary impact - CLI and MCP/tool-catalog contract: none. - Process execution and cleanup: one extra read-only `hdiutil info -plist`, run only after a failed detach. Cleanup failures are still reported when a device remains attached. - Generated metadata: none. ## Evidence and regression coverage `tests/boundary/providers/native/nativeDmgArtifactReader.test.ts` has two new cases. Both model the real APFS attach output: - Detaching the container ejects the image disk. `close()` succeeds and records `info`. This fails on `main`. - The device that rejected detach is still attached. `close()` still fails. The existing attach-cleanup failure test now answers `info` with the device still attached. ## Validation performed - `npm run test:focused -- tests/boundary/providers/native/nativeDmgArtifactReader.test.ts`: 5 passed. - Real APFS DMG through the built CLI (`rea inspect-artifact`): complete inventory, no image left attached. - `npm run check:changed`: passed. ## Compatibility, safety, and release - Breaking changes: none. - Real Hopper/Ghidra coverage: not applicable. - Real OS coverage: macOS 26.6.2 arm64. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
bsakaguchi 2026-10-16 21:17:37 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
morluto/rea#2347
No description provided.