From ae0c01aae107c55958455b79c49fb13b97b5b783 Mon Sep 17 00:00:00 2001 From: Michael Cerisano Date: Mon, 19 Oct 2026 20:15:43 -0400 Subject: [PATCH] Refresh reliability roadmap and unreleased notes --- CHANGELOG.md | 7 +++-- .../Fixtures/EvidenceCompatibility/README.md | 6 ++--- docs/TODO.md | 26 +++++++++---------- 3 files changed, 21 insertions(+), 18 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 027ca964..872f7d8e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,8 +12,11 @@ All notable changes to this project will be documented in this file. - Remote backups now claim a new filename before upload and recover only files BitMatch can still identify as its own. Existing remote files are left alone; unsupported server setups stop with an issue. - Cancelling a remote backup now stops the SSH work it started, including child processes. - Camera hints skip oversized XML metadata instead of loading it all into memory. This does not change the transfer file list. -- The finish screen describes the checks actually performed and acknowledges files that did verify even when the transfer as a whole needs attention. -- Keep copy and verification failures below 100% in live progress; the engine emits “Complete” only when all selected files pass the chosen mode. The final safety verdict still includes later ASC MHL and report steps. +- Finish, History and reports separate the selected verification plan from the results actually recorded. Older checksum reports no longer get labeled as a mode they did not record, and unknown or conflicting checksum algorithms stay unverified. Partial results stay visible without claiming the transfer completed. +- Interrupted exFAT copies leave a visible incomplete-transfer warning on the destination. Existing files stay untouched, and unfinished copies cannot earn a safe verdict. +- Made saving ASC MHL histories on exFAT safer: unfinished or damaged histories stay unverified, and an existing history is never replaced. +- Check can validate supported ASC MHL inventory chains, including intact histories extended by another tool, without rewriting them. Directory hashes and recorded renames remain unsupported. +- Large clips now move progress as their bytes are copied and checked. Queue cards are weighted by estimated work, and the bar stays below 100% while reports and final transfer records finish. Failed or interrupted work never appears complete. - Ignore a disappearing root `.fseventsd` metadata directory during card scans without hiding ordinary files. A regular source file with that name now contributes to the source fingerprint. - Bound saved JSON, MHL and adjacent checksum-manifest reads during loading. Damaged, oversized, conflicting or empty adjacent records are reported instead of silently falling back to partial evidence, including when another companion looks valid. - Keep a retained remote verification timestamp from claiming a photographer card is fully backed up when its local evidence is rejected. Remote status labels distinguish downloaded readback from older server-checksum evidence, including backups with mixed evidence. Refreshing a saved backup no longer changes its completion time. diff --git a/Packages/BitMatchEngine/Tests/BitMatchEngineTests/Fixtures/EvidenceCompatibility/README.md b/Packages/BitMatchEngine/Tests/BitMatchEngineTests/Fixtures/EvidenceCompatibility/README.md index 17521476..f184f54f 100644 --- a/Packages/BitMatchEngine/Tests/BitMatchEngineTests/Fixtures/EvidenceCompatibility/README.md +++ b/Packages/BitMatchEngine/Tests/BitMatchEngineTests/Fixtures/EvidenceCompatibility/README.md @@ -14,7 +14,7 @@ The tests copy fixtures into disposable roots. MD5/XXH64, zero-byte files, Unico `reports/` captures current, older, extended, Quick, unsafe, unknown-method, unknown-algorithm and truncated JSON. Only current and compatible extra-field snapshots may supply a verified saved-report status. These handcrafted snapshots test reader compatibility; they are not fresh verification evidence or output attributed to an external offload application. -October 14 additions use the same pinned reference commit and license: `sha1/` and `xxh128/` are valid external inventories that BitMatch must explicitly reject as unsupported, both alone and beside a readable history. `xxh64-boundaries/` contains original byte sequences (`byte[index] = index % 251`) of lengths 0, 1, 31, 32, 33, 255, 256, 257 and 1025, covering XXH64's lane and tail boundaries. These fixtures passed the independent checks below; the new Swift consumer regressions still require an Apple test run. +October 14 additions use the same pinned reference commit and license: `sha1/` and `xxh128/` are valid external inventories that BitMatch must explicitly reject as unsupported, both alone and beside a readable history. `xxh64-boundaries/` contains original byte sequences (`byte[index] = index % 251`) of lengths 0, 1, 31, 32, 33, 255, 256, 257 and 1025, covering XXH64's lane and tail boundaries. These fixtures passed the independent checks below; their Swift consumer regressions also passed on Mac. October 17 addition: `md5-renames/` is another output of the same pinned reference CLI, generated with `create -h md5` and then `create -h md5 -dr`. Between those generations, one synthetic file is renamed and `Reel B` is renamed to `Reel C`. The second manifest records two file `` values and one directory ``; the reference verifier and diff accept the final folder, while a further unrecorded directory move fails. BitMatch Check deliberately rejects this history as unsupported until it can interpret rename lineage and structure. It does not call the old paths missing or claim to have verified the chain. The media payloads and fixture script are original/MIT; the reference-tool output retains its MIT notice in `ASC-LICENSE.md`. @@ -24,11 +24,11 @@ Run the corpus checks on Linux or macOS without Swift, using the reference venv: python Scripts/ascmhl/validate_corpus.py /path/to/pinned/ascmitc/mhl ``` -The runner requires the pinned, unmodified checkout, uses its code and schemas, suppresses the CLI's online update check, and checks inventory/chain schemas, generation counts, C4 chain digests, bytes and paths. It checks changed, missing, renamed, extra, modified-manifest and missing-manifest cases only in disposable copies, requiring specific failure codes. A rename must report both the new and missing path. SHA-1/XXH128/C4 are verified by the reference tool here, not claimed as supported by BitMatch. Originals must remain byte-for-byte unchanged. `validate_reference.sh` runs this subset as well as the Apple-only freshly generated BitMatch workflow. The corpus-only runner is also a Linux CI job. +The runner requires the pinned, unmodified checkout, uses its code and schemas, suppresses the CLI's online update check, and checks inventory/chain schemas, generation counts, C4 chain digests, bytes and paths. It checks changed, missing, renamed, extra, modified-manifest and missing-manifest cases only in disposable copies, requiring specific failure codes. A rename must report both the new and missing path. SHA-1/XXH128/C4 file hashes are verified by the reference tool here, not claimed as supported file digests by BitMatch. Originals must remain byte-for-byte unchanged. `validate_reference.sh` runs this subset as well as the Apple-only freshly generated BitMatch workflow. The corpus-only runner is also a Linux CI job. Generate just new datasets without replacing existing originals using `--datasets sha1 xxh128 xxh64-boundaries md5-renames`. Default generation creates all seven datasets. Generation suppresses the reference CLI's online update check as well. -`classic-v1.mhl` is a handcrafted boundary fixture, not external-tool output. It is rejected inside an ASC history both alone and beside a valid reference history; standalone classic-MHL discovery is still unsupported. This batch does not claim full chain, rename or directory-hash verification. ASC checks explicitly describe their file-content scope. Histories are never rewritten by these checks. +`classic-v1.mhl` is a handcrafted boundary fixture, not external-tool output. It is rejected inside an ASC history both alone and beside a valid reference history; standalone classic-MHL discovery is still unsupported. Check's supported inventory-chain scope is described below; directory hashes, rename lineage and historical authenticity remain outside it. Histories are never rewritten by these checks. October 19 addition: `reference/bitmatch-fat-extended/` is a **sanitized derivative** of the actual engine's initial FAT-v1 history generated by `ASCMHLFixture` on a disposable mounted exFAT image. The real mounted sample separately passed official extension/verification/diff with its original status unchanged. For the public fixture, the initial hostname was replaced with `bitmatch-fixture-host` and the synthetic clip filename changed to ASCII `Camera A/clip.txt`, and its exact v1 single-generation chain/status was rebuilt during fixture creation only. The pinned official `ascmhl create -h md5 -i '._*'` then appended generation two to that sanitized copy; this is not a byte-for-byte mounted-volume capture. The first media payload comes from the original/MIT fixture executable; `added.txt` is original synthetic text. The new reference output retains the ASC MIT notice above. The official CLI hostname is the synthetic `bitmatch-fixture-host`. Its explicit metadata pattern excludes only test-volume AppleDouble companions from this portable dataset; it does not define BitMatch's production filtering policy. No existing fixture was rewritten. diff --git a/docs/TODO.md b/docs/TODO.md index 017284c1..3b4ce1d9 100644 --- a/docs/TODO.md +++ b/docs/TODO.md @@ -1,6 +1,6 @@ # To do -The working list for BitMatch, reprioritized on October 16, 2026 against 0.2.9. These are roadmap candidates, not instructions to implement every feature or a promised release scope. The report and transfer-details batch shipped in 0.2.7; see [validation](TODO_REPORTS_VALIDATION.md). When something ships, record it in the [changelog](../CHANGELOG.md) and remove the finished task here. +The working list for BitMatch, reprioritized on October 16 and reviewed on October 19, 2026 against 0.2.9. These are roadmap candidates, not instructions to implement every feature or a promised release scope. The report and transfer-details batch shipped in 0.2.7; see [validation](TODO_REPORTS_VALIDATION.md). When something ships, record it in the [changelog](../CHANGELOG.md) and remove the finished task here. **Source media → trustworthy copies → independent verification → accurate evidence → safe-to-erase decision.** @@ -12,12 +12,12 @@ This is the order to **investigate or start a bounded slice**, not a promise to The two active reports come first as **casework**, but neither is a ready-to-ship fix: [#23](https://github.com/BitmatchApp/Bitmatch/issues/23) needs the reporter's version/phase or a reproduced memory path, and [#10](https://github.com/BitmatchApp/Bitmatch/issues/10) needs decisive diagnostics or a physical reproduction. Synthetic passes alone cannot close either report. -Unreleased work on `main`: terminal/History presentation, Mac card-event reconciliation, the verification wording audit's first slice, unknown-drive Setup wording, the expanded MHL corpus, the Mac menu bar companion and per-drive I/O detail have landed. SFTP first-upload and subprocess-cancellation fixes, a compact menu bar icon, bounded camera XML reads, finish-screen wording and opt-in local crash evidence have also merged. The engine test runner now executes both test frameworks. The menu bar and speed display still need a signed-app walkthrough, and crash evidence needs signed-app and device checks before release. None of this closes the active user reports or replaces the physical checks below. +Unreleased work on `main`: terminal/History presentation, byte-weighted progress, Mac card-event reconciliation, recorded verification scope, unknown-drive Setup wording, the MHL corpus and read-only inventory-chain checks, the Mac menu bar companion and per-drive I/O detail have landed. SFTP first-upload and subprocess-cancellation fixes, a compact menu bar icon, bounded camera XML reads, FAT copy/history publication guards and opt-in local crash evidence have also merged. The engine test runner now executes both test frameworks. The menu bar and speed display still need a signed-app walkthrough, and crash evidence needs signed-app and device checks before release. None of this closes the active user reports or replaces the physical checks below. | Rank | Build or decision work | Usefulness | Difficulty | Blast radius | Shippability | | ---: | --- | --- | --- | --- | --- | | 1 | Terminal progress and outcome parity (merged; signed-app release check open) | High | Low–medium | Medium | Quick | -| 2 | Verification coverage and wording audit (first mode/fault slice merged; wider audit open) | High | Medium | Medium | Scoped | +| 2 | Verification coverage and default-policy audit (recorded-scope wording merged; hardware/default decisions open) | High | Medium | Medium | Scoped | | 3 | Honest claims when physical drive identity is unknown (Setup note merged; verdict decision open) | High | Medium | Medium | Scoped | | 4 | Distinguish local-source, local-backup and SFTP assurance (upload guards merged; broader assurance audit open) | High | Low–medium | Low–medium | Quick | | 5 | Expand the MHL interoperability corpus (rename/move fixture merged; classic interop open) | High | Medium | Low | Scoped | @@ -26,7 +26,7 @@ Unreleased work on `main`: terminal/History presentation, Mac card-event reconci | 8 | Mark failed readback output unmistakably on disk | High | High | High | After publication ownership | | 9 | Mac menu bar companion and icon (merged; signed-app walkthrough open) | High | Medium | Medium | Scoped | | 10 | Per-drive copy/readback speed (merged; signed-app walkthrough open) | Medium–high | Medium | Low–medium | Scoped | -| 11 | Honest byte-weighted transfer and queue progress | High | High | Medium | After terminal parity | +| 11 | Byte-weighted transfer and queue progress (merged; reuse refinement and walkthrough open) | High | High | Medium | Field validation open | | 12 | Local, opt-in crash and hang evidence (merged; signed-app and device checks open) | Medium–high | Medium | Low–medium | Scoped | | 13 | History discovered from connected authorized drives | High | High | Medium | Long | | 14 | Investigate a macOS 15.0 minimum | Medium | Low–medium | Medium | Scoped; older OS test | @@ -35,7 +35,7 @@ Unreleased work on `main`: terminal/History presentation, Mac card-event reconci | 17 | Storage-aware verification scheduling | High | High | Medium–high | After physical benchmark | | 18 | Bounded source-read retry with card-health warning | High | High | High | Long; fault model first | | 19 | Verify upstream MHL/source provenance | Medium–high | High | Medium | Long | -| 20 | ASC MHL structural verification | Medium–high | High | Medium | After corpus | +| 20 | ASC MHL structural verification (inventory-chain slice merged; directory/rename work open) | Medium–high | High | Medium | Scoped | | 21 | Decide when compatibility digests are computed | Medium | Medium | Medium | After measurements | | 22 | Read-only Remote Mac mode on iPhone/iPad | Very high | Very high | High | Long; after menu bar | | 23 | Finder “Offload with BitMatch” action | Medium | Medium | Medium | Scoped | @@ -76,7 +76,7 @@ Dependencies matter more than the row number: physical measurements precede a ve - [ ] **Transfer interruption on the reporter's setup ([#10](https://github.com/BitmatchApp/Bitmatch/issues/10)).** Later releases fixed reproduced exFAT handoff, cancellation-state and large-file verification defects, but the reporter's exact interruption has not been reproduced. Correlate any new 0.2.9 diagnostic export, outcome record and macOS termination evidence with the original drive, dock, filesystem and verification phase. Keep a disposable physical-drive reproduction separate from conclusions about the reporter's run. **Acceptance:** establish the cause with a reproduction or decisive diagnostic evidence; otherwise record what was ruled out and keep the issue open. -- [ ] **Reported application-memory exhaustion ([#23](https://github.com/BitmatchApp/Bitmatch/issues/23)).** The 0.2.9 fixes address measured memory growth in ASC MHL generation and saved-checksum Check, but the reporter's version and failing phase remain unknown. Analyze the existing diagnostics if supplied; measure peak memory through copy, verification, MHL, Check and optional PDF preview work with large disposable files, including a physical destination. Keep the source untouched and avoid asking for another large transfer solely to gather data. **Acceptance:** distinguish a reproduced cause from a plausible fix, verify bounded memory on the affected path, and leave the report open until field evidence supports closing it. +- [ ] **Reported application-memory exhaustion ([#23](https://github.com/BitmatchApp/Bitmatch/issues/23)).** The 0.2.9 fixes address measured memory growth in ASC MHL generation and saved-checksum Check, but the reporter's version and failing phase remain unknown. Opt-in probes merged in #53 cover 512 MiB APFS copies to one/two destinations and Paranoid folder comparison; they do not reproduce the reported full-app failure. Analyze the existing diagnostics if supplied; measure peak memory through copy, verification, MHL, Check and optional PDF preview work with large disposable files, including a physical destination. Keep the source untouched and avoid asking for another large transfer solely to gather data. **Acceptance:** distinguish a reproduced cause from a plausible fix, verify bounded memory on the affected path, and leave the report open until field evidence supports closing it. ## P1 — Reliability and recovery @@ -88,11 +88,11 @@ The priority buckets are not a strict implementation sequence: investigate P0 re - [x] **Close the exFAT/FAT media-file publication race in code.** The no-hard-link FAT-family path now durably creates a visible incomplete-status warning before opening each media file at its final name with exclusive create. It never renames or removes that final name. An interrupted copy leaves its partial bytes and warning in place; existing files and another writer's bytes remain untouched. Exact marker validation, independent readback and named-file identity checks guard status advancement and the safe verdict. Deterministic replacement, cleanup, interruption and recovery regressions pass on the forced-direct path; mounted exFAT marker/root sync and full Standard-to-ASC-MHL handoff pass. See the [design and limits](EXFAT_PUBLICATION_DESIGN.md). **Remaining validation:** FAT32 images could not be mounted on this Mac, and no physical drive or sudden-power-loss result is recorded. Confirm FAT32 sync and transfer behavior on another host, then test representative physical drives without treating OS flush success as a power-loss guarantee. -- [x] **Close the ASC MHL exFAT empty-directory claim race in code.** FAT-family publication now claims `ascmhl` once and writes through its pinned descriptor; it never renames over the claim or deletes a mutable public name. A durable neutral status file remains incomplete until a completion record binds the exact manifest and chain bytes. BitMatch Check refuses partial or altered FAT histories, even if the status file is removed or a valid report sits beside them. Deterministic replacement, interruption, status-substitution and AppleDouble-lookalike regressions pass; mounted exFAT handoff passes, and the official ASC reference verifier accepts the completed history and can append a generation. **Remaining validation:** FAT32 and physical-drive/power-loss behavior are untested. BitMatch Check deliberately refuses an externally extended chain because its completion record binds the original chain; read-only chain-lineage validation belongs in the existing upstream MHL item. This code fix does not establish the cause of issue #10. +- [x] **Close the ASC MHL exFAT empty-directory claim race in code.** Merged in #54. FAT-family publication claims `ascmhl` once and writes through its pinned descriptor; it never renames over the claim or deletes a mutable public name. A durable status remains incomplete until a completion record binds the exact initial manifest and chain bytes. Check refuses incomplete histories or altered witnessed bytes, even if a valid report sits beside them. After #57, it accepts supported external extensions only when the original completion witness remains valid and the current inventory chain passes its read-only checks; it never rewrites or reseals the status. Deterministic adversarial regressions and a mounted-exFAT handoff/official-tool extension pass. **Remaining validation:** FAT32 and physical-drive/power-loss behavior are untested. Directory/root hashes, rename lineage and historical authenticity remain outside the chain slice. These fixes do not establish the cause of issue #10. - [ ] **Make failed readback output unmistakable on disk.** BitMatch publishes a copied file at its normal destination name before readback; the existing corruption regression confirms that the bad file remains there even though the app verdict correctly fails closed. Investigate marking or moving only an attempt-owned, identity-checked file that fails verification. A read error does not prove the bytes are corrupt, and even bad bytes may be worth preserving. **Acceptance:** injected mismatch, read error, external replacement, interrupted marking and marking failure never overwrite, delete or relabel another writer's file; the real on-disk path and uncertainty appear in History/reports and recovery; source media stays untouched. -- [ ] **Verification coverage and default-policy audit.** Standard is the fresh-install default; a previously saved mode stays selected. Setup, History and PDF/CSV/JSON wording have been aligned with recorded checks, and Compare has its own check-plan wording. Still map Quick, Standard, Thorough and Paranoid to copy-stream source hashing, independent source rereads, destination readback, byte comparison, source-change checks, ASC MHL/report evidence and the actual safe-to-erase verdict. Include a one-time transient source misread and a repeatably wrong read: a second read can catch differing bytes, but cannot prove the original camera bytes or detect every stable fault. Treat the recommended default as a product choice informed by safety, user workflows and measured time; it may move up or down the assurance ladder, but every verdict must name the checks actually performed and the selected-file scope. **Acceptance:** finish-screen, README and Guide mode claims need a final check against the engine and fault-injection tests; Quick and intentionally excluded-file transfers stay unsafe; injected source and destination faults produce honest outcomes. Any default change has explicit behavior for fresh versus saved preferences, release notes and Mac/iPad/iPhone validation. +- [ ] **Verification coverage and default-policy audit.** Standard is the fresh-install default; a previously saved mode stays selected. The [assurance audit](VERIFICATION_ASSURANCE_AUDIT.md) maps current reads, digests and limits. Setup, expanded Finish details, History, README, Guide and PDF/CSV/JSON distinguish the selected plan from recorded results; Compare keeps its own check plan. The #55 reader preserves an explicit recorded mode, leaves generic legacy modes unknown and rejects contradictory scope/counts. The #58 follow-up rejects unsupported or contradictory supplied digests in older named-mode reports while preserving genuine missing-algorithm records. Quick and intentionally excluded-file transfers remain unsafe. **Remaining:** check the compact wording on narrow devices and keep transient-source, repeatably wrong-source and destination-fault regressions current. A second read can catch differing bytes, but cannot prove the original camera bytes or detect every stable fault. The default remains a product decision informed by physical end-to-end measurements; any change needs explicit fresh/saved-preference behavior, release notes and Mac/iPad/iPhone validation. - [ ] **Separate local-source and remote-destination assurance.** A local source can be independently re-read before a later SFTP upload; the current Mac SFTP queue uploads an already verified local backup, not the card. Its SHA-256 readback downloads the remote file, while upload-only remains **Uploaded · Unverified**. The screen and report labels landed in #26. First-upload exclusivity and subprocess-group cancellation landed in #35/#36 after adversarial and localhost tests; broader server and filesystem compatibility remains unproven. Keep local source reread, local backup verification, remote upload and remote readback as distinct facts in diagnostics and future changes. Do not infer source assurance from a remote readback or deny source assurance merely because a later destination is remote. **Acceptance:** no remote result becomes a whole-card safe verdict without the required local checks; unsupported server setups fail closed, and broader support requires representative server tests. Apply the same evidence separation to any future cloud provider, with Mac-only SFTP scope explicit on iPad/iPhone. @@ -120,15 +120,15 @@ The priority buckets are not a strict implementation sequence: investigate P0 re ## P2 — Evidence and interoperability -October 14 cloud progress: the independent ASC corpus added SHA-1/XXH128 unsupported-format fixtures and XXH64 lane/tail boundaries. Its reference runner passed 68 checks on Linux and macOS, including negative controls and unchanged originals. Swift consumer tests, fresh BitMatch output against the pinned reference, Mac tests and iPhone/iPad simulator suites also passed. October 17 adds an official reference-tool two-generation file-rename/directory-move fixture; the expanded runner passes 82 checks. Physical-media and signed-app checks still remain before a release. Interoperability and structural/history work below remain open. +The independent ASC corpus covers unsupported file hashes, XXH64 boundaries and an official two-generation file/directory-rename history; its reference runner passes 82 checks. October 19 adds read-only inventory-chain validation and a separately reference-checked extended FAT-history fixture (#57), after full engine/Mac tests and iPhone/iPad simulator suites passed. Physical-media and signed-app checks still remain before a release. Interoperability and structural/history work below remain open. - [ ] **Upstream MHL / source provenance.** Reuse `SavedChecksumCheck` where appropriate to offer source verification against accompanying classic MHL or ASC MHL evidence. Record “source arrived intact” separately from “BitMatch created verified backups.” Preserve original manifests. Current Check discovers ASC inventories under `ascmhl/`; standalone classic-MHL discovery and an upstream transfer verdict still need work. **Acceptance:** incomplete, mismatched, malformed and unsupported evidence gets an honest separate verdict; a failed provenance check never becomes success and never prevents preservation of damaged-but-irreplaceable media. -- [ ] **MHL interoperability corpus.** The permanent corpus covers official ASC reference-tool MD5/XXH64 output, two generations, unsupported C4/SHA-1/XXH128, Unicode/whitespace paths, nested inventories, damaged records, a recorded file rename and directory move, and report compatibility. The classic-v1 boundary is handcrafted and explicitly identified as such. See [the validation record](EVIDENCE_COMPATIBILITY_VALIDATION.md). Continue with redistributable, independently attributable classic MHL and representative output from another implementation before claiming broad interoperability. Keep multi-file saved-record and relative-path regressions current. **Acceptance:** validate with independent reference implementations, record fixture provenance/licensing and expected outcomes, and never silently treat unsupported evidence as fully verified. +- [ ] **MHL interoperability corpus.** The permanent corpus covers official ASC reference-tool MD5/XXH64 output, two generations, unsupported C4/SHA-1/XXH128 file hashes, Unicode/whitespace paths, nested inventories, damaged records, a recorded file rename and directory move, externally extended FAT history, and report compatibility. The classic-v1 boundary is handcrafted and explicitly identified as such. See [the validation record](EVIDENCE_COMPATIBILITY_VALIDATION.md). Continue with redistributable, independently attributable classic MHL and representative output from another implementation before claiming broad interoperability. Keep multi-file saved-record and relative-path regressions current. **Acceptance:** validate with independent reference implementations, record fixture provenance/licensing and expected outcomes, and never silently treat unsupported evidence as fully verified. -- [ ] **ASC MHL structural verification.** After the corpus establishes expected semantics, extend Check to validate supported root/directory hashes and detect renamed, moved, missing or structurally altered content. **Acceptance:** distinguish file-content verification from structural verification; older manifests without structural evidence remain usable with an explicit scope. Do not claim full history verification before the chain semantics are implemented and independently tested. +- [ ] **ASC MHL structural verification.** The #57 slice validates supported inventory-chain records read-only: referenced inventory digests, ordered generations, safe paths, exact inventory coverage and unchanged evidence during Check. Legacy no-chain inventories remain content-only. **Remaining:** supported root/directory hashes and rename/move lineage; unsupported records must stay explicit. Chain validation does not authenticate custody or prove that an unanchored historical tail was never removed. **Acceptance:** keep file contents, supported chain records and directory/rename structure as separate scopes; do not call this full history verification. -- [ ] **Extend existing MHL histories.** Check already verifies recorded file contents; generating another history generation is still unsupported. Coordinate with structural verification and the reference corpus. **Acceptance:** preserve existing histories, validate the new chain independently, and ensure interruption cannot expose a partial generation as complete. Keep the current refusal until this is proven. +- [ ] **Extend existing MHL histories.** Check verifies recorded file contents and supported inventory chains without writing to them; generating another history generation is still unsupported. Coordinate with structural verification and the reference corpus. **Acceptance:** preserve existing histories, validate the new chain independently, and ensure interruption cannot expose a partial generation as complete. Keep the current refusal until this is proven. - [ ] **Measure before changing the transfer hash.** The saved-checksum reader supports XXH64; transfer verdicts currently rely on SHA-256. First measure complete runs through MHL/report publication, per-stage CPU and I/O, and peak memory on real drives. A cheaper hot-path hash saves time only if it replaces measured work; adding it alongside unchanged per-byte SHA-256 cannot remove that work and may slow the run. If substitution is proposed, compare collision/assurance properties, source and destination readback coverage, old evidence, report labels and interoperability; keep the chosen manifest's required digests valid. A non-cryptographic match must not silently inherit the current SHA-256 safe verdict. **Acceptance:** a repeatable end-to-end gain on relevant hardware and a documented safety/compatibility decision, or an explicit decision to keep SHA-256. No change to the default algorithm on a micro-benchmark alone. @@ -161,7 +161,7 @@ Remote scope excludes screen sharing, arbitrary filesystem browsing, remote shel - [ ] **Portable settings/workflow export and import.** Build on existing project recipes and saved settings. Include safe preferences, verification/report choices, naming recipes and reusable destination configurations; preview changes before import and revalidate destinations on the receiving machine. **Acceptance:** omit credentials, security-scoped bookmarks, private history and machine-specific identities. No facility configuration-management system. - [ ] **Simplified operator mode, only if users ask.** Investigate preconfigured destinations, naming and verification with an everyday source → start → review flow. Warnings stay visible and validation still runs; no facility administration or permission system. - [ ] **Organize and rename.** Extend existing project naming and folder recipes with remaining naming-pattern and organize-by-date workflows. Preserve original card contents and test destination collisions before adding new options. -- [ ] **Honest byte-weighted progress.** The shared implementation now budgets selected-file bytes for source reads, writes/reuse checks, required verification and optional ASC MHL work; live chunk callbacks advance large clips, and finishing reports never reset the bar or show active 100%. Destination bars use their own byte work. Queue cards use persisted size estimates, destination counts and verification mode; a queue with unknown sizes stays indeterminate. Estimates stay separate from copy evidence and remain stable per attempt. Focused synthetic tests cover tiny-plus-large files, uneven destinations, three verification modes, reuse, cancellation/failure, MHL mapping, duplicate planning entries and 10,000 small files; the tiny-file regression fails on the previous engine at 25%. **Remaining:** full integration/platform validation, signed-app walkthrough, and finer progress through extra source-hashing passes on reused files. The current retry budget remains deliberately logical rather than an exact tally of every physical read. Keep the main UI quiet and reserve 100% for the authoritative result. +- [ ] **Honest byte-weighted progress.** Implemented in #56. Integration passed full engine/Mac tests, the universal iOS build and iPhone/iPad simulator suites. The shared implementation budgets selected-file bytes for source reads, writes/reuse checks, required verification and optional ASC MHL work; live chunk callbacks advance large clips, and finishing reports never reset the bar or show active 100%. Destination bars use their own byte work. Queue cards use persisted size estimates, destination counts and verification mode; a queue with unknown sizes stays indeterminate. Estimates stay separate from copy evidence and remain stable per attempt. Synthetic regressions cover tiny-plus-large files, uneven destinations, reuse, cancellation/failure, MHL mapping and 10,000 small files. **Remaining:** signed-app/physical-drive walkthroughs and finer progress through extra source-hashing passes on reused files. The current retry budget remains deliberately logical rather than an exact tally of every physical read. Reserve 100% for the authoritative result. - [x] **Speed for each drive.** Expanded transfer details show each local destination's written and read-back bytes with separate live I/O rates. These are measured write/read calls, not a durability benchmark or verification verdict. The telemetry is shared with future storage-scheduling work; this change does not alter scheduling. - [x] **Reconcile missed Mac card events.** Mount notifications and manual rescan now reconcile the mounted filesystem's identity with published cards and drives. Deterministic event-gap tests cover unmount/reinsert, same-path replacement, stale asynchronous analysis and source selection; stale discovery cannot authorize auto-queue. This is a bounded event-triggered backstop, not a new polling service. A real removable-card walkthrough remains in the release gate below. - [ ] **Slow-cable hint.** On Mac, show a quiet hint when reliable connection information identifies a USB 2 bottleneck. Do not promise a speed multiplier without measurements.