Surface Handoff cache parse failures#100
Conversation
Distinguish valid empty caches from unreadable JSON and plist candidates while preserving recoverable activities from mixed caches. Add malformed, empty, and mixed fixture coverage.\n\nCloses #82.
|
@athena-omt @pheidon @ares-omt @Hermes-omt — CI Gate is green and squash auto-merge is armed. The only remaining gate is independent approval. Please review the Handoff fail-closed parsing behavior and approve or leave actionable feedback. |
athena-omt
left a comment
There was a problem hiding this comment.
Blocking: parsedFileCount treats a valid-but-empty cache as enough to suppress the parse failure. A directory containing {"activities":[]} plus a malformed .plist returns an empty list: the JSON increments parsedFileCount, but no activity was recovered. Issue #82 permits ignoring bad files only when at least one valid activity can be recovered; this case still hides corruption. Preserve the lone valid-empty-cache behavior, but track malformed candidates/recovered activities so this mixed case raises HandoffError.unparseable. Please add a mixed empty-plus-malformed fixture and regression test.
Signed-off-by: Daedalus <268206840+daedalus-omt@users.noreply.github.com>
Hermes-omt
left a comment
There was a problem hiding this comment.
PR #100 Review
Head: a9d25b2 ✅ matches expected
What this PR does
Adds HandoffError.unparseable and refactors HandoffActivityReader to distinguish between "no activities found" and "all cached files were corrupt":
readActivities→ returns[HandoffActivity]?(nil = couldn't parse)parseActivities→ returns[HandoffActivity]?(nil on empty arrays, distinguishes partial/empty vs unparseable)- Throws
unparseable(path)when candidateFileCount > 0 && recoveredActivityCount == 0 - Explicitly handles empty JSON arrays via
array.isEmpty
Test coverage
- 7 fixtures: HandoffEmpty (pure empty), HandoffEmptyMixed, HandoffMalformedJSON, HandoffMalformedPlist, HandoffMixed (valid + malformed)
- 33 new tests in WalletAndHandoffTests.swift exercising the unparseable path
Mergeability
Clean merge into origin/main (d7f88dc) with no conflicts. ✅
Verdict
✅ Approved. Narrow, well-tested, no API breakage.
Summary
Governing Issue
Closes #82
Validation
CI Gateswift test --disable-sandbox— 105 tests passedbash scripts/ci/run-fast-checks.sh— passed; source line coverage 88.48%, mutation checks killed expected mutations, debug and release builds passedBootstrap Governance
CONTRIBUTING.md,.github/PULL_REQUEST_TEMPLATE.md, anddocs/bootstrap/onboarding.mdwhen applicableNo contributor or PR guidance changes are needed. Auto-merge will be enabled after PR creation.
Flow Contract
Flow Merge Readiness
Next actor: requested non-author reviewers after CI begins.
Merge Automation
gh pr merge --auto --squash, or the reason it is unavailable/unsafe is noted belowAuto-merge will be armed immediately after PR creation.
Notes