Repository navigation
Materialize a compiler generation's artifact axis from the path cargo named - #8172
gunbai-bot[bot] wants to merge 2 commits into
Conversation
… named #8158 landed the decode: which executable cargo REPORTED for a target, read from its --message-format=json stream rather than assembled from target dir, profile and binary name. #8153 landed the carrier: ArtifactIdentity whose materialized arm holds a sole_constructor ObservedArtifactDigest over a validated Sha512Digest, so an artifact identity cannot be authored without an observation. This joins them. The chain is build -> the path cargo named -> a digest of THAT path -> ArtifactIdentity, and its load-bearing property is that one path VALUE flows through the digest and out to any later invocation. A convention-derived path breaks that at both ends simultaneously — digesting one file while executing another, each operation individually honest and the composition silently wrong — and it also makes the artifact axis a function of the build-configuration axis, collapsing two of the six axes #8153 exists to keep independent. DECOMPOSED SO THE DECISIONS ARE WITNESSED PER PR. Every decision sits in one of two pure folds — select_artifact_path decides what the build reported, materialization_from_digest decides what the observation means — with only a thin wet composition needed between them. One wet function carrying the decisions would put every refusal arm behind a cadence that does not run per PR, which is how a decision nobody executes reads as a decision that holds. Arms kept separate on purpose: a build that exited nonzero never reaches the stream decode at all, because "the candidate did not build" and "the candidate built but we cannot say what it produced" have different remedies and a later behavioural comparison must not read one as the other. No arm yields ArtifactMaterialized without a digest in hand; every failure projects ArtifactNotMaterialized, which promotion admission already refuses by name rather than treating as equivalent. 10 witnesses green by execution, compile-clean on both frontends. Mutation-probed: collapsing the build-failure arm reds exactly the three build claims, and making a path refusal fall back to a conventional path — the precise defect this lane exists to prevent — reds exactly the two claims that guard it. One receipt worth keeping: the fixture digest was hand-typed at first and was 130 hex characters instead of 128. The refinement rejected it, the observation became a refusal, and three positive claims went red rather than a malformed digest flowing into the carrier. The fixture is now a real sha512, reproducible with printf and sha512sum. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Closing as superseded rather than rebasing — this PR's content is already on main and re-merging it would revert working code. Why. #8176 was branched from this branch, so it carried these commits, and it merged first ( Why a rebase would have been wrong, not merely redundant. Diffing main against this branch shows main is ahead: the branch state would remove Nothing is lost: the ten hermetic folds and the module are on main, verified executing in CI on #8176's run (per-row receipts, — sent from sharp-hawk-59 |
Joins the two halves that landed separately:
--message-format=jsonrather than assembled from target dir + profile + binary name.ArtifactIdentitywhose materialized arm holds asole_constructorObservedArtifactDigestover a validatedSha512Digest, so an artifact identity cannot be authored without an observation.This is the join. The chain is build → the path cargo named → a digest of that path →
ArtifactIdentity.Why the path has to come from cargo
The load-bearing property is that one path value flows through the digest and out to any later invocation.
service cargo.Buildreports onlysuccess/stdout/stderr— never the artifact path — so without the decode a consumer must predict the path, and a stale binary at the predicted location satisfies that observation completely.That failure is bad in a specific way: it breaks both ends at once, digesting one file while executing another, with each operation individually honest and the composition silently wrong. It also makes the artifact axis a function of the build-configuration axis, collapsing two of the six axes #8153 exists to keep independent — so a per-axis invalidation control could no longer discriminate them.
Decomposition
Every decision sits in one of two pure folds:
select_artifact_path— what the build reportedmaterialization_from_digest— what the observation meanswith only a thin wet composition needed between them. This is deliberate: one wet function carrying the decisions would put every refusal arm behind a cadence that doesn't run per-PR, which is how a decision nobody executes reads as a decision that holds. As written, all ten claims run on ordinary discovery.
Arms kept separate on purpose. A build that exited nonzero never reaches the stream decode — "the candidate did not build" and "the candidate built but we cannot say what it produced" have different remedies, and a later behavioural comparison must not read one as the other. No arm yields
ArtifactMaterializedwithout a digest in hand; every failure projectsArtifactNotMaterialized, which promotion admission already refuses by name rather than treating as equivalent.Evidence
10 witnesses green by execution; compile-clean on both frontends (
claim_batchandgunbc compileare different frontends, and some rules live only on the second).Mutation-probed rather than asserted:
The second is the defect this lane exists to prevent, planted deliberately.
One receipt worth keeping: the fixture digest was hand-typed at first and was 130 hex characters instead of 128. The refinement rejected it, the observation became a refusal, and three positive claims went red — rather than a malformed digest flowing into the carrier. That's the construction wall working, exercised by the witness that depends on it. The fixture is now a real sha512, reproducible with
printf … | sha512sum.Scope, stated so the split isn't mistaken for completeness
This lands the materialization vertical and its decision logic. Not in this PR:
cargo.Buildoperation carrying--message-format=json(an extdeps interface addition) and the wet execution witness that drives build → digest → run end-to-end. Those are execution-kind with a real resource profile, so they need an exact row ingunbc.explicit_witness_admissionnaming the cadence that runs them — not a directory, and not per-PR discovery.tools.host_preludewitness_bin_pathand the three transports built on it). That's one shared authority, and it touches the live bin-witness execution path, so it deserves its own PR.Lane: SH-C (bootstrap artifact materialization).
🤖 Generated with Claude Code