feat(ios): complete P2.1 schema versioning and P2.2 combined edge case tests

P2.1: iOS Schema Versioning Strategy
- Added SCHEMA_VERSION constant and checkSchemaVersion() method in PersistenceController
- Version stored in NSPersistentStore metadata (observability contract, not migration gate)
- CoreData auto-migration remains authoritative; version mismatches logged, not blocked
- Documentation added to ios/Plugin/README.md with migration contract

P2.2: Combined Edge Case Tests
- Added 3 resilience test scenarios to DailyNotificationRecoveryTests.swift:
  - test_combined_dst_boundary_duplicate_delivery_cold_start()
  - test_combined_rollover_duplicate_delivery_cold_start()
  - test_combined_schema_version_cold_start_recovery()
- All tests labeled with @resilience @combined-scenarios comments
- Tests verify idempotency and correctness under combined stressors

P2.3: Android Combined Tests Design
- Created P2.3-DESIGN.md with scope, invariants, and acceptance criteria
- Created P2.3-IMPLEMENTATION-CHECKLIST.md with step-by-step execution plan
- Design ready for implementation to achieve parity with iOS P2.2

Documentation Updates
- Fixed parity matrix: iOS invalid data handling now correctly shows " Recovery tested" with test references
- Updated progress docs (00-STATUS.md, 01-CHANGELOG-WORK.md, 03-TEST-RUNS.md, 04-PARITY-MATRIX.md)
- Updated P2-DESIGN.md to reflect P2.3 scope (Android combined tests)
- Updated SYSTEM_INVARIANTS.md baseline tag references

Baseline Tag
- Created and pushed v1.0.11-p2-complete tag
- Tag represents P2.x completion (schema versioning + combined resilience tests)

All invariants preserved. CI passes. Tests runnable via xcodebuild on macOS.
This commit is contained in:
Matthew Raymer
2025-12-22 12:59:40 +00:00
parent eb1fc9f220
commit 6b5b886951
16 changed files with 2131 additions and 72 deletions

View File

@@ -17,7 +17,30 @@ For release notes, see [CHANGELOG.md](../../CHANGELOG.md).
- **Audit Result**: Codebase already follows type safety best practices; all external boundaries use `unknown`, all data payloads use `Record<string, unknown>`
- **Remaining Exception**: `src/utils/PlatformServiceMixin.ts:258``any[]` required for TypeScript mixin pattern (documented with inline comment)
- **Verification**: `rg '\bany\b' src/` returns zero matches except documented exception; TypeScript compilation passes
- **CI Status**: All checks pass (`./ci/run.sh`); P2.6 closed out in progress docs
- **2025-12-22 — P2.7 COMPLETE**: Created `docs/SYSTEM_INVARIANTS.md` — single authoritative document naming and explaining all enforced invariants
- **2025-12-22 — P2.1 COMPLETE**: Schema versioning strategy — iOS explicit version tracking in CoreData metadata
- **Implementation**: Added `SCHEMA_VERSION` constant and `checkSchemaVersion()` method in `PersistenceController`
- **Approach**: Version stored in `NSPersistentStore` metadata (non-intrusive, observability contract)
- **Behavior**: Version logged on store load; mismatches logged as warnings (not blocked)
- **Documentation**: Added schema versioning strategy section to `ios/Plugin/README.md` with migration contract
- **Parity**: iOS now has explicit version tracking matching Android's Room versioning approach
- **Verification**: CI passes; version logging verified; parity matrix updated
- **2025-12-22 — P2.2 COMPLETE**: Combined edge case tests — added 3 resilience test scenarios
- **Scenario A**: DST boundary + duplicate delivery + cold start (must-have)
- Tests recovery idempotency under DST transitions
- Verifies only one logical delivery recorded after dedupe
- Validates next notification time is DST-consistent
- **Scenario B**: Rollover + duplicate delivery + cold start (must-have)
- Tests rollover idempotency under re-entry
- Verifies duplicate delivery doesn't double-apply state transitions
- Validates cold start reconciliation produces correct state
- **Scenario C**: Schema version metadata + cold start recovery (nice-to-have)
- Confirms P2.1 schema version metadata is present and logged
- Verifies version check doesn't interfere with recovery
- **Implementation**: Added to `ios/Tests/DailyNotificationRecoveryTests.swift`
- **Test Labels**: All tests labeled with `@resilience @combined-scenarios` comments
- **Verification**: Tests runnable via xcodebuild on macOS; skipped on Linux CI (expected)
- **P1.5 COMPLETE**: Documentation consolidation phase finished
- **Step 1**: Updated `docs/00-INDEX.md` to elevate contracts and progress docs as authoritative
- **Step 2**: Added drift guards (Purpose, Owner, Last Updated, Status) to all progress docs