Skip to content

Manifest resolution: app region = release's firmware-<slug>.bin; prereleases need --allow-prerelease - #4

Merged
daniel-frenkel merged 1 commit into
mainfrom
feat/manifest-release-checks
Sep 26, 2026
Merged

daniel-frenkel merged 1 commit into
mainfrom
feat/manifest-release-checks

Conversation

@daniel-frenkel

Copy link
Copy Markdown
Member

Base: 615d01d0999e0c0faf9501a12dd1005268c53681 (origin/main, fetched immediately before the commit).

What the existing path already established

sync_variant fetches every file the manifest names from the same release, and check_variant_dir hashes each one against the manifest. So an app region naming firmware-<slug>.bin whose hash differs from that release's asset was already refused. test_app_hash_differing_from_the_releases_firmware_bin_is_refused pins that, and it stays green under sabotage A because the pre-existing check catches it.

It did not establish:

  • which file the app region names: a self-consistent set naming app-s3-128.bin passed while the release's OTA binary was something else;
  • whether the release was a prerelease (never recorded);
  • that bench mode writes a release at all (a local_build and a record-less cache both reached flash_pairs).

Change

  • sync: refuse unless the app region is firmware-<slug>.bin and the manifest's slug is the variant's. Refuse a prerelease without --allow-prerelease; a response missing the prerelease field counts as one.
  • record: .release.json {tag, prerelease, app_sha256} beside each synced set.
  • use time, on both write paths: refuse a set with no record, and a prerelease without the flag. Bench also refuses a local build, even with the flag.

Evidence

Predictions were frozen before the code (sha256 fb7a91c5165e5a90).

  • Sabotage A (app check removed): exactly 1 red, test_app_region_not_named_firmware_slug_is_refused.
  • Sabotage B (sync prerelease refusal removed): exactly 1 red, test_a_prerelease_is_refused_without_the_flag.
  • Sabotage C (bench use-time check removed): exactly 3 red, the no-record, cached-prerelease and local-build tests.
  • The one pre-registered outside-the-set case fired: test_a_baked_in_key_is_refused rebuilt its cache without a record, so the new check refused before the scan could. Fixed in the fixture, and the scan is still what that test exercises.
  • 49 tests green after restore.

Operational consequence (read before installing)

The installed copy pins release_tag to factory-manifest-scratch-2026-09-24, a prerelease. After this installs, bench mode refuses it unless --allow-prerelease is passed. That is the point: no tagged release carries factory assets yet (v14 predates valar-scopes #347).

🤖 Generated with Claude Code

…bin; prereleases need --allow-prerelease

- sync refuses a manifest whose app region is not firmware-<slug>.bin (the
  existing region hashes proved each file matched the manifest, but not WHICH
  file the app region named), and one whose slug is not the variant's.
- sync refuses a prerelease unless --allow-prerelease; a missing prerelease
  field counts as one.
- a .release.json record {tag, prerelease} is written with each synced set,
  and both write paths check it at USE time: bench refuses a prerelease cache
  without the flag, a cache with no record, and a local build even with it.

Sabotages (one per check, asserted applied, restored byte-exact):
A app check -> exactly 1 red; B sync prerelease -> 1; C bench use-time -> 3.
49 tests green.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@daniel-frenkel
daniel-frenkel merged commit a800a77 into main Sep 26, 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.

1 participant