Skip to content

package: TRUST_STORE=1 on UCI products; releases refuse the test bundle key (#155 phase 2, L3) - #269

Merged
JC-000 merged 3 commits into
masterfrom
feat/p2-l3-package
Oct 6, 2026
Merged

JC-000 merged 3 commits into
masterfrom
feat/p2-l3-package

Conversation

@JC-000

@JC-000 JC-000 commented Oct 1, 2026 •

Copy link
Copy Markdown
Owner

#155 phase 2, L3 part 2. Stacked on the trust-policy PR (base feat/p2-l3-policy).

Merge order: #268 → #269 (base stays feat/p2-l3-policy until #268 merges).

  • Packaging (DECISIONS 11, Q1). uci-onchip and uci-comb now build with TRUST_STORE=1. The signed bundle stays out of packages until a production key exists.
  • Release guard (DECISIONS 10, from adv-l4). build_prgs.sh builds every product with TRUST_RELEASE=1, via variant_make_args in _common.sh.
    • It records that in build-info, so verify_release.py rebuilds identically.
    • With TRUST_BUNDLE=1, the TEST-ONLY key is refused three ways:
      1. a parse-time $(error) on its 64 key bytes;
      2. an .assert in trust_bundle.s on the flag;
      3. (adv-269) a link-time check, tools/check_release_key.py. It derives the test key from its PEM, so no .inc is parsed, and searches the whole PRG for it, the comb cold image included. On a hit it deletes the PRG.
    • Before (3), an .inc that spelled byte 0 in decimal and claimed IS_TEST_ONLY = 0 linked a release carrying the test key. It is now refused, and a non-test key still builds.
    • Without the bundle, TRUST_RELEASE adds no flag and changes no byte.
  • adv-269 also:
    • make -n on a fresh tree no longer fails on build/https_host.inc.
    • tools/trust_bundle.py documents the production-key path.
    • make package-verify gives the VICE boot 600 s (it was 240 s, which failed 2 of 3 runs on a loaded host), and a failed boot check prints the budget it used.

Red-green

tools/test_trust_release_guard.py uses make -n plus direct ca65 and link checks: no VICE. Result: 24/24.

Red, by removing each layer in turn:

layer removed result
Makefile byte guard red
source assert red
TRUST_RELEASE=1 in variant_make_args red
the link-time check_release_key.py recipe line red

Controls that must still pass:

  • a dev build with the test key;
  • a release with a throwaway non-test key;
  • TRUST_RELEASE=2 refused.

Products

These are the "ship" rows of #268's margins table, from tools/measure_margins.py on master c26e268 + #268 + this branch (8fdebe7):

product PRG LOADER NET OVERLAY HOT (free B)
uci-onchip TS rel da4d607e 588 184 333 166
uci-comb TS rel e6750100 78 38 47 1,237

ip65-onchip (78a10748) is unchanged.

Restack only

This branch was only restacked onto #268 011209b. git range-diff 04af8b9..e0b118d 011209b..8fdebe7, where e0b118d is the version adv-269 cleared, shows all three commits as = (identical patches):

cleared now commit
da127f4 21570f2 package
6ada951 b35dd07 release guard
e0b118d 8fdebe7 package-verify

On 8fdebe7: test_trust_release_guard 24/24, test_build_flags_stamp 17/17.

Hardware

The products are #268's hardware rows: local comb TS PASS 28/28 and onchip TS PASS 28/28 on U64E fw 3.15 3a1ff9ff, FPGA 126, core 1.50. Those rig builds add only TRUST_STORE_DIR / HTTPS_PORT. The shipped TRUST_RELEASE=1 images are da4d607e / e6750100.

🤖 Generated with Claude Code

JC-000 and others added 3 commits October 6, 2026 12:39
…t bundle key

DECISIONS 11 (Q1): uci-onchip and uci-comb ship with the trust store; the
signed bundle stays out of packages until a production key exists.

DECISIONS 10 (adv-l4): build_prgs.sh builds every product with
TRUST_RELEASE=1 (variant_make_args in _common.sh, recorded in build-info
so verify_release.py rebuilds the same way). With TRUST_BUNDLE=1 that
refuses the TEST-ONLY key twice: a parse-time $(error) on its 64 key
bytes (a hand-relabelled IS_TEST_ONLY = 0 does not get through) and an
.assert in trust_bundle.s on the flag. Without the bundle it changes no
byte. tools/test_trust_release_guard.py pins all three layers.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ey path (adv-269)

1. The parse-time guard compares the key .inc's `$XX` tokens, so an .inc
   that spells byte 0 as `234`, pads the count with a commented `$00` and
   says IS_TEST_ONLY = 0 linked a release carrying the test key (PRG offset
   5901). The link now runs tools/check_release_key.py under TRUST_RELEASE=1
   TRUST_BUNDLE=1: the test key derived from its PEM (no .inc parsed) is
   searched for in the whole PRG -- the comb cold image included (offset
   47929) -- and the PRG is deleted on a hit. Red on the old head, refused
   after; a non-test key still builds.
2. tools/test_trust_release_guard.py failed 2 of 20 controls in a fresh
   checkout ("No rule to make target build/https_host.inc"): a dry run
   skips the parse-time write. build/https_host.inc gets the same write as
   a recipe, so `make -n` on a fresh tree answers (and still writes
   nothing). The test now also pins the link-time check: 24/24, red with
   the recipe line removed.
3. tools/trust_bundle.py documents the production-key path: key outside
   the repo, `inc` for the public half + floor, TRUST_BUNDLE_KEY_INC=.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…sses it

The fixed 240 s sat too close to the d64 load-and-boot on a loaded host:
on master it failed 2 of 3 runs at 240 s and passed at 900 s with the
ip65-onchip banner at 90 s; UCI banners swung 5-150 s. Default 600 s,
VICE_BOOT_TIMEOUT still overrides it, and a failed boot check now prints
the budget it used.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@JC-000
JC-000 force-pushed the feat/p2-l3-policy branch from d1bb592 to 011209b Compare October 6, 2026 17:39
@JC-000
JC-000 force-pushed the feat/p2-l3-package branch from 402bc54 to 8fdebe7 Compare October 6, 2026 17:39
@JC-000
JC-000 changed the base branch from feat/p2-l3-policy to master October 6, 2026 18:11
@JC-000
JC-000 merged commit 489efd0 into master Oct 6, 2026
JC-000 added a commit that referenced this pull request Oct 6, 2026
#211 is closed: the stretch-goal bullet, the wikipedia-stall bullet and
the rig list no longer describe it as open (no replacement claim). "There
is no trust store, no root CAs" is false for the UCI images (#268/#269)
and the M3 demo; the chain-validation bullet keeps only the issuer skip.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@JC-000
JC-000 deleted the feat/p2-l3-package branch October 14, 2026 15:36
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