The package suite now includes AppModel regression coverage for failed structural reconciliation and
retry, failed document loading, background refresh during operations, session preservation after
renaming, restoring different text with the same ID/revision, and retaining editable unsaved text
when flushing fails. Persistence tests cover metadata reads without access to the body column,
export isolation between novels, malformed-record rejection before restore, malformed progress
rejection during reads/saves, strict scalar results, retention of healthy backups after repeated
failed copies, and maximum-interval autosave resuming after prolonged composition. Run
./scripts/verify.sh for the current suite and Xcode build. The hosted-test and manual UI evidence
below predates this refactor.
Additional tests verify editor-session preservation on backup/export failure and cancellation, flushing before a successful backup, and word-count coalescing. A controllable suspended counter proves that bursts start only the latest pending request, no second computation starts while one is in flight, and results from previous generations or chapters are discarded without depending on CPU timing.
Reference machine: Apple M3 MacBook Air (8 CPU cores), 24 GB RAM, macOS 26.5.1. Xcode 26.6 (17F113), Swift 6.3.3, macOS SDK 26.5, system SQLite 3.51.0. Recorded 13 September 2026.
swift test
xcodebuild -project Gingerwrite.xcodeproj -scheme Gingerwrite \
-configuration Debug -derivedDataPath build CODE_SIGNING_ALLOWED=NO build
xcodebuild -project Gingerwrite.xcodeproj -scheme Gingerwrite \
-destination 'platform=macOS,arch=arm64' -derivedDataPath build \
CODE_SIGNING_ALLOWED=NO test
open build/Build/Products/Debug/Gingerwrite.app./scripts/verify.sh runs package tests and the Xcode build with repository-local caches. Xcode
hosted tests require access to macOS testmanager services; the restricted agent sandbox cannot
provide those services, so hosted tests were run with normal host access. Swift package tests run in
the restricted environment, but OS spelling services can be unavailable there. This is distinct from
an application sandbox restriction: the development app is not sandboxed.
The project is checked in and has no external package dependencies. python3 scripts/generate-project.py deterministically regenerates project file references after adding
sources; generation is not a build prerequisite.
Twenty XCTest cases pass in the final app-hosted suite (20:03, 10.1 seconds, zero failures). A separate clean Release build with a fresh derived-data directory also passed for arm64 and x86_64. No Swift compiler warnings remain. Xcode emits its standard notice that App Intents metadata extraction was skipped because the app does not use that framework.
Coverage:
- Word-count policy: apostrophes, hyphens, decimals, punctuation, whitespace, emoji, combining marks, embedded NUL, RTL, and unspaced scripts.
- Goal examples: initial pace, missed day, new writing, due today, overdue, completion, over-target, deletion after completion, invalid values, leap days, DST, and differing time-zone dates.
- SQLite: pragmas/runtime version, migration, unknown newer schema, foreign-key failure, transactional rollback, exact Unicode bytes including normalization-only edits, idempotent retries, stale revision rejection, and unchanged revisions after renames.
- Structural ordering, invalid reorder rollback, same-novel moves, rejected cross-novel moves, guarded act deletion, and net progress after deletion.
- Online backups, seven-copy rotation, staged restoration, corrupted candidate rejection, restoration when the live library cannot open, and pre-restore preservation.
- Recounting caches without new progress; historical time zones preserved across changes; goals and progress survive reopen.
- Exact ordered text export and a 200,000-word novel with 100 subsequent revisions and matching reopened totals/progress.
- Real SQLite
SQLITE_FULLfrom an enforced page limit, proving body/revision/count/progress rollback together. Read-only save failure preserves the in-memory editor buffer and succeeds after retry. - Native editor undo/redo, independent chapter undo managers, selection retention, marked-text composition, TextKit 2 retention, generation feature opt-outs, and rendering-attribute highlights without changing text.
- Debounced autosave, continuous-typing maximum interval, composition deferral, and overlapping flush requests.
Fixtures are deterministic authored phrases generated in the tests. They have no external corpus rights or download requirements. Temporary databases are isolated from the normal Application Support library. App-hosted tests suppress normal app startup.
The app-hosted Debug run at 20:01 on the reference machine measured:
| Measurement | Result |
|---|---|
| Count a 50k chapter and 200k novel together | 14.7 ms |
| 50k chapter assignment plus forced complete TextKit 2 layout, p95 of 20 | 197.0 ms |
| Single native insertion plus display request, p95 of 20 | 40.7 ms |
| Complete 20-case hosted suite | 10.6 s |
These are developer microbenchmarks, not OS event-to-photon or end-to-end navigation guarantees. The editor spike meets the initial 250 ms / 50 ms budgets in the recorded hosted run. A concurrent, restricted run under load measured 703 ms / 109 ms; performance is not uniformly below budget under contention. UI scrolling, cold launch, power/thermal conditions, and long real-world sessions need separate release measurements. No artificial full-document layout is forced by the production editor on each keystroke.
On macOS 26.5.1, launched the built app and verified:
- Create novel/default act/chapter; paste and save multilingual text; live chapter/novel counts.
- Undo/redo, find a word, add a chapter, and switch back with original text intact.
- Set a goal; observe required daily pace and today's signed net change.
- Light and system-dark appearance, selection, visible spelling underline, and Unicode fallback.
- Focus mode hides supporting UI while keeping the active chapter.
- Accessibility tree exposes named editor, title/goal controls, structure, counts, and actions.
- Orderly quit and relaunch restore both chapters, exact text, manuscript totals, and the saved goal.
- File → Export Novel as Text produces exactly the expected 156 UTF-8 bytes for the two-chapter UI fixture, including headings and unmodified chapter bodies.
- Restored appearance to System after testing; the app is left open with the verification manuscript.
The implementation is a usable development build, not a signed/notarized release. macOS 15 and Intel compile targets are supported by the build settings but were not runtime tested on separate machines. A full VoiceOver listening journey, input-method matrix using actual installed IMEs, prolonged real-world writing sessions, forced-process/power failure during staged restore, physical disk exhaustion, and clean-machine install/upgrade remain release qualification tasks. Simulated marked text, SQLite page exhaustion, transaction rollback, and byte-exact reopen are automated evidence, not claims that every hardware failure has been reproduced.
M0–M3 implementation is complete with the evidence above. M4 must finish this matrix before distribution; no language-analysis milestone has been started.