Description
dfcad review is the one command a consumer cannot run the way this project ships itself.
The published image is scratch — there is no shell in it, which is right, and no git
either. review shells out to git, so against the image it fails before it reads anything:
$ podman run --rm -v $PWD:/model:ro \
ghcr.io/z5labs/dfcad@sha256:f3f36430d3dc212f9590ab1c5997a62ec5be233b1e8c454f1610ad37a5e3c01d \
review --root /model
dfcad review: git rev-parse --show-toplevel in /model: git is not on the path
exit 2, stdout 0 bytes
Measured 2026-08-11 against d9e9cab. Every other command in the pipeline works from the image
— check, measure, plan, tessellate, export and export-map all ran clean against a
read-only mount in the same session, byte-identically across two runs. review is the only
hole, and it is the command whose whole job is to report what changed in a revision, so a
consumer's model gate is exactly where it would be called.
The result is that a repository consuming dfcad as a container — which is what
docs/decisions/0019-the-registry-is-the-distribution-channel.md says the distribution channel
is — can gate on every rule the model states and cannot gate on whether a change needed an
explanation. The workaround available today is extracting the binary
out of the image and running it on a host that has git, which gives up the pinned, stamped,
attested artefact for the one command that needed it most.
This is a report about a boundary, not a request for a particular fix. Three shapes exist
and they are genuinely different decisions:
- Put
git in the image. Cheapest, and it stops the image being scratch — which is a real
cost, not a bookkeeping one, since the current image is the reason the attestations mean
something.
- Read the revision without shelling out, so
review needs no git on the path.
- Say plainly that
review is a host command, document it beside the others as such, and let
a consumer's gate stop expecting it. This is a legitimate answer and it is better than the
status quo, because right now the boundary is discovered by hitting it.
Consumer context: Zaba505/mi-casa records this in its own adoption and gate stories
(Zaba505/mi-casa#76, Zaba505/mi-casa#83), which currently plan around it by extracting the
binary. It was not one of the eleven issues filed as #206–#216 — it surfaced while verifying
those against the container rather than a local build.
Acceptance Criteria
Related Issues
Description
dfcad reviewis the one command a consumer cannot run the way this project ships itself.The published image is
scratch— there is no shell in it, which is right, and nogiteither.
reviewshells out to git, so against the image it fails before it reads anything:Measured 2026-08-11 against
d9e9cab. Every other command in the pipeline works from the image—
check,measure,plan,tessellate,exportandexport-mapall ran clean against aread-only mount in the same session, byte-identically across two runs.
reviewis the onlyhole, and it is the command whose whole job is to report what changed in a revision, so a
consumer's model gate is exactly where it would be called.
The result is that a repository consuming dfcad as a container — which is what
docs/decisions/0019-the-registry-is-the-distribution-channel.mdsays the distribution channelis — can gate on every rule the model states and cannot gate on whether a change needed an
explanation. The workaround available today is extracting the binary
out of the image and running it on a host that has git, which gives up the pinned, stamped,
attested artefact for the one command that needed it most.
This is a report about a boundary, not a request for a particular fix. Three shapes exist
and they are genuinely different decisions:
gitin the image. Cheapest, and it stops the image beingscratch— which is a realcost, not a bookkeeping one, since the current image is the reason the attestations mean
something.
reviewneeds nogiton the path.reviewis a host command, document it beside the others as such, and leta consumer's gate stop expecting it. This is a legitimate answer and it is better than the
status quo, because right now the boundary is discovered by hitting it.
Consumer context:
Zaba505/mi-casarecords this in its own adoption and gate stories(Zaba505/mi-casa#76, Zaba505/mi-casa#83), which currently plan around it by extracting the
binary. It was not one of the eleven issues filed as #206–#216 — it surfaced while verifying
those against the container rather than a local build.
Acceptance Criteria
decision names the cost it accepts
dfcad reviewruns against the published image, or the documentation states thatit does not and why — in the same place a reader learns what
reviewis for, not only ina decision record
reviewstays a host command,docs/publishing.mdsays which commands the imageis a complete answer for, so a consumer building a gate knows the boundary before it
writes one
git is not on the pathis a good diagnostic and theexit-2-with-empty-stdout behaviour is correct; whatever changes, a consumer still gets a
sentence rather than a silent empty result
Related Issues