Skip to content

Cache-key hardening (full key + base image in key)#142

Draft
markovejnovic wants to merge 2 commits into
mainfrom
feat/cache-key-hardening
Draft

Cache-key hardening (full key + base image in key)#142
markovejnovic wants to merge 2 commits into
mainfrom
feat/cache-key-hardening

Conversation

@markovejnovic

Copy link
Copy Markdown
Contributor

Cache-key hardening

Two correctness/robustness fixes to the content-addressed layer cache key, in support of the cloud cross-build cache (harmont-dev/simci#91). No user-facing changes.

1. hm-exec: use the full cache key in the docker tag

stable_cache_tag truncated the cache key to 16 hex chars (64 bits) when building the local Docker image tag. 64 bits is collision-feasible; the full SHA-256 is now used. (One-time effect: existing local hm run Docker-tag caches cold-rebuild once.)

2. keygen: include the base image in the layer cache key

A layer's output depends on the base image it ran on, but the image was not part of the cache key — so the same command on two different base images would collide on one cache entry (a real correctness bug). The image is now folded into the key pre-image, in both the Python and TypeScript DSLs with byte-identical layout (… step_key NUL image NUL parent_resolved NUL policy_resolution). All formula/golden tests were recomputed to include the image slot. (One-time effect: cache keys change once, invalidating prior cached layers.)

Tests

  • Python: 483 passed (ruff check + format clean).
  • TypeScript: 378 passed (tsc --noEmit clean).

Fold the step's `image` field into the outer SHA-256 pre-image so that
the same command run on two different base images no longer collides on
one cache entry.  Image is inserted right after step_key, before
parent_resolved_key, using the same NUL-delimited layout in both the
Python and TypeScript implementations (byte-identical output for
identical input).

Pre-image layout (v0.1):
  pipeline_org NUL pipeline_slug NUL step_key NUL image NUL
  parent_resolved_key NUL policy_resolution

This is a deliberate one-time cache invalidation: old snapshots keyed
under the previous format will not be reachable after this change.
@markovejnovic markovejnovic marked this pull request as draft June 12, 2026 00:16
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