Skip to content

feat(7.15): integrate reviewed Python stack through block 08 - #229

Merged
BitHighlander merged 28 commits into
reconcile/upstream-syncfrom
integrate/python-canonical-through-08-20260927
Sep 27, 2026
Merged

BitHighlander merged 28 commits into
reconcile/upstream-syncfrom
integrate/python-canonical-through-08-20260927

Conversation

@BitHighlander

@BitHighlander BitHighlander commented Sep 27, 2026 •

Copy link
Copy Markdown
Contributor

Canonical Python integration through Stack 08

Owner explicitly authorized merging into keepkey/python-keepkey:reconcile/upstream-sync. Canonical base 98c717ff2204124bf67cc78cab8ca1d501fd4e92 is an ancestor; there are no conflicting canonical changes. Candidate 6033aab2116b89abb6e1df6afed9e1321481ec19 integrates accepted Stack 07, consolidated 7b and Stack 08 from fork #119/#120. No Stack 09 changes are included.

Changes after reviewed Python d9a02d9

Production/library files, runtime test semantics and dependency pins equal reviewed d9a02d981ee43fe3e80b28ba02466670e6e8409d (clean review 5329239805). Nine trailing-whitespace occurrences were removed from compiler tests; parsed AST is identical. The workflow aligns both full/BTC 7.15 CI firmware pins with accepted consolidated 7b 2483977523d9b6beab52a69429ace9aeefd00f76 (#871). The 7.14.3 pins remain unchanged.

Initial CI 36349775654 passed lint, 7.14.3 full and both BTC jobs, but full 7.15 reported 54 failures against the historical firmware #843 pin, which predates these test contracts. The pin update qualifies the tests against their accepted implementation. No assertion, skip or product gate was weakened. New exact-head CI must pass before merge.

Verification

  • Firmware CI 36347898088 with reviewed Python d9a02d9: 1,497 pass, 89 expected skips, zero failures/errors, both ARM variants. Earlier compiler/catalog/protocol/report qualification: 39 tests with mandatory firmware validator and registry.
  • Local focused checks: 51 pass, 17 subtests; two token-generator tests skip because the large ethereum-lists checkout exhausted local disk. Hosted lint with recursive submodules passed the generator checks.
  • Canonical ancestor, full-range whitespace, unchanged-production comparison, compiler-test AST equality and workflow syntax checks pass. Optional shellcheck reports inherited SC2016/SC2129 info/style diagnostics in unchanged workflow blocks.
  • Upstream CircleCI smoke and the four-variant GitHub matrix are required on this final candidate.

This integrates Python only. Firmware B's separate local-preflight ancestry issue remains recorded and is not declared repaired or accepted. Canonical-to-master remains separate upstream PR #197. No extra Copilot request or repository-setting change.

Staged qualification boundary

Run 36350138324 against accepted 7b passed 782 tests and skipped 93, with 13 failures in capabilities explicitly deferred by the accepted firmware ledger. The final workflow reads that ledger from the immutable firmware checkout into only the full staged 7.15 job; it rejects missing/duplicate ledger declarations. No waiver is invented in the Python branch. Ledger: evm-max-amount-review,evm-unknown-token-review,entropy-audit-budget,osmosis-wire-guards,hive-release-review,storage-v19-kdf,solana-lut-attestation. The job summary publishes these omissions. Test assertions and default release behavior are unchanged; this is staged 7.15 qualification, not approval of deferred release features. 7.14.3 remains fully unchanged.

BitHighlander and others added 28 commits September 22, 2026 23:43
…oder

Array-of-structs, Permit2 batch and multidimensional device walks now
compare the device's domain/message hashes with a spec-derived reference
encoder and recover the signature to the device address. The multidim
walk is Stack 07 work and is gated by the structured-EIP-712 probe, not
by the later evm-unknown-token-review capability.
…e wire

set_expected_responses() raised a CallException whose text embedded the
expected message, so the old assertIn passed whatever the device sent.
Send EthereumSignTx with call_raw and require the first response to be
Failure_ActionCancelled with the exact message (no ButtonRequest first).
…nputs

The firmware-validation step ran only behind 'if validator:' so compile
tests passed without ever reaching firmware. Missing validator or
registry is now an explicit skip, and a failure when CI sets
KK_REQUIRE_ERC7730_EVIDENCE=1.
…ong bytes

Every signing walk now requires exactly one ButtonRequest_SignTx
"Sign Typed Data" screen at the end. New device tests: declining that
screen returns ActionCancelled and no signature; primaryType
EIP712Domain signs keccak(0x1901||domainSeparator) (checked by the
independent encoder and signer recovery); unlimited EIP-2612 and Permit2
amounts are refused before their leaf is displayed; a 1024-byte bytes
leaf signs and verifies independently.
The registry conformance test had never run against a firmware
validator. Run through the firmware's own catalog verifier, 56 of the
1,450 official calldata formats compiled to programs the device
refuses:

- 46 tokenAmount fields with no token compiled to formatter kind 3,
  which the verifier refuses without a token argument. With no token the
  device can only show the raw integer, so compile the raw formatter.
- 8 paths iterated two nested arrays; the verifier accepts one "[]"
  step per path. Refuse them by name.
- 2 ABIs nested deeper than the device's 8 levels. Refuse them by name.

The registry test now requires every format to pass the firmware
validator or be refused for one of those named device limits, and pins
that count at 10.
The device response buffer is shared with DebugLink, and a state read
during the final sign screen erased an address written before it. The
signature still recovered to the right key, so only the reported address
was wrong. Under screenshot capture the unfixed firmware returns an empty
address and these assertions fail.
Firmware calldata and typed-data captures refuse ERC7730_ABI_MAX_DEPTH (8)
or more path steps, and the catalog verifier now does too. Refuse such
paths by name at compile time. No official registry format is affected.
Firmware now refuses at preload every ERC-7730 program its runtime cannot
finish, using one capability table shared by the verifier and the runtime.
Mirror that table here as DEVICE_CAPABILITIES:

- compile_calldata/compile_eip712 raise DeviceCannotExecute with the exact
  reason unless executable_only=False;
- device_refusal() reports why a compiled program would be refused;
- the registry test asserts that the device verifier and this mirror agree
  on every compiled format in both directions, and that exactly 92 of the
  1,450 official formats are signable (not 94: two raw fields read the
  @.from container, which the runtime never captured).

Also pin device-protocol at the canonical release protocol plus the Solana
LUT merge and DebugLinkState.confirm_title/confirm_body, and add
DebugLink.read_confirm_text() so tests can assert exact screen text.
…actly

The capability mirror treated every permitted role as required, walked
non-value paths against the ABI and read an index after every step opcode.
None of that could fire under the Phase 0 table, but each would misfire as
soon as the table widens. Separate required roles, list executable
containers, and parse whole-array and slice steps as the firmware does.
…ants

Phase A of the ERC-7730 formatter plan. The device now executes
tokenAmount (value, token, threshold, message, native aliases),
addressName, @.from/@.to (calldata only) and signed constants, and
type-checks every argument at preload. Mirror that table, including the
value classes: amount and threshold are integers, token and addressName
values are addresses, raw literals are integers, addresses or strings, and
an alias set names at most four addresses.

The registry test now asserts 812 signable formats (from 92). The device
still refuses addressName and tokenAmount over bytes32/uint256 words that
pack an address or an encrypted amount.
Phase B. The device executes display opcodes 2 and 3 as one run directly
after the plain intent, showing each fragment and value as a numbered part.
Mirror the opcodes and the run rule, and trim fragment edges: each part is
its own screen, and the device escapes edge spaces. The registry test now
asserts 954 signable formats.
Phase C. Mirror the device's new formatters and their argument classes:
a date encoding must be the string "timestamp" or "blockheight", unit
decimals a one-byte literal and the prefix a flag, an enum map at most 16
entries, an NFT collection an address, and @.value an unsigned value. The
registry test now asserts 1,138 signable formats.
@BitHighlander
BitHighlander merged commit 76d876a into reconcile/upstream-sync Sep 27, 2026
6 checks passed
@BitHighlander

Copy link
Copy Markdown
Contributor Author

Python canonical integration completed — 2026-09-27T21:16:03.158649+00:00

Owner explicitly authorized merging the reviewed Python work into canonical. Upstream PR #229 is merged into keepkey/python-keepkey:reconcile/upstream-sync at 76d876a86fe92e791f87c8db3dccec04bf05af7a. GitHub branch and PR state verified; merge parents are prior canonical 98c717ff2204124bf67cc78cab8ca1d501fd4e92 and tested candidate 6033aab2116b89abb6e1df6afed9e1321481ec19. The merge tree exactly equals the tested candidate tree 537b10f8f8ca4dbd1a008a46ae7a79d44644da01.

Includes accepted Stack 07, consolidated 7b, and Stack 08 Python work through reviewed d9a02d981ee43fe3e80b28ba02466670e6e8409d; no Stack 09. Compared with that reviewed head, production/library files, runtime tests and dependency pins are unchanged. Compiler-test trailing whitespace was removed with identical AST. CI pins both 7.15 variants to accepted firmware 2483977523d9b6beab52a69429ace9aeefd00f76 and imports its existing staged capability ledger only into the full staged 7.15 job. No new waiver is invented; default release assertions and 7.14.3 behavior remain unchanged.

Final candidate CI 36350596825 passed lint, full 7.14.3, staged full 7.15, and both Bitcoin-only variants. CircleCI 812 passed. Staged full 7.15: 778 passed, 110 skipped under version/product/accepted staged guards, zero failures, 188 subtests passed. This is staged qualification and does not certify deferred release capabilities. Local focused checks: 51 passed, 17 subtests, two generator skips from incomplete local ethereum-lists checkout due disk exhaustion; hosted recursive-checkout lint passed generator checks. Workflow syntax passed; optional shellcheck's inherited info/style diagnostics were recorded.

Initial CI 36349775654 failed 54 full-7.15 cases against the historical firmware pin. Run 36350138324 reduced that to 13 cases after pinning accepted 7b; all were covered by its explicit deferred-capability ledger. The final run applies that immutable ledger and is green. No test assertions were weakened. Canonical integration was not merged until final checks passed.

Upstream #197 remains the separate canonical-to-master PR. Firmware Stack 08 B's local-preflight ancestry issue remains unresolved, with its review budget exhausted; this Python merge does not mark that firmware audit complete or change its pinned Python SHA. No additional Copilot request, firmware merge, master merge or repository-setting change was made.

BitHighlander added a commit to BitHighlander/python-keepkey that referenced this pull request Oct 3, 2026
Merges, into one head, everything a firmware pin has used:
- reconcile/upstream-sync 76d876a: the canonical upstream PR (keepkey#197), with the
  reviewed stack through 08 (keepkey#229) and its CI workflow changes
- 010cdd3: the 7.15/7.16 line, with the staged-capability gates (b47769e)
- dabf5a4 and 6dd8503: the b13 and b14 firmware pins, which sit on side
  branches and are patch-equivalent to commits already on the line

The merged tree differs from 010cdd3 only by canonical's own workflow and
whitespace changes (2 files). Every firmware pin from b1 to b15 is now an
ancestor of this head, with its tree unchanged.
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