Skip to content

fix(build): an unlabelled release image is adopted only from a pinned release - #1152

Merged
antoinetoussaint-byte merged 1 commit into
mainfrom
fix/unlabelled-release-adopted-only-from-a-pinned-release
Oct 25, 2026
Merged

antoinetoussaint-byte merged 1 commit into
mainfrom
fix/unlabelled-release-adopted-only-from-a-pinned-release

Conversation

@antoinetoussaint-byte

Copy link
Copy Markdown
Contributor

Why

Audit of #1148 (unreleased). A released tag whose image predates per-class build labels records only the aggregate input key, so its code can't be compared with this build's. #1148 adopted such an image from any source. That means an edited checkout whose version didn't move would ship the earlier release's image, with only a warning.

What

  • The image is adopted, with a warning, only when the service builds from a pinned release the CLI materialized (the git-clone or verified-package cache roots, which hold nothing but CLI output). That code is the release's by construction.
  • From a checkout or an override, it refuses and names the ways out: build from the pinned release, or release a new version.
  • A root configured through CODEFLY_MODULE_CACHE never counts as proof, since developers may keep their own checkouts there. This matches how pkg/composition already treats that root for ownership.
  • The cache roots move unchanged to a leaf package, pkg/modulecache, so pkg/orchestration can ask without importing pkg/composition (which imports it). pkg/composition delegates to it.

Classification: fix at the owner (the adoption verdict). Reused: the existing cache roots and their ownership rule. Nothing new decides ownership.

Effect on today's cells: renders of pinned modules from the module cache, which is how obin-blue and obin-staging render, keep adopting the unlabelled releases. Only a checkout render is refused.

Docs: docs/commands.md (the published-release verdict table).

Tests

  • TestAPublishedVersionLabelledBeforeClassesIsAdoptedFromAPinnedRelease and …IsRefusedFromACheckout cover both sides.
  • TestPublishedReleaseVerdictNamesTheClass and TestAPublishedReleaseIsJudgedByItsCode cover the checkout row.
  • pkg/modulecache TestOwnedIsOnlyTheCLIsOwnRoots.
  • go test ./pkg/orchestration ./pkg/composition ./pkg/modulecache passes.

🤖 Generated with Claude Code

… release

A released tag whose image predates per-class build labels records only the
aggregate input key, so its code cannot be compared with this build's.
#1148 adopted it anyway, from any source: an edited checkout whose version
did not move would be handed the earlier release's image, with a warning
and nothing compared.

It is now adopted only when the service builds from a pinned release the CLI
materialized — under the git-clone or verified-package cache roots, which
hold nothing but CLI output — because that code is the release's by
construction. From a checkout or an override it refuses, naming the two
ways out. A root configured through CODEFLY_MODULE_CACHE is never proof: a
developer may keep their own checkouts there.

The cache roots move to a leaf package, pkg/modulecache, so the builder can
ask without an import cycle; pkg/composition delegates to it unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@antoinetoussaint-byte
antoinetoussaint-byte added this pull request to the merge queue Oct 25, 2026
Merged via the queue into main with commit e98bc10 Oct 25, 2026
14 checks passed
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.

1 participant