Fail-closed whole-disk image deployment for Linux
Diskforge verifies a raw or Zstandard-compressed disk image, evaluates the current Linux host against an explicit safety policy, binds operator consent to the observed target and image identities, and writes the verified bytes to a whole block device. It is available as a reusable Go package and a JSON-first CLI.
Caution
A successful diskforge write irreversibly replaces data on the selected
block device. Read the safety model, inspect the JSON
decision, and keep independent recovery media before using it.
- Fail closed: missing or ambiguous Linux state rejects the operation.
- Consent bound to evidence: the confirmation token covers the canonical path, serial, WWN, capacity, image size, and complete SHA-256 digest.
- Descriptor-held source: the verified file descriptor, not a reopened pathname, supplies the bytes written to disk.
- Bounded streaming: raw and Zstandard sources have exact expanded-size enforcement; short and surplus streams fail.
- Two explicit policies: rescue mode requires an unused whole disk; live mode adds root-disk, tmpfs, memory, SysRq, read-only remount, and reboot gates.
- Automation contract: stable JSON, typed gate codes, distinct exit codes, and monotonic progress on stderr.
- Container-only engineering: formatting, analysis, tests, and builds run in the pinned OCI development image through Podman.
flowchart LR
I[Inspect Linux state] --> V[Verify complete source]
V --> C[Validate bound confirmation]
C --> R[Recheck target identity]
R --> O[Open whole block device]
O --> W[Write exact expanded bytes]
W --> F[Sync and flush]
F --> D[Return verified result]
The target is not opened writable until inspection, full source verification, confirmation, and applicable live-mode preparation have succeeded. Immediately after opening, Diskforge compares the descriptor device number and current sysfs identity with the confirmed snapshot.
Download a Linux AMD64 archive from
GitHub Releases, verify its
checksum, and place diskforge on the executable path. Release artifacts are
static binaries. See release verification for checksum,
signature, SBOM, and provenance verification.
Every command writes its result as JSON to stdout. Progress and structured errors go to stderr.
diskforge inspect \
--mode rescue \
--target /dev/vdb \
--image /run/diskforge/oracle-linux.raw.zst \
--sha256 0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef \
--expected-bytes 34359738368Review the returned target identity and copy its confirmation_token exactly:
diskforge write \
--mode rescue \
--target /dev/vdb \
--image /run/diskforge/oracle-linux.raw.zst \
--sha256 0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef \
--expected-bytes 34359738368 \
--confirmation 'confirm-v1-vdb-0123456789ab-0123456789abcdef'Use --dry-run with write to repeat inspection and complete source
verification without opening the target. The full command and exit-code
contract is in the CLI reference.
engine, err := diskforge.New()
if err != nil {
return err
}
inspection, err := engine.Inspect(ctx, diskforge.InspectRequest{
Mode: diskforge.ModeRescue,
TargetPath: "/dev/vdb",
ImagePath: "/run/diskforge/oracle-linux.raw.zst",
SHA256: digest,
ExpectedBytes: expandedBytes,
})
if err != nil {
return err
}The package exposes stable request, result, progress, and gate-error types.
Callers can use errors.As with *diskforge.GateError and must not parse human
messages. See the API documentation
and architecture.
Development requires Podman and the Compose provider. Host Go installations are not part of the supported workflow.
/opt/podman/bin/podman build --pull=never \
--tag localhost/ioplane/diskforge-dev:1.26.5 \
--file deployments/containers/development.Containerfile .
/opt/podman/bin/podman compose run --rm test
/opt/podman/bin/podman compose run --rm lint
/opt/podman/bin/podman compose run --rm integrationrelease-snapshot writes generated verification artifacts only below the
ignored .artifacts/release tree.
The integration service is privileged but can write only to the temporary loop-backed file it creates. Run services sequentially on memory-constrained Podman machines. See development for every verification gate.
| Document | Purpose |
|---|---|
| Architecture | Components, trust boundaries, and data flow |
| Safety model | Refusal rules and destructive guarantees |
| CLI reference | Commands, JSON streams, and exit codes |
| Naming contract | Mandatory public and artifact naming rules |
| Development | Container-only contributor workflow |
| Release | SemVer automation and artifact verification |
| API validation | Upstream API and ownership evidence |
Diskforge is pre-1.0. Safety refusals may become stricter in minor releases. Public Go types, JSON fields, gate codes, and CLI exit codes follow Semantic Versioning; incompatible changes are documented before release.
Read CONTRIBUTING.md before proposing changes. Security reports follow SECURITY.md; general help follows SUPPORT.md. Community participation is governed by the Code of Conduct.
Licensed under the Apache License 2.0. See NOTICE.