# Plan How the app gets built, in the order it gets built, and what it is built out of. The product is specified in [design.md](design.md) and [features.md](features.md); this document is about the work rather than the result, and it exists so that somebody picking the repository up in six months can see why the pieces landed in the order they did. Work is cut into milestones, and a milestone into work packages. A package is a unit somebody can finish: it owns a set of files, it ends with something that runs, and it never edits another package's files. The package names below are the ones the source comments already use, so a placeholder that says "the contract lands in F3" means the work package named here. ## The milestones **M0, foundations.** F1 is the scaffold: the Tauri crate, the Vite front end, the icons, the justfile and CI. F2 is the design system, which is `src/styles/tokens.css` and the primitives that sit on it, reviewed through the Kit page. F3 is the contracts: `src-tauri/src/dto.rs` and its mirror `src/ipc.ts`, frozen before anything implements them. F4 is the documentation, this file among it. None of M0 sends a byte to Google, and that is the point: the shape is settled while it is still cheap to change. **M1, read.** The milestone that proves the two hard things. R1 is authentication and accounts: the loopback flow, the sealed token, the granted scopes. R2 is the Gmail client behind the `Provider` trait, with the quota arithmetic and the backoff in it. R3 is the mirror and the sync loop, including the storage window and eviction. R4 is the message pipeline: the MIME parse, the sanitiser, the tracker stripper. R5 is the shell, which is the header, the list column, the reading pane and the keyboard. R6 is connect and onboarding, the first thing a new user meets and the last thing built in this milestone, because it cannot be designed honestly until the sync it narrates exists. At the end of M1 the app reads mail and does nothing else. **M2, triage.** T1 is flags and undo: seen, star, archive, trash, spam, each optimistic and each reversible. T2 is selection and bulk actions. T3 is search, local over the window with the provider as the second pass. T4 is labels. At the end of M2 it is a fast Gmail client and nothing more, which is worth having in the hands of one user for a week before the next milestone changes what it is. **M3, places.** P1 is the state database and its journal, the schema that everything after this depends on. P2 is routing: sender rules, the suggestion function, the overrides. P3 is the Screener and the first-run pass. P4 is the Feed and the Paper Trail. P5 is contacts, the contact card and autocomplete. This is the milestone where it stops being a Gmail client. **M4, piles.** L1 is Reply later, Set aside and Focus & Reply. L2 is snooze with lazy evaluation. L3 is notes, rename and merge. L4 is the rest of what the state database makes possible: clips, All files, ignore, per-thread notifications and unsubscribe. **M5, writing.** W1 is the editor and drafts. W2 is the send pipeline: the outbox, the undo delay, attachments, threading headers. W3 is instant intro, remind me if no reply, and calendar invites including the re-authorization that RSVP needs. **M6, accounts, settings and backup.** A1 is more than one account and the unified view. A2 is the settings screen, specified in [settings.md](settings.md). A3 is the backup store, the encryption and the recovery phrase, with the journal merge behind it. **M7, ship.** S1 is the release pipeline: signing, notarisation, the updater. S2 is the verification materials Google's restricted scope review wants, which is a privacy policy that is true, a demo video, and a written justification for each scope. Then the platforms in order: S3 the iPhone, S4 Linux, S5 the IMAP provider. They are last because each one is a second copy of a problem already solved once, and solving it twice before it is solved once is how a project stalls. ## What comes from the siblings Very little here is new, and that is deliberate. Margin Mail sits beside margin and Margin Calendar on disk and takes from both. From the calendar: the OAuth loopback flow with PKCE and its Google-specific handling, the sealed token store, the deep-link path that mobile needs instead of a loopback listener, the overlay title bar and the macOS window behaviour, the `data-phone` and `data-touch` scheme with the boot script that sets them before first paint, the escape-layer stack, the palette, the zustand store idiom, the release workflow's shape, and the `build.rs` trick that embeds `google-credentials.json` with the example file as a fallback. From margin: the HTTP half of `gdrive.rs`, which is folder lookup, upload and download against Drive's v3 API; the trick of putting heavy synchronous work behind `#[tauri::command(async)]`; and `margin-shared`, which is a real dependency rather than a copy. The tokens, the icon strings and the font catalogue come from that package through a relative path in `package.json`, which is why CI checks out both repositories side by side. From neither: the mirror, the state database, the journal, the sanitiser and everything to do with mail. Those are this repository's own work. ## The libraries Every version below was checked against crates.io and npm on 3 September 2026. On the Rust side, `mail-parser` 0.11 with `full_encoding` parses bodies from the raw RFC 2822 bytes; the feature is not optional, because the charsets it adds are the ones that still turn up in real mail every day. `mail-builder` 0.5 builds outgoing MIME. `css-inline` 0.21 folds the editor's stylesheet into the markup before the message is built, so a client that drops `