Skip to content

Stamp each object with a hash of its own content - #149

Merged
ps-pufferfish merged 2 commits into
mainfrom
manifest-id
Sep 28, 2026
Merged

ps-pufferfish merged 2 commits into
mainfrom
manifest-id

Conversation

@ps-pufferfish

@ps-pufferfish ps-pufferfish commented Sep 24, 2026 •

Copy link
Copy Markdown
Contributor

Replaces the noa.re/deploy-id annotation with noa.re/manifest-id, a hash of the object's own generated content.

The deploy-id hashed the builder version and config commit. So the same objects generated by two builder versions differed in every changed file and couldn't be compared byte for byte. Unchanged files also had to be found and restored with a text mask. A manifest-id depends only on content, so the output doesn't depend on which builder version wrote it, an unchanged object is written back identically, and the restore code goes away.

  • GenerationResult.manifest_ids gives the expected id of each created or modified object. relcoord needs this to wait on each object; its change is a follow-up draft PR.
  • deploy_id is removed from GenerationResult. It was only a hash of manifest_ids and the removals, which callers already have. relcoord, its only caller, stops using it in the release that takes this.
  • The first generation after release rewrites every manifest, swapping the deploy-id for a manifest-id. The change is to top-level metadata only, so no pods restart.

Validation: all 311 tests pass, as do ruff check, ruff format --check and ty check. I also generated the system repo's platform-dev target into a copy of manifests, with this branch and with main:

  • Apart from the id annotations, the output is identical.
  • All 248 files are stamped with distinct ids.
  • Regenerating on top of the committed output changes nothing.

The deploy-id hashed the builder version and config commit, so the same
objects generated by two builder versions differed in every changed file and
could not be compared byte for byte. It also meant unchanged files had to be
detected and restored with a text mask.

A manifest-id depends only on the object's generated content, so it is the
same whichever builder writes it, and an unchanged object is written back
byte-identical. It is also a truer thing for a caller to wait on: a live object
carrying it holds that content.

The first generation with this rewrites every manifest, swapping the deploy-id
for a manifest-id. Callers get the expected id of each changed object from
GenerationResult.manifest_ids; deploy_id remains as one id for the change.
It was only a hash of manifest_ids and removed, which callers already have. relcoord, the only caller, stops using it in the same release.
@ps-pufferfish
ps-pufferfish merged commit 1ab7a56 into main Sep 28, 2026
1 check 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.

2 participants