"""Offline app-only flash contracts; every flash operation is a temporary file. Reuse the data-restoration test's pinned fake parser/flasher boundary. The real adapter runs unchanged, including input validation, guards, sole app write, readbacks and runtime finish. No installed flasher, serial port or PIO is used. """ import hashlib import json import os from pathlib import Path import shutil import struct import unittest import zlib import test_mcfirmware_bench_data_restore as fixture TOOL = fixture.ROOT / 'tools/hil/mcfirmware_bench_app_flash.sh' IMAGE_PARSER = r''' def image_header(image): if len(image)<36 or image[0]!=0xe9: raise ExpansionError('bad image header') return struct.unpack_from('>4)) def endf_identity(image): trailer=image[-56:] if len(trailer)!=56 or trailer[:4]!=b'EndF' or struct.unpack_from('