calternaldav: IMAP mail proxy, all Connected Accounts as one mail account (grill) #486

Open
opened 2026-09-30 06:09:29 +00:00 by kayg · 55 comments
Owner

Idea (owner, 2026-09-30)

"can't calternaldav do a mail proxy as well? basically expose all imap accounts as one? we don't need to think about smtp yet! but it wouldn't hurt"

Shape

calternaldav already runs an IMAP listener for the Notes bridge (#428). Extend it so a mail client (Apple Mail, iOS Mail, Thunderbird) signs in ONCE to calternal and sees every Connected Account's mail, served from the Mail plugin's store (M2/M3), with changes written back to the upstream accounts.

Grill (open; do not build until answered and recorded in DESIGN)

  • G1 Layout: one IMAP account with a unified Inbox plus per-account folder trees (iCloud/…, Fastmail/…), or per-account namespaces only?
  • G2 Write-through: flags, moves and deletes go to the upstream account at once (calternal as a caching proxy), or calternal is the store of record?
  • G3 Categories (People, Newsletters, Receipts…) exposed as virtual folders?
  • G4 Scope: an App Password scope mail (like notes) with an on/off switch in Settings → Apps & Devices.
  • G5 SMTP later: a submission endpoint that relays through the right upstream account. Now: only the minimal port-465 responder that #428 needs to pass the macOS profile check (it refuses to send).
  • G6 Performance: IDLE fan-out across accounts, the UID and UIDVALIDITY mapping for merged views, and a large-mailbox stress run.
    Depends on: #428 IMAP listener, Mail M3 (#397), Connected Accounts (#407).
## Idea (owner, 2026-09-30) "can't calternaldav do a mail proxy as well? basically expose all imap accounts as one? we don't need to think about smtp yet! but it wouldn't hurt" ## Shape calternaldav already runs an IMAP listener for the Notes bridge (#428). Extend it so a mail client (Apple Mail, iOS Mail, Thunderbird) signs in ONCE to calternal and sees every Connected Account's mail, served from the Mail plugin's store (M2/M3), with changes written back to the upstream accounts. ## Grill (open; do not build until answered and recorded in DESIGN) - G1 Layout: one IMAP account with a unified Inbox plus per-account folder trees (`iCloud/…`, `Fastmail/…`), or per-account namespaces only? - G2 Write-through: flags, moves and deletes go to the upstream account at once (calternal as a caching proxy), or calternal is the store of record? - G3 Categories (People, Newsletters, Receipts…) exposed as virtual folders? - G4 Scope: an App Password scope `mail` (like `notes`) with an on/off switch in Settings → Apps & Devices. - G5 SMTP later: a submission endpoint that relays through the right upstream account. Now: only the minimal port-465 responder that #428 needs to pass the macOS profile check (it refuses to send). - G6 Performance: IDLE fan-out across accounts, the UID and UIDVALIDITY mapping for merged views, and a large-mailbox stress run. Depends on: #428 IMAP listener, Mail M3 (#397), Connected Accounts (#407).
Author
Owner

Owner answers (2026-09-30):

  • G1: a unified Inbox plus per-account folders, named <Account Name> / <Folder Name>. The Account Name is the User's own editable name for the Connected Account in calternal.
  • G2: agreed. Changes pass straight through to the upstream account; calternal is a cache, and the provider stays the source of truth.
  • G3: no. Categories and views are features of calternal's own Mail client and are NOT exposed over IMAP for now.
  • G4: no separate Mail App Password. calternaldav exposes Contacts, Calendar, Reminders, Mail and Notes together behind ONE App Password preset (see #412 for the naming). Per-service scopes can stay internally; the User sees one choice.
  • G5 (SMTP): not now. Only the minimal port-465 responder #428 needs for the macOS profile check. It refuses to send.
**Owner answers (2026-09-30):** - **G1:** a unified Inbox plus per-account folders, named `<Account Name> / <Folder Name>`. The Account Name is the User's own editable name for the Connected Account in calternal. - **G2:** agreed. Changes pass straight through to the upstream account; calternal is a cache, and the provider stays the source of truth. - **G3:** no. Categories and views are features of calternal's own Mail client and are NOT exposed over IMAP for now. - **G4:** no separate Mail App Password. calternaldav exposes Contacts, Calendar, Reminders, Mail and Notes together behind ONE App Password preset (see #412 for the naming). Per-service scopes can stay internally; the User sees one choice. - **G5 (SMTP):** not now. Only the minimal port-465 responder #428 needs for the macOS profile check. It refuses to send.
Author
Owner

Owner decisions, grill round 1 (2026-10-01): G2: calternal is a caching proxy: flags, moves and deletes go straight to the upstream account (queued while offline); the upstream accounts stay the truth. Special folders: unified Inbox, Sent, Drafts, Trash, Archive and Junk plus each account's real folders as " / "; delete/archive route to the message's own account. Sending waits (SMTP is not settled in the main app yet). Owner: "Please test it too": real Apple Mail on the macOS VM is part of the acceptance. Earlier: categories are not exposed as folders; the Sync with Your Devices App Password covers Mail.

**Owner decisions, grill round 1 (2026-10-01):** G2: calternal is a **caching proxy**: flags, moves and deletes go straight to the upstream account (queued while offline); the upstream accounts stay the truth. Special folders: **unified Inbox, Sent, Drafts, Trash, Archive and Junk** plus each account's real folders as "<Account Name> / <Folder>"; delete/archive route to the message's own account. **Sending waits** (SMTP is not settled in the main app yet). Owner: "Please test it too": real Apple Mail on the macOS VM is part of the acceptance. Earlier: categories are not exposed as folders; the Sync with Your Devices App Password covers Mail.
Author
Owner

Owner decisions, grill round 2 (2026-10-01): drafts saved from Apple Mail go to the account matching the From address (else the default Mail account), stored upstream at once. Performance: "stress test and optimise aggressively. Network latency should be the only delay." Budgets: unified Inbox newest messages within 2 s for 3 accounts / ~10k messages; new mail via IDLE within 5 s; flags/moves visible upstream within 5 s; calternal's own overhead per command must be negligible next to upstream round trips. Real Apple Mail on the macOS VM + a large-mailbox stress run.

**Owner decisions, grill round 2 (2026-10-01):** drafts saved from Apple Mail go to the account matching the From address (else the default Mail account), stored upstream at once. **Performance:** "stress test and optimise aggressively. Network latency should be the only delay." Budgets: unified Inbox newest messages within 2 s for 3 accounts / ~10k messages; new mail via IDLE within 5 s; flags/moves visible upstream within 5 s; calternal's own overhead per command must be negligible next to upstream round trips. Real Apple Mail on the macOS VM + a large-mailbox stress run.
Author
Owner

Started #486 on job/mailproxy-486 at base 2f4482ded. Read CLAUDE.md, CONTEXT.md, DESIGN §49/§53 and all three owner comments. Reuse the existing calternal-imap listener and encrypted Connected Account resolver. The cache currently retains only bounded parsed bodies, not complete MIME; the proxy needs a separate bounded raw-message cache and stable virtual UIDs. Job brief overrides §53 on sending and a Mail preset; these differences will be documented.

Started #486 on job/mailproxy-486 at base 2f4482ded. Read CLAUDE.md, CONTEXT.md, DESIGN §49/§53 and all three owner comments. Reuse the existing calternal-imap listener and encrypted Connected Account resolver. The cache currently retains only bounded parsed bodies, not complete MIME; the proxy needs a separate bounded raw-message cache and stable virtual UIDs. Job brief overrides §53 on sending and a Mail preset; these differences will be documented.
Author
Owner

Findings on base 2f4482ded:

  • mail::sync::fetch_window requests BODY.PEEK[]<0.65536>; normalize_fetch retains parsed text/HTML only. That projection cannot supply exact MIME, attachments or signed messages to IMAP clients. Keep it unchanged and add a separate bounded full-message cache on demand.
  • IntegrationAccount has no display-name field. Use the existing email label in the first protocol slice and record editable Account Name as pending.
  • calternal-imap::Session hard-codes Notes mailbox validation, rejects INBOX, reports every message Seen, and parses every APPEND as an Apple Note. These need provider hooks while preserving the Notes default behavior.
  • §53 and all owner comments explicitly defer sending and keep one device preset, whereas the job brief asks for SMTP relay and a Mail preset. The report must identify this scope difference rather than claim owner acceptance.
Findings on base 2f4482ded: - `mail::sync::fetch_window` requests `BODY.PEEK[]<0.65536>`; `normalize_fetch` retains parsed text/HTML only. That projection cannot supply exact MIME, attachments or signed messages to IMAP clients. Keep it unchanged and add a separate bounded full-message cache on demand. - `IntegrationAccount` has no display-name field. Use the existing email label in the first protocol slice and record editable Account Name as pending. - `calternal-imap::Session` hard-codes Notes mailbox validation, rejects INBOX, reports every message Seen, and parses every APPEND as an Apple Note. These need provider hooks while preserving the Notes default behavior. - §53 and all owner comments explicitly defer sending and keep one device preset, whereas the job brief asks for SMTP relay and a Mail preset. The report must identify this scope difference rather than claim owner acceptance.
Author
Owner

Progress: commits 6865af634 (provider mailbox namespaces) and a086a5748 (provider flags/unread reads) pass calternal-imap format, clippy and tests. Read-only review found valid $Junk keywords rejected by the new flag validator and missing namespace-independent mailbox wire limits. Regression tests are written; corrections follow after the Mail test build completes.

The first calternal-plugin-mail test build has taken about 27 minutes on the shared host, with four build jobs, and is compiling the crate itself. Its owner-isolation and UID-reset tests use an inert local Index fixture and never open a real mailbox. The cache provider is a test stub until these tests execute; it is not a delivered endpoint.

Progress: commits 6865af634 (provider mailbox namespaces) and a086a5748 (provider flags/unread reads) pass calternal-imap format, clippy and tests. Read-only review found valid `$Junk` keywords rejected by the new flag validator and missing namespace-independent mailbox wire limits. Regression tests are written; corrections follow after the Mail test build completes. The first calternal-plugin-mail test build has taken about 27 minutes on the shared host, with four build jobs, and is compiling the crate itself. Its owner-isolation and UID-reset tests use an inert local Index fixture and never open a real mailbox. The cache provider is a test stub until these tests execute; it is not a delivered endpoint.
Author
Owner

Cache foundation in progress. The shared IMAP prerequisite commits remain 6865af634, a086a5748 and 8dbd99815. The first full Mail crate run produced:

test result: FAILED. 47 passed; 1 failed; 4 ignored; 0 measured; 0 filtered out; finished in 6.87s

The failed assertion enumerates all mail_* tables. Migration 0010 adds mail_proxy_bodies, mail_proxy_clock, mail_proxy_uids and mail_proxy_views, so the test now includes those four tables. No prior table or assertion was removed. This is the schema change requested by #486, rather than a changed protocol expectation. The next run includes additional tests for cached-body ownership, disabled accounts and concurrent SELECTs. Read-side implementation and its gates are still pending; no listener, sending or setup completion is claimed.

Cache foundation in progress. The shared IMAP prerequisite commits remain 6865af634, a086a5748 and 8dbd99815. The first full Mail crate run produced: ``` test result: FAILED. 47 passed; 1 failed; 4 ignored; 0 measured; 0 filtered out; finished in 6.87s ``` The failed assertion enumerates all mail_* tables. Migration 0010 adds mail_proxy_bodies, mail_proxy_clock, mail_proxy_uids and mail_proxy_views, so the test now includes those four tables. No prior table or assertion was removed. This is the schema change requested by #486, rather than a changed protocol expectation. The next run includes additional tests for cached-body ownership, disabled accounts and concurrent SELECTs. Read-side implementation and its gates are still pending; no listener, sending or setup completion is claimed.
Author
Owner

Read-only review found two concrete cache defects before listener integration:

  1. The per-view fingerprint omitted message MODSEQ. Flags can change and return to the original value through another view, leaving an older account-view HIGHESTMODSEQ below the message revision. An overlapping-view regression is added before the fix.
  2. Vendored async-imap parse_fetches can exhaust at clean EOF without a tagged completion. A complete untagged body must not enter the exact MIME cache after that disconnect. A finite duplex-stream regression is added before the fix. The provider will use an explicit checked completion boundary.

The most recent full Mail run passed 50 tests, with 4 manual tests ignored. Clippy is still compiling dependencies on the shared host (load average above 100); the review regressions are queued behind that build. This is build progress, not a request to wait for a quiet host. No API or listener completion is claimed.

Read-only review found two concrete cache defects before listener integration: 1. The per-view fingerprint omitted message MODSEQ. Flags can change and return to the original value through another view, leaving an older account-view HIGHESTMODSEQ below the message revision. An overlapping-view regression is added before the fix. 2. Vendored async-imap parse_fetches can exhaust at clean EOF without a tagged completion. A complete untagged body must not enter the exact MIME cache after that disconnect. A finite duplex-stream regression is added before the fix. The provider will use an explicit checked completion boundary. The most recent full Mail run passed 50 tests, with 4 manual tests ignored. Clippy is still compiling dependencies on the shared host (load average above 100); the review regressions are queued behind that build. This is build progress, not a request to wait for a quiet host. No API or listener completion is claimed.
Author
Owner

Checkpoint: 9dd99c56c persists the owner-bound Mail proxy cache and its profile. DESIGN/CONTEXT choices are recorded in 309774149. The provider is not connected to the listener yet.

Review fixes are tested: overlapping unified/account views include message MODSEQ in their fingerprint, and a cache miss requires an explicit checked tagged NOOP after FETCH. The latter adds one upstream round trip and rejects a disconnect before caching.

Current Mail test output:

test result: ok. 52 passed; 0 failed; 4 ignored; 0 measured; 0 filtered out; finished in 9.18s

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

The existing bench/mail-sync.py sampler ran the new 3-account / 10,001-message profile locally in a debug build. Three serial runs: cold 769–2350 ms; warm p50 1045–1300 ms; p95 1808–3036 ms; worker CPU 18.7–39.4%; peak RSS 25.0–25.1 MiB. Three concurrent workers: p50 267–956 ms; p95 1543–2520 ms; CPU 18.4–25.8%; peak RSS 24.4–25.0 MiB. Load averages were 118.25/116.38/117.54 before and 115.48/114.29/116.24 after. Each worker has its own fixture Index. The baseline file has no comparable proxy snapshot profile; mail.accounts measures HTTP account listing. These loaded-host debug numbers do not prove the §53 2 s budget.

Clippy is still building dependencies. The local TLS Dovecot fixture is reachable on its isolated port and has the expected 2000 messages and UIDVALIDITY. Its exact-body cache test is pending the feature build. Authentication, queued writes, SMTP relay, setup UI and client acceptance remain open.

Checkpoint: 9dd99c56c persists the owner-bound Mail proxy cache and its profile. DESIGN/CONTEXT choices are recorded in 309774149. The provider is not connected to the listener yet. Review fixes are tested: overlapping unified/account views include message MODSEQ in their fingerprint, and a cache miss requires an explicit checked tagged NOOP after FETCH. The latter adds one upstream round trip and rejects a disconnect before caching. Current Mail test output: ``` test result: ok. 52 passed; 0 failed; 4 ignored; 0 measured; 0 filtered out; finished in 9.18s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s ``` The existing bench/mail-sync.py sampler ran the new 3-account / 10,001-message profile locally in a debug build. Three serial runs: cold 769–2350 ms; warm p50 1045–1300 ms; p95 1808–3036 ms; worker CPU 18.7–39.4%; peak RSS 25.0–25.1 MiB. Three concurrent workers: p50 267–956 ms; p95 1543–2520 ms; CPU 18.4–25.8%; peak RSS 24.4–25.0 MiB. Load averages were 118.25/116.38/117.54 before and 115.48/114.29/116.24 after. Each worker has its own fixture Index. The baseline file has no comparable proxy snapshot profile; mail.accounts measures HTTP account listing. These loaded-host debug numbers do not prove the §53 2 s budget. Clippy is still building dependencies. The local TLS Dovecot fixture is reachable on its isolated port and has the expected 2000 messages and UIDVALIDITY. Its exact-body cache test is pending the feature build. Authentication, queued writes, SMTP relay, setup UI and client acceptance remain open.
Author
Owner

One additional protocol finding from source review: LIST bounds each display name and pattern, but its dynamic matcher has no aggregate work budget across the provider namespace. #486 adds a larger namespace. A finite in-memory regression now checks that the shared session rejects excessive total matching work without emitting partial LIST data. It uses no live server or mailbox. The regression is queued behind the current dependency build; the guard is not implemented or claimed passing yet.

One additional protocol finding from source review: LIST bounds each display name and pattern, but its dynamic matcher has no aggregate work budget across the provider namespace. #486 adds a larger namespace. A finite in-memory regression now checks that the shared session rejects excessive total matching work without emitting partial LIST data. It uses no live server or mailbox. The regression is queued behind the current dependency build; the guard is not implemented or claimed passing yet.
Author
Owner

Merged origin/dev at 440e19dce2 and moved origin/job/merge-round-7a at efe8323fe8. Head: 7981706f1. Migration 0010 remains unique on both fetched branches.

Final merged IMAP gates passed:

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 1m 27s

The seven IMAP integration suites passed: 5, 3, 8, 30, 7, 5 and 5 tests; unit/doc tests have no cases. cargo fmt --check exited 0 without output. Web check:

svelte-check found 0 errors and 0 warnings

Mail clippy and web tests are running. Web tests currently include a 5,009 ms timeout in untouched collaborationUndo.svelte.test.ts. No existing expectation was changed.

Final source review found SQLite length(TEXT) counts characters instead of bytes. An uncommitted fix uses length(CAST(flags_json AS BLOB)) and adds a multibyte regression. The benchmark is extended to 100,000-message worst/burst workloads; that extension is awaiting compilation and measurement.

This remains a cache/IMAP prerequisite, not a usable Mail endpoint. Listener/authentication wiring, queued mutations, generic Mail client FETCH/APPEND/COPY/MOVE support, SMTP relay, app-password preset, profile/setup UI, live IMAP/SMTP xuser matrix and complete protocol probes are outstanding. No owner mailbox or Mac VM was contacted.

Merged origin/dev at 440e19dce23040ac8ebaae88f0469b6535b1afcb and moved origin/job/merge-round-7a at efe8323fe827e106d1e1b669308602f64e7fb7d1. Head: 7981706f1. Migration 0010 remains unique on both fetched branches. Final merged IMAP gates passed: ``` Finished `dev` profile [unoptimized + debuginfo] target(s) in 1m 27s ``` The seven IMAP integration suites passed: 5, 3, 8, 30, 7, 5 and 5 tests; unit/doc tests have no cases. cargo fmt --check exited 0 without output. Web check: ``` svelte-check found 0 errors and 0 warnings ``` Mail clippy and web tests are running. Web tests currently include a 5,009 ms timeout in untouched collaborationUndo.svelte.test.ts. No existing expectation was changed. Final source review found SQLite length(TEXT) counts characters instead of bytes. An uncommitted fix uses length(CAST(flags_json AS BLOB)) and adds a multibyte regression. The benchmark is extended to 100,000-message worst/burst workloads; that extension is awaiting compilation and measurement. This remains a cache/IMAP prerequisite, not a usable Mail endpoint. Listener/authentication wiring, queued mutations, generic Mail client FETCH/APPEND/COPY/MOVE support, SMTP relay, app-password preset, profile/setup UI, live IMAP/SMTP xuser matrix and complete protocol probes are outstanding. No owner mailbox or Mac VM was contacted.
Author
Owner

Partial handoff: Mail proxy cache foundation. #486 is NOT complete and does not provide a usable Mail endpoint. Do not merge this as the full #486 slice.

Branch: job/mailproxy-486. Head: 7f796c4ca8. Base: 2f4482ded. Required remote branches were fetched and merged once: origin/dev 440e19dce2 and origin/job/merge-round-7a efe8323fe8. Mail migration 0010 was free on both fetched branches. No push or deploy.

Built:

  • Shared IMAP provider hooks for mailbox namespaces and flags. Notes defaults stay compatible. Mail STATUS, SEARCH and FETCH agree on unread state.
  • Owner-bound Mail cache views for the six unified folders and enabled accounts' real folders. Persistent virtual UIDs survive sessions and change after provider epoch resets. Concurrent views share a single writer clock.
  • A bounded exact MIME cache, with shared encrypted credential resolution and upstream TLS/SSRF checks. Bodies require UID, epoch, size and tagged completion checks.
  • Per-name and total LIST matching bounds. A rejected LIST emits no partial folder list. UTF-8 flag metadata is counted in bytes.
  • Cache isolation, concurrent SELECT, UID epoch and MIME completion regression tests. The shared IMAP test uses a scripted normal Mail command sequence.
  • A bench profile for 10,001 messages, 100,000 messages and a three-client burst. DESIGN and CONTEXT describe the implemented prerequisite.

Files:

  • crates/calternal-imap/src/store.rs; src/session.rs; tests/mail.rs.
  • crates/plugins/mail/src/proxy.rs; src/proxy_tests.rs; src/lib.rs; src/cache/store.rs; migrations/0010_mail_proxy.sql; Cargo.toml.
  • Cargo.lock; bench/mail-sync.py; docs/DESIGN.md; CONTEXT.md.
    Module and changed function comments were reviewed before handoff. No UI files changed.

Gates, output quoted verbatim:

cargo fmt --check (exit 0; no formatter output):

fmt exit: 0

cargo clippy -p calternal-imap --all-targets -- -D warnings (exit 0):

Finished `dev` profile [unoptimized + debuginfo] target(s) in 1m 27s

cargo test -p calternal-imap (exit 0; 63 integration tests):

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.63s
test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s
test result: ok. 8 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
test result: ok. 30 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.63s
test result: ok. 7 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.02s
test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

cargo test -p calternal-plugin-mail (exit 0):

test result: ok. 53 passed; 0 failed; 4 ignored; 0 measured; 0 filtered out; finished in 14.89s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

cargo clippy -p calternal-plugin-mail --all-targets -- -D warnings did not finish. It was interrupted during dependency compilation at the handoff time-box, then resumed with the final fix and interrupted again. It is not a passing gate:

Mail clippy exit: 255

No calternal-server gates were run. No server route or listener was changed; server integration remains unverified.

Web bun run check (exit 0):

svelte-check found 0 errors and 0 warnings

Web bun run test -- --maxWorkers=1 (exit 1):

Error: Test timed out in 5000ms.
 Test Files  1 failed | 153 passed (154)
      Tests  1 failed | 1072 passed (1073)
error: script "test" exited with code 1

The failing test is the untouched collaborationUndo.svelte.test.ts case “undoes duplicate removal without undoing later text”. Existing expectations were not relaxed.

Performance (local debug build, shared host; no comparable cache-view baseline):

  • Three accounts, 10,001 messages, three runs: p50 267.73–391.80 ms; p95 918.62–1830.51 ms; cold 675.21–4975.04 ms. CPU 45.62–51.47%; CPU time 15.00–17.15 s; peak RSS 24.86–26.01 MiB.
  • 100,000 messages: p50 4107.35 ms; p95 6070.54 ms; cold 10042.25 ms; CPU 58.72%; CPU time 84.83 s; peak RSS 108.34 MiB.
  • Three concurrent 100,000-message workers: p50 5733.85–6655.32 ms; p95 9259.63–11238.13 ms; CPU 59.44–61.94%; peak RSS about 107.75–107.87 MiB per worker.
  • Load averages before: 123.11 / 121.81 / 112.27; after: 118.55 / 124.01 / 117.02. The existing docs/perf/baseline.json mail.accounts values (p50 1.3 ms, p95 3.8 ms) measure HTTP account listing, not this path. These results do not prove the §53 2-second budget; the cold result exceeds it. The perf VM was not used. JSON: artifacts/486-proxy-perf-final.json.

Known gaps:

  • Mail provider registration with the existing TLS listener, app-password service scope and new Mail preset. Authentication and listener rate limits have not been tested for Mail.
  • Generic Mail client FETCH structure/parts, raw APPEND, flags, COPY/MOVE, deletes/archive, durable offline write queue and From/default-account draft routing. Mutation methods remain unavailable.
  • SMTP submission and matching-From relay, including rejection of open relay use.
  • Editable Connected Account names and Settings → Apps setup profile/instructions.
  • Live IMAP/SMTP cross-user matrix and a complete hostile-protocol round. Finite defensive in-memory tests cover display bounds, LIST work, flags, epoch and completion rules; they are not a live endpoint audit.
  • The ignored test-provider exact-body TLS test was added but was not compiled/run with that feature. A positive scripted TLS login/STATUS succeeded against the isolated Dovecot fixture, which had 2,000 messages. No owner mailbox was contacted.
  • Mail clippy, server integration gates, real Mail clients and release/perf-VM measurements remain pending.

Decisions:

  • Use one persistent per-User virtual UID clock, with provider folder generation and remote UID as coordinates. Unified and real-folder views share UIDs.
  • Limit MIME to 4 MiB per body and 128 MiB per User; limit selected metadata to 100,000 messages and 16 MiB of flags; limit LIST matching to 8 MiB of work cells. Oversized bodies are refused, never truncated.
  • Use email as the account label until editable Account Name exists; duplicate labels include the stable account ID. This is temporary and does not settle the requested Account Name behavior.
  • Check a NOOP completion after FETCH because the vendored FETCH stream can accept clean EOF. This adds one upstream round trip on a body cache miss.
  • The latest job brief requests SMTP and a Mail preset while §53 currently defers sending and specifies the shared Sync preset. Those features were not implemented; the contradiction remains recorded rather than silently rewriting the owner decision.

UX gaps closed: none; no UI was built.
UX gaps left: Settings setup/profile, editable names and functional Mail read/write/send actions.

Mac checks pending (VM offline; no connection attempted):

  1. Install the completed macOS/iOS setup profile and sign in with the intended app-password preset.
  2. Apple Mail: verify all unified and real folders, Unicode names, 3 accounts/10,000 messages, IDLE arrival and account isolation.
  3. Verify read/unread, move, delete/archive to the message's own account, offline queue/reconnect and cross-view updates.
  4. Verify drafts by From/default account, matching-account SMTP submission, unknown From rejection and app-password revocation.
  5. Repeat setup and basic sync on iOS Mail; verify the same shared IMAP stack still serves Apple Notes.

Cleanup: Dovecot fixture stopped; generated fixture keys and web build output removed. cargo clean exited 0:

     Removed 6030 files, 2.4GiB total
``` Review artifacts remain ignored in artifacts/.
Partial handoff: Mail proxy cache foundation. #486 is NOT complete and does not provide a usable Mail endpoint. Do not merge this as the full #486 slice. Branch: job/mailproxy-486. Head: 7f796c4ca84034f1d645573e097c36a738daba30. Base: 2f4482ded. Required remote branches were fetched and merged once: origin/dev 440e19dce23040ac8ebaae88f0469b6535b1afcb and origin/job/merge-round-7a efe8323fe827e106d1e1b669308602f64e7fb7d1. Mail migration 0010 was free on both fetched branches. No push or deploy. Built: - Shared IMAP provider hooks for mailbox namespaces and flags. Notes defaults stay compatible. Mail STATUS, SEARCH and FETCH agree on unread state. - Owner-bound Mail cache views for the six unified folders and enabled accounts' real folders. Persistent virtual UIDs survive sessions and change after provider epoch resets. Concurrent views share a single writer clock. - A bounded exact MIME cache, with shared encrypted credential resolution and upstream TLS/SSRF checks. Bodies require UID, epoch, size and tagged completion checks. - Per-name and total LIST matching bounds. A rejected LIST emits no partial folder list. UTF-8 flag metadata is counted in bytes. - Cache isolation, concurrent SELECT, UID epoch and MIME completion regression tests. The shared IMAP test uses a scripted normal Mail command sequence. - A bench profile for 10,001 messages, 100,000 messages and a three-client burst. DESIGN and CONTEXT describe the implemented prerequisite. Files: - crates/calternal-imap/src/store.rs; src/session.rs; tests/mail.rs. - crates/plugins/mail/src/proxy.rs; src/proxy_tests.rs; src/lib.rs; src/cache/store.rs; migrations/0010_mail_proxy.sql; Cargo.toml. - Cargo.lock; bench/mail-sync.py; docs/DESIGN.md; CONTEXT.md. Module and changed function comments were reviewed before handoff. No UI files changed. Gates, output quoted verbatim: cargo fmt --check (exit 0; no formatter output): ``` fmt exit: 0 ``` cargo clippy -p calternal-imap --all-targets -- -D warnings (exit 0): ``` Finished `dev` profile [unoptimized + debuginfo] target(s) in 1m 27s ``` cargo test -p calternal-imap (exit 0; 63 integration tests): ``` test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.63s test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s test result: ok. 8 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s test result: ok. 30 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.63s test result: ok. 7 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.02s test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s ``` cargo test -p calternal-plugin-mail (exit 0): ``` test result: ok. 53 passed; 0 failed; 4 ignored; 0 measured; 0 filtered out; finished in 14.89s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s ``` cargo clippy -p calternal-plugin-mail --all-targets -- -D warnings did not finish. It was interrupted during dependency compilation at the handoff time-box, then resumed with the final fix and interrupted again. It is not a passing gate: ``` Mail clippy exit: 255 ``` No calternal-server gates were run. No server route or listener was changed; server integration remains unverified. Web bun run check (exit 0): ``` svelte-check found 0 errors and 0 warnings ``` Web bun run test -- --maxWorkers=1 (exit 1): ``` Error: Test timed out in 5000ms. Test Files 1 failed | 153 passed (154) Tests 1 failed | 1072 passed (1073) error: script "test" exited with code 1 ``` The failing test is the untouched collaborationUndo.svelte.test.ts case “undoes duplicate removal without undoing later text”. Existing expectations were not relaxed. Performance (local debug build, shared host; no comparable cache-view baseline): - Three accounts, 10,001 messages, three runs: p50 267.73–391.80 ms; p95 918.62–1830.51 ms; cold 675.21–4975.04 ms. CPU 45.62–51.47%; CPU time 15.00–17.15 s; peak RSS 24.86–26.01 MiB. - 100,000 messages: p50 4107.35 ms; p95 6070.54 ms; cold 10042.25 ms; CPU 58.72%; CPU time 84.83 s; peak RSS 108.34 MiB. - Three concurrent 100,000-message workers: p50 5733.85–6655.32 ms; p95 9259.63–11238.13 ms; CPU 59.44–61.94%; peak RSS about 107.75–107.87 MiB per worker. - Load averages before: 123.11 / 121.81 / 112.27; after: 118.55 / 124.01 / 117.02. The existing docs/perf/baseline.json mail.accounts values (p50 1.3 ms, p95 3.8 ms) measure HTTP account listing, not this path. These results do not prove the §53 2-second budget; the cold result exceeds it. The perf VM was not used. JSON: artifacts/486-proxy-perf-final.json. Known gaps: - Mail provider registration with the existing TLS listener, app-password service scope and new Mail preset. Authentication and listener rate limits have not been tested for Mail. - Generic Mail client FETCH structure/parts, raw APPEND, flags, COPY/MOVE, deletes/archive, durable offline write queue and From/default-account draft routing. Mutation methods remain unavailable. - SMTP submission and matching-From relay, including rejection of open relay use. - Editable Connected Account names and Settings → Apps setup profile/instructions. - Live IMAP/SMTP cross-user matrix and a complete hostile-protocol round. Finite defensive in-memory tests cover display bounds, LIST work, flags, epoch and completion rules; they are not a live endpoint audit. - The ignored test-provider exact-body TLS test was added but was not compiled/run with that feature. A positive scripted TLS login/STATUS succeeded against the isolated Dovecot fixture, which had 2,000 messages. No owner mailbox was contacted. - Mail clippy, server integration gates, real Mail clients and release/perf-VM measurements remain pending. Decisions: - Use one persistent per-User virtual UID clock, with provider folder generation and remote UID as coordinates. Unified and real-folder views share UIDs. - Limit MIME to 4 MiB per body and 128 MiB per User; limit selected metadata to 100,000 messages and 16 MiB of flags; limit LIST matching to 8 MiB of work cells. Oversized bodies are refused, never truncated. - Use email as the account label until editable Account Name exists; duplicate labels include the stable account ID. This is temporary and does not settle the requested Account Name behavior. - Check a NOOP completion after FETCH because the vendored FETCH stream can accept clean EOF. This adds one upstream round trip on a body cache miss. - The latest job brief requests SMTP and a Mail preset while §53 currently defers sending and specifies the shared Sync preset. Those features were not implemented; the contradiction remains recorded rather than silently rewriting the owner decision. UX gaps closed: none; no UI was built. UX gaps left: Settings setup/profile, editable names and functional Mail read/write/send actions. Mac checks pending (VM offline; no connection attempted): 1. Install the completed macOS/iOS setup profile and sign in with the intended app-password preset. 2. Apple Mail: verify all unified and real folders, Unicode names, 3 accounts/10,000 messages, IDLE arrival and account isolation. 3. Verify read/unread, move, delete/archive to the message's own account, offline queue/reconnect and cross-view updates. 4. Verify drafts by From/default account, matching-account SMTP submission, unknown From rejection and app-password revocation. 5. Repeat setup and basic sync on iOS Mail; verify the same shared IMAP stack still serves Apple Notes. Cleanup: Dovecot fixture stopped; generated fixture keys and web build output removed. cargo clean exited 0: ``` Removed 6030 files, 2.4GiB total ``` Review artifacts remain ignored in artifacts/.
Author
Owner

Static audit evidence for DESIGN §53 Mail proxy over CalternalDAV:

The server IMAP listener is explicitly the Apple Notes bridge: crates/calternal-imap/README.md:1-5 and crates/calternal-server/src/notes_imap.rs:1-4. The Mail plugin IMAP module instead connects to user-supplied provider endpoints: crates/plugins/mail/src/imap.rs:1-6. I found no unified CalternalDAV IMAP account over Connected Accounts.

Expected: one Calternal IMAP login exposes unified folders plus each account folder and proxies upstream changes. Regression idea: verify a real mail client sees both accounts and that queued flag/move/delete operations reach the correct upstream after reconnect.

Static audit evidence for DESIGN §53 Mail proxy over CalternalDAV: The server IMAP listener is explicitly the Apple Notes bridge: crates/calternal-imap/README.md:1-5 and crates/calternal-server/src/notes_imap.rs:1-4. The Mail plugin IMAP module instead connects to user-supplied provider endpoints: crates/plugins/mail/src/imap.rs:1-6. I found no unified CalternalDAV IMAP account over Connected Accounts. Expected: one Calternal IMAP login exposes unified folders plus each account folder and proxies upstream changes. Regression idea: verify a real mail client sees both accounts and that queued flag/move/delete operations reach the correct upstream after reconnect.
Author
Owner

Independent read-only review started on job/rev2-mailproxy-486, base 440e19dce2. Review target: 7f796c4ca. Scope: Mail proxy cache, virtual UIDs, MIME cache and shared IMAP hooks. No builds, tests, servers or browser runs will be made (LIGHT class). Findings will be committed in audit-findings.md and review-mailproxy-486.md.

Independent read-only review started on job/rev2-mailproxy-486, base 440e19dce23040ac8ebaae88f0469b6535b1afcb. Review target: 7f796c4ca. Scope: Mail proxy cache, virtual UIDs, MIME cache and shared IMAP hooks. No builds, tests, servers or browser runs will be made (LIGHT class). Findings will be committed in audit-findings.md and review-mailproxy-486.md.
Author
Owner

Independent read-only review of job/mailproxy-486 at 7f796c4ca is complete.
Review head: 042b0e92392f196992f306cdac7491e868b96d3f on
job/rev2-mailproxy-486. Commits: 6c6dee440, 042b0e923.

Built: review documents only, review-mailproxy-486.md and audit-findings.md.
The source worktree was not changed. The author's report was not used.

Findings, ranked:

  1. P1 completion gap — #486 remains incomplete.
    crates/calternal-server/src/notes_imap.rs:368 constructs only the Notes
    provider. crates/plugins/mail/src/proxy.rs:329 supplies no upstream write
    or draft methods. Connect Mail to the authenticated listener, implement
    upstream flags/moves/deletes and offline writes, route drafts by From or
    default account, and finish the shared App Password setup. This branch's
    DESIGN addition explicitly calls the work a cache foundation; that partial
    scope does not satisfy full §53 acceptance.
  2. P2 — #897: ordinary Mail
    BODYSTRUCTURE fails.
    crates/calternal-imap/src/session.rs:544 calls the
    helper at crates/calternal-imap/src/mime.rs:302, which requires an Apple
    Note. Use a bounded general MIME helper or provider hook and keep Note-only
    validation at the Notes boundary.
  3. P2 — #898: a provider
    epoch reset hides the live mailbox during backfill.

    crates/plugins/mail/src/proxy.rs:31 compares old live memberships to the
    new f.uid_validity written at cache/store.rs:796. Resolve the committed
    epoch through the live generation record and switch views only at activation.
  4. P2 — #899: account
    visibility changes restore expunged UIDs and change retained sequence numbers.

    crates/plugins/mail/src/proxy.rs:156 retains old mappings;
    crates/calternal-imap/src/session.rs:659 cannot report insertion before a
    retained UID. Preserve append-only membership per mailbox epoch or reset
    that epoch before old UIDs return.
  5. P2 — evidence added to #684:
    metadata FETCH downloads full MIME.

    crates/calternal-imap/src/session.rs:476, :492 call render; the Mail
    miss path fetches the full body at crates/plugins/mail/src/proxy.rs:291.
    Calls are serial. Headers of messages above 4 MiB also fail. Store exact
    headers and size during sync and add provider metadata hooks.

Each issue has static evidence, expected behaviour, a fix and a regression
test idea. Searches found no issue with the same fix for #897–#899. No direct
cross-User read path was found in the provider joins. Production Mail
authority remains unverified because this provider has no production caller.

Gate output: none. The LIGHT instructions prohibit builds, tests, servers and
browsers. git diff --check returned exit 0 with no output. No performance
numbers or runtime reproductions are claimed. No product decisions were made.
UX gaps closed: none. UX gaps left: the production listener and the four read
defects above. The review document lists exact deferred gate and profile
commands and the Apple-client behaviours that the merge round must prove.

At the reviewed commit, DESIGN §58 is Agent discovery, not the later speed
architecture. The performance assessment uses the owner rule and §53 budgets.
The foundation text also says sending must be complete; correct that wording
to the existing refusal responder, because the main §53 decision excludes sending.

Do not mark #486 complete. A foundation-only merge needs separate scope review
and the read-path fixes above.

Independent read-only review of `job/mailproxy-486` at `7f796c4ca` is complete. Review head: `042b0e92392f196992f306cdac7491e868b96d3f` on `job/rev2-mailproxy-486`. Commits: `6c6dee440`, `042b0e923`. Built: review documents only, `review-mailproxy-486.md` and `audit-findings.md`. The source worktree was not changed. The author's report was not used. Findings, ranked: 1. **P1 completion gap — #486 remains incomplete.** `crates/calternal-server/src/notes_imap.rs:368` constructs only the Notes provider. `crates/plugins/mail/src/proxy.rs:329` supplies no upstream write or draft methods. Connect Mail to the authenticated listener, implement upstream flags/moves/deletes and offline writes, route drafts by From or default account, and finish the shared App Password setup. This branch's DESIGN addition explicitly calls the work a cache foundation; that partial scope does not satisfy full §53 acceptance. 2. **P2 — [#897](https://git.kayg.org/kayg/calternal/issues/897): ordinary Mail BODYSTRUCTURE fails.** `crates/calternal-imap/src/session.rs:544` calls the helper at `crates/calternal-imap/src/mime.rs:302`, which requires an Apple Note. Use a bounded general MIME helper or provider hook and keep Note-only validation at the Notes boundary. 3. **P2 — [#898](https://git.kayg.org/kayg/calternal/issues/898): a provider epoch reset hides the live mailbox during backfill.** `crates/plugins/mail/src/proxy.rs:31` compares old live memberships to the new `f.uid_validity` written at `cache/store.rs:796`. Resolve the committed epoch through the live generation record and switch views only at activation. 4. **P2 — [#899](https://git.kayg.org/kayg/calternal/issues/899): account visibility changes restore expunged UIDs and change retained sequence numbers.** `crates/plugins/mail/src/proxy.rs:156` retains old mappings; `crates/calternal-imap/src/session.rs:659` cannot report insertion before a retained UID. Preserve append-only membership per mailbox epoch or reset that epoch before old UIDs return. 5. **P2 — evidence added to [#684](https://git.kayg.org/kayg/calternal/issues/684): metadata FETCH downloads full MIME.** `crates/calternal-imap/src/session.rs:476`, `:492` call `render`; the Mail miss path fetches the full body at `crates/plugins/mail/src/proxy.rs:291`. Calls are serial. Headers of messages above 4 MiB also fail. Store exact headers and size during sync and add provider metadata hooks. Each issue has static evidence, expected behaviour, a fix and a regression test idea. Searches found no issue with the same fix for #897–#899. No direct cross-User read path was found in the provider joins. Production Mail authority remains unverified because this provider has no production caller. Gate output: none. The LIGHT instructions prohibit builds, tests, servers and browsers. `git diff --check` returned exit 0 with no output. No performance numbers or runtime reproductions are claimed. No product decisions were made. UX gaps closed: none. UX gaps left: the production listener and the four read defects above. The review document lists exact deferred gate and profile commands and the Apple-client behaviours that the merge round must prove. At the reviewed commit, DESIGN §58 is Agent discovery, not the later speed architecture. The performance assessment uses the owner rule and §53 budgets. The foundation text also says sending must be complete; correct that wording to the existing refusal responder, because the main §53 decision excludes sending. Do not mark #486 complete. A foundation-only merge needs separate scope review and the read-path fixes above.
Author
Owner

Started the next #486 round on job/mailproxy-486 at base 7f796c4ca8. Read repository rules, DESIGN §§7,21,45,49,53, the prior report and independent review. Fix #897, #898, #899 and the #684 metadata finding first with focused regressions. Fetched job/mailsql-825 at f6c62f291; reuse its folder paging work. No new dependency is planned. Sending conflicts with the explicit DESIGN §53 deferral; do not claim sending acceptance. The latest verification policy defers full adversarial matrices, Mac interop and non-performance-job measurements to the merge round.

Started the next #486 round on job/mailproxy-486 at base 7f796c4ca84034f1d645573e097c36a738daba30. Read repository rules, DESIGN §§7,21,45,49,53, the prior report and independent review. Fix #897, #898, #899 and the #684 metadata finding first with focused regressions. Fetched job/mailsql-825 at f6c62f291; reuse its folder paging work. No new dependency is planned. Sending conflicts with the explicit DESIGN §53 deferral; do not claim sending acceptance. The latest verification policy defers full adversarial matrices, Mac interop and non-performance-job measurements to the merge round.
Author
Owner

Read-path fixes are written and compiling, not yet claimed passing. #897: a bounded general MIME structure supports text, multipart attachments and forwarded RFC822 messages; Note validation stays at NoteMessage::parse. #898: live membership coordinates select the committed generation; cached old bodies remain readable during ensure_generation backfill, and old-epoch cache misses fail before opening an upstream connection. #899: a fingerprint of account/folder visibility resets the shared User UIDVALIDITY before restored lower UIDs can change retained sequence numbers; the session clears stale selection. #684: exact headers and RFC822.SIZE persist in memberships; metadata FETCH and ENVELOPE use a provider hook without full MIME reads. Existing memberships reopen the same resumable backfill.

Reused #825 folder-page SQL from 86ef7ef50 with bff19d376/f6c62f291 fixes. Migrations 0010 proxy, 0011 folder paging and 0012 metadata are distinct. Fetched origin/dev c4faf184d and merged it once in 0a33da180; its only change was DESIGN documentation. IMAP SELECT still materializes the full mailbox; the shared web folder paging fix does not claim to solve that protocol snapshot cost. No listener/authentication or queued writes are delivered yet.

Read-path fixes are written and compiling, not yet claimed passing. #897: a bounded general MIME structure supports text, multipart attachments and forwarded RFC822 messages; Note validation stays at NoteMessage::parse. #898: live membership coordinates select the committed generation; cached old bodies remain readable during ensure_generation backfill, and old-epoch cache misses fail before opening an upstream connection. #899: a fingerprint of account/folder visibility resets the shared User UIDVALIDITY before restored lower UIDs can change retained sequence numbers; the session clears stale selection. #684: exact headers and RFC822.SIZE persist in memberships; metadata FETCH and ENVELOPE use a provider hook without full MIME reads. Existing memberships reopen the same resumable backfill. Reused #825 folder-page SQL from 86ef7ef50 with bff19d376/f6c62f291 fixes. Migrations 0010 proxy, 0011 folder paging and 0012 metadata are distinct. Fetched origin/dev c4faf184d and merged it once in 0a33da180; its only change was DESIGN documentation. IMAP SELECT still materializes the full mailbox; the shared web folder paging fix does not claim to solve that protocol snapshot cost. No listener/authentication or queued writes are delivered yet.
Author
Owner

Checkpoint 5569e3eed7: shared IMAP read fixes committed. 69 integration tests pass, including ordinary MIME, forwarded messages, large cached metadata, aggregate response limits and selection invalidation. Mail gates are now compiling in sequence; no listener or Mail write completion is claimed.

IMAP clippy output, verbatim:

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 24m 20s

IMAP test output, verbatim:

    Finished `test` profile [unoptimized + debuginfo] target(s) in 16m 08s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
test result: ok. 8 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.62s
test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
test result: ok. 10 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s
test result: ok. 30 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.47s
test result: ok. 8 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s
test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s
test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
Checkpoint 5569e3eed757c678ad44c1c85d0b4462ba3dbd30: shared IMAP read fixes committed. 69 integration tests pass, including ordinary MIME, forwarded messages, large cached metadata, aggregate response limits and selection invalidation. Mail gates are now compiling in sequence; no listener or Mail write completion is claimed. IMAP clippy output, verbatim: ``` Finished `dev` profile [unoptimized + debuginfo] target(s) in 24m 20s ``` IMAP test output, verbatim: ``` Finished `test` profile [unoptimized + debuginfo] target(s) in 16m 08s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s test result: ok. 8 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.62s test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s test result: ok. 10 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s test result: ok. 30 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.47s test result: ok. 8 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s ```
Author
Owner

Mail clippy stopped in an untouched dependency because the shared sccache daemon used another worktree's deleted temporary directory. Retry uses RUSTC_WRAPPER= for this job only, with the prescribed target and TMPDIR unchanged. No shared daemon was stopped. Output, verbatim:

error: error writing dependencies to `/home/kayg/Developer/calternal-wt/authfix/target/tmp/sccachebBaFUl/deps.d`: No such file or directory (os error 2)

error: could not compile `crossbeam-queue` (lib) due to 1 previous error
warning: build failed, waiting for other jobs to finish...
Mail clippy stopped in an untouched dependency because the shared sccache daemon used another worktree's deleted temporary directory. Retry uses RUSTC_WRAPPER= for this job only, with the prescribed target and TMPDIR unchanged. No shared daemon was stopped. Output, verbatim: ``` error: error writing dependencies to `/home/kayg/Developer/calternal-wt/authfix/target/tmp/sccachebBaFUl/deps.d`: No such file or directory (os error 2) error: could not compile `crossbeam-queue` (lib) due to 1 previous error warning: build failed, waiting for other jobs to finish... ```
Author
Owner

Read-service slice in progress: the existing TLS listener now constructs an authenticated Notes/Mail provider union. The internal mail App Password scope is separate from notes, and each service uses its own Plugin switches. A combined session retains its actual login grant set and rechecks both before commands and IDLE; disabling either ends that session. The port-465 refusal responder can validate a Mail credential but still refuses sending, as DESIGN §53 requires.

Static inspection found that the previous command/IDLE credential check filtered revoked passwords but did not check expires_at. The new check reads current expiry from the database. Its regression retains the login authority through expiration, User disablement and revocation.

Three provider-routing regressions cover single-service grants and overlapping UIDs in a combined grant. Rust gates are in progress. API client result so far, verbatim:

 18 pass
 0 fail
 49 expect() calls
Ran 18 tests across 1 file. [5.60s]

This is not the full P1 completion. Durable upstream flags/moves/deletes/drafts, the device setup preset, a window-proportional IMAP SELECT path and real client acceptance remain. I will not report this head as ready for the Mac Mail acceptance run.

Read-service slice in progress: the existing TLS listener now constructs an authenticated Notes/Mail provider union. The internal `mail` App Password scope is separate from `notes`, and each service uses its own Plugin switches. A combined session retains its actual login grant set and rechecks both before commands and IDLE; disabling either ends that session. The port-465 refusal responder can validate a Mail credential but still refuses sending, as DESIGN §53 requires. Static inspection found that the previous command/IDLE credential check filtered revoked passwords but did not check `expires_at`. The new check reads current expiry from the database. Its regression retains the login authority through expiration, User disablement and revocation. Three provider-routing regressions cover single-service grants and overlapping UIDs in a combined grant. Rust gates are in progress. API client result so far, verbatim: ``` 18 pass 0 fail 49 expect() calls Ran 18 tests across 1 file. [5.60s] ``` This is not the full P1 completion. Durable upstream flags/moves/deletes/drafts, the device setup preset, a window-proportional IMAP SELECT path and real client acceptance remain. I will not report this head as ready for the Mac Mail acceptance run.
Author
Owner

Auth gate finding, kept without changing the existing expectation:

cargo test -p calternal-auth -- --test-threads=2:

test store::tests::mail_scope_is_separate_auditable_and_bound_to_one_user ... ok
test store::tests::mail_usage_migration_preserves_existing_credentials_and_grants ... ok
test result: FAILED. 89 passed; 1 failed; 1 ignored; 0 measured; 0 filtered out; finished in 100.59s

The existing app_password_revoke_rejects_queued_verification panics at the retained worker result because it receives Err(Unavailable) instead of the asserted Ok(None). The focused rerun with one test thread also failed:

called `Result::unwrap()` on an `Err` value: Unavailable
test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 90 filtered out; finished in 3.01s

No authority was accepted in either failure. I cannot label this as full-suite load. I have not changed the verification cache, the existing test or its expectation; the production Auth changes are the internal Mail protocol and its usage migration. This is an unresolved gate failure for review. I will not broaden this job into a verification-cache behavior change.

The only updated existing expectation is the migration version list, from 1..=12 to 1..=13, because #486 adds migration 0013 to extend the usage CHECK constraint. The upgrade regression proves that credentials, grants, expiry and revocation survive it and that existing Notes grants do not acquire Mail access.

Server Clippy, Mail Clippy, web check and the production web build passed. Server tests are compiling; the read listener is not yet committed or accepted.

Auth gate finding, kept without changing the existing expectation: `cargo test -p calternal-auth -- --test-threads=2`: ``` test store::tests::mail_scope_is_separate_auditable_and_bound_to_one_user ... ok test store::tests::mail_usage_migration_preserves_existing_credentials_and_grants ... ok test result: FAILED. 89 passed; 1 failed; 1 ignored; 0 measured; 0 filtered out; finished in 100.59s ``` The existing `app_password_revoke_rejects_queued_verification` panics at the retained worker result because it receives `Err(Unavailable)` instead of the asserted `Ok(None)`. The focused rerun with one test thread also failed: ``` called `Result::unwrap()` on an `Err` value: Unavailable test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 90 filtered out; finished in 3.01s ``` No authority was accepted in either failure. I cannot label this as full-suite load. I have not changed the verification cache, the existing test or its expectation; the production Auth changes are the internal Mail protocol and its usage migration. This is an unresolved gate failure for review. I will not broaden this job into a verification-cache behavior change. The only updated existing expectation is the migration version list, from `1..=12` to `1..=13`, because #486 adds migration 0013 to extend the usage CHECK constraint. The upgrade regression proves that credentials, grants, expiry and revocation survive it and that existing Notes grants do not acquire Mail access. Server Clippy, Mail Clippy, web check and the production web build passed. Server tests are compiling; the read listener is not yet committed or accepted.
Author
Owner

#486 round report — incomplete; not ready for Mac Mail acceptance

Branch: job/mailproxy-486. Head: f8c122f77bc40d5967553627879c4f9008a8df41. Worktree is restored to this head. No push, deploy or issue closure. origin/dev was merged once before the cache gates. Work stopped at the approximately four-hour job limit.

Built and committed

  • #897: ordinary MIME BODYSTRUCTURE, real parameters/encoding and forwarded-message envelopes. Apple Note validation stays at the Notes boundary. Added codec round-trip regressions.
  • #898: keep the committed live generation visible during UIDVALIDITY rebuild. Its cached MIME and metadata remain readable; an uncached old-epoch body is refused before upstream access. Added a real generation activation regression.
  • #899: an observed account/folder visibility change resets the User's mailbox epoch. A selected session must select again. Restored account UIDs cannot reappear under the expunged epoch. Added two-account regressions.
  • #684: store exact complete outer headers and advertised size during sync. ENVELOPE/header/size FETCH uses metadata without downloading attachments; legacy exact cached bodies can supply metadata while resumable backfill runs. Added large-message, reply-budget and inconsistent-size regressions.
  • Reused origin/job/mailsql-825 (f6c62f291e88fb14319d16db1d92400e988aede3), its covering indexes, keyset folder page and profile. No second folder-page path was built. Mail migrations are 0011 and 0012; existing 0010 was preserved.
  • Extended the existing Mail proxy profile with a real 50-message metadata session and shared-Index clients. This does not resolve the full-snapshot IMAP SELECT cost.

Eight atomic work commits follow the dev merge. The four P2 review findings have regression coverage. P1, the full usable service, remains incomplete.

Files at the committed head

bench/mail-folder-page.py
bench/mail-sync.py
crates/calternal-imap/src/mime.rs
crates/calternal-imap/src/session.rs
crates/calternal-imap/src/store.rs
crates/calternal-imap/tests/mail.rs
crates/calternal-imap/tests/mime.rs
crates/calternal-imap/tests/session.rs
crates/plugins/mail/migrations/0011_folder_page_index.sql
crates/plugins/mail/migrations/0012_proxy_metadata.sql
crates/plugins/mail/src/cache/store.rs
crates/plugins/mail/src/proxy.rs
crates/plugins/mail/src/proxy_tests.rs
crates/plugins/mail/src/sync.rs
docs/DESIGN.md

Committed-head gates — verbatim result output

cargo fmt --check: passed with no output. IMAP Clippy:

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 24m 20s

IMAP tests:

    Finished `test` profile [unoptimized + debuginfo] target(s) in 16m 08s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
test result: ok. 8 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.62s
test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
test result: ok. 10 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s
test result: ok. 30 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.47s
test result: ok. 8 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s
test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s
test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

Mail Clippy after the final metadata guard:

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 11m 09s

Mail full tests, then the focused regression for the final size guard:

    Finished `test` profile [unoptimized + debuginfo] target(s) in 28m 14s
test result: ok. 59 passed; 0 failed; 5 ignored; 0 measured; 0 filtered out; finished in 30.68s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.10s
    Finished `test` profile [unoptimized + debuginfo] target(s) in 18m 24s
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 64 filtered out; finished in 0.48s

Full local logs are retained in artifacts/. Earlier compiler/test setup errors were corrected: a test import, SQLx's static SQL requirement, and the shared sccache daemon's deleted TMPDIR. Subsequent Cargo commands used an empty RUSTC_WRAPPER without changing the shared daemon. No existing behavioral test expectation was changed in the committed fixes.

Listener prototype — preserved, not committed

artifacts/486-device-listener-wip.patch applies cleanly to the reported head. artifacts/486-device-listener-wip.md explains its status. The worktree was restored rather than committing an unverified feature slice.

The prototype includes the internal Mail scope, usage-constraint migration 0013, Notes/Mail provider union, TLS listener routing, shared per-IP/User connection limits, password scope/prefix/plugin restriction and expiry rechecks, SMTP refusal-responder authentication, API types and one UI label compatibility addition. Mail writes remain refused.

Auth Clippy and the two new Mail scope/upgrade tests passed. The full Auth gate and its focused rerun failed on the unchanged queued-revocation test, both returning Unavailable rather than the asserted None; neither accepted authority. This is not classified as suite-only load and its expectation was kept:

test result: FAILED. 89 passed; 1 failed; 1 ignored; 0 measured; 0 filtered out; finished in 100.59s
test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 90 filtered out; finished in 3.01s

Server Clippy passed before the final policy-comparison addition. The final Server Clippy rerun and Server test compilation were cancelled at the time limit; Server tests have no runtime result. Prototype web check reported svelte-check found 0 errors and 0 warnings; the production web build and 18 API client tests passed. No prototype screenshots were captured. These results do not establish a verified listener at the committed head.

Known gaps / UX gaps left

  • No production Mail listener at the committed head. The prototype needs completed Server tests and resolution of the Auth gate failure.
  • Durable upstream flags, moves, deletes and drafts; draft From/default-account routing; failure reconciliation and shared setup preset are not built.
  • IMAP SELECT still scans and retains a full mailbox snapshot. The prior 100k p50/p95 4.1/6.1 s and burst p95 11.2 s remain the known comparison, not a new measurement. The 100 ms cached-open target is not proven or resolved by #825's folder page.
  • The existing exact body-cache 4 MiB miss limit and temporary email account labels remain.
  • No live local protocol matrix, release build, perf-VM measurements, six-width/theme Mac-platform screenshots or real Mac acceptance test was run.

UX gaps closed

Ordinary Mail MIME is readable by the shared structure helper. Large attachments no longer prevent a subject, envelope or size request. Rebuilding an upstream generation no longer removes committed cached messages. Epoch changes force reselection instead of reviving expunged UIDs. Oversized FETCH replies are refused without a partial reply.

Decisions

  • Visibility changes reset the shared per-User Mail epoch; unchanged virtual UIDs stay stable across real/unified views under that new epoch.
  • Exact headers are bounded at 64 KiB. Incomplete headers stay unavailable; no synthetic metadata or truncated full body is served.
  • Reopened resumable backfill supplies legacy metadata while the live generation remains readable.
  • Reuse #825 for the shared folder page; do not describe this as an IMAP snapshot speed fix.
  • Sending stays deferred under DESIGN §53, despite the brief's mention of sends.
  • Prototype only: reuse the existing TLS configuration and close a connection when its credential policy changes rather than retain the old grant set. A Mail scope is internal; no separate Mail setup preset was added.

For the merge round / continued implementation

Continue P1 implementation before claiming #486 acceptance. If the prototype is reused, apply its patch on a job branch, recheck Auth/Mail migration numbers on current origin/dev, and run:

cargo fmt --check
cargo clippy -p calternal-auth --all-targets -- -D warnings
cargo test -p calternal-auth -- --test-threads=2
cargo clippy -p calternal-server --all-targets -- -D warnings
cargo test -p calternal-server -- --test-threads=2
packages/api-client/check-generated.sh

The Auth revocation regression must pass unchanged. The Server regressions must prove single-service grants, combined equal-UID routing, cross-service APPEND-base refusal and retained-authority policy/expiry enforcement. Build the production web app before the Server gate.

The combined merge round runs bun run test in apps/web, the existing e2e/protocol verification and six screenshot combinations (390/820/1440, light/dark, macOS platform). Mac Mail acceptance belongs on the staging server after the usable service and windowed IMAP path exist.

For perf, use a current prebuilt release Mail test binary and hold /root/perf.lock for each phase. bench/mail-sync.py <binary> --label perf-vm --test profile_mail_proxy --profile-prefix 'MAIL_PROXY_PROFILE ' measures the cached IMAP view, metadata window and 100k/burst cases. bench/mail-folder-page.py <binary> <HDD-fixture> --phase <prepare|baseline|cold|warm|burst> measures #825's 200k page path. Record load average inside the lock and compare with docs/perf/baseline.json; no new numbers are claimed here.

#486 round report — incomplete; not ready for Mac Mail acceptance Branch: `job/mailproxy-486`. Head: `f8c122f77bc40d5967553627879c4f9008a8df41`. Worktree is restored to this head. No push, deploy or issue closure. `origin/dev` was merged once before the cache gates. Work stopped at the approximately four-hour job limit. ## Built and committed - #897: ordinary MIME BODYSTRUCTURE, real parameters/encoding and forwarded-message envelopes. Apple Note validation stays at the Notes boundary. Added codec round-trip regressions. - #898: keep the committed live generation visible during UIDVALIDITY rebuild. Its cached MIME and metadata remain readable; an uncached old-epoch body is refused before upstream access. Added a real generation activation regression. - #899: an observed account/folder visibility change resets the User's mailbox epoch. A selected session must select again. Restored account UIDs cannot reappear under the expunged epoch. Added two-account regressions. - #684: store exact complete outer headers and advertised size during sync. ENVELOPE/header/size FETCH uses metadata without downloading attachments; legacy exact cached bodies can supply metadata while resumable backfill runs. Added large-message, reply-budget and inconsistent-size regressions. - Reused `origin/job/mailsql-825` (`f6c62f291e88fb14319d16db1d92400e988aede3`), its covering indexes, keyset folder page and profile. No second folder-page path was built. Mail migrations are 0011 and 0012; existing 0010 was preserved. - Extended the existing Mail proxy profile with a real 50-message metadata session and shared-Index clients. This does not resolve the full-snapshot IMAP SELECT cost. Eight atomic work commits follow the dev merge. The four P2 review findings have regression coverage. P1, the full usable service, remains incomplete. ## Files at the committed head ```text bench/mail-folder-page.py bench/mail-sync.py crates/calternal-imap/src/mime.rs crates/calternal-imap/src/session.rs crates/calternal-imap/src/store.rs crates/calternal-imap/tests/mail.rs crates/calternal-imap/tests/mime.rs crates/calternal-imap/tests/session.rs crates/plugins/mail/migrations/0011_folder_page_index.sql crates/plugins/mail/migrations/0012_proxy_metadata.sql crates/plugins/mail/src/cache/store.rs crates/plugins/mail/src/proxy.rs crates/plugins/mail/src/proxy_tests.rs crates/plugins/mail/src/sync.rs docs/DESIGN.md ``` ## Committed-head gates — verbatim result output `cargo fmt --check`: passed with no output. IMAP Clippy: ```text Finished `dev` profile [unoptimized + debuginfo] target(s) in 24m 20s ``` IMAP tests: ```text Finished `test` profile [unoptimized + debuginfo] target(s) in 16m 08s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s test result: ok. 8 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.62s test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s test result: ok. 10 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s test result: ok. 30 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.47s test result: ok. 8 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s ``` Mail Clippy after the final metadata guard: ```text Finished `dev` profile [unoptimized + debuginfo] target(s) in 11m 09s ``` Mail full tests, then the focused regression for the final size guard: ```text Finished `test` profile [unoptimized + debuginfo] target(s) in 28m 14s test result: ok. 59 passed; 0 failed; 5 ignored; 0 measured; 0 filtered out; finished in 30.68s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.10s Finished `test` profile [unoptimized + debuginfo] target(s) in 18m 24s test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 64 filtered out; finished in 0.48s ``` Full local logs are retained in `artifacts/`. Earlier compiler/test setup errors were corrected: a test import, SQLx's static SQL requirement, and the shared sccache daemon's deleted TMPDIR. Subsequent Cargo commands used an empty RUSTC_WRAPPER without changing the shared daemon. No existing behavioral test expectation was changed in the committed fixes. ## Listener prototype — preserved, not committed `artifacts/486-device-listener-wip.patch` applies cleanly to the reported head. `artifacts/486-device-listener-wip.md` explains its status. The worktree was restored rather than committing an unverified feature slice. The prototype includes the internal Mail scope, usage-constraint migration 0013, Notes/Mail provider union, TLS listener routing, shared per-IP/User connection limits, password scope/prefix/plugin restriction and expiry rechecks, SMTP refusal-responder authentication, API types and one UI label compatibility addition. Mail writes remain refused. Auth Clippy and the two new Mail scope/upgrade tests passed. The full Auth gate and its focused rerun failed on the unchanged queued-revocation test, both returning `Unavailable` rather than the asserted `None`; neither accepted authority. This is not classified as suite-only load and its expectation was kept: ```text test result: FAILED. 89 passed; 1 failed; 1 ignored; 0 measured; 0 filtered out; finished in 100.59s test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 90 filtered out; finished in 3.01s ``` Server Clippy passed before the final policy-comparison addition. The final Server Clippy rerun and Server test compilation were cancelled at the time limit; Server tests have no runtime result. Prototype web check reported `svelte-check found 0 errors and 0 warnings`; the production web build and 18 API client tests passed. No prototype screenshots were captured. These results do not establish a verified listener at the committed head. ## Known gaps / UX gaps left - No production Mail listener at the committed head. The prototype needs completed Server tests and resolution of the Auth gate failure. - Durable upstream flags, moves, deletes and drafts; draft From/default-account routing; failure reconciliation and shared setup preset are not built. - IMAP SELECT still scans and retains a full mailbox snapshot. The prior 100k p50/p95 4.1/6.1 s and burst p95 11.2 s remain the known comparison, not a new measurement. The 100 ms cached-open target is not proven or resolved by #825's folder page. - The existing exact body-cache 4 MiB miss limit and temporary email account labels remain. - No live local protocol matrix, release build, perf-VM measurements, six-width/theme Mac-platform screenshots or real Mac acceptance test was run. ## UX gaps closed Ordinary Mail MIME is readable by the shared structure helper. Large attachments no longer prevent a subject, envelope or size request. Rebuilding an upstream generation no longer removes committed cached messages. Epoch changes force reselection instead of reviving expunged UIDs. Oversized FETCH replies are refused without a partial reply. ## Decisions - Visibility changes reset the shared per-User Mail epoch; unchanged virtual UIDs stay stable across real/unified views under that new epoch. - Exact headers are bounded at 64 KiB. Incomplete headers stay unavailable; no synthetic metadata or truncated full body is served. - Reopened resumable backfill supplies legacy metadata while the live generation remains readable. - Reuse #825 for the shared folder page; do not describe this as an IMAP snapshot speed fix. - Sending stays deferred under DESIGN §53, despite the brief's mention of sends. - Prototype only: reuse the existing TLS configuration and close a connection when its credential policy changes rather than retain the old grant set. A Mail scope is internal; no separate Mail setup preset was added. ## For the merge round / continued implementation Continue P1 implementation before claiming #486 acceptance. If the prototype is reused, apply its patch on a job branch, recheck Auth/Mail migration numbers on current origin/dev, and run: ```sh cargo fmt --check cargo clippy -p calternal-auth --all-targets -- -D warnings cargo test -p calternal-auth -- --test-threads=2 cargo clippy -p calternal-server --all-targets -- -D warnings cargo test -p calternal-server -- --test-threads=2 packages/api-client/check-generated.sh ``` The Auth revocation regression must pass unchanged. The Server regressions must prove single-service grants, combined equal-UID routing, cross-service APPEND-base refusal and retained-authority policy/expiry enforcement. Build the production web app before the Server gate. The combined merge round runs `bun run test` in `apps/web`, the existing e2e/protocol verification and six screenshot combinations (390/820/1440, light/dark, macOS platform). Mac Mail acceptance belongs on the staging server after the usable service and windowed IMAP path exist. For perf, use a current prebuilt release Mail test binary and hold `/root/perf.lock` for each phase. `bench/mail-sync.py <binary> --label perf-vm --test profile_mail_proxy --profile-prefix 'MAIL_PROXY_PROFILE '` measures the cached IMAP view, metadata window and 100k/burst cases. `bench/mail-folder-page.py <binary> <HDD-fixture> --phase <prepare|baseline|cold|warm|burst>` measures #825's 200k page path. Record load average inside the lock and compare with `docs/perf/baseline.json`; no new numbers are claimed here.
Author
Owner

Final-report correction: there are seven atomic work commits after the dev merge, not eight. Head remains f8c122f77bc40d5967553627879c4f9008a8df41.

Cleanup completed; the worktree is clean. Output verbatim:

     Removed 17955 files, 7.9GiB total

The production web output was removed. The preserved listener prototype patch still passes git apply --check against this head. The corrected complete report is at artifacts/486-final-report.md in the worktree.

Final-report correction: there are **seven** atomic work commits after the dev merge, not eight. Head remains `f8c122f77bc40d5967553627879c4f9008a8df41`. Cleanup completed; the worktree is clean. Output verbatim: ``` Removed 17955 files, 7.9GiB total ``` The production web output was removed. The preserved listener prototype patch still passes `git apply --check` against this head. The corrected complete report is at `artifacts/486-final-report.md` in the worktree.
Author
Owner

Resumed #486 on job/mailproxy-486, base f8c122f77b. Read CLAUDE.md, CONTEXT.md, DESIGN §49/§53 and the prior reports. Restored the preserved listener prototype for completion and verification. It supplies the internal Mail scope and Notes/Mail grant union, but has no Mail writes yet. Sending remains deferred per §53.

Fetched origin. origin/dev still has Mail migrations through 0009; origin/job/merge-round-7b2 already owns 0010 (preference revision) and 0011 (bounded expunge cursor). This job will reserve its proxy, folder index and metadata migrations after that set. Auth and listener gates are starting early. No push, deploy or Mac session has occurred.

Resumed #486 on job/mailproxy-486, base f8c122f77bc40d5967553627879c4f9008a8df41. Read CLAUDE.md, CONTEXT.md, DESIGN §49/§53 and the prior reports. Restored the preserved listener prototype for completion and verification. It supplies the internal Mail scope and Notes/Mail grant union, but has no Mail writes yet. Sending remains deferred per §53. Fetched origin. origin/dev still has Mail migrations through 0009; origin/job/merge-round-7b2 already owns 0010 (preference revision) and 0011 (bounded expunge cursor). This job will reserve its proxy, folder index and metadata migrations after that set. Auth and listener gates are starting early. No push, deploy or Mac session has occurred.
Author
Owner

Auth regression resolved without changing the existing assertion. A queued same-credential follower checked is_changing() before taking its verification lock. It could return Unavailable while revocation was committing instead of waiting for the active verifier's denial. The check now follows the bounded credential lock; a cold leader still refuses during a Security state change. The existing queued-revocation and mutation tests pass unchanged.

Full Auth test output:

test result: ok. 90 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out; finished in 280.10s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

Merged origin/dev once at bd11bacb51 (merge head 1543d47cc). The listener additionally rechecks changed future expiry, and its complete command now has a deadline rather than multiplying the upstream timeout for every FETCH item. Final Auth Clippy and the focused revocation test are queued with Mail/server gates.

Auth regression resolved without changing the existing assertion. A queued same-credential follower checked `is_changing()` before taking its verification lock. It could return `Unavailable` while revocation was committing instead of waiting for the active verifier's denial. The check now follows the bounded credential lock; a cold leader still refuses during a Security state change. The existing queued-revocation and mutation tests pass unchanged. Full Auth test output: ``` test result: ok. 90 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out; finished in 280.10s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s ``` Merged origin/dev once at bd11bacb5189d39176e7cd48d5e977f1694321c1 (merge head 1543d47cc). The listener additionally rechecks changed future expiry, and its complete command now has a deadline rather than multiplying the upstream timeout for every FETCH item. Final Auth Clippy and the focused revocation test are queued with Mail/server gates.
Author
Owner

Resume finding: the server suite first returned 162 passed; 4 failed; 5 ignored. Three failures came from historical #407/#626 fixtures installing the new proxy schema before rebuilding their old mail_memberships table. The fourth was this job's retained-authority fixture hitting the production one-second pool checkout under shared-host load.

The historical fixture now explicitly uses its reviewed Mail 0009 schema. Its original version, byte-preservation and SQL assertions are unchanged. A separate test checks the current proxy schema in both integration migration orders. The focused independent-review run returned:

test result: ok. 17 passed; 0 failed; 0 ignored; 0 measured; 155 filtered out; finished in 6.77s

The retained-authority fixture uses a private test pool; production pool limits stay unchanged. Its focused check is running. A standard TLS IMAP/SMTP client currently reaches the listener but its initial LOGIN closes with EOF. This is unresolved evidence, not an acceptance pass. P1 writes, drafts and shared setup remain incomplete.

Resume finding: the server suite first returned `162 passed; 4 failed; 5 ignored`. Three failures came from historical #407/#626 fixtures installing the new proxy schema before rebuilding their old `mail_memberships` table. The fourth was this job's retained-authority fixture hitting the production one-second pool checkout under shared-host load. The historical fixture now explicitly uses its reviewed Mail 0009 schema. Its original version, byte-preservation and SQL assertions are unchanged. A separate test checks the current proxy schema in both integration migration orders. The focused independent-review run returned: ``` test result: ok. 17 passed; 0 failed; 0 ignored; 0 measured; 155 filtered out; finished in 6.77s ``` The retained-authority fixture uses a private test pool; production pool limits stay unchanged. Its focused check is running. A standard TLS IMAP/SMTP client currently reaches the listener but its initial LOGIN closes with EOF. This is unresolved evidence, not an acceptance pass. P1 writes, drafts and shared setup remain incomplete.
Author
Owner

READY FOR MERGE: no

Branch: job/mailproxy-486. Resume base: f8c122f77. Head: 152b4322d35da485324eb666ae5466bf7418a531.
Merged origin/dev once, at bd11bacb5189d39176e7cd48d5e977f1694321c1, before final Rust gates. No push or deployment was done. The issue stays open.

Built: a TLS listener that accepts internal Mail and Notes App Password grants. It binds each provider to the authenticated User and routes their folder union without mixing equal UIDs or private source tags. Commands and IDLE check the captured service grants, Plugin switches, password policy, expiry, User disablement and revocation. IMAP and SMTP share IP/User connection caps. A complete command has one timeout. SMTP accepts the device credential and refuses sending.

Auth now records Mail usage without widening any existing password. The production migration registry includes Auth 0013; its omission caused the first local LOGIN to close. The live regression now covers that registry. A verifier follower waits for its leader before checking mutation contention; the existing queued-revocation test passes unchanged.

Mail migrations are 0012, 0013 and 0014, after the 7b reservations 0010 and 0011. Historical #407/#626 tests use their reviewed Mail 0009 fixture and retain their original assertions. A separate test checks populated current proxy cache preservation in both integration upgrade orders. Generated contracts include Mail and the documentation from the dev merge. App Password lists display internal Mail grants.

Files, relative to the worktree (R means migration rename):

A	apps/web/e2e/mail-proxy-486.mjs
M	apps/web/src/routes/settings/account/AppPasswordsGroup.svelte
M	contracts/openapi.json
A	crates/calternal-auth/migrations/0013_mail_app_password_usage.sql
M	crates/calternal-auth/src/store.rs
A	crates/calternal-server/src/device_imap.rs
M	crates/calternal-server/src/integrations.rs
M	crates/calternal-server/src/integrations_review.rs
M	crates/calternal-server/src/notes_imap.rs
M	crates/calternal-server/src/notes_submission.rs
M	crates/calternal-server/src/wire.rs
R100	crates/plugins/mail/migrations/0010_mail_proxy.sql	crates/plugins/mail/migrations/0012_mail_proxy.sql
R100	crates/plugins/mail/migrations/0011_folder_page_index.sql	crates/plugins/mail/migrations/0013_folder_page_index.sql
R100	crates/plugins/mail/migrations/0012_proxy_metadata.sql	crates/plugins/mail/migrations/0014_proxy_metadata.sql
M	crates/plugins/mail/src/cache/store.rs
M	crates/plugins/mail/src/lib.rs
M	docs/DESIGN.md
M	packages/api-client/src/generated.ts
A	tests/adversarial/mail_proxy.py

Verification: terminal summaries below are quoted verbatim. Full command output is in artifacts/resume-*.log in this worktree. All Rust commands used CARGO_PROFILE_DEV_DEBUG=line-tables-only CARGO_INCREMENTAL=0 CARGO_BUILD_JOBS=4 and the preset target directory. cargo fmt --check exited 0 with no output. git diff --check exited 0.

cargo clippy -p calternal-auth --all-targets -- -D warnings

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 3m 45s

cargo test -p calternal-auth -- --test-threads=4

test result: ok. 90 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out; finished in 280.10s

The full Auth run passed before the dev merge. Final Clippy and the unchanged revocation regression ran after the merge:

test store::tests::app_password_revoke_rejects_queued_verification ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 90 filtered out; finished in 5.18s

cargo clippy -p calternal-plugin-mail --all-targets -- -D warnings

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 3m 39s

cargo test -p calternal-plugin-mail -- --test-threads=4

test result: ok. 60 passed; 0 failed; 5 ignored; 0 measured; 0 filtered out; finished in 10.11s

cargo clippy -p calternal-server --all-targets -- -D warnings

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 2m 48s

cargo test -p calternal-server -- --test-threads=4

test result: ok. 167 passed; 0 failed; 5 ignored; 0 measured; 0 filtered out; finished in 22.47s

bun run check in apps/web

User browser caches use userStorage; only documented device/public-link exceptions remain.
Text sizes and UI shape values use shared role tokens.
UI transitions and animation options use shared motion tokens or documented exceptions.
svelte-check found 0 errors and 0 warnings

bunx vitest run src/routes/settings/shared-components.guard.test.ts --maxWorkers=2

 Test Files  1 passed (1)
      Tests  2 passed (2)

bun run build passed. bash packages/api-client/check-generated.sh passed after regeneration. node apps/web/e2e/mail-proxy-486.mjs against the job's debug server passed:

PASS mail: IMAP namespace and authenticated SMTP refusal
PASS notes: IMAP namespace and authenticated SMTP refusal
PASS combined: IMAP namespace and authenticated SMTP refusal
PASS other: IMAP namespace and authenticated SMTP refusal
PASS caldav: IMAP and SMTP authentication denied
PASS production App Password scope labels: 390/820/1440, light/dark, macOS platform
PASS revoked: IMAP and SMTP authentication denied

This is a focused standard-client regression, not the full adversarial matrix. The two Users have real empty Mail accounts. This does not prove populated Mail FETCH, upstream writes or full Apple Mail acceptance.

Decisions: reuse notes_imap configuration and the existing submission responder. Keep the initial grant union fixed for the socket. End access after a scope or expiry policy change. Reserve Notes and Notes/ for Notes. Use private source tags only for server routing; strip them before provider calls. Refuse every Mail write until a durable provider write path exists. These choices are recorded in DESIGN §53. Existing temporary email labels remain; no new Account Name or default-account rule was chosen.

Known gaps / UX gaps left: P1 is NOT complete. Durable STORE flags, COPY/MOVE, delete/archive routing and the offline mutation queue are absent. Raw draft APPEND and From/default-account routing are absent. The shared device preset/profile still omits Mail and tells the User to switch Mail off. The full IMAP surface required by Apple Mail needs acceptance, including body sections/partial FETCH. SELECT still loads a full snapshot. Editable Account Names remain absent. The phone screenshot shows the existing Calendar feeds sheet title while the App Password section is visible; that Settings title defect was not changed in this label-only UI change. No icons or alignment CSS were added.

UX gaps closed: internal Mail grants no longer have an undefined label in the password list. The production screen shows real API credentials and real empty Mail folders. Six production screenshots cover 390, 820 and 1440 px, light/dark, with macOS platform emulation. They are attached below for Claude's visual review; no review artifacts were committed.

Mac: the nonblocking VM lock succeeded. A locked, read-only AppleScript query for Mail account count returned no result and was stopped after about 80 seconds. No VM account, lab profile, trust setting or password prompt was changed. No real Apple Mail acceptance is claimed. Owner steps: after P1 is complete, open the existing lab profile, satisfy any local automation/password prompts, install the finished device profile, and run the §53 read/write/draft matrix.

STAGING read-only preflight:

STAGING readiness: HTTP 200
STAGING public contract: HTTP 200 ; internal Mail grant: False
Read-only preflight. This does not verify the job branch on STAGING.

Read /home/kayg/.local/state/codex-jobs/calternal/deploy-staging.sh. Deployment, release builds, full matrices, Mac interop and performance runs were deferred by the 2026-10-02 verification policy. The branch was not tested on STAGING.

For the merge round, after the missing P1 code is complete:

  • cd apps/web && bun run test -- --maxWorkers=2 and bun run test:e2e:app-passwords: full web checks and the shared setup flow.
  • CALTERNAL_SERVER_BIN=<combined-server> node apps/web/e2e/mail-proxy-486.mjs: production registry and scoped listener regression.
  • CALTERNAL_SERVER_BIN=<combined-server> tests/adversarial/run-split.sh: combined User/authz/robustness matrices, plus populated Mail and mutation cases. Extend tests/adversarial/mail_proxy.py for those new surfaces.
  • CALTERNAL_REPO=$PWD /home/kayg/.local/state/codex-jobs/calternal/deploy-staging.sh <reviewed-image-tag>: deploy only after P1 and release checks pass. Supply Instance TLS secrets and reachable IMAP/submission ports. Run python3 tests/adversarial/mail_proxy.py < <private-staging-fixture.json> with scoped test credentials; never put credentials in a report.
  • Hold flock /root/perf.lock on the perf VM, record load inside the lock, then run python3 bench/mail-sync.py <shared-release-mail-test-binary> --label perf-vm --test profile_mail_proxy --profile-prefix 'MAIL_PROXY_PROFILE '. The existing profile covers 10k/100k and a three-worker burst. There is no comparable Mail proxy baseline in docs/perf/baseline.json; HTTP mail.accounts is a different path. No new performance numbers are claimed.

Cleanup: cargo clean ran against this job's preset target directory. Web production build output was removed. Gate logs and screenshots remain in ignored artifacts/. Working tree is clean.

Screenshot attachments:

READY FOR MERGE: no Branch: `job/mailproxy-486`. Resume base: `f8c122f77`. Head: `152b4322d35da485324eb666ae5466bf7418a531`. Merged `origin/dev` once, at `bd11bacb5189d39176e7cd48d5e977f1694321c1`, before final Rust gates. No push or deployment was done. The issue stays open. Built: a TLS listener that accepts internal Mail and Notes App Password grants. It binds each provider to the authenticated User and routes their folder union without mixing equal UIDs or private source tags. Commands and IDLE check the captured service grants, Plugin switches, password policy, expiry, User disablement and revocation. IMAP and SMTP share IP/User connection caps. A complete command has one timeout. SMTP accepts the device credential and refuses sending. Auth now records Mail usage without widening any existing password. The production migration registry includes Auth 0013; its omission caused the first local LOGIN to close. The live regression now covers that registry. A verifier follower waits for its leader before checking mutation contention; the existing queued-revocation test passes unchanged. Mail migrations are 0012, 0013 and 0014, after the 7b reservations 0010 and 0011. Historical #407/#626 tests use their reviewed Mail 0009 fixture and retain their original assertions. A separate test checks populated current proxy cache preservation in both integration upgrade orders. Generated contracts include Mail and the documentation from the dev merge. App Password lists display internal Mail grants. Files, relative to the worktree (R means migration rename): ``` A apps/web/e2e/mail-proxy-486.mjs M apps/web/src/routes/settings/account/AppPasswordsGroup.svelte M contracts/openapi.json A crates/calternal-auth/migrations/0013_mail_app_password_usage.sql M crates/calternal-auth/src/store.rs A crates/calternal-server/src/device_imap.rs M crates/calternal-server/src/integrations.rs M crates/calternal-server/src/integrations_review.rs M crates/calternal-server/src/notes_imap.rs M crates/calternal-server/src/notes_submission.rs M crates/calternal-server/src/wire.rs R100 crates/plugins/mail/migrations/0010_mail_proxy.sql crates/plugins/mail/migrations/0012_mail_proxy.sql R100 crates/plugins/mail/migrations/0011_folder_page_index.sql crates/plugins/mail/migrations/0013_folder_page_index.sql R100 crates/plugins/mail/migrations/0012_proxy_metadata.sql crates/plugins/mail/migrations/0014_proxy_metadata.sql M crates/plugins/mail/src/cache/store.rs M crates/plugins/mail/src/lib.rs M docs/DESIGN.md M packages/api-client/src/generated.ts A tests/adversarial/mail_proxy.py ``` Verification: terminal summaries below are quoted verbatim. Full command output is in `artifacts/resume-*.log` in this worktree. All Rust commands used `CARGO_PROFILE_DEV_DEBUG=line-tables-only CARGO_INCREMENTAL=0 CARGO_BUILD_JOBS=4` and the preset target directory. `cargo fmt --check` exited 0 with no output. `git diff --check` exited 0. `cargo clippy -p calternal-auth --all-targets -- -D warnings` ``` Finished `dev` profile [unoptimized + debuginfo] target(s) in 3m 45s ``` `cargo test -p calternal-auth -- --test-threads=4` ``` test result: ok. 90 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out; finished in 280.10s ``` The full Auth run passed before the dev merge. Final Clippy and the unchanged revocation regression ran after the merge: ``` test store::tests::app_password_revoke_rejects_queued_verification ... ok test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 90 filtered out; finished in 5.18s ``` `cargo clippy -p calternal-plugin-mail --all-targets -- -D warnings` ``` Finished `dev` profile [unoptimized + debuginfo] target(s) in 3m 39s ``` `cargo test -p calternal-plugin-mail -- --test-threads=4` ``` test result: ok. 60 passed; 0 failed; 5 ignored; 0 measured; 0 filtered out; finished in 10.11s ``` `cargo clippy -p calternal-server --all-targets -- -D warnings` ``` Finished `dev` profile [unoptimized + debuginfo] target(s) in 2m 48s ``` `cargo test -p calternal-server -- --test-threads=4` ``` test result: ok. 167 passed; 0 failed; 5 ignored; 0 measured; 0 filtered out; finished in 22.47s ``` `bun run check` in `apps/web` ``` User browser caches use userStorage; only documented device/public-link exceptions remain. Text sizes and UI shape values use shared role tokens. UI transitions and animation options use shared motion tokens or documented exceptions. svelte-check found 0 errors and 0 warnings ``` `bunx vitest run src/routes/settings/shared-components.guard.test.ts --maxWorkers=2` ``` Test Files 1 passed (1) Tests 2 passed (2) ``` `bun run build` passed. `bash packages/api-client/check-generated.sh` passed after regeneration. `node apps/web/e2e/mail-proxy-486.mjs` against the job's debug server passed: ``` PASS mail: IMAP namespace and authenticated SMTP refusal PASS notes: IMAP namespace and authenticated SMTP refusal PASS combined: IMAP namespace and authenticated SMTP refusal PASS other: IMAP namespace and authenticated SMTP refusal PASS caldav: IMAP and SMTP authentication denied PASS production App Password scope labels: 390/820/1440, light/dark, macOS platform PASS revoked: IMAP and SMTP authentication denied ``` This is a focused standard-client regression, not the full adversarial matrix. The two Users have real empty Mail accounts. This does not prove populated Mail FETCH, upstream writes or full Apple Mail acceptance. Decisions: reuse `notes_imap` configuration and the existing submission responder. Keep the initial grant union fixed for the socket. End access after a scope or expiry policy change. Reserve Notes and Notes/ for Notes. Use private source tags only for server routing; strip them before provider calls. Refuse every Mail write until a durable provider write path exists. These choices are recorded in DESIGN §53. Existing temporary email labels remain; no new Account Name or default-account rule was chosen. Known gaps / UX gaps left: P1 is NOT complete. Durable STORE flags, COPY/MOVE, delete/archive routing and the offline mutation queue are absent. Raw draft APPEND and From/default-account routing are absent. The shared device preset/profile still omits Mail and tells the User to switch Mail off. The full IMAP surface required by Apple Mail needs acceptance, including body sections/partial FETCH. SELECT still loads a full snapshot. Editable Account Names remain absent. The phone screenshot shows the existing Calendar feeds sheet title while the App Password section is visible; that Settings title defect was not changed in this label-only UI change. No icons or alignment CSS were added. UX gaps closed: internal Mail grants no longer have an undefined label in the password list. The production screen shows real API credentials and real empty Mail folders. Six production screenshots cover 390, 820 and 1440 px, light/dark, with macOS platform emulation. They are attached below for Claude's visual review; no review artifacts were committed. Mac: the nonblocking VM lock succeeded. A locked, read-only AppleScript query for Mail account count returned no result and was stopped after about 80 seconds. No VM account, lab profile, trust setting or password prompt was changed. No real Apple Mail acceptance is claimed. Owner steps: after P1 is complete, open the existing lab profile, satisfy any local automation/password prompts, install the finished device profile, and run the §53 read/write/draft matrix. STAGING read-only preflight: ``` STAGING readiness: HTTP 200 STAGING public contract: HTTP 200 ; internal Mail grant: False Read-only preflight. This does not verify the job branch on STAGING. ``` Read `/home/kayg/.local/state/codex-jobs/calternal/deploy-staging.sh`. Deployment, release builds, full matrices, Mac interop and performance runs were deferred by the 2026-10-02 verification policy. The branch was not tested on STAGING. For the merge round, after the missing P1 code is complete: - `cd apps/web && bun run test -- --maxWorkers=2` and `bun run test:e2e:app-passwords`: full web checks and the shared setup flow. - `CALTERNAL_SERVER_BIN=<combined-server> node apps/web/e2e/mail-proxy-486.mjs`: production registry and scoped listener regression. - `CALTERNAL_SERVER_BIN=<combined-server> tests/adversarial/run-split.sh`: combined User/authz/robustness matrices, plus populated Mail and mutation cases. Extend `tests/adversarial/mail_proxy.py` for those new surfaces. - `CALTERNAL_REPO=$PWD /home/kayg/.local/state/codex-jobs/calternal/deploy-staging.sh <reviewed-image-tag>`: deploy only after P1 and release checks pass. Supply Instance TLS secrets and reachable IMAP/submission ports. Run `python3 tests/adversarial/mail_proxy.py < <private-staging-fixture.json>` with scoped test credentials; never put credentials in a report. - Hold `flock /root/perf.lock` on the perf VM, record load inside the lock, then run `python3 bench/mail-sync.py <shared-release-mail-test-binary> --label perf-vm --test profile_mail_proxy --profile-prefix 'MAIL_PROXY_PROFILE '`. The existing profile covers 10k/100k and a three-worker burst. There is no comparable Mail proxy baseline in `docs/perf/baseline.json`; HTTP `mail.accounts` is a different path. No new performance numbers are claimed. Cleanup: `cargo clean` ran against this job's preset target directory. Web production build output was removed. Gate logs and screenshots remain in ignored `artifacts/`. Working tree is clean. Screenshot attachments: - [mailproxy-486-1440-dark.png](https://git.kayg.org/attachments/abb12182-2917-4ac5-a1e3-4314563342d7) - [mailproxy-486-1440-light.png](https://git.kayg.org/attachments/0b232dac-0dbb-4d5c-8504-c28eaee9647b) - [mailproxy-486-390-dark.png](https://git.kayg.org/attachments/7557a23b-644d-44c1-a743-619ab7ae18cc) - [mailproxy-486-390-light.png](https://git.kayg.org/attachments/a265265c-b550-4da1-82f3-f4b77007b6bf) - [mailproxy-486-820-dark.png](https://git.kayg.org/attachments/5adfeb12-c90d-40bf-92c0-389d3f91da6b) - [mailproxy-486-820-light.png](https://git.kayg.org/attachments/b441e304-e42c-4c8f-b7cb-ac76f92e7280)
Author
Owner

Continuing mailproxy-486 from branch mailproxy-486, base 152b4322d. Reading the durable Mail action queue and shared IMAP provider contracts before implementing mutations, MOVE/COPY, draft APPEND and device setup. Final verification follows the current per-crate policy; client acceptance and any remaining merge-round checks will be reported explicitly.

Continuing mailproxy-486 from branch mailproxy-486, base 152b4322d. Reading the durable Mail action queue and shared IMAP provider contracts before implementing mutations, MOVE/COPY, draft APPEND and device setup. Final verification follows the current per-crate policy; client acceptance and any remaining merge-round checks will be reported explicitly.
Author
Owner

Finding: the shared provider only accepted Deleted intent, so Mail STORE could not save Seen, Answered, Flagged, Draft or keywords. Added a full-flag provider operation while preserving Notes semantics. The new mutation queue pins owner, folder generation, remote UID and UIDVALIDITY; its Job wake commits in the same writer transaction through a small public calternal-db enqueue helper. A stale concurrent sync window must not restore pre-STORE flags: accepted intent remains until sync observes a checked delivered flag set. EXPUNGE uses UIDPLUS selective deletion only; no plain EXPUNGE fallback. Scripted upstream tests cover epoch mismatch, tagged rejection and missing UIDPLUS. Focused first pass: 14 passed, 0 failed, 1 ignored.

Finding: the shared provider only accepted Deleted intent, so Mail STORE could not save Seen, Answered, Flagged, Draft or keywords. Added a full-flag provider operation while preserving Notes semantics. The new mutation queue pins owner, folder generation, remote UID and UIDVALIDITY; its Job wake commits in the same writer transaction through a small public calternal-db enqueue helper. A stale concurrent sync window must not restore pre-STORE flags: accepted intent remains until sync observes a checked delivered flag set. EXPUNGE uses UIDPLUS selective deletion only; no plain EXPUNGE fallback. Scripted upstream tests cover epoch mismatch, tagged rejection and missing UIDPLUS. Focused first pass: 14 passed, 0 failed, 1 ignored.
Author
Owner

READY FOR MERGE: no

Head: 638394ae5f5353b8700e2e8d98db623507a2be77. Branch: job/mailproxy-486. Base: 152b4322d.
Four atomic commits: b645039fa, 30d75ec3e, 5701d961d, 638394ae5.
Fetched origin once and merged origin/dev once: Already up to date.
Checked origin/dev's Mail migrations; 0015 was free. No dependency changes.

Built

  • Durable generation-scoped IMAP STORE for Seen, Answered, Flagged, Deleted, Draft and keywords. Intent and its private Job wake commit together.
  • Conditional STORE checks committed MODSEQ, including a second connection's changes. Selected FETCH sees committed flags immediately.
  • Offline intent overlays stale sync data and updates the web reader's unread-first projection. Provider delivery uses checked tagged completions, absolute flag sets and revision-checked receipts.
  • Selective EXPUNGE rechecks current Deleted intent. Normal sync records upstream UIDPLUS support; unknown or absent support returns an error before hiding a message. Delivery never uses plain EXPUNGE.
  • Sync fetch windows and delivery share a folder lock. IDLE does not hold it. Worker ownership and epoch checks run after lock acquisition. Unavailable sources retain intent for retry.
  • Extended the existing bench/mail-sync.py profile with queued STORE p50/p95 and a three-client contention burst, at the existing 10k/100k dataset sizes.

Files

bench/mail-sync.py
crates/calternal-db/src/jobs.rs
crates/calternal-imap/src/session.rs
crates/calternal-imap/src/store.rs
crates/calternal-server/src/device_imap.rs
crates/plugins/mail/migrations/0015_proxy_mutations.sql
crates/plugins/mail/src/cache.rs
crates/plugins/mail/src/cache/store.rs
crates/plugins/mail/src/lib.rs
crates/plugins/mail/src/proxy.rs
crates/plugins/mail/src/proxy_mutations.rs
crates/plugins/mail/src/proxy_tests.rs
crates/plugins/mail/src/sync.rs
docs/DESIGN.md

Verification
Focused populated local TCP listener: production CommandReader and Session accepted SELECT, UID STORE, UID FETCH, UID EXPUNGE and NOOP. Scripted upstream peer checked pinned UIDVALIDITY, exact UID STORE/UID EXPUNGE commands, tagged rejection and missing UIDPLUS. Regression tests cover restart, cross-User rejection, stale CONDSTORE, Deleted-clear races, hostile flags, stale sync windows, disabled accounts and obsolete epochs.
cargo fmt --check: exit 0; no output. Python benchmark syntax check: exit 0.
Gate completion/result output, verbatim:

cargo clippy -p calternal-db --all-targets -- -D warnings

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 21.36s

cargo test -p calternal-db

test result: ok. 22 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 5.84s
test result: ok. 16 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out; finished in 0.43s
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.02s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

cargo clippy -p calternal-imap --all-targets -- -D warnings

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 25.37s

cargo test -p calternal-imap

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
test result: ok. 8 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.15s
test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
test result: ok. 10 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
test result: ok. 30 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.13s
test result: ok. 8 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

cargo clippy -p calternal-plugin-mail --all-targets -- -D warnings

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 3.79s

cargo test -p calternal-plugin-mail

test result: ok. 68 passed; 0 failed; 5 ignored; 0 measured; 0 filtered out; finished in 2.37s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

cargo clippy -p calternal-server --all-targets -- -D warnings

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 22.41s

cargo test -p calternal-server

test result: ok. 167 passed; 0 failed; 5 ignored; 0 measured; 0 filtered out; finished in 20.29s

One existing expectation changed: the schema inventory gained only mail_proxy_mutations, which #486 requires for the durable queue. No existing table, status or behavior assertion was removed. Re-read the touched doc comments; updated DESIGN §53 to describe this slice and remaining work. Built the real web production bundle as the RustEmbed prerequisite. No UI source changed, so there is no new screenshot set.

UX gaps closed

  • Mail clients can save read/unread, flag, reply and deletion state rather than receiving unavailable-write errors.
  • Same-connection FETCH and other IMAP aliases see accepted flags; the web unread-first projection updates in the queue transaction.
  • A stale connection cannot expunge a message whose Deleted intent another connection cleared.

Known gaps / UX gaps left

  • This continuation completes only the flag/delete queue slice. MOVE/COPY, draft APPEND and From/default-account routing, the shared Sync with Your Devices preset/profile, and populated Apple Mail acceptance remain unimplemented.
  • No real-provider offline/reconnect worker run, Mac command capture, staging Mail grant or staging deployment was done. The local populated test uses an isolated authenticated provider fixture; it does not constitute Apple Mail acceptance.
  • Queue delivery has 100 attempts. Dead Jobs retain mutation intent for explicit retry. A retired generation cannot be replayed against replacement UIDs.
  • Upstream flag changes made by another client still depend on the existing sync behavior; this slice does not add general upstream flag reconciliation.

Decisions

  • Absolute flag state makes delivery replay idempotent; one pending revision belongs to one owner-bound virtual UID. A stale receipt cannot discard newer accepted intent.
  • Require known UIDPLUS for deletion; refuse unsupported deletion instead of issuing mailbox-wide EXPUNGE.
  • Use a folder lock for each fetch/commit window and delivery; leave IDLE outside that lock.
  • Use 100 delivery attempts and retain failed intent. No secrets enter payloads or error text.

Performance
Measurement not run: the 2026-10-02 verification policy limits performance runs to performance issues. The existing baseline has no comparable Mail proxy view profile (mail.accounts measures HTTP account listing). New profile fields are queued_flags and queued_flags_burst; the sampler still reports CPU and RSS. Perf VM command for the merge round, with a copied prebuilt test binary and no compile on the VM:
flock /root/perf.lock bash -c 'uptime; python3 bench/mail-sync.py /path/to/prebuilt-mail-test-binary --label perf-vm --test profile_mail_proxy --profile-prefix "MAIL_PROXY_PROFILE "'

For the merge round

  • bun run test --maxWorkers=2 in apps/web: full web regressions.
  • bun apps/web/e2e/mail-proxy-486.mjs: TLS listener scopes, revocation and submission refusal; the existing fixture is empty, so this does not replace populated Mail acceptance.
  • bash tests/adversarial/run.sh: combined XUser/authz/robustness checks with the merge round's server and credentials supplied through its existing environment setup.
  • Real upstream offline/reconnect delivery and populated Apple Mail acceptance after MOVE/COPY, drafts and the device preset exist. Use the Mac lock and lab profile without reconfiguration.
  • No release build, full e2e matrix, staging deploy or Mac interop run here, per the current verification policy.
READY FOR MERGE: no Head: `638394ae5f5353b8700e2e8d98db623507a2be77`. Branch: `job/mailproxy-486`. Base: `152b4322d`. Four atomic commits: `b645039fa`, `30d75ec3e`, `5701d961d`, `638394ae5`. Fetched origin once and merged origin/dev once: `Already up to date.` Checked origin/dev's Mail migrations; 0015 was free. No dependency changes. Built - Durable generation-scoped IMAP STORE for Seen, Answered, Flagged, Deleted, Draft and keywords. Intent and its private Job wake commit together. - Conditional STORE checks committed MODSEQ, including a second connection's changes. Selected FETCH sees committed flags immediately. - Offline intent overlays stale sync data and updates the web reader's unread-first projection. Provider delivery uses checked tagged completions, absolute flag sets and revision-checked receipts. - Selective EXPUNGE rechecks current Deleted intent. Normal sync records upstream UIDPLUS support; unknown or absent support returns an error before hiding a message. Delivery never uses plain EXPUNGE. - Sync fetch windows and delivery share a folder lock. IDLE does not hold it. Worker ownership and epoch checks run after lock acquisition. Unavailable sources retain intent for retry. - Extended the existing bench/mail-sync.py profile with queued STORE p50/p95 and a three-client contention burst, at the existing 10k/100k dataset sizes. Files ```text bench/mail-sync.py crates/calternal-db/src/jobs.rs crates/calternal-imap/src/session.rs crates/calternal-imap/src/store.rs crates/calternal-server/src/device_imap.rs crates/plugins/mail/migrations/0015_proxy_mutations.sql crates/plugins/mail/src/cache.rs crates/plugins/mail/src/cache/store.rs crates/plugins/mail/src/lib.rs crates/plugins/mail/src/proxy.rs crates/plugins/mail/src/proxy_mutations.rs crates/plugins/mail/src/proxy_tests.rs crates/plugins/mail/src/sync.rs docs/DESIGN.md ``` Verification Focused populated local TCP listener: production CommandReader and Session accepted SELECT, UID STORE, UID FETCH, UID EXPUNGE and NOOP. Scripted upstream peer checked pinned UIDVALIDITY, exact UID STORE/UID EXPUNGE commands, tagged rejection and missing UIDPLUS. Regression tests cover restart, cross-User rejection, stale CONDSTORE, Deleted-clear races, hostile flags, stale sync windows, disabled accounts and obsolete epochs. `cargo fmt --check`: exit 0; no output. Python benchmark syntax check: exit 0. Gate completion/result output, verbatim: `cargo clippy -p calternal-db --all-targets -- -D warnings` ```text Finished `dev` profile [unoptimized + debuginfo] target(s) in 21.36s ``` `cargo test -p calternal-db` ```text test result: ok. 22 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 5.84s test result: ok. 16 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out; finished in 0.43s test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.02s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s ``` `cargo clippy -p calternal-imap --all-targets -- -D warnings` ```text Finished `dev` profile [unoptimized + debuginfo] target(s) in 25.37s ``` `cargo test -p calternal-imap` ```text test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s test result: ok. 8 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.15s test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s test result: ok. 10 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s test result: ok. 30 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.13s test result: ok. 8 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s ``` `cargo clippy -p calternal-plugin-mail --all-targets -- -D warnings` ```text Finished `dev` profile [unoptimized + debuginfo] target(s) in 3.79s ``` `cargo test -p calternal-plugin-mail` ```text test result: ok. 68 passed; 0 failed; 5 ignored; 0 measured; 0 filtered out; finished in 2.37s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s ``` `cargo clippy -p calternal-server --all-targets -- -D warnings` ```text Finished `dev` profile [unoptimized + debuginfo] target(s) in 22.41s ``` `cargo test -p calternal-server` ```text test result: ok. 167 passed; 0 failed; 5 ignored; 0 measured; 0 filtered out; finished in 20.29s ``` One existing expectation changed: the schema inventory gained only `mail_proxy_mutations`, which #486 requires for the durable queue. No existing table, status or behavior assertion was removed. Re-read the touched doc comments; updated DESIGN §53 to describe this slice and remaining work. Built the real web production bundle as the RustEmbed prerequisite. No UI source changed, so there is no new screenshot set. UX gaps closed - Mail clients can save read/unread, flag, reply and deletion state rather than receiving unavailable-write errors. - Same-connection FETCH and other IMAP aliases see accepted flags; the web unread-first projection updates in the queue transaction. - A stale connection cannot expunge a message whose Deleted intent another connection cleared. Known gaps / UX gaps left - This continuation completes only the flag/delete queue slice. MOVE/COPY, draft APPEND and From/default-account routing, the shared Sync with Your Devices preset/profile, and populated Apple Mail acceptance remain unimplemented. - No real-provider offline/reconnect worker run, Mac command capture, staging Mail grant or staging deployment was done. The local populated test uses an isolated authenticated provider fixture; it does not constitute Apple Mail acceptance. - Queue delivery has 100 attempts. Dead Jobs retain mutation intent for explicit retry. A retired generation cannot be replayed against replacement UIDs. - Upstream flag changes made by another client still depend on the existing sync behavior; this slice does not add general upstream flag reconciliation. Decisions - Absolute flag state makes delivery replay idempotent; one pending revision belongs to one owner-bound virtual UID. A stale receipt cannot discard newer accepted intent. - Require known UIDPLUS for deletion; refuse unsupported deletion instead of issuing mailbox-wide EXPUNGE. - Use a folder lock for each fetch/commit window and delivery; leave IDLE outside that lock. - Use 100 delivery attempts and retain failed intent. No secrets enter payloads or error text. Performance Measurement not run: the 2026-10-02 verification policy limits performance runs to performance issues. The existing baseline has no comparable Mail proxy view profile (mail.accounts measures HTTP account listing). New profile fields are `queued_flags` and `queued_flags_burst`; the sampler still reports CPU and RSS. Perf VM command for the merge round, with a copied prebuilt test binary and no compile on the VM: `flock /root/perf.lock bash -c 'uptime; python3 bench/mail-sync.py /path/to/prebuilt-mail-test-binary --label perf-vm --test profile_mail_proxy --profile-prefix "MAIL_PROXY_PROFILE "'` For the merge round - `bun run test --maxWorkers=2` in apps/web: full web regressions. - `bun apps/web/e2e/mail-proxy-486.mjs`: TLS listener scopes, revocation and submission refusal; the existing fixture is empty, so this does not replace populated Mail acceptance. - `bash tests/adversarial/run.sh`: combined XUser/authz/robustness checks with the merge round's server and credentials supplied through its existing environment setup. - Real upstream offline/reconnect delivery and populated Apple Mail acceptance after MOVE/COPY, drafts and the device preset exist. Use the Mac lock and lab profile without reconfiguration. - No release build, full e2e matrix, staging deploy or Mac interop run here, per the current verification policy.
Author
Owner

Continuing on job/mailproxy-486 at head 638394ae5 (the worktree already contains durable STORE/UID EXPUNGE commits after requested head 152b4322d). Read CLAUDE.md, CONTEXT.md and DESIGN §§45, 49–53. Next: MOVE/COPY with durable upstream intent, draft APPEND/routing, then the shared setup preset. Current verification policy defers full matrices, release builds, staging deployment and Mac interop to the merge round.

Continuing on job/mailproxy-486 at head 638394ae5 (the worktree already contains durable STORE/UID EXPUNGE commits after requested head 152b4322d). Read CLAUDE.md, CONTEXT.md and DESIGN §§45, 49–53. Next: MOVE/COPY with durable upstream intent, draft APPEND/routing, then the shared setup preset. Current verification policy defers full matrices, release builds, staging deployment and Mac interop to the merge round.
Author
Owner

Commits 30c79c5ab, 06fac423a and 3a64127e2 add the shared raw-draft/COPY/MOVE boundary, durable owner-bound transfer journal and authorized device routing. Offline MOVE now has a stable, exact-readable destination UID and hides its source in both IMAP views; a mixed-owner batch rolls back all intent and wakes. Delivery requires known permanent keywords, recovers a dispatched operation by its unique keyword, and never blindly repeats COPY after an uncertain response. Source deletion uses UID EXPUNGE only after a durable destination receipt. Finding: sync after a crash could prune the last source membership and cascade away pending intent. A five-case focused regression run passes with journal metadata retention and pending-message preservation; the latest full Mail gates are running. Server clippy and tests passed (167 passed, 5 ignored). Draft routing, profile/setup, populated listener acceptance and the web projection of queued moves remain to be completed.

Commits 30c79c5ab, 06fac423a and 3a64127e2 add the shared raw-draft/COPY/MOVE boundary, durable owner-bound transfer journal and authorized device routing. Offline MOVE now has a stable, exact-readable destination UID and hides its source in both IMAP views; a mixed-owner batch rolls back all intent and wakes. Delivery requires known permanent keywords, recovers a dispatched operation by its unique keyword, and never blindly repeats COPY after an uncertain response. Source deletion uses UID EXPUNGE only after a durable destination receipt. Finding: sync after a crash could prune the last source membership and cascade away pending intent. A five-case focused regression run passes with journal metadata retention and pending-message preservation; the latest full Mail gates are running. Server clippy and tests passed (167 passed, 5 ignored). Draft routing, profile/setup, populated listener acceptance and the web projection of queued moves remain to be completed.
Author
Owner

READY FOR MERGE: no

Branch: job/mailproxy-486; head: 92feb6d1347e31480f40d374784584ce79782f35. Start: 638394ae5 (the worktree was already ahead of requested 152b4322d). Merged origin/dev once at fdd5b364c3d8f746c53bc4c511afee15bf07999b via cb3dec01b; kept both the Settings cache changes and Mail preset. The remote has advanced since that merge. No push or deploy. No new dependencies. Mail migration 0016 was free on the fetched dev tree (remote Mail migrations ended at 0009; this branch already had 0012–0015).

Built

  • Durable owner- and epoch-bound COPY/MOVE through the existing Jobs worker. Accepted destinations receive stable virtual UIDs and are readable offline; MOVE hides its source in overlapping IMAP views. A bad item rolls back its whole command. Queued STORE flags settle before COPY. Provider receipt keywords recover lost replies without blindly duplicating messages. MOVE uses selective UID EXPUNGE only after the destination receipt is durable.
  • Exact MIME draft APPEND, APPENDUID, flags and INTERNALDATE. From routes to an enabled Connected Account; the oldest enabled account is the fallback. Raw bytes, metadata, UID and Job wake commit together. Normal sync resolves the actual provider identity, including drafts without Message-ID.
  • Shared device preset/profile: Calendar, Reminders, Notes and Mail; configured TLS IMAP/submission ports and Copy actions. Notes-only profile behavior remains covered. Generated API contracts carry the configured Mail settings. Fixed the phone setup title so Calendar Feeds cannot label App Passwords.
  • MIME-part and bounded partial FETCH, RFC822/TEXT and CLOSE. Partial reads do not create full-body served evidence for Notes.
  • Focused real TLS provider check with 2,000 messages, plus production setup/list screenshots at 390/820/1440 in light/dark with macOS platform emulation. Test credentials and profile QR codes are masked.
  • Extended bench/mail-sync.py / profile_mail_proxy with COPY and draft p50/p95 and acceptance at the 1,024-operation queue ceiling. Measurement is deferred by the current verification policy. docs/perf/baseline.json has no comparable Mail proxy queue baseline.

Files (this continuation)

  • crates/calternal-imap/src/{store,session,mime}.rs; crates/calternal-imap/tests/{mail,mime}.rs.
  • crates/plugins/mail/migrations/0016_proxy_transfers.sql; crates/plugins/mail/src/{proxy_transfers,proxy_mutations,proxy,proxy_tests,sync,lib}.rs; crates/plugins/mail/src/cache/store.rs.
  • crates/calternal-server/src/device_imap.rs; crates/calternal-auth/src/api.rs.
  • contracts/openapi.json; packages/api-client/src/generated.ts.
  • apps/web/src/routes/settings/account/AppPasswordsGroup.svelte; apps/web/e2e/{mail-proxy-486,app-passwords}.mjs.
  • tests/adversarial/mail_proxy.py; bench/mail-sync.py; docs/DESIGN.md §53.

Gates

cargo fmt --check: exit 0, no output. Cargo commands used line-tables-only debug info, no incremental build, four build jobs and worktree TMPDIR. Clippy and tests ran per touched crate. Summaries below are verbatim.

cargo clippy -p calternal-imap --all-targets -- -D warnings; cargo test -p calternal-imap:

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.45s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
test result: ok. 10 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.13s
test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
test result: ok. 11 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s
test result: ok. 30 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.13s
test result: ok. 8 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s
test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

cargo clippy -p calternal-auth --all-targets -- -D warnings; cargo test -p calternal-auth:

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.69s
test result: ok. 91 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out; finished in 55.23s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

cargo clippy -p calternal-plugin-mail --all-targets -- -D warnings; cargo test -p calternal-plugin-mail:

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 7.58s
test result: ok. 75 passed; 0 failed; 5 ignored; 0 measured; 0 filtered out; finished in 2.88s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

cargo clippy -p calternal-server --all-targets -- -D warnings; cargo test -p calternal-server:

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 43.91s
test result: ok. 167 passed; 0 failed; 5 ignored; 0 measured; 0 filtered out; finished in 15.68s

Web: bun run check; bunx vitest run src/routes/settings/shared-components.guard.test.ts --maxWorkers=2; bun run build all exited 0. Focused API client bun test exited 0.

svelte-check found 0 errors and 0 warnings
 Test Files  1 passed (1)
      Tests  2 passed (2)
 18 pass
 0 fail
 49 expect() calls
Ran 18 tests across 1 file. [889.00ms]

Focused local regression:

CALTERNAL_SERVER_BIN="$CARGO_TARGET_DIR/debug/calternal-server" CALTERNAL_E2E_ASSET_OVERRIDE=1 CALTERNAL_MAIL_PROXY_POPULATED=1 node apps/web/e2e/mail-proxy-486.mjs

The feature binary was built with cargo build -p calternal-server --features mail-test-provider. The populated run exited 0. After the phone-title correction, the focused listener/UI run without the populated fixture also exited 0. The final production screenshots come from that last UI run. Verbatim evidence:

PASS populated provider started with 2,000 fixture messages
PASS populated Mail projection and Connected Account reconciliation
PASS mail: IMAP namespace and authenticated SMTP refusal
PASS notes: IMAP namespace and authenticated SMTP refusal
PASS combined: IMAP namespace and authenticated SMTP refusal
PASS other: IMAP namespace and authenticated SMTP refusal
PASS caldav: IMAP and SMTP authentication denied
PASS populated Mail: metadata/part/partial FETCH, queued STORE → COPY, MOVE, exact draft APPEND, selective EXPUNGE, CLOSE
PASS production App Password scope labels: 390/820/1440, light/dark, macOS platform
PASS revoked: IMAP and SMTP authentication denied

Findings fixed

  • Receipt/message retention survives sync pruning the source after an upstream MOVE, including exact headers/body cache access.
  • A queued source flag change no longer prevents an immediate COPY. Delivery drains the same mutation journal before creating its copy marker.
  • SELECT discovers permanent keyword support; read-only EXAMINE can report no permanent flags.
  • The isolated provider must advertise Archive/Drafts/Trash roles. A matching folder name alone is not the real provider role.
  • The phone setup header now names App Passwords. Screenshot capture applies Appearance before creating one-time setup state and stays within each test User's profile limit.

UX gaps closed

  • The standard device preset grants Mail, keeps Mail enabled in the Apple profile and shows actual TLS ports with working copy controls.
  • Queued MOVE destinations and exact drafts are readable in IMAP before upstream delivery. From routing, flag preservation and UID stability have regression tests.
  • Mail part/partial FETCH and CLOSE now work on populated accounts. Read-only and unrelated service grants remain isolated.

UX gaps left / known gaps

  • Pending destination STORE and EXPUNGE are unavailable until transfer/draft delivery completes. Full offline draft editing needs chained mutations after the receipt.
  • The web Mail folder view does not yet show pending COPY/MOVE/draft destinations; it receives them through sync after delivery. MOVE's immediate source hide currently applies to IMAP views. This does not meet the owner rule that edits flow everywhere immediately.
  • Non-PEEK body FETCH does not yet set Seen. Explicit STORE works.
  • Ambiguous dispatch retains intent and stops safely, but there is no explicit recovery UI for a missing or duplicate provider keyword receipt.
  • No configurable default Mail account or editable Account Name exists yet. From routing currently matches account email; folder labels still use email. Cross-account copies and providers without permanent keywords are refused.
  • Full-snapshot SELECT and the 4 MiB body limit remain inherited performance/large-message limits.
  • Real Apple Mail acceptance and the large-mailbox stress run remain unverified. Staging was not deployed and no Mac account was reconfigured.

Decisions

  • Reuse the existing encrypted account resolver, Jobs worker, flag delivery, folder locks, sync hydration and shared device profile. The server remains the single writer.
  • Require permanent provider keywords for recoverable COPY/APPEND, with a random operation keyword and a retained dispatched receipt. Never blindly retry a non-idempotent write after an uncertain response.
  • Keep unified transfers in the source account. Refuse cross-account COPY/MOVE until there is a decided import path.
  • Bound one command and each User's transfer queue at 1,024 operations, with 128 MiB of queued draft MIME and the existing 4 MiB per-message bound.
  • Use the oldest enabled Connected Account as the stable default until the default-account preference exists. An explicit real Drafts folder must belong to that account.

For the merge round

  • (cd apps/web && bun run test --maxWorkers=2) and (cd apps/web && bun run test:e2e && bun run test:e2e:app-passwords): prove combined web behavior and all device-profile flows, including existing Notes-only setup.
  • tests/adversarial/run.sh: one time-boxed combined API authorization/robustness round. This job ran only its ordinary-command regression, per the verification policy.
  • Rebuild the combined feature server and rerun the populated focused command above. It must retain exact drafts, preserve accepted flags and delete only the addressed UID.
  • On the perf VM, copy the build-host Mail test binary and run flock /root/perf.lock python3 bench/mail-sync.py /root/mailproxy-486/calternal_plugin_mail --label perf-vm --test profile_mail_proxy --profile-prefix 'MAIL_PROXY_PROFILE '. The sampler records load, CPU, RSS, p50/p95, 100k-message worst case and burst. Do not compile there. The copied paths must be set up before the run.
  • Real Apple Mail: flock -w 7200 ~/.local/state/codex-jobs/calternal/macvm.lock netbird ssh --no-browser calternal@10.69.69.21, using macdav-lab/apple-interop-2026-10-02.md, the lab profile and the combined populated server. Prove login, full message/attachment reads, flags, copy/move/delete and draft updates without changing other Mac accounts. This is required acceptance, not proven by macOS platform emulation.
  • The merge round owns release build, staging deploy with a Mail grant and final deployed checks. Credentials stay in the private staging environment.

Evidence (attached to #486; all from the production app, macOS platform)

Setup: setup-1440-dark.png, setup-1440-light.png, setup-390-dark.png, setup-390-light.png, setup-820-dark.png, setup-820-light.png

Credential list: 1440-dark.png, 1440-light.png, 390-dark.png, 390-light.png, 820-dark.png, 820-light.png

Cleanup: cargo clean completed; web build output was deleted; the real test server and isolated provider were stopped. Review artifacts remain ignored. Working tree is clean. No screenshots are committed.

     Removed 18331 files, 9.8GiB total
READY FOR MERGE: no Branch: `job/mailproxy-486`; head: `92feb6d1347e31480f40d374784584ce79782f35`. Start: `638394ae5` (the worktree was already ahead of requested `152b4322d`). Merged `origin/dev` once at `fdd5b364c3d8f746c53bc4c511afee15bf07999b` via `cb3dec01b`; kept both the Settings cache changes and Mail preset. The remote has advanced since that merge. No push or deploy. No new dependencies. Mail migration 0016 was free on the fetched dev tree (remote Mail migrations ended at 0009; this branch already had 0012–0015). Built - Durable owner- and epoch-bound COPY/MOVE through the existing Jobs worker. Accepted destinations receive stable virtual UIDs and are readable offline; MOVE hides its source in overlapping IMAP views. A bad item rolls back its whole command. Queued STORE flags settle before COPY. Provider receipt keywords recover lost replies without blindly duplicating messages. MOVE uses selective UID EXPUNGE only after the destination receipt is durable. - Exact MIME draft APPEND, APPENDUID, flags and INTERNALDATE. From routes to an enabled Connected Account; the oldest enabled account is the fallback. Raw bytes, metadata, UID and Job wake commit together. Normal sync resolves the actual provider identity, including drafts without Message-ID. - Shared device preset/profile: Calendar, Reminders, Notes and Mail; configured TLS IMAP/submission ports and Copy actions. Notes-only profile behavior remains covered. Generated API contracts carry the configured Mail settings. Fixed the phone setup title so Calendar Feeds cannot label App Passwords. - MIME-part and bounded partial FETCH, RFC822/TEXT and CLOSE. Partial reads do not create full-body served evidence for Notes. - Focused real TLS provider check with 2,000 messages, plus production setup/list screenshots at 390/820/1440 in light/dark with macOS platform emulation. Test credentials and profile QR codes are masked. - Extended `bench/mail-sync.py` / `profile_mail_proxy` with COPY and draft p50/p95 and acceptance at the 1,024-operation queue ceiling. Measurement is deferred by the current verification policy. `docs/perf/baseline.json` has no comparable Mail proxy queue baseline. Files (this continuation) - `crates/calternal-imap/src/{store,session,mime}.rs`; `crates/calternal-imap/tests/{mail,mime}.rs`. - `crates/plugins/mail/migrations/0016_proxy_transfers.sql`; `crates/plugins/mail/src/{proxy_transfers,proxy_mutations,proxy,proxy_tests,sync,lib}.rs`; `crates/plugins/mail/src/cache/store.rs`. - `crates/calternal-server/src/device_imap.rs`; `crates/calternal-auth/src/api.rs`. - `contracts/openapi.json`; `packages/api-client/src/generated.ts`. - `apps/web/src/routes/settings/account/AppPasswordsGroup.svelte`; `apps/web/e2e/{mail-proxy-486,app-passwords}.mjs`. - `tests/adversarial/mail_proxy.py`; `bench/mail-sync.py`; `docs/DESIGN.md` §53. Gates `cargo fmt --check`: exit 0, no output. Cargo commands used line-tables-only debug info, no incremental build, four build jobs and worktree TMPDIR. Clippy and tests ran per touched crate. Summaries below are verbatim. `cargo clippy -p calternal-imap --all-targets -- -D warnings`; `cargo test -p calternal-imap`: ```text Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.45s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s test result: ok. 10 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.13s test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s test result: ok. 11 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s test result: ok. 30 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.13s test result: ok. 8 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s ``` `cargo clippy -p calternal-auth --all-targets -- -D warnings`; `cargo test -p calternal-auth`: ```text Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.69s test result: ok. 91 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out; finished in 55.23s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s ``` `cargo clippy -p calternal-plugin-mail --all-targets -- -D warnings`; `cargo test -p calternal-plugin-mail`: ```text Finished `dev` profile [unoptimized + debuginfo] target(s) in 7.58s test result: ok. 75 passed; 0 failed; 5 ignored; 0 measured; 0 filtered out; finished in 2.88s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s ``` `cargo clippy -p calternal-server --all-targets -- -D warnings`; `cargo test -p calternal-server`: ```text Finished `dev` profile [unoptimized + debuginfo] target(s) in 43.91s test result: ok. 167 passed; 0 failed; 5 ignored; 0 measured; 0 filtered out; finished in 15.68s ``` Web: `bun run check`; `bunx vitest run src/routes/settings/shared-components.guard.test.ts --maxWorkers=2`; `bun run build` all exited 0. Focused API client `bun test` exited 0. ```text svelte-check found 0 errors and 0 warnings Test Files 1 passed (1) Tests 2 passed (2) 18 pass 0 fail 49 expect() calls Ran 18 tests across 1 file. [889.00ms] ``` Focused local regression: ```sh CALTERNAL_SERVER_BIN="$CARGO_TARGET_DIR/debug/calternal-server" CALTERNAL_E2E_ASSET_OVERRIDE=1 CALTERNAL_MAIL_PROXY_POPULATED=1 node apps/web/e2e/mail-proxy-486.mjs ``` The feature binary was built with `cargo build -p calternal-server --features mail-test-provider`. The populated run exited 0. After the phone-title correction, the focused listener/UI run without the populated fixture also exited 0. The final production screenshots come from that last UI run. Verbatim evidence: ```text PASS populated provider started with 2,000 fixture messages PASS populated Mail projection and Connected Account reconciliation PASS mail: IMAP namespace and authenticated SMTP refusal PASS notes: IMAP namespace and authenticated SMTP refusal PASS combined: IMAP namespace and authenticated SMTP refusal PASS other: IMAP namespace and authenticated SMTP refusal PASS caldav: IMAP and SMTP authentication denied PASS populated Mail: metadata/part/partial FETCH, queued STORE → COPY, MOVE, exact draft APPEND, selective EXPUNGE, CLOSE PASS production App Password scope labels: 390/820/1440, light/dark, macOS platform PASS revoked: IMAP and SMTP authentication denied ``` Findings fixed - Receipt/message retention survives sync pruning the source after an upstream MOVE, including exact headers/body cache access. - A queued source flag change no longer prevents an immediate COPY. Delivery drains the same mutation journal before creating its copy marker. - SELECT discovers permanent keyword support; read-only EXAMINE can report no permanent flags. - The isolated provider must advertise Archive/Drafts/Trash roles. A matching folder name alone is not the real provider role. - The phone setup header now names App Passwords. Screenshot capture applies Appearance before creating one-time setup state and stays within each test User's profile limit. UX gaps closed - The standard device preset grants Mail, keeps Mail enabled in the Apple profile and shows actual TLS ports with working copy controls. - Queued MOVE destinations and exact drafts are readable in IMAP before upstream delivery. From routing, flag preservation and UID stability have regression tests. - Mail part/partial FETCH and CLOSE now work on populated accounts. Read-only and unrelated service grants remain isolated. UX gaps left / known gaps - Pending destination STORE and EXPUNGE are unavailable until transfer/draft delivery completes. Full offline draft editing needs chained mutations after the receipt. - The web Mail folder view does not yet show pending COPY/MOVE/draft destinations; it receives them through sync after delivery. MOVE's immediate source hide currently applies to IMAP views. This does not meet the owner rule that edits flow everywhere immediately. - Non-PEEK body FETCH does not yet set Seen. Explicit STORE works. - Ambiguous dispatch retains intent and stops safely, but there is no explicit recovery UI for a missing or duplicate provider keyword receipt. - No configurable default Mail account or editable Account Name exists yet. From routing currently matches account email; folder labels still use email. Cross-account copies and providers without permanent keywords are refused. - Full-snapshot SELECT and the 4 MiB body limit remain inherited performance/large-message limits. - Real Apple Mail acceptance and the large-mailbox stress run remain unverified. Staging was not deployed and no Mac account was reconfigured. Decisions - Reuse the existing encrypted account resolver, Jobs worker, flag delivery, folder locks, sync hydration and shared device profile. The server remains the single writer. - Require permanent provider keywords for recoverable COPY/APPEND, with a random operation keyword and a retained dispatched receipt. Never blindly retry a non-idempotent write after an uncertain response. - Keep unified transfers in the source account. Refuse cross-account COPY/MOVE until there is a decided import path. - Bound one command and each User's transfer queue at 1,024 operations, with 128 MiB of queued draft MIME and the existing 4 MiB per-message bound. - Use the oldest enabled Connected Account as the stable default until the default-account preference exists. An explicit real Drafts folder must belong to that account. For the merge round - `(cd apps/web && bun run test --maxWorkers=2)` and `(cd apps/web && bun run test:e2e && bun run test:e2e:app-passwords)`: prove combined web behavior and all device-profile flows, including existing Notes-only setup. - `tests/adversarial/run.sh`: one time-boxed combined API authorization/robustness round. This job ran only its ordinary-command regression, per the verification policy. - Rebuild the combined feature server and rerun the populated focused command above. It must retain exact drafts, preserve accepted flags and delete only the addressed UID. - On the perf VM, copy the build-host Mail test binary and run `flock /root/perf.lock python3 bench/mail-sync.py /root/mailproxy-486/calternal_plugin_mail --label perf-vm --test profile_mail_proxy --profile-prefix 'MAIL_PROXY_PROFILE '`. The sampler records load, CPU, RSS, p50/p95, 100k-message worst case and burst. Do not compile there. The copied paths must be set up before the run. - Real Apple Mail: `flock -w 7200 ~/.local/state/codex-jobs/calternal/macvm.lock netbird ssh --no-browser calternal@10.69.69.21`, using `macdav-lab/apple-interop-2026-10-02.md`, the lab profile and the combined populated server. Prove login, full message/attachment reads, flags, copy/move/delete and draft updates without changing other Mac accounts. This is required acceptance, not proven by macOS platform emulation. - The merge round owns release build, staging deploy with a Mail grant and final deployed checks. Credentials stay in the private staging environment. Evidence (attached to #486; all from the production app, macOS platform) Setup: [setup-1440-dark.png](https://git.kayg.org/attachments/81e5ed4a-b333-4de9-a5df-257a93cf594d), [setup-1440-light.png](https://git.kayg.org/attachments/52a33e94-43c1-467b-8f0c-19af86e6ce80), [setup-390-dark.png](https://git.kayg.org/attachments/d5ce1340-1fdb-402f-b21b-9b0acd075c35), [setup-390-light.png](https://git.kayg.org/attachments/da87d2ec-e939-4e4f-a3b7-07a53da408a0), [setup-820-dark.png](https://git.kayg.org/attachments/f68c25da-a936-4066-8ad9-e9ca8a02eaea), [setup-820-light.png](https://git.kayg.org/attachments/be3a9058-bfa2-4352-97b7-792b16c3b795) Credential list: [1440-dark.png](https://git.kayg.org/attachments/161eb5bc-150e-48c1-a4af-f9fc8796bdc3), [1440-light.png](https://git.kayg.org/attachments/f3a376bf-8d0d-459f-9569-79abab59a6d9), [390-dark.png](https://git.kayg.org/attachments/817f6d33-0bed-4236-a68e-5245198bf2d2), [390-light.png](https://git.kayg.org/attachments/9a7c18ca-a1dd-4f37-ae5b-c62fe292c123), [820-dark.png](https://git.kayg.org/attachments/d6075b3d-08f8-4ca1-bd94-9388898770c8), [820-light.png](https://git.kayg.org/attachments/671425b3-69d3-41fb-8b0e-d8eaa7bef63d) Cleanup: `cargo clean` completed; web build output was deleted; the real test server and isolated provider were stopped. Review artifacts remain ignored. Working tree is clean. No screenshots are committed. ```text Removed 18331 files, 9.8GiB total ```
Author
Owner

Continuing #486 on job/mailproxy-486 at base/head 92feb6d134. Read CLAUDE.md, CONTEXT.md, DESIGN §53 and continuation report. Remaining work: pending destination edits, immediate web projection and invalidation, implicit Seen on non-PEEK FETCH, populated scripted Apple Mail acceptance. Real Mac check only if its lock is free. No dependency additions planned.

Continuing #486 on job/mailproxy-486 at base/head 92feb6d1347e31480f40d374784584ce79782f35. Read CLAUDE.md, CONTEXT.md, DESIGN §53 and continuation report. Remaining work: pending destination edits, immediate web projection and invalidation, implicit Seen on non-PEEK FETCH, populated scripted Apple Mail acceptance. Real Mac check only if its lock is free. No dependency additions planned.
Author
Owner

Committed 23073699b (implicit Seen) and 55a5e377e (pending destination edits and immediate web projection). Focused tests now pass: IMAP body/PEEK/EXAMINE semantics; pending destination flags, stale MODSEQ rejection, owner isolation, selective deletion and web pages; authenticated owner-filtered Mail SSE. Existing folder-page indexed-window and schema-upgrade tests remain unchanged and pass. Mail crate output: test result: ok. 77 passed; 0 failed; 5 ignored; 0 measured; 0 filtered out; finished in 4.93s. Mail clippy passes. Web consumer and populated client replay are next.

Evidence-driven decisions: retain separate epoch-bound upstream coordinates and read-only pending markers; extend the existing mutation journal to let the transfer own flag/delete intent until receipt handoff. Cleanup triggers retain the old lifetime rule. Queue-free pages retain the covering-index path. Mail invalidations reuse the shared Plugin event bus and stream permits, with no message data in SSE.

Real Mac lock was free. The lab SSH connection succeeded, but Apple Mail's account enumeration timed out (-1712). A separate guarded system-process query succeeded and reported Notes as foreground. No Mac account was changed and no real Mail acceptance is claimed.

Committed 23073699b (implicit Seen) and 55a5e377e (pending destination edits and immediate web projection). Focused tests now pass: IMAP body/PEEK/EXAMINE semantics; pending destination flags, stale MODSEQ rejection, owner isolation, selective deletion and web pages; authenticated owner-filtered Mail SSE. Existing folder-page indexed-window and schema-upgrade tests remain unchanged and pass. Mail crate output: `test result: ok. 77 passed; 0 failed; 5 ignored; 0 measured; 0 filtered out; finished in 4.93s`. Mail clippy passes. Web consumer and populated client replay are next. Evidence-driven decisions: retain separate epoch-bound upstream coordinates and read-only pending markers; extend the existing mutation journal to let the transfer own flag/delete intent until receipt handoff. Cleanup triggers retain the old lifetime rule. Queue-free pages retain the covering-index path. Mail invalidations reuse the shared Plugin event bus and stream permits, with no message data in SSE. Real Mac lock was free. The lab SSH connection succeeded, but Apple Mail's account enumeration timed out (-1712). A separate guarded system-process query succeeded and reported Notes as foreground. No Mac account was changed and no real Mail acceptance is claimed.
Author
Owner

READY FOR MERGE: no

Continuation result

Branch: job/mailproxy-486. Starting head: 92feb6d134. Final head: d2b0c7fad8.

The remaining code gaps are closed. Pending COPY/MOVE and draft destinations accept flags and selective deletion before provider delivery. The existing mutation journal retains those edits through receipt handoff. Owner, enabled-account, epoch and conditional MODSEQ checks apply to pending destinations. Web pages, message bodies and folder counts show accepted moves/deletes/flags at once. One owner-filtered SSE stream refreshes open readers and sidebar badges without a browser reload. Non-PEEK body reads set Seen in writable selections; PEEK, header reads and EXAMINE preserve unread state. Bounded cached-header SEARCH supports the normal client replay.

The populated replay passed against 2,000 messages on the isolated TLS provider. Real Apple Mail acceptance is still incomplete. The Mac lock was free and SSH worked, but Mail was waiting at its first-run privacy dialog. The lab also showed a credential-required notice. No account, preference or credential was changed. This is why this report says no.

Files

  • crates/calternal-imap/src/session.rs and tests/mail.rs: Seen and cached-header SEARCH, with regression tests.
  • crates/plugins/mail/src/proxy.rs, proxy_mutations.rs, proxy_transfers.rs, proxy_tests.rs, cache/store.rs and routes.rs: pending journal handoff, visible membership reads, notifications and authenticated SSE, with regression tests.
  • crates/plugins/mail/migrations/0017_proxy_projection.sql: pending mutation lifetime and read-only projection.
  • apps/web/src/lib/mail/MailView.svelte, MailSidebar.svelte, live.ts and live.test.ts: shared invalidations and current open views.
  • tests/adversarial/mail_proxy.py and apps/web/e2e/mail-proxy-486.mjs: populated client replay and production screenshots.
  • bench/mail-sync.py: document the extended proxy projection profile in proxy_tests.rs.
  • contracts/openapi.json, contracts/actions.json and packages/api-client/src/generated.ts: regenerated contract. Action registry regeneration also updates previously stale upstream entries.
  • docs/DESIGN.md §53: current behavior, limits and remaining acceptance requirement.

Eight atomic continuation commits plus the authorized origin/dev merge are in history. Fetch/merge ran once: origin/dev e3915b5b79. Incoming Calendar changes were retained. Mail migration 0017 was free on that fetched dev. No new dependencies or changed existing test expectations. No push, deploy or issue closure.

Gates

All cargo commands used CARGO_PROFILE_DEV_DEBUG=line-tables-only, CARGO_INCREMENTAL=0, CARGO_BUILD_JOBS=4 and the worktree target/tmp. CARGO_TARGET_DIR was retained. cargo fmt --check passed with no output. Clippy and tests ran per crate. The following output is verbatim; zero-test summaries are omitted below when repeated.

cargo clippy -p calternal-imap --all-targets -- -D warnings

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 1m 02s

cargo test -p calternal-imap

test result: ok. 12 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.87s
test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
test result: ok. 11 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
test result: ok. 30 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.16s
test result: ok. 8 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s
test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

cargo clippy -p calternal-plugin-mail --all-targets -- -D warnings

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 8.00s

cargo test -p calternal-plugin-mail

test result: ok. 78 passed; 0 failed; 5 ignored; 0 measured; 0 filtered out; finished in 3.74s

cargo clippy -p calternal-server --all-targets -- -D warnings

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 48.18s

cargo test -p calternal-server

test result: ok. 167 passed; 0 failed; 5 ignored; 0 measured; 0 filtered out; finished in 16.16s

bun run check (apps/web):

svelte-check found 0 errors and 0 warnings

bunx vitest run src/lib/mail/live.test.ts src/lib/mail/MailSidebar.svelte.test.ts --maxWorkers=2 (apps/web):

 Test Files  2 passed (2)
      Tests  2 passed (2)

Production web build, Python syntax and Node syntax checks passed. The fixture-enabled debug server build passed. All changed module/function comments were read again before reporting. Cleanup completed:

     Removed 16948 files, 9.0GiB total

Generated web build and .svelte-kit/output were removed. The working tree is clean. No fixture container remains.

Focused populated acceptance

Command from the repo root, before cleanup:

CALTERNAL_SERVER_BIN="$CARGO_TARGET_DIR/debug/calternal-server" CALTERNAL_E2E_ASSET_OVERRIDE=1 CALTERNAL_MAIL_PROXY_POPULATED=1 CALTERNAL_SCREENSHOT_DIR="$PWD/artifacts/mail-proxy-486-continuation-2" node apps/web/e2e/mail-proxy-486.mjs

Verbatim output:

PASS populated provider started with 2,000 fixture messages
PASS populated Mail projection and Connected Account reconciliation
PASS mail: IMAP namespace and authenticated SMTP refusal
PASS notes: IMAP namespace and authenticated SMTP refusal
PASS combined: IMAP namespace and authenticated SMTP refusal
PASS other: IMAP namespace and authenticated SMTP refusal
PASS caldav: IMAP and SMTP authentication denied
PASS populated Mail: metadata/part/partial FETCH, queued STORE → COPY, MOVE, exact draft APPEND, selective EXPUNGE, CLOSE
PASS device live edit: read
PASS device live edit: unread
PASS device live edit: move
PASS device live edit: delete
PASS live web projection: device BODY[]/read/unread/MOVE/EXPUNGE without browser reload
PASS production Mail views: inbox/folder/message/thread at 390/820/1440, light/dark, macOS platform
PASS production App Password scope labels: 390/820/1440, light/dark, macOS platform
PASS revoked: IMAP and SMTP authentication denied

The replay checks exact draft bytes and pending draft flags at the real upstream. It also keeps the production browser open while a device reads, marks unread, moves and expunges Mail. One initial replay exposed missing HEADER SEARCH and led to its regression fix. Another browser run exited with Target page/context/browser has been closed; a single retry passed. No cause is claimed for that browser exit. No unresolved functional failure was found in the focused replay.

UX gaps closed

  • Device edits update open Inbox, folder, message and thread projections and sidebar counts without reload.
  • Pending destinations retain their flags and deletion intent after delivery. Web read edits use the journal rather than a provisional provider UID.
  • A pending COPY of an existing message produces one unread-first web row while IMAP keeps distinct UIDs.
  • A deleted open message clears its body; transient refresh errors keep readable content.
  • Shared SSE opens/reconnects refetch and closes when the last view leaves.

UX gaps left / known gaps

  • Real Apple Mail acceptance remains required by DESIGN §53. Scripted replay proves these commands, not the full Apple Mail application.
  • Existing remote-image wording appears in the reader, including a plain draft. The silent image-protection flow belongs to #726; it was not changed here.
  • Existing receipt-recovery UI, editable Connected Account display names/default-account choice and larger full-MIME bodies remain outside this continuation. Existing full-body cache ceiling is 4 MiB, snapshot ceiling is 100,000 messages. Sending remains deferred as designed.
  • A pending destination can be edited/deleted, but cannot be used as a new COPY/MOVE source until its provider receipt exists.
  • No performance numbers or 2 s/5 s Apple Mail timing claims. The proxy profile now covers queued web projection and its burst. The latest verification policy permits measurements only for performance issues; #486 is not one. The existing HTTP mail.accounts baseline is not a comparable IMAP measure.

Owner steps for real Apple Mail

Hold the Mac lock for the whole session. Complete Mail's first-run privacy choice, then renew/install only the lab calternal profile with a current full Mail grant and trust the lab CA if required. Run a local fixture server and reverse-forward HTTPS 8443, IMAP 31993 and SMTP 31465 as in the lab method. Check folders, bodies, Seen/flags, moves/deletes, draft save and edit, offline reconnect, and simultaneous web updates. Do not change any other Mac account. The old lab credential cannot establish acceptance.

Decisions

  • Reuse the existing mutation journal. A pending transfer owns intent until it installs the durable UID; cleanup triggers retain lifetime rules without requiring a destination UID before it exists.
  • Use negative membership markers only inside web reads, never in provider commands. Keep the original covering-index path when no intent is queued.
  • Reuse the shared Plugin bus and stream permits. Events contain no Mail content; lag/reconnect causes a refetch.
  • Cache-only HEADER SEARCH has a 64 KiB per-message and 16 MiB aggregate budget. Nested predicates share the budget; unsupported/oversized work returns no partial result. Flag/range searches retain their metadata-free path.
  • These choices are recorded in DESIGN §53 and code comments. No new product-level design decision was required.

For the merge round

Run the combined branch's full suites once, per the verification policy:

  • (cd apps/web && bun run test --maxWorkers=2) — cross-feature unit regressions.
  • (cd apps/web && bun run test:e2e && bun run test:e2e:app-passwords) — shell and credential UI contracts, plus the merge round's full scheduled e2e set.
  • CARGO_PROFILE_DEV_DEBUG=line-tables-only CARGO_INCREMENTAL=0 CARGO_BUILD_JOBS=4 bash tests/adversarial/run.sh — real-server XUser/authz/robustness matrices, including owner isolation for Mail events.
  • CARGO_PROFILE_DEV_DEBUG=line-tables-only CARGO_INCREMENTAL=0 CARGO_BUILD_JOBS=4 cargo build --release -p calternal-server — release build, then staging checks through the orchestrator's deployment workflow.
  • flock -n ~/.local/state/codex-jobs/calternal/macvm.lock netbird ssh --no-browser calternal@10.69.69.21 — begin the single-tenant real Apple Mail acceptance after the owner steps above. Hold the lock throughout subsequent GUI/forward sessions.

Performance profile, when scheduled on the perf VM (no compile there): flock /root/perf.lock bash -c 'uptime; python3 bench/mail-sync.py "$MAIL_PLUGIN_TEST_BIN" --test profile_mail_proxy --profile-prefix "MAIL_PROXY_PROFILE " --label perf-vm', with MAIL_PLUGIN_TEST_BIN pointing to the shared prebuilt test binary. Compare its average/worst-case measurements to the Mail baseline; this is not a merge gate.

Production screenshot evidence

These are real production views with macOS platform emulation. Each view has phone 390 px, tablet 820 px and desktop 1440 px in light/dark. Attachments are review evidence; the orchestrator supplies visual judgment. No screenshots are committed.

View 390 light 390 dark 820 light 820 dark 1440 light 1440 dark
inbox image image image image image image
folder image image image image image image
message image image image image image image
thread image image image image image image
READY FOR MERGE: no Continuation result Branch: job/mailproxy-486. Starting head: 92feb6d1347e31480f40d374784584ce79782f35. Final head: d2b0c7fad8c6ca0e27e8b1e3258b2e24b3427cd3. The remaining code gaps are closed. Pending COPY/MOVE and draft destinations accept flags and selective deletion before provider delivery. The existing mutation journal retains those edits through receipt handoff. Owner, enabled-account, epoch and conditional MODSEQ checks apply to pending destinations. Web pages, message bodies and folder counts show accepted moves/deletes/flags at once. One owner-filtered SSE stream refreshes open readers and sidebar badges without a browser reload. Non-PEEK body reads set Seen in writable selections; PEEK, header reads and EXAMINE preserve unread state. Bounded cached-header SEARCH supports the normal client replay. The populated replay passed against 2,000 messages on the isolated TLS provider. Real Apple Mail acceptance is still incomplete. The Mac lock was free and SSH worked, but Mail was waiting at its first-run privacy dialog. The lab also showed a credential-required notice. No account, preference or credential was changed. This is why this report says no. Files - crates/calternal-imap/src/session.rs and tests/mail.rs: Seen and cached-header SEARCH, with regression tests. - crates/plugins/mail/src/proxy.rs, proxy_mutations.rs, proxy_transfers.rs, proxy_tests.rs, cache/store.rs and routes.rs: pending journal handoff, visible membership reads, notifications and authenticated SSE, with regression tests. - crates/plugins/mail/migrations/0017_proxy_projection.sql: pending mutation lifetime and read-only projection. - apps/web/src/lib/mail/MailView.svelte, MailSidebar.svelte, live.ts and live.test.ts: shared invalidations and current open views. - tests/adversarial/mail_proxy.py and apps/web/e2e/mail-proxy-486.mjs: populated client replay and production screenshots. - bench/mail-sync.py: document the extended proxy projection profile in proxy_tests.rs. - contracts/openapi.json, contracts/actions.json and packages/api-client/src/generated.ts: regenerated contract. Action registry regeneration also updates previously stale upstream entries. - docs/DESIGN.md §53: current behavior, limits and remaining acceptance requirement. Eight atomic continuation commits plus the authorized origin/dev merge are in history. Fetch/merge ran once: origin/dev e3915b5b79c39b6086db40d4c93f24c4289b36ed. Incoming Calendar changes were retained. Mail migration 0017 was free on that fetched dev. No new dependencies or changed existing test expectations. No push, deploy or issue closure. Gates All cargo commands used CARGO_PROFILE_DEV_DEBUG=line-tables-only, CARGO_INCREMENTAL=0, CARGO_BUILD_JOBS=4 and the worktree target/tmp. CARGO_TARGET_DIR was retained. cargo fmt --check passed with no output. Clippy and tests ran per crate. The following output is verbatim; zero-test summaries are omitted below when repeated. `cargo clippy -p calternal-imap --all-targets -- -D warnings` ```text Finished `dev` profile [unoptimized + debuginfo] target(s) in 1m 02s ``` `cargo test -p calternal-imap` ```text test result: ok. 12 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.87s test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s test result: ok. 11 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s test result: ok. 30 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.16s test result: ok. 8 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s ``` `cargo clippy -p calternal-plugin-mail --all-targets -- -D warnings` ```text Finished `dev` profile [unoptimized + debuginfo] target(s) in 8.00s ``` `cargo test -p calternal-plugin-mail` ```text test result: ok. 78 passed; 0 failed; 5 ignored; 0 measured; 0 filtered out; finished in 3.74s ``` `cargo clippy -p calternal-server --all-targets -- -D warnings` ```text Finished `dev` profile [unoptimized + debuginfo] target(s) in 48.18s ``` `cargo test -p calternal-server` ```text test result: ok. 167 passed; 0 failed; 5 ignored; 0 measured; 0 filtered out; finished in 16.16s ``` `bun run check` (apps/web): ```text svelte-check found 0 errors and 0 warnings ``` `bunx vitest run src/lib/mail/live.test.ts src/lib/mail/MailSidebar.svelte.test.ts --maxWorkers=2` (apps/web): ```text Test Files 2 passed (2) Tests 2 passed (2) ``` Production web build, Python syntax and Node syntax checks passed. The fixture-enabled debug server build passed. All changed module/function comments were read again before reporting. Cleanup completed: ```text Removed 16948 files, 9.0GiB total ``` Generated web build and .svelte-kit/output were removed. The working tree is clean. No fixture container remains. Focused populated acceptance Command from the repo root, before cleanup: ```sh CALTERNAL_SERVER_BIN="$CARGO_TARGET_DIR/debug/calternal-server" CALTERNAL_E2E_ASSET_OVERRIDE=1 CALTERNAL_MAIL_PROXY_POPULATED=1 CALTERNAL_SCREENSHOT_DIR="$PWD/artifacts/mail-proxy-486-continuation-2" node apps/web/e2e/mail-proxy-486.mjs ``` Verbatim output: ```text PASS populated provider started with 2,000 fixture messages PASS populated Mail projection and Connected Account reconciliation PASS mail: IMAP namespace and authenticated SMTP refusal PASS notes: IMAP namespace and authenticated SMTP refusal PASS combined: IMAP namespace and authenticated SMTP refusal PASS other: IMAP namespace and authenticated SMTP refusal PASS caldav: IMAP and SMTP authentication denied PASS populated Mail: metadata/part/partial FETCH, queued STORE → COPY, MOVE, exact draft APPEND, selective EXPUNGE, CLOSE PASS device live edit: read PASS device live edit: unread PASS device live edit: move PASS device live edit: delete PASS live web projection: device BODY[]/read/unread/MOVE/EXPUNGE without browser reload PASS production Mail views: inbox/folder/message/thread at 390/820/1440, light/dark, macOS platform PASS production App Password scope labels: 390/820/1440, light/dark, macOS platform PASS revoked: IMAP and SMTP authentication denied ``` The replay checks exact draft bytes and pending draft flags at the real upstream. It also keeps the production browser open while a device reads, marks unread, moves and expunges Mail. One initial replay exposed missing HEADER SEARCH and led to its regression fix. Another browser run exited with Target page/context/browser has been closed; a single retry passed. No cause is claimed for that browser exit. No unresolved functional failure was found in the focused replay. UX gaps closed - Device edits update open Inbox, folder, message and thread projections and sidebar counts without reload. - Pending destinations retain their flags and deletion intent after delivery. Web read edits use the journal rather than a provisional provider UID. - A pending COPY of an existing message produces one unread-first web row while IMAP keeps distinct UIDs. - A deleted open message clears its body; transient refresh errors keep readable content. - Shared SSE opens/reconnects refetch and closes when the last view leaves. UX gaps left / known gaps - Real Apple Mail acceptance remains required by DESIGN §53. Scripted replay proves these commands, not the full Apple Mail application. - Existing remote-image wording appears in the reader, including a plain draft. The silent image-protection flow belongs to #726; it was not changed here. - Existing receipt-recovery UI, editable Connected Account display names/default-account choice and larger full-MIME bodies remain outside this continuation. Existing full-body cache ceiling is 4 MiB, snapshot ceiling is 100,000 messages. Sending remains deferred as designed. - A pending destination can be edited/deleted, but cannot be used as a new COPY/MOVE source until its provider receipt exists. - No performance numbers or 2 s/5 s Apple Mail timing claims. The proxy profile now covers queued web projection and its burst. The latest verification policy permits measurements only for performance issues; #486 is not one. The existing HTTP mail.accounts baseline is not a comparable IMAP measure. Owner steps for real Apple Mail Hold the Mac lock for the whole session. Complete Mail's first-run privacy choice, then renew/install only the lab calternal profile with a current full Mail grant and trust the lab CA if required. Run a local fixture server and reverse-forward HTTPS 8443, IMAP 31993 and SMTP 31465 as in the lab method. Check folders, bodies, Seen/flags, moves/deletes, draft save and edit, offline reconnect, and simultaneous web updates. Do not change any other Mac account. The old lab credential cannot establish acceptance. Decisions - Reuse the existing mutation journal. A pending transfer owns intent until it installs the durable UID; cleanup triggers retain lifetime rules without requiring a destination UID before it exists. - Use negative membership markers only inside web reads, never in provider commands. Keep the original covering-index path when no intent is queued. - Reuse the shared Plugin bus and stream permits. Events contain no Mail content; lag/reconnect causes a refetch. - Cache-only HEADER SEARCH has a 64 KiB per-message and 16 MiB aggregate budget. Nested predicates share the budget; unsupported/oversized work returns no partial result. Flag/range searches retain their metadata-free path. - These choices are recorded in DESIGN §53 and code comments. No new product-level design decision was required. For the merge round Run the combined branch's full suites once, per the verification policy: - `(cd apps/web && bun run test --maxWorkers=2)` — cross-feature unit regressions. - `(cd apps/web && bun run test:e2e && bun run test:e2e:app-passwords)` — shell and credential UI contracts, plus the merge round's full scheduled e2e set. - `CARGO_PROFILE_DEV_DEBUG=line-tables-only CARGO_INCREMENTAL=0 CARGO_BUILD_JOBS=4 bash tests/adversarial/run.sh` — real-server XUser/authz/robustness matrices, including owner isolation for Mail events. - `CARGO_PROFILE_DEV_DEBUG=line-tables-only CARGO_INCREMENTAL=0 CARGO_BUILD_JOBS=4 cargo build --release -p calternal-server` — release build, then staging checks through the orchestrator's deployment workflow. - `flock -n ~/.local/state/codex-jobs/calternal/macvm.lock netbird ssh --no-browser calternal@10.69.69.21` — begin the single-tenant real Apple Mail acceptance after the owner steps above. Hold the lock throughout subsequent GUI/forward sessions. Performance profile, when scheduled on the perf VM (no compile there): `flock /root/perf.lock bash -c 'uptime; python3 bench/mail-sync.py "$MAIL_PLUGIN_TEST_BIN" --test profile_mail_proxy --profile-prefix "MAIL_PROXY_PROFILE " --label perf-vm'`, with MAIL_PLUGIN_TEST_BIN pointing to the shared prebuilt test binary. Compare its average/worst-case measurements to the Mail baseline; this is not a merge gate. Production screenshot evidence These are real production views with macOS platform emulation. Each view has phone 390 px, tablet 820 px and desktop 1440 px in light/dark. Attachments are review evidence; the orchestrator supplies visual judgment. No screenshots are committed. | View | 390 light | 390 dark | 820 light | 820 dark | 1440 light | 1440 dark | | --- | --- | --- | --- | --- | --- | --- | | inbox | [image](https://git.kayg.org/attachments/f54e86be-06a7-48a6-a11b-1e9afd138beb) | [image](https://git.kayg.org/attachments/cfb5cd67-5191-4ecf-b992-10a4302e3458) | [image](https://git.kayg.org/attachments/23d63b46-4253-4f51-8f43-6efb78ad76f5) | [image](https://git.kayg.org/attachments/f696c34d-35dd-4fee-8685-a13328e4e704) | [image](https://git.kayg.org/attachments/355ac15d-0f19-4642-ab5d-49ee6799d22b) | [image](https://git.kayg.org/attachments/8fd64581-fd86-46fd-b5ac-fedc66578a76) | | folder | [image](https://git.kayg.org/attachments/caaf517a-22da-41e5-8ea1-a8518731160e) | [image](https://git.kayg.org/attachments/cbf169ca-2df6-4d2d-9495-253eb026ac06) | [image](https://git.kayg.org/attachments/f62fec9d-e891-4770-8af7-4dc432813d59) | [image](https://git.kayg.org/attachments/b0db8f0e-a5d8-4d14-a794-dccefaf6fa56) | [image](https://git.kayg.org/attachments/e01ca85a-0c6c-408b-9dac-733fb392082a) | [image](https://git.kayg.org/attachments/9081861e-9c43-4429-85b3-26c6657eac17) | | message | [image](https://git.kayg.org/attachments/3701d633-b788-44b2-b25d-e3b361c2a56c) | [image](https://git.kayg.org/attachments/d1f90c92-bd12-478e-a237-89b3beced5ac) | [image](https://git.kayg.org/attachments/8059a042-a11d-45c8-a398-390ff50be7b7) | [image](https://git.kayg.org/attachments/1e2cffd8-43ba-45a4-9554-dc8652539b9c) | [image](https://git.kayg.org/attachments/c483bede-073e-4662-80a8-42d8c5181781) | [image](https://git.kayg.org/attachments/012f234f-286d-4e4d-b5be-f02daf6395a9) | | thread | [image](https://git.kayg.org/attachments/d78aa7e5-8cd7-48cc-b4be-56ab0e0943d2) | [image](https://git.kayg.org/attachments/213a8185-0e41-434f-8ff6-e6ea1f4ba145) | [image](https://git.kayg.org/attachments/bd7f0b9e-a567-4284-8530-5640029b6ae9) | [image](https://git.kayg.org/attachments/57a804ad-4797-44c9-814a-3712d0945cbb) | [image](https://git.kayg.org/attachments/8150f3de-d4ff-4118-bfa4-469e64ffd7c2) | [image](https://git.kayg.org/attachments/ac2f992a-e6a5-4ef5-868c-dda4c72d4421) |
Author
Owner

Continuing real Apple Mail acceptance on job/mailproxy-486, base/head d2b0c7fad8c6ca0e27e8b1e3258b2e24b3427cd3. Repo rules and DESIGN §53 read. Mac lock acquired for the whole session. Use generated fixture data only; build this branch, renew the lab device profile and check Apple Mail. If macOS needs an owner-only profile install step, report its exact steps and stop as instructed. No pushes or deployment.

Continuing real Apple Mail acceptance on `job/mailproxy-486`, base/head `d2b0c7fad8c6ca0e27e8b1e3258b2e24b3427cd3`. Repo rules and DESIGN §53 read. Mac lock acquired for the whole session. Use generated fixture data only; build this branch, renew the lab device profile and check Apple Mail. If macOS needs an owner-only profile install step, report its exact steps and stop as instructed. No pushes or deployment.
Author
Owner

Real Mac preflight: SSH works on macOS 27.0 (26A428), and CuaDriver reads the Mail main window. Mail first-run privacy no longer blocks the window. AppleScript account enumeration still times out (-1712), so GUI acceptance uses CuaDriver. Actual remote home is /Users/calternalvm1; capture to /tmp succeeds. The production branch build completed: Finished dev profile [unoptimized + debuginfo] target(s) in 5m 01s. The local generated upstream was correctly rejected by the production endpoint guard. Rebuilding with the existing mail-test-provider lab feature; no guard changes. Mac lock remains held, and the three reverse-forward sessions are active.

Real Mac preflight: SSH works on macOS 27.0 (26A428), and CuaDriver reads the Mail main window. Mail first-run privacy no longer blocks the window. AppleScript account enumeration still times out (-1712), so GUI acceptance uses CuaDriver. Actual remote home is `/Users/calternalvm1`; capture to `/tmp` succeeds. The production branch build completed: `Finished `dev` profile [unoptimized + debuginfo] target(s) in 5m 01s`. The local generated upstream was correctly rejected by the production endpoint guard. Rebuilding with the existing `mail-test-provider` lab feature; no guard changes. Mac lock remains held, and the three reverse-forward sessions are active.
Author
Owner

APPLE MAIL ACCEPTANCE: needs-owner-step

Branch job/mailproxy-486; tested code base d2b0c7fad8c6ca0e27e8b1e3258b2e24b3427cd3; final head 393c7ca9b023038438e174852328d871f88fa6ec. Fetched and merged origin/dev once before final formatting checks, without conflicts. No push, deployment, issue closure or change to another Mac account.

What was built and checked

  • Built the branch server and production web app. Rebuilt the server with the existing mail-test-provider feature for the local fixture. The normal build correctly rejected a local provider endpoint with HTTP 400; no endpoint guard was changed.
  • Started a separate local Instance with a generated User and isolated TLS Dovecot provider. Synced 2,000 fixture messages plus eight ordinary generated messages, including HTML, an attachment, a draft and nested folders. The production web Inbox showed real API data from that fixture.
  • Started separate NetBird reverse-forward sessions for HTTPS 8443, IMAP 31993 and submission 31465 under the Mac lock. Reused the existing lab certificate for calternal.lab, valid through 2026-10-05. No owner mailbox was used.
  • Created a fresh full caldav, notes, mail App Password through the API. Downloaded the server-generated device profile through its one-use link and transferred it privately to the Mac.
  • macOS 27.0 (26A428): Mail's privacy dialog is gone and CuaDriver reads the main Inbox window. AppleScript account enumeration still times out (-1712). The fresh profile appears under Downloaded in Device Management.
  • A background and then an exact-window foreground double-click returned effect: unverifiable. A subsequent window read still showed Profile not installed. Double-click to review. No install sheet appeared. Stopped as instructed; this is not a Mail protocol failure or an acceptance pass.

Exact owner steps

  1. On the Mac VM, open /Users/calternalvm1/Downloads/applemail-486/calternal-applemail-486.mobileconfig.
  2. Open System Settings → General → Device Management. The pane is already open.
  3. Double-click calternal under Downloaded, whose subtitle is Profile not installed. Double-click to review. Do not select the older calternal entry under User.
  4. In the review sheet, click Install; click Install again if a confirmation appears. If macOS requests local authorization, complete that prompt directly on the Mac. Do not put a password in the issue or job prompt.
  5. Report whether the new profile installed. Resume the acceptance job with the same private lab state and restart the server/provider/forwards under the lock before checking the account. All services and forwards are stopped now.

The Mac profile contains credentials and is mode 0600; it is not attached or committed. Private local state is retained under target/tmp/mail-proxy-486-sSARxi/; artifacts/applemail-486/lab-state.json identifies the directories. The test certificate expires on 5 October, so a later resumption may need a renewed lab certificate.

Files and commit

tests/adversarial/mail-sync.md: extended the existing provider guide with the real Mac procedure, origin/credential invariants, separate-forward rule, owner install steps and observed blocker. Commit 393c7ca9b records this one documentation concern. No production Rust or web code changed in this run. Re-read the changed documentation before reporting.

Verification output (verbatim)

cargo build -p calternal-server:

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 5m 01s

cargo build -p calternal-server --features mail-test-provider:

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 59.01s

Local fixture setup:

PASS generated acceptance folders and messages
PASS populated provider started with 2,000 fixture messages
LAB_HTTPS_READY 8443
PASS populated Mail projection and Connected Account reconciliation
LAB_READY profile saved privately; fixture synced

bun run build: exit 0. cargo fmt --check: exit 0, no output. git diff --check: exit 0, no output. No Rust crate or web implementation was changed, so clippy, crate tests, web check and Vitest were not repeated. The prior branch's gates remain in earlier #486 reports. The built server used the pre-merge Rust code; the dev merge added only unrelated web/performance changes.

Cleanup:

     Removed 7270 files, 5.1GiB total

Generated web build and .svelte-kit/output deleted. Fixture provider, lab runner and three forwards stopped. Mac lock released. Worktree clean.

Known gaps / UX gaps left

Real Apple Mail folder discovery, bodies/attachments, Seen/flags, moves/deletes, draft save/edit, offline reconnect and simultaneous web updates are all unverified. No side-by-side accepted-client screenshot is claimed. No UX implementation gap was fixed. Sending stays deferred under DESIGN §53. No performance measurement was run; this is an acceptance job, not a performance job.

Decisions

No new product decision. Used the existing local-provider feature and fixture helpers; used CuaDriver after the AppleScript timeout; stopped when profile installation could not be verified, as the job required. Kept private fixture state for resumption. Documentation records the real remote home rather than inferring it from the SSH login name.

For the merge round / next acceptance run

After the owner install step, hold flock -n ~/.local/state/codex-jobs/calternal/macvm.lock for the whole session, restart the preserved fixture Instance and separate forwards, and complete the real Apple Mail matrix above. Full adversarial matrices and full web suites stay with the merge round. No matrix was run after this documentation-only dev merge.

Evidence

The screenshots show the populated fixture web Inbox, empty old Apple Mail account and downloaded-profile blocker. They establish setup evidence only. No credentials are visible.

APPLE MAIL ACCEPTANCE: needs-owner-step Branch `job/mailproxy-486`; tested code base `d2b0c7fad8c6ca0e27e8b1e3258b2e24b3427cd3`; final head `393c7ca9b023038438e174852328d871f88fa6ec`. Fetched and merged `origin/dev` once before final formatting checks, without conflicts. No push, deployment, issue closure or change to another Mac account. ## What was built and checked - Built the branch server and production web app. Rebuilt the server with the existing `mail-test-provider` feature for the local fixture. The normal build correctly rejected a local provider endpoint with HTTP 400; no endpoint guard was changed. - Started a separate local Instance with a generated User and isolated TLS Dovecot provider. Synced 2,000 fixture messages plus eight ordinary generated messages, including HTML, an attachment, a draft and nested folders. The production web Inbox showed real API data from that fixture. - Started separate NetBird reverse-forward sessions for HTTPS 8443, IMAP 31993 and submission 31465 under the Mac lock. Reused the existing lab certificate for `calternal.lab`, valid through 2026-10-05. No owner mailbox was used. - Created a fresh full `caldav`, `notes`, `mail` App Password through the API. Downloaded the server-generated device profile through its one-use link and transferred it privately to the Mac. - macOS 27.0 (26A428): Mail's privacy dialog is gone and CuaDriver reads the main Inbox window. AppleScript account enumeration still times out (-1712). The fresh profile appears under Downloaded in Device Management. - A background and then an exact-window foreground double-click returned `effect: unverifiable`. A subsequent window read still showed `Profile not installed. Double-click to review.` No install sheet appeared. Stopped as instructed; this is not a Mail protocol failure or an acceptance pass. ## Exact owner steps 1. On the Mac VM, open `/Users/calternalvm1/Downloads/applemail-486/calternal-applemail-486.mobileconfig`. 2. Open **System Settings → General → Device Management**. The pane is already open. 3. Double-click **calternal under Downloaded**, whose subtitle is **Profile not installed. Double-click to review.** Do not select the older calternal entry under User. 4. In the review sheet, click **Install**; click **Install** again if a confirmation appears. If macOS requests local authorization, complete that prompt directly on the Mac. Do not put a password in the issue or job prompt. 5. Report whether the new profile installed. Resume the acceptance job with the same private lab state and restart the server/provider/forwards under the lock before checking the account. All services and forwards are stopped now. The Mac profile contains credentials and is mode 0600; it is not attached or committed. Private local state is retained under `target/tmp/mail-proxy-486-sSARxi/`; `artifacts/applemail-486/lab-state.json` identifies the directories. The test certificate expires on 5 October, so a later resumption may need a renewed lab certificate. ## Files and commit `tests/adversarial/mail-sync.md`: extended the existing provider guide with the real Mac procedure, origin/credential invariants, separate-forward rule, owner install steps and observed blocker. Commit `393c7ca9b` records this one documentation concern. No production Rust or web code changed in this run. Re-read the changed documentation before reporting. ## Verification output (verbatim) `cargo build -p calternal-server`: ```text Finished `dev` profile [unoptimized + debuginfo] target(s) in 5m 01s ``` `cargo build -p calternal-server --features mail-test-provider`: ```text Finished `dev` profile [unoptimized + debuginfo] target(s) in 59.01s ``` Local fixture setup: ```text PASS generated acceptance folders and messages PASS populated provider started with 2,000 fixture messages LAB_HTTPS_READY 8443 PASS populated Mail projection and Connected Account reconciliation LAB_READY profile saved privately; fixture synced ``` `bun run build`: exit 0. `cargo fmt --check`: exit 0, no output. `git diff --check`: exit 0, no output. No Rust crate or web implementation was changed, so clippy, crate tests, web check and Vitest were not repeated. The prior branch's gates remain in earlier #486 reports. The built server used the pre-merge Rust code; the dev merge added only unrelated web/performance changes. Cleanup: ```text Removed 7270 files, 5.1GiB total ``` Generated web build and `.svelte-kit/output` deleted. Fixture provider, lab runner and three forwards stopped. Mac lock released. Worktree clean. ## Known gaps / UX gaps left Real Apple Mail folder discovery, bodies/attachments, Seen/flags, moves/deletes, draft save/edit, offline reconnect and simultaneous web updates are all unverified. No side-by-side accepted-client screenshot is claimed. No UX implementation gap was fixed. Sending stays deferred under DESIGN §53. No performance measurement was run; this is an acceptance job, not a performance job. ## Decisions No new product decision. Used the existing local-provider feature and fixture helpers; used CuaDriver after the AppleScript timeout; stopped when profile installation could not be verified, as the job required. Kept private fixture state for resumption. Documentation records the real remote home rather than inferring it from the SSH login name. ## For the merge round / next acceptance run After the owner install step, hold `flock -n ~/.local/state/codex-jobs/calternal/macvm.lock` for the whole session, restart the preserved fixture Instance and separate forwards, and complete the real Apple Mail matrix above. Full adversarial matrices and full web suites stay with the merge round. No matrix was run after this documentation-only dev merge. ## Evidence - [fixture-inbox.png](https://git.kayg.org/attachments/872c8e22-eae1-484e-9fc8-5f9f2ab5e331) - [mail-preflight.png](https://git.kayg.org/attachments/05675d3e-1ef9-4b11-bec1-ee4857e4109a) - [settings-profile.png](https://git.kayg.org/attachments/0a375a1c-2761-4c4c-8126-17c09fe1328c) The screenshots show the populated fixture web Inbox, empty old Apple Mail account and downloaded-profile blocker. They establish setup evidence only. No credentials are visible.
Author
Owner

Started Apple Mail acceptance round 2 on job/mailproxy-486 at base/head 393c7ca9b0. Repository contract, glossary, DESIGN §53 and retained procedure read. Owner authorized VNC profile installation and account prompts. Resume retained private fixture; hold Mac lock for the full session. No sending, push, deploy or other-account changes.

Started Apple Mail acceptance round 2 on job/mailproxy-486 at base/head 393c7ca9b023038438e174852328d871f88fa6ec. Repository contract, glossary, DESIGN §53 and retained procedure read. Owner authorized VNC profile installation and account prompts. Resume retained private fixture; hold Mac lock for the full session. No sending, push, deploy or other-account changes.
Author
Owner

Round 2 setup finding: VNC profile installation succeeded. A persistent VNC connection and original Retina capture coordinates selected the Downloaded row and opened both install sheets. macOS profiles list -type configuration shows the new profile, and Apple Mail shows a new calternal account. Mail now asks whether to continue with the isolated calternal.lab test certificate; accepting only that lab-account prompt as authorized. Commit b1a53654f adds the private VNC driver and procedure. Full Mail acceptance remains in progress.

Round 2 setup finding: VNC profile installation succeeded. A persistent VNC connection and original Retina capture coordinates selected the Downloaded row and opened both install sheets. macOS `profiles list -type configuration` shows the new profile, and Apple Mail shows a new calternal account. Mail now asks whether to continue with the isolated calternal.lab test certificate; accepting only that lab-account prompt as authorized. Commit b1a53654f adds the private VNC driver and procedure. Full Mail acceptance remains in progress.
Author
Owner

Post-crash checks: Mail reopened. The account folder names include the provider's nested Autumn folder, so #1030's claimed missing-tree blocker is withdrawn (correction posted). The Inbox copy of the real HTML/attachment fixture returns “Autumn workshop / Bring your sketchbook” and Mail identifies “Workshop agenda.txt”. A native double-click on the saved Apple acceptance draft opens an editable compose window. Saved edit replaced the old upstream draft (one matching draft, UID advanced from 2 to 4); its text is in the HTML MIME part, with an empty plain-text alternative. Initial test extraction checked only the plain part and was corrected to inspect all text parts. The VNC helper dropped a leading uppercase R; enabling explicit Shift key events fixes the helper. No product data-loss finding is claimed for that test-driver error. The client crash #1031 and incomplete source removal/delete receipts remain acceptance failures.

Post-crash checks: Mail reopened. The account folder names include the provider's nested Autumn folder, so #1030's claimed missing-tree blocker is withdrawn (correction posted). The Inbox copy of the real HTML/attachment fixture returns “Autumn workshop / Bring your sketchbook” and Mail identifies “Workshop agenda.txt”. A native double-click on the saved Apple acceptance draft opens an editable compose window. Saved edit replaced the old upstream draft (one matching draft, UID advanced from 2 to 4); its text is in the HTML MIME part, with an empty plain-text alternative. Initial test extraction checked only the plain part and was corrected to inspect all text parts. The VNC helper dropped a leading uppercase R; enabling explicit Shift key events fixes the helper. No product data-loss finding is claimed for that test-driver error. The client crash #1031 and incomplete source removal/delete receipts remain acceptance failures.
Author
Owner

Offline/reconnect evidence: stopped only the IMAP reverse-forward session, changed Autumn workshop notes to flagged and unread in real Apple Mail, confirmed that upstream UID 12661 still had no flags while disconnected, restored the separate IMAP forward and synchronized only the lab account. Upstream UID 12661 now has \Flagged and no \Seen. The edited draft has one matching upstream copy, UID 4, with the revised text in its HTML MIME part. The HTML fixture opened in Mail and its attachment download contains exactly “Agenda / Welcome / Sketching”. These checks pass. The crash and incomplete move/delete source receipts still fail the complete acceptance.

Offline/reconnect evidence: stopped only the IMAP reverse-forward session, changed Autumn workshop notes to flagged and unread in real Apple Mail, confirmed that upstream UID 12661 still had no flags while disconnected, restored the separate IMAP forward and synchronized only the lab account. Upstream UID 12661 now has \Flagged and no \Seen. The edited draft has one matching upstream copy, UID 4, with the revised text in its HTML MIME part. The HTML fixture opened in Mail and its attachment download contains exactly “Agenda / Welcome / Sketching”. These checks pass. The crash and incomplete move/delete source receipts still fail the complete acceptance.
Author
Owner

APPLE MAIL ACCEPTANCE: fail

Branch: job/mailproxy-486. Started at 393c7ca9b023038438e174852328d871f88fa6ec. Tested server code is that starting head. Final head: 7edc39592e02afba73eb517d5b5857e22870ea4f. Fetched origin and merged origin/dev once before final checks: Already up to date. No push, deployment or issue closure.

Built / files

  • tests/adversarial/apple_mail_vnc.py: persistent VNC acceptance driver. Credentials stay in the environment; JSON actions use original capture pixels. Supports observed clicks, double-clicks, keys, fixture text, private prompt fields and captures. Uses explicit Shift events for capitals.
  • tests/adversarial/mail-sync.md: VNC procedure and real round-two observations. Re-read all changed module and function comments before reporting.
  • Atomic commits: b1a53654f, 55522445c, e3d4349de, fb4316dda, 7edc39592. No production Rust or web implementation changed. Screenshots and review artifacts were not committed.

Acceptance evidence

The new generated profile installed through both VNC install sheets. Local certificate authorization completed. All Mac sessions and the VNC tunnel ran under the Mac lock. HTTPS 8443, IMAP 31993 and submission 31465 had separate reverse forwards. The fixture used 2,000 messages plus eight generated ordinary messages. No owner mailbox was used.

Check Result
Unified folders and Connected Account tree Pass after synchronization; nested Autumn message opened. Initial missing-tree claim in #1030 was corrected.
Text body Pass: Apple Mail returned the expected Weekend walking plan text.
HTML and attachment Pass: Mail rendered Autumn workshop and downloaded the exact Agenda/Welcome/Sketching bytes.
Seen / flag writes Pass for eventual upstream receipt and open-web invalidation. First writes were delayed during the large initial client download; no 5-second budget pass is claimed.
Move Fail: an Archive copy arrived, but the upstream Inbox source remained.
Delete Fail: no matching Trash receipt; source remained.
Draft save Pass: one generated Apple acceptance draft reached upstream.
Draft edit Pass: native double-click opened compose; saved edit replaced the old draft, leaving one matching upstream draft. Revised text is in its HTML part; plain alternative is empty.
Offline / reconnect Pass: dropped only IMAP forward, changed the HTML message to flagged and unread locally, checked unchanged upstream state, restored forward; upstream then showed Flagged without Seen.
Simultaneous open-web updates Pass for Seen changes and web-origin read-state edit. Sources stayed visible after the incomplete move/delete, as reported.
Client stability Fail: Mail crashed; macOS recorded EXC_CRASH / SIGABRT in its mailbox-persistence task. Server stayed ready.
Sending Not tested; deferred by DESIGN §53.

Crash: #1031. Stack includes MFLibrary mailboxIDForMailboxURLString and imap_mailboxHasInconsistencies:. Source-removal/delete follow-up: #1032. Crash may have interrupted the client's remaining mutation commands. A separate server root cause is not established.

#1030 remains open per the job rule, but its alleged Apple Mail tree blocker is withdrawn: the later VNC tree and nested-folder read disproved it. Root LIST still omits a non-selectable account parent; the orchestrator can decide whether that protocol follow-up is useful.

Verification output (verbatim)

Branch server build with existing mail-test-provider feature:

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 2m 17s

bun run build: exit 0. Final source checks:

cargo fmt --check exit: 0
python3 -m py_compile exit: 0
git diff --check exit: 0

Web evidence runner:

Page URL: https://calternal.lab:8443/mail
Web account API: 200
PASS real web Inbox screenshots: phone/tablet/desktop, light/dark, macOS

Real final VNC helper capture:

VNC action complete

No Rust crate or web implementation changed, so crate clippy/test, web check and focused Vitest were not repeated. No performance measurement: this is an acceptance job, under the latest verification policy.

Cleanup

Removed only the new round-two profile. macOS profile enumeration then showed the two pre-existing profiles and omitted the round-two identifier. Deleted the new transferred profile and generated attachment download. Browser session sign-out returned 204, revoking the generated cookie that a Playwright diagnostic accidentally printed earlier; the private log was redacted and raw error logging removed. App Password deletion returned 403 because it required renewed authorization; it was not bypassed. Its isolated Instance is stopped and its profile is removed.

Stopped browser, server, provider, VNC connection, all forwards and the suspended auxiliary SSH check. Confirmed no listeners on 5900/8443/31993/31465, no mail-proxy fixture containers and that the Mac lock was released. Kept private fixture state for investigating #1031/#1032. Generated web output was deleted. Cargo cleanup:

     Removed 7238 files, 4.6GiB total

Worktree is clean.

Known gaps / UX gaps left

The full Apple Mail acceptance is not complete. Client crash, correct move source removal, and deletion receipt need correction and a clean native retest. Timing budgets remain unproven on this initial-download run. Root cause of the client crash is unknown. No product UX gap was fixed in this acceptance-only job; the test-driver setup, credential transport and capital-letter gaps were closed.

Decisions

No new product decision. The old fixture did not retain a usable web browser sign-in, so used a fresh isolated Instance with the same fixture procedure and saved its browser session privately. Copied the generated HTML fixture to Inbox while folder discovery was pending; later also opened the original nested-folder message. Used targeted AppleScript operations for the new account and VNC for real screen evidence, profile installation, account prompts and native draft editing. Kept one VNC connection open and inspected captures after actions. Never sent mail or changed another account.

For the merge round

Run CALTERNAL_MAIL_PROXY_POPULATED=1 node apps/web/e2e/mail-proxy-486.mjs after building the server with mail-test-provider and the web production app. It must prove real-listener MIME, mutation, scope and revocation behavior. Full web suite: (cd apps/web && bun run test -- --maxWorkers=2). Repeat the real Apple Mail sequence in tests/adversarial/mail-sync.md under the Mac lock after fixing #1031/#1032; prove no crash, exact source removal, correct-account Trash, stable draft edit and bidirectional updates. Scripted conformance alone cannot pass #486.

Evidence

APPLE MAIL ACCEPTANCE: fail Branch: `job/mailproxy-486`. Started at `393c7ca9b023038438e174852328d871f88fa6ec`. Tested server code is that starting head. Final head: `7edc39592e02afba73eb517d5b5857e22870ea4f`. Fetched origin and merged `origin/dev` once before final checks: `Already up to date.` No push, deployment or issue closure. ## Built / files - `tests/adversarial/apple_mail_vnc.py`: persistent VNC acceptance driver. Credentials stay in the environment; JSON actions use original capture pixels. Supports observed clicks, double-clicks, keys, fixture text, private prompt fields and captures. Uses explicit Shift events for capitals. - `tests/adversarial/mail-sync.md`: VNC procedure and real round-two observations. Re-read all changed module and function comments before reporting. - Atomic commits: b1a53654f, 55522445c, e3d4349de, fb4316dda, 7edc39592. No production Rust or web implementation changed. Screenshots and review artifacts were not committed. ## Acceptance evidence The new generated profile installed through both VNC install sheets. Local certificate authorization completed. All Mac sessions and the VNC tunnel ran under the Mac lock. HTTPS 8443, IMAP 31993 and submission 31465 had separate reverse forwards. The fixture used 2,000 messages plus eight generated ordinary messages. No owner mailbox was used. | Check | Result | |---|---| | Unified folders and Connected Account tree | Pass after synchronization; nested Autumn message opened. Initial missing-tree claim in #1030 was corrected. | | Text body | Pass: Apple Mail returned the expected Weekend walking plan text. | | HTML and attachment | Pass: Mail rendered Autumn workshop and downloaded the exact Agenda/Welcome/Sketching bytes. | | Seen / flag writes | Pass for eventual upstream receipt and open-web invalidation. First writes were delayed during the large initial client download; no 5-second budget pass is claimed. | | Move | Fail: an Archive copy arrived, but the upstream Inbox source remained. | | Delete | Fail: no matching Trash receipt; source remained. | | Draft save | Pass: one generated Apple acceptance draft reached upstream. | | Draft edit | Pass: native double-click opened compose; saved edit replaced the old draft, leaving one matching upstream draft. Revised text is in its HTML part; plain alternative is empty. | | Offline / reconnect | Pass: dropped only IMAP forward, changed the HTML message to flagged and unread locally, checked unchanged upstream state, restored forward; upstream then showed Flagged without Seen. | | Simultaneous open-web updates | Pass for Seen changes and web-origin read-state edit. Sources stayed visible after the incomplete move/delete, as reported. | | Client stability | Fail: Mail crashed; macOS recorded EXC_CRASH / SIGABRT in its mailbox-persistence task. Server stayed ready. | | Sending | Not tested; deferred by DESIGN §53. | Crash: [#1031](https://git.kayg.org/kayg/calternal/issues/1031). Stack includes `MFLibrary mailboxIDForMailboxURLString` and `imap_mailboxHasInconsistencies:`. Source-removal/delete follow-up: [#1032](https://git.kayg.org/kayg/calternal/issues/1032). Crash may have interrupted the client's remaining mutation commands. A separate server root cause is not established. [#1030](https://git.kayg.org/kayg/calternal/issues/1030) remains open per the job rule, but its alleged Apple Mail tree blocker is withdrawn: the later VNC tree and nested-folder read disproved it. Root LIST still omits a non-selectable account parent; the orchestrator can decide whether that protocol follow-up is useful. ## Verification output (verbatim) Branch server build with existing mail-test-provider feature: ```text Finished `dev` profile [unoptimized + debuginfo] target(s) in 2m 17s ``` `bun run build`: exit 0. Final source checks: ```text cargo fmt --check exit: 0 python3 -m py_compile exit: 0 git diff --check exit: 0 ``` Web evidence runner: ```text Page URL: https://calternal.lab:8443/mail Web account API: 200 PASS real web Inbox screenshots: phone/tablet/desktop, light/dark, macOS ``` Real final VNC helper capture: ```text VNC action complete ``` No Rust crate or web implementation changed, so crate clippy/test, web check and focused Vitest were not repeated. No performance measurement: this is an acceptance job, under the latest verification policy. ## Cleanup Removed only the new round-two profile. macOS profile enumeration then showed the two pre-existing profiles and omitted the round-two identifier. Deleted the new transferred profile and generated attachment download. Browser session sign-out returned 204, revoking the generated cookie that a Playwright diagnostic accidentally printed earlier; the private log was redacted and raw error logging removed. App Password deletion returned 403 because it required renewed authorization; it was not bypassed. Its isolated Instance is stopped and its profile is removed. Stopped browser, server, provider, VNC connection, all forwards and the suspended auxiliary SSH check. Confirmed no listeners on 5900/8443/31993/31465, no mail-proxy fixture containers and that the Mac lock was released. Kept private fixture state for investigating #1031/#1032. Generated web output was deleted. Cargo cleanup: ```text Removed 7238 files, 4.6GiB total ``` Worktree is clean. ## Known gaps / UX gaps left The full Apple Mail acceptance is not complete. Client crash, correct move source removal, and deletion receipt need correction and a clean native retest. Timing budgets remain unproven on this initial-download run. Root cause of the client crash is unknown. No product UX gap was fixed in this acceptance-only job; the test-driver setup, credential transport and capital-letter gaps were closed. ## Decisions No new product decision. The old fixture did not retain a usable web browser sign-in, so used a fresh isolated Instance with the same fixture procedure and saved its browser session privately. Copied the generated HTML fixture to Inbox while folder discovery was pending; later also opened the original nested-folder message. Used targeted AppleScript operations for the new account and VNC for real screen evidence, profile installation, account prompts and native draft editing. Kept one VNC connection open and inspected captures after actions. Never sent mail or changed another account. ## For the merge round Run `CALTERNAL_MAIL_PROXY_POPULATED=1 node apps/web/e2e/mail-proxy-486.mjs` after building the server with `mail-test-provider` and the web production app. It must prove real-listener MIME, mutation, scope and revocation behavior. Full web suite: `(cd apps/web && bun run test -- --maxWorkers=2)`. Repeat the real Apple Mail sequence in `tests/adversarial/mail-sync.md` under the Mac lock after fixing #1031/#1032; prove no crash, exact source removal, correct-account Trash, stable draft edit and bidirectional updates. Scripted conformance alone cannot pass #486. ## Evidence - [apple-mail-and-web.png](https://git.kayg.org/attachments/104770d7-0849-4846-bf39-f914cf81ef6d) - [mail-after-crash.png](https://git.kayg.org/attachments/c06f1b44-4d8f-41b7-a9dd-c5c0abc2e233) - [mail-final-native.png](https://git.kayg.org/attachments/8d527e54-724a-4bb2-83a7-02317d1e46b4) - [mail-html-attachment.png](https://git.kayg.org/attachments/7b450c51-ac02-4f01-a78b-4a04df83dbfd) - [mail-native-draft-edit.png](https://git.kayg.org/attachments/eca7dce5-e7a9-4989-a385-407d85ead1f6) - [mail-offline.png](https://git.kayg.org/attachments/3f257782-ceb1-4a88-b878-310f9f9d4231) - [mail-reconnected.png](https://git.kayg.org/attachments/8e5b9abd-2fb9-48ee-b1ec-9667dc8085fb) - [web-1440-dark.png](https://git.kayg.org/attachments/49a91f90-196a-414d-8de0-039ecb24f1fe) - [web-1440-light.png](https://git.kayg.org/attachments/555949c4-838d-4c5a-8870-2fe62eadfb69) - [web-390-dark.png](https://git.kayg.org/attachments/ae3de7de-454c-42ae-ae67-7092970343cc) - [web-390-light.png](https://git.kayg.org/attachments/ae93fbe8-c428-4a89-b7b2-cc382355c4eb) - [web-820-dark.png](https://git.kayg.org/attachments/9cc684e1-6f10-47e6-8700-bf63b05aae50) - [web-820-light.png](https://git.kayg.org/attachments/22c881eb-beaa-4ecc-8537-5bc99e986e88) - [web-after-apple-move.png](https://git.kayg.org/attachments/48dcd8da-b163-49fa-8f06-cf9edce5b29e) - [web-after-client-crash.png](https://git.kayg.org/attachments/95a37f2b-0490-4476-a50e-89093518ebef) - [web-apple-seen-flag.png](https://git.kayg.org/attachments/d2f4d985-5dcd-4b37-8968-9ed6cc4488ec) - [web-bidirectional-flags.png](https://git.kayg.org/attachments/a5a8c3db-1146-49b1-b624-cf2519fc2e29) - [web-final-state.png](https://git.kayg.org/attachments/58b422d4-ee5b-4fbf-bb4b-dd37de172aa1)
Author
Owner

Verification boundary for the final report: open-web invalidation after Apple Seen changes passed, and a web read-state edit reached upstream. The Apple UI read state after that web edit and an exact concurrent conflict were not independently checked before profile cleanup. Treat that row as partial, not a complete bidirectional concurrency pass. The retained local final report is corrected. Overall APPLE MAIL ACCEPTANCE remains fail (#1031 crash, #1032 incomplete move/delete receipts).

Verification boundary for the final report: open-web invalidation after Apple Seen changes passed, and a web read-state edit reached upstream. The Apple UI read state after that web edit and an exact concurrent conflict were not independently checked before profile cleanup. Treat that row as partial, not a complete bidirectional concurrency pass. The retained local final report is corrected. Overall APPLE MAIL ACCEPTANCE remains fail (#1031 crash, #1032 incomplete move/delete receipts).
Author
Owner

Started #486 mutation fix on job/mailproxy-486, base 7edc39592e02afba73eb517d5b5857e22870ea4f. Read CLAUDE, CONTEXT, DESIGN §45/§53, #1031/#1032 and the round-two report. Source review confirms unconditional rejection of STORE on a pending COPY source. Investigate receipt-safe deferred source delivery and special-use discovery. Shared verification policy reserves real Mac interop and full matrices for the merge round; this job will run focused regressions and per-crate gates, and will not claim native acceptance without a real run. No pushes or deploys.

Started #486 mutation fix on `job/mailproxy-486`, base `7edc39592e02afba73eb517d5b5857e22870ea4f`. Read CLAUDE, CONTEXT, DESIGN §45/§53, #1031/#1032 and the round-two report. Source review confirms unconditional rejection of STORE on a pending COPY source. Investigate receipt-safe deferred source delivery and special-use discovery. Shared verification policy reserves real Mac interop and full matrices for the merge round; this job will run focused regressions and per-crate gates, and will not claim native acceptance without a real run. No pushes or deploys.
Author
Owner

Receipt-safe source fix committed as 974b6bda4. Focused TCP regressions accept COPY → STORE Deleted → plain/UID EXPUNGE while the journal is pending. The mutation worker returns a fixed deferred error before provider I/O; the destination keeps the flags captured at COPY acceptance. A same-destination MOVE upgrades the pending COPY and reuses its receipt/UID. Other conflicting transfers stay rejected.

Focused real Dovecot regression now passes (fresh isolated 2,000-message fixture): both workers deliver COPY/delete and COPY/MOVE; repeated delivery leaves exactly two destinations for two sources; source UIDs are removed; virtual UIDs stay stable; destination flags contain Seen and no later source Deleted. This is protocol evidence, not a native crash fix claim.

Additional finding: shared LIST emitted () for every Mail folder, including Trash/Drafts/Archive. Added static unified special-use attributes; unified destinations already resolve by the source Connected Account. Two-account Trash regression passes, including overlapping remote UIDs. RFC 6154 permits these hints in ordinary LIST without advertising extended SPECIAL-USE. Listener capability text lacked MOVE while the authenticated session advertised it; the text now agrees. Bounded mutation transcript capture is opt-in and compiled only for the local-provider fixture feature.

Fetched origin and merged origin/dev once before final gates: Already up to date. No migration or dependency added. Native Mac interop remains reserved for the merge round by the shared verification policy. APPLE MAIL ACCEPTANCE remains fail until the native capture and full clean retest.

Receipt-safe source fix committed as `974b6bda4`. Focused TCP regressions accept COPY → STORE Deleted → plain/UID EXPUNGE while the journal is pending. The mutation worker returns a fixed deferred error before provider I/O; the destination keeps the flags captured at COPY acceptance. A same-destination MOVE upgrades the pending COPY and reuses its receipt/UID. Other conflicting transfers stay rejected. Focused real Dovecot regression now passes (fresh isolated 2,000-message fixture): both workers deliver COPY/delete and COPY/MOVE; repeated delivery leaves exactly two destinations for two sources; source UIDs are removed; virtual UIDs stay stable; destination flags contain Seen and no later source Deleted. This is protocol evidence, not a native crash fix claim. Additional finding: shared LIST emitted `()` for every Mail folder, including Trash/Drafts/Archive. Added static unified special-use attributes; unified destinations already resolve by the source Connected Account. Two-account Trash regression passes, including overlapping remote UIDs. RFC 6154 permits these hints in ordinary LIST without advertising extended SPECIAL-USE. Listener capability text lacked MOVE while the authenticated session advertised it; the text now agrees. Bounded mutation transcript capture is opt-in and compiled only for the local-provider fixture feature. Fetched origin and merged origin/dev once before final gates: `Already up to date.` No migration or dependency added. Native Mac interop remains reserved for the merge round by the shared verification policy. APPLE MAIL ACCEPTANCE remains fail until the native capture and full clean retest.
Author
Owner

APPLE MAIL ACCEPTANCE: fail

The server repair and focused protocol checks pass. The native Apple Mail command sequence has not been captured in this repair run, and the client crash has not been shown resolved. The shared verification policy explicitly reserves Mac interop for the merge round even when a brief requests it. Do not treat this report as native acceptance.

Branch: job/mailproxy-486. Base: 7edc39592e02afba73eb517d5b5857e22870ea4f. Head: 197e3829546e44dbd83ce813472989fc40cb37d8. Fetched origin and merged origin/dev once before final gates, at f2f8491ff5c76ab28f140c964542c97362e6b119:

Already up to date.

No push, deployment or issue closure. No dependencies or migrations added.

Built:

  • Pending COPY sources accept STORE and plain/UID EXPUNGE. Source mutation delivery waits while a transfer owns the source. COPY restores its captured flags before setting its receipt keyword, so later source Deleted intent does not enter the destination. The transfer installs the destination and queues source delivery in one transaction. Its confirmed upstream UID remains durable before any source deletion.
  • MOVE to a pending COPY's same pinned destination reuses the existing virtual UID and receipt. A COPY-to-MOVE upgrade during provider I/O cannot retire a COPY-only receipt: the worker retains its confirmed UID for retry. Other overlapping transfers remain conflicts.
  • Ordinary LIST identifies unified Trash, Archive, Drafts, Sent and Junk. Each unified target resolves against the source Connected Account. Real folders retain neutral attributes to avoid competing special-use choices. The listener greeting and pre-authentication CAPABILITY now include the implemented MOVE, consistent with the authenticated session. UIDPLUS remains advertised. Extended SPECIAL-USE is not advertised because its LIST options are not implemented. RFC 6154 permits special-use attributes in ordinary LIST without that capability.
  • An opt-in transcript hook in the local-provider feature captures at most 256 mutation completions per connection: connection number, bounded tag, verb, status and allowlisted response-code name. It excludes LOGIN, command arguments, mailbox names, flags, UID maps, response text and MIME. The normal server build has no logging hook. A regression checks LOGIN omission and MIME-shaped fake response lines.
  • TCP regressions cover COPY → STORE Deleted → EXPUNGE and UID EXPUNGE while the journal is pending. Two Connected Accounts with overlapping remote UIDs route unified Trash independently. Existing expectations were not relaxed.
  • A focused real Dovecot test executes both workers with two generated messages. COPY/delete and COPY/MOVE preserve virtual UIDs; source UIDs disappear; repeated delivery creates exactly two destinations for two sources; destination flags contain Seen without the later source Deleted flag. This test was run, not merely added.
  • The existing benchmark profile now includes COPY/STORE Deleted/EXPUNGE p50/p95, alongside the queue-ceiling and burst workloads. Measurement was not run: this issue is not a performance issue, under the latest verification policy. No new baseline comparison or timing-budget pass is claimed.

Files:

bench/mail-sync.py
crates/calternal-imap/src/session.rs
crates/calternal-imap/src/store.rs
crates/calternal-server/src/device_imap.rs
crates/calternal-server/src/notes_imap.rs
crates/plugins/mail/src/proxy.rs
crates/plugins/mail/src/proxy_mutations.rs
crates/plugins/mail/src/proxy_tests.rs
crates/plugins/mail/src/proxy_transfers.rs
docs/DESIGN.md
tests/adversarial/mail-sync.md

Re-read the changed module and function comments before reporting. Five atomic commits: 974b6bda4, e8ddf2867, da1ce8b0b, c5040669d, 197e38295.

Gate output, verbatim:

cargo fmt --check: exit 0, no output.

cargo clippy -p calternal-imap --all-targets -- -D warnings: exit 0.

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 11.50s

cargo test -p calternal-imap: exit 0.

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
test result: ok. 12 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.02s
test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
test result: ok. 11 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
test result: ok. 30 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.18s
test result: ok. 8 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s
test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

cargo clippy -p calternal-plugin-mail --all-targets --features test-provider -- -D warnings: exit 0.

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 10.59s

cargo test -p calternal-plugin-mail --features test-provider: exit 0.

test result: ok. 82 passed; 0 failed; 7 ignored; 0 measured; 0 filtered out; finished in 5.61s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

Focused fixture regression, cargo test -p calternal-plugin-mail --features test-provider real_tls_copy_delete -- --ignored --nocapture: exit 0.

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 88 filtered out; finished in 5.15s

cargo clippy -p calternal-server --all-targets --features mail-test-provider -- -D warnings: exit 0.

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 50.42s

cargo test -p calternal-server --features mail-test-provider -- --test-threads=4: exit 0.

test result: ok. 168 passed; 0 failed; 5 ignored; 0 measured; 0 filtered out; finished in 19.58s

Web production build: (cd apps/web && bun run build) exited 0; it supplies the embedded frontend required by server compilation. No web source changed. Web check/Vitest/screenshots were not repeated. Python benchmark syntax compilation and git diff --check exited 0.

UX gaps closed:

  • COPY-based move/delete commands no longer receive a pending-COPY STORE rejection.
  • Special-use folder discovery identifies the unified destinations that route to each source account.
  • Native receipt capture now has a bounded, argument-free procedure.

Known gaps / UX gaps left:

  • No native transcript yet. Protocol regressions replay the #1032 interoperability lead, not an observed Apple Mail sequence.
  • #1031's Mail persistence crash is still unverified after this repair. #1032's native archive source removal and correct-account Trash receipt require a clean native retest.
  • Native flags, draft save/edit, offline reconnect and simultaneous open-web updates need that same retest. Prior round-two evidence is not a pass for this build.
  • Other overlapping pending transfers still conflict; only a same-destination COPY can be upgraded to MOVE. Pending MOVE sources remain absent from the live projection. Existing stale-source conflict assertions remain intact.
  • No performance or five-second budget claim. No full adversarial matrix, full web suite, release build or staging check in this job. Sending stays deferred by DESIGN §53.

Decisions:

  • Preserve the COPY acceptance flag snapshot and defer later absolute source state until the receipt retires. This avoids both source loss and receipt-keyword removal by STORE.
  • Upgrade same-destination COPY to MOVE using its existing receipt; preserve the single-transfer conflict contract for other destinations.
  • Advertise special-use roles only on the unified destinations so a client has one target per role. The source account determines the real upstream destination.
  • Restrict transcript capture to the fixture feature, opt-in environment flag, 64-byte tags and 256 completions per connection. Document these implementation choices; no new product decision.

For the merge round:

  1. Build with (cd apps/web && bun run build) and cargo build -p calternal-server --features mail-test-provider, using the documented bounded Cargo environment.
  2. Run CALTERNAL_MAIL_PROXY_POPULATED=1 node apps/web/e2e/mail-proxy-486.mjs. It must prove populated real-listener MIME, mutation, draft, scope and revocation behavior. Full web suite: (cd apps/web && bun run test -- --maxWorkers=2).
  3. Follow tests/adversarial/mail-sync.md under flock -w 7200 ~/.local/state/codex-jobs/calternal/macvm.lock for the whole native session. Start the isolated server with CALTERNAL_MAIL_TEST_TRANSCRIPT=1 RUST_LOG=calternal_mail_fixture_transcript=info. Use the existing VNC driver and environment-only private credentials. Capture native archive/delete events, add a replay if the sequence differs, then prove no new Mail crash, exact source removal, one correct-account Trash copy, stable drafts, flags, offline reconnect and live web updates. This is required before APPLE MAIL ACCEPTANCE can pass.
  4. Full adversarial matrices, release/staging checks and periodic performance measurements remain merge-round work. The extended performance command is python3 bench/mail-sync.py <Mail-test-binary> --test profile_mail_proxy --profile-prefix 'MAIL_PROXY_PROFILE ', inside the perf-VM lock with load average recorded if a performance review runs it.

Cleanup:
Stopped and removed only this run's Dovecot container. Deleted its generated fixture and TLS keys. Deleted generated web build and .svelte-kit/output. No Mac account or profile was touched in this run. Cargo cleanup:

     Removed 16916 files, 7.6GiB total

Worktree clean. Logs remain ignored under artifacts/mailproxy-fix/; no screenshot or other artifact committed.

APPLE MAIL ACCEPTANCE: fail The server repair and focused protocol checks pass. The native Apple Mail command sequence has not been captured in this repair run, and the client crash has not been shown resolved. The shared verification policy explicitly reserves Mac interop for the merge round even when a brief requests it. Do not treat this report as native acceptance. Branch: `job/mailproxy-486`. Base: `7edc39592e02afba73eb517d5b5857e22870ea4f`. Head: `197e3829546e44dbd83ce813472989fc40cb37d8`. Fetched origin and merged `origin/dev` once before final gates, at `f2f8491ff5c76ab28f140c964542c97362e6b119`: ```text Already up to date. ``` No push, deployment or issue closure. No dependencies or migrations added. Built: - Pending COPY sources accept STORE and plain/UID EXPUNGE. Source mutation delivery waits while a transfer owns the source. COPY restores its captured flags before setting its receipt keyword, so later source Deleted intent does not enter the destination. The transfer installs the destination and queues source delivery in one transaction. Its confirmed upstream UID remains durable before any source deletion. - MOVE to a pending COPY's same pinned destination reuses the existing virtual UID and receipt. A COPY-to-MOVE upgrade during provider I/O cannot retire a COPY-only receipt: the worker retains its confirmed UID for retry. Other overlapping transfers remain conflicts. - Ordinary LIST identifies unified Trash, Archive, Drafts, Sent and Junk. Each unified target resolves against the source Connected Account. Real folders retain neutral attributes to avoid competing special-use choices. The listener greeting and pre-authentication CAPABILITY now include the implemented MOVE, consistent with the authenticated session. UIDPLUS remains advertised. Extended SPECIAL-USE is not advertised because its LIST options are not implemented. [RFC 6154](https://www.rfc-editor.org/rfc/rfc6154.html) permits special-use attributes in ordinary LIST without that capability. - An opt-in transcript hook in the local-provider feature captures at most 256 mutation completions per connection: connection number, bounded tag, verb, status and allowlisted response-code name. It excludes LOGIN, command arguments, mailbox names, flags, UID maps, response text and MIME. The normal server build has no logging hook. A regression checks LOGIN omission and MIME-shaped fake response lines. - TCP regressions cover COPY → STORE Deleted → EXPUNGE and UID EXPUNGE while the journal is pending. Two Connected Accounts with overlapping remote UIDs route unified Trash independently. Existing expectations were not relaxed. - A focused real Dovecot test executes both workers with two generated messages. COPY/delete and COPY/MOVE preserve virtual UIDs; source UIDs disappear; repeated delivery creates exactly two destinations for two sources; destination flags contain Seen without the later source Deleted flag. This test was run, not merely added. - The existing benchmark profile now includes COPY/STORE Deleted/EXPUNGE p50/p95, alongside the queue-ceiling and burst workloads. Measurement was not run: this issue is not a performance issue, under the latest verification policy. No new baseline comparison or timing-budget pass is claimed. Files: ```text bench/mail-sync.py crates/calternal-imap/src/session.rs crates/calternal-imap/src/store.rs crates/calternal-server/src/device_imap.rs crates/calternal-server/src/notes_imap.rs crates/plugins/mail/src/proxy.rs crates/plugins/mail/src/proxy_mutations.rs crates/plugins/mail/src/proxy_tests.rs crates/plugins/mail/src/proxy_transfers.rs docs/DESIGN.md tests/adversarial/mail-sync.md ``` Re-read the changed module and function comments before reporting. Five atomic commits: `974b6bda4`, `e8ddf2867`, `da1ce8b0b`, `c5040669d`, `197e38295`. Gate output, verbatim: `cargo fmt --check`: exit 0, no output. `cargo clippy -p calternal-imap --all-targets -- -D warnings`: exit 0. ```text Finished `dev` profile [unoptimized + debuginfo] target(s) in 11.50s ``` `cargo test -p calternal-imap`: exit 0. ```text test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s test result: ok. 12 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.02s test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s test result: ok. 11 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s test result: ok. 30 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.18s test result: ok. 8 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s ``` `cargo clippy -p calternal-plugin-mail --all-targets --features test-provider -- -D warnings`: exit 0. ```text Finished `dev` profile [unoptimized + debuginfo] target(s) in 10.59s ``` `cargo test -p calternal-plugin-mail --features test-provider`: exit 0. ```text test result: ok. 82 passed; 0 failed; 7 ignored; 0 measured; 0 filtered out; finished in 5.61s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s ``` Focused fixture regression, `cargo test -p calternal-plugin-mail --features test-provider real_tls_copy_delete -- --ignored --nocapture`: exit 0. ```text test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 88 filtered out; finished in 5.15s ``` `cargo clippy -p calternal-server --all-targets --features mail-test-provider -- -D warnings`: exit 0. ```text Finished `dev` profile [unoptimized + debuginfo] target(s) in 50.42s ``` `cargo test -p calternal-server --features mail-test-provider -- --test-threads=4`: exit 0. ```text test result: ok. 168 passed; 0 failed; 5 ignored; 0 measured; 0 filtered out; finished in 19.58s ``` Web production build: `(cd apps/web && bun run build)` exited 0; it supplies the embedded frontend required by server compilation. No web source changed. Web check/Vitest/screenshots were not repeated. Python benchmark syntax compilation and `git diff --check` exited 0. UX gaps closed: - COPY-based move/delete commands no longer receive a pending-COPY STORE rejection. - Special-use folder discovery identifies the unified destinations that route to each source account. - Native receipt capture now has a bounded, argument-free procedure. Known gaps / UX gaps left: - No native transcript yet. Protocol regressions replay the #1032 interoperability lead, not an observed Apple Mail sequence. - #1031's Mail persistence crash is still unverified after this repair. #1032's native archive source removal and correct-account Trash receipt require a clean native retest. - Native flags, draft save/edit, offline reconnect and simultaneous open-web updates need that same retest. Prior round-two evidence is not a pass for this build. - Other overlapping pending transfers still conflict; only a same-destination COPY can be upgraded to MOVE. Pending MOVE sources remain absent from the live projection. Existing stale-source conflict assertions remain intact. - No performance or five-second budget claim. No full adversarial matrix, full web suite, release build or staging check in this job. Sending stays deferred by DESIGN §53. Decisions: - Preserve the COPY acceptance flag snapshot and defer later absolute source state until the receipt retires. This avoids both source loss and receipt-keyword removal by STORE. - Upgrade same-destination COPY to MOVE using its existing receipt; preserve the single-transfer conflict contract for other destinations. - Advertise special-use roles only on the unified destinations so a client has one target per role. The source account determines the real upstream destination. - Restrict transcript capture to the fixture feature, opt-in environment flag, 64-byte tags and 256 completions per connection. Document these implementation choices; no new product decision. For the merge round: 1. Build with `(cd apps/web && bun run build)` and `cargo build -p calternal-server --features mail-test-provider`, using the documented bounded Cargo environment. 2. Run `CALTERNAL_MAIL_PROXY_POPULATED=1 node apps/web/e2e/mail-proxy-486.mjs`. It must prove populated real-listener MIME, mutation, draft, scope and revocation behavior. Full web suite: `(cd apps/web && bun run test -- --maxWorkers=2)`. 3. Follow `tests/adversarial/mail-sync.md` under `flock -w 7200 ~/.local/state/codex-jobs/calternal/macvm.lock` for the whole native session. Start the isolated server with `CALTERNAL_MAIL_TEST_TRANSCRIPT=1 RUST_LOG=calternal_mail_fixture_transcript=info`. Use the existing VNC driver and environment-only private credentials. Capture native archive/delete events, add a replay if the sequence differs, then prove no new Mail crash, exact source removal, one correct-account Trash copy, stable drafts, flags, offline reconnect and live web updates. This is required before APPLE MAIL ACCEPTANCE can pass. 4. Full adversarial matrices, release/staging checks and periodic performance measurements remain merge-round work. The extended performance command is `python3 bench/mail-sync.py <Mail-test-binary> --test profile_mail_proxy --profile-prefix 'MAIL_PROXY_PROFILE '`, inside the perf-VM lock with load average recorded if a performance review runs it. Cleanup: Stopped and removed only this run's Dovecot container. Deleted its generated fixture and TLS keys. Deleted generated web build and `.svelte-kit/output`. No Mac account or profile was touched in this run. Cargo cleanup: ```text Removed 16916 files, 7.6GiB total ``` Worktree clean. Logs remain ignored under `artifacts/mailproxy-fix/`; no screenshot or other artifact committed.
Author
Owner

Continuing real Apple Mail acceptance after the mutation repair. Branch job/mailproxy-486, starting HEAD 197e3829546e44dbd83ce813472989fc40cb37d8. I will hold the Mac VM lock, use only generated lab Mail, capture the bounded native archive/delete command transcript, check upstream receipts and live web changes, and remove the lab profile and stop services at the end. Sending remains deferred by DESIGN §53.

Continuing real Apple Mail acceptance after the mutation repair. Branch `job/mailproxy-486`, starting HEAD `197e3829546e44dbd83ce813472989fc40cb37d8`. I will hold the Mac VM lock, use only generated lab Mail, capture the bounded native archive/delete command transcript, check upstream receipts and live web changes, and remove the lab profile and stop services at the end. Sending remains deferred by DESIGN §53.
Author
Owner

Continuing real Apple Mail acceptance after the mutation repair. Branch job/mailproxy-486, starting HEAD 197e3829546e44dbd83ce813472989fc40cb37d8. I will hold the Mac VM lock, use only generated lab Mail, capture the bounded native archive/delete command transcript, check upstream receipts and live web changes, and remove the lab profile and stop services at the end. Sending remains deferred by DESIGN §53.

Continuing real Apple Mail acceptance after the mutation repair. Branch `job/mailproxy-486`, starting HEAD `197e3829546e44dbd83ce813472989fc40cb37d8`. I will hold the Mac VM lock, use only generated lab Mail, capture the bounded native archive/delete command transcript, check upstream receipts and live web changes, and remove the lab profile and stop services at the end. Sending remains deferred by DESIGN §53.
Author
Owner

Checkpoint commit 59012e78d: added acceptance session checks and e2e child logging instructions to tests/adversarial/mail-sync.md. Repaired server build passed (Finished dev profile [unoptimized + debuginfo] target(s) in 1m 53s); production web build exited 0. Retained browser session was revoked during prior cleanup, so a fresh isolated Instance was registered through normal setup; /api/v1/auth/me now returns 200 and the populated web Inbox stays open. VNC installed and removed only the retained acceptance profile. Fresh profile installation is in progress. No mutation acceptance result yet.

Checkpoint commit `59012e78d`: added acceptance session checks and e2e child logging instructions to `tests/adversarial/mail-sync.md`. Repaired server build passed (`Finished `dev` profile [unoptimized + debuginfo] target(s) in 1m 53s`); production web build exited 0. Retained browser session was revoked during prior cleanup, so a fresh isolated Instance was registered through normal setup; `/api/v1/auth/me` now returns 200 and the populated web Inbox stays open. VNC installed and removed only the retained acceptance profile. Fresh profile installation is in progress. No mutation acceptance result yet.
Author
Owner

Native Apple Mail mutation check at starting server HEAD 197e3829546e44dbd83ce813472989fc40cb37d8: Archive uses UID COPY → UID STORE → UID EXPUNGE (OK, COPYUID). The selected conversation contains the Inbox message and its separate Sent reply; both now have one Archive receipt and no source receipt. Delete uses UID COPY → UID STORE → UID EXPUNGE (OK, COPYUID); the generated Community garden message has no Inbox source and one own-account Trash receipt. The production web Inbox was kept open and removed both source rows without reload. Read-only receipt checks passed 5 Archive folder checks and 3 delete folder checks. Draft save has one upstream draft. No new Mail crash report yet; only the earlier Mail-2026-10-04-103511.ips exists. Remaining acceptance: native draft edit, HTML/attachment, offline reconnect and simultaneous web edit. Startup download delays and recurring provider invalid-response errors are being recorded separately; no latency-budget pass is claimed.

Native Apple Mail mutation check at starting server HEAD `197e3829546e44dbd83ce813472989fc40cb37d8`: Archive uses UID COPY → UID STORE → UID EXPUNGE (OK, COPYUID). The selected conversation contains the Inbox message and its separate Sent reply; both now have one Archive receipt and no source receipt. Delete uses UID COPY → UID STORE → UID EXPUNGE (OK, COPYUID); the generated Community garden message has no Inbox source and one own-account Trash receipt. The production web Inbox was kept open and removed both source rows without reload. Read-only receipt checks passed 5 Archive folder checks and 3 delete folder checks. Draft save has one upstream draft. No new Mail crash report yet; only the earlier `Mail-2026-10-04-103511.ips` exists. Remaining acceptance: native draft edit, HTML/attachment, offline reconnect and simultaneous web edit. Startup download delays and recurring provider invalid-response errors are being recorded separately; no latency-budget pass is claimed.
Author
Owner

Receipt verifier commit 2680e9533 adds read-only upstream checks to the existing Mail probe. Archive and delete passed exact source/destination counts and body checks. Draft save passed; native draft edit leaves one revised draft, with a new UID and Message-ID, and removes the old identity. HTML renders and the attachment saved from Apple Mail has exact expected bytes. Native Seen/Flagged writes reached the provider and web API. No new crash report yet. Provider protocol errors are filed as #1037. Remaining: offline plus simultaneous web read edit, final native state checks and cleanup. origin/dev was fetched and merged once as 24ba1c947. Current head 0fde75ed8 adds a VNC text settling pause. Tested server binary remains 197e38295.

Receipt verifier commit `2680e9533` adds read-only upstream checks to the existing Mail probe. Archive and delete passed exact source/destination counts and body checks. Draft save passed; native draft edit leaves one revised draft, with a new UID and Message-ID, and removes the old identity. HTML renders and the attachment saved from Apple Mail has exact expected bytes. Native Seen/Flagged writes reached the provider and web API. No new crash report yet. Provider protocol errors are filed as #1037. Remaining: offline plus simultaneous web read edit, final native state checks and cleanup. `origin/dev` was fetched and merged once as `24ba1c947`. Current head `0fde75ed8` adds a VNC text settling pause. Tested server binary remains `197e38295`.
Author
Owner

APPLE MAIL ACCEPTANCE: pass (functional checks)

Head: 86f2e061e6363d837d122574530e44caf843e47d. Native acceptance tested the server binary built from repair head 197e3829546e44dbd83ce813472989fc40cb37d8. The final branch includes one merge of origin/dev (24ba1c947); this run does not certify later merged server changes. No push, deploy or issue closure.

Built: read-only native receipt verification (exact source/destination counts, flags and MIME text); a VNC input-settle fix for dropped leading characters; updated acceptance procedure and results. Files: tests/adversarial/mail_proxy.py, tests/adversarial/apple_mail_vnc.py, tests/adversarial/mail-sync.md. Atomic commits: 59012e78d, 2680e9533, 0fde75ed8, 86f2e061e.

Results:

  • Generated lab profile installed through VNC. Connected Account folders and nested Autumn opened. Text and HTML bodies rendered. Native attachment download matched exact fixture bytes.
  • Seen and flag writes reached the provider and open web view.
  • Archive used UID COPY → UID STORE → UID EXPUNGE. All completions were OK; COPY returned COPYUID. Apple Mail selected two conversation messages (Inbox original and Sent reply). Both sources were removed and Archive held exactly one copy of each, with bodies intact.
  • Delete used the same sequence. Inbox source removed; exactly one copy appeared in the source Connected Account's Trash. The open web Inbox removed archive/delete rows without a reload. #1032 verified for this account.
  • Native draft save and reopen/edit left exactly one matching draft with the revised text and Draft flag. The old Message-ID was absent after replacement. The open web Drafts view updated without a reload.
  • Offline flag removal stayed local while IMAP was disconnected. A concurrent web unread edit reached the provider. Reconnect retained both changes: no Seen and no Flagged, with the body intact. The open web view converged. The native sidebar showed the unread Autumn item before reopening; reopening then made a new Seen edit.
  • No new Mail crash. The diagnostic directory contained only the earlier Mail-2026-10-04-103511.ips. #1031 verified for this run.

Gate output (verbatim where present):

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 1m 53s
PASS native Mail upstream receipts: 5 folder checks
PASS native Mail upstream receipts: 3 folder checks
PASS native Mail upstream receipts: 2 folder checks
PASS native Mail upstream receipts: 4 folder checks
PASS native Mail upstream receipts: 1 folder checks
     Removed 7242 files, 4.6GiB total
Removed web build output

cargo fmt --check, python -m py_compile tests/adversarial/mail_proxy.py tests/adversarial/apple_mail_vnc.py, and git diff --check exited 0 with no output. The initial interrupted server build exited 143 without a compiler diagnostic; its retry passed. Production web build exited 0. The new receipt checker also rejected a deliberately incorrect count. No production Rust or web code changed in this acceptance continuation, so per-crate clippy/test and focused Vitest are not applicable to these changes. Full combined suites remain with the merge round.

Known gaps: #1037 records provider sync invalid-response errors and repeated timeouts, including failures with roughly 1.6–4.0 second sync durations. Later timeouts reached roughly 302–304 seconds despite independent fixture TLS reads taking about 1–2 seconds. Sync recovered and exact receipt checks passed, but the cause is not established. No five-second propagation or performance pass is claimed. Sending remains deferred by DESIGN §53. This is one isolated provider account, not native multiple-provider acceptance.

UX gaps closed: reliable VNC text entry for the acceptance driver; authenticated web evidence established before native writes. UX gaps left: provider sync delays (#1037). No production UI changed.

Decisions: the revoked retained browser session had no usable sign-in credential, so the run created a fresh isolated Instance through normal setup, without editing security state. Receipt checks use read-only SELECT and BODY.PEEK. Native draft replacement can change Message-ID, so final validation requires one matching draft with exact text and absence of its previous identity. The VNC settle delay belongs only to the lab driver.

Cleanup: removed only the new acceptance profile; kept the existing lab profile. Deleted the downloaded acceptance profile and saved fixture attachment on the Mac. Stopped the fixture server/container and all HTTPS/IMAP/SMTP/VNC forwards; released the Mac lock. Ran cargo clean and removed generated web output. Private retained fixture state stays outside version control. No credentials or profiles are attached.

Evidence: 16 screenshots attached, including macOS web rendering at 390/820/1440 px in light/dark. Screenshots are review evidence; visual approval belongs to the orchestrator. Bounded mutation transcript (50 events, verbs/tags/status/static response codes only) attached to #1032: transcript.

APPLE MAIL ACCEPTANCE: pass (functional checks) Head: `86f2e061e6363d837d122574530e44caf843e47d`. Native acceptance tested the server binary built from repair head `197e3829546e44dbd83ce813472989fc40cb37d8`. The final branch includes one merge of `origin/dev` (`24ba1c947`); this run does not certify later merged server changes. No push, deploy or issue closure. Built: read-only native receipt verification (exact source/destination counts, flags and MIME text); a VNC input-settle fix for dropped leading characters; updated acceptance procedure and results. Files: `tests/adversarial/mail_proxy.py`, `tests/adversarial/apple_mail_vnc.py`, `tests/adversarial/mail-sync.md`. Atomic commits: `59012e78d`, `2680e9533`, `0fde75ed8`, `86f2e061e`. Results: - Generated lab profile installed through VNC. Connected Account folders and nested Autumn opened. Text and HTML bodies rendered. Native attachment download matched exact fixture bytes. - Seen and flag writes reached the provider and open web view. - Archive used UID COPY → UID STORE → UID EXPUNGE. All completions were OK; COPY returned COPYUID. Apple Mail selected two conversation messages (Inbox original and Sent reply). Both sources were removed and Archive held exactly one copy of each, with bodies intact. - Delete used the same sequence. Inbox source removed; exactly one copy appeared in the source Connected Account's Trash. The open web Inbox removed archive/delete rows without a reload. #1032 verified for this account. - Native draft save and reopen/edit left exactly one matching draft with the revised text and Draft flag. The old Message-ID was absent after replacement. The open web Drafts view updated without a reload. - Offline flag removal stayed local while IMAP was disconnected. A concurrent web unread edit reached the provider. Reconnect retained both changes: no Seen and no Flagged, with the body intact. The open web view converged. The native sidebar showed the unread Autumn item before reopening; reopening then made a new Seen edit. - No new Mail crash. The diagnostic directory contained only the earlier `Mail-2026-10-04-103511.ips`. #1031 verified for this run. Gate output (verbatim where present): ```text Finished `dev` profile [unoptimized + debuginfo] target(s) in 1m 53s PASS native Mail upstream receipts: 5 folder checks PASS native Mail upstream receipts: 3 folder checks PASS native Mail upstream receipts: 2 folder checks PASS native Mail upstream receipts: 4 folder checks PASS native Mail upstream receipts: 1 folder checks Removed 7242 files, 4.6GiB total Removed web build output ``` `cargo fmt --check`, `python -m py_compile tests/adversarial/mail_proxy.py tests/adversarial/apple_mail_vnc.py`, and `git diff --check` exited 0 with no output. The initial interrupted server build exited 143 without a compiler diagnostic; its retry passed. Production web build exited 0. The new receipt checker also rejected a deliberately incorrect count. No production Rust or web code changed in this acceptance continuation, so per-crate clippy/test and focused Vitest are not applicable to these changes. Full combined suites remain with the merge round. Known gaps: #1037 records provider sync invalid-response errors and repeated timeouts, including failures with roughly 1.6–4.0 second sync durations. Later timeouts reached roughly 302–304 seconds despite independent fixture TLS reads taking about 1–2 seconds. Sync recovered and exact receipt checks passed, but the cause is not established. No five-second propagation or performance pass is claimed. Sending remains deferred by DESIGN §53. This is one isolated provider account, not native multiple-provider acceptance. UX gaps closed: reliable VNC text entry for the acceptance driver; authenticated web evidence established before native writes. UX gaps left: provider sync delays (#1037). No production UI changed. Decisions: the revoked retained browser session had no usable sign-in credential, so the run created a fresh isolated Instance through normal setup, without editing security state. Receipt checks use read-only SELECT and BODY.PEEK. Native draft replacement can change Message-ID, so final validation requires one matching draft with exact text and absence of its previous identity. The VNC settle delay belongs only to the lab driver. Cleanup: removed only the new acceptance profile; kept the existing lab profile. Deleted the downloaded acceptance profile and saved fixture attachment on the Mac. Stopped the fixture server/container and all HTTPS/IMAP/SMTP/VNC forwards; released the Mac lock. Ran cargo clean and removed generated web output. Private retained fixture state stays outside version control. No credentials or profiles are attached. Evidence: 16 screenshots attached, including macOS web rendering at 390/820/1440 px in light/dark. Screenshots are review evidence; visual approval belongs to the orchestrator. Bounded mutation transcript (50 events, verbs/tags/status/static response codes only) attached to #1032: [transcript](https://git.kayg.org/attachments/8c96ff75-b611-480d-b20d-34e915e2a70e). - [mail-archive-verified.png](https://git.kayg.org/attachments/fd249a1d-d72a-49bc-94ce-d66a03d13269) - [mail-trash-verified.png](https://git.kayg.org/attachments/6480d187-87b4-45c5-b298-8147fec282f2) - [mail-html-window.png](https://git.kayg.org/attachments/2288f162-5721-410e-85c3-56d4066fed45) - [draft-revised-confirmed.png](https://git.kayg.org/attachments/6a2095de-0deb-4555-8bb9-4ead35e5afbf) - [mail-autumn-folder-tree.png](https://git.kayg.org/attachments/e6c67c36-33a5-4c70-9eda-e0982184799d) - [mail-offline-flag-removed.png](https://git.kayg.org/attachments/0a5d6bf2-2e84-4191-80d8-e9d2dea2c04f) - [web-archive-complete.png](https://git.kayg.org/attachments/0bdd2f94-47bb-43aa-b5d9-dc05ae5f1eec) - [web-delete-receipt.png](https://git.kayg.org/attachments/ee9e4b80-444b-47e7-9842-7bc848f29abf) - [web-concurrent-converged.png](https://git.kayg.org/attachments/e73bfe1e-7c1b-4e90-8113-791d8156a4e4) - [web-draft-live-edit.png](https://git.kayg.org/attachments/76ba34be-ec82-43b9-a839-8ae80e1fe4b7) - [web-390-light.png](https://git.kayg.org/attachments/e9b50f0e-9bc1-4a0a-a09e-670fc755f382) - [web-390-dark.png](https://git.kayg.org/attachments/4eb4ce5f-ec98-450b-ad4c-5ae3de056617) - [web-820-light.png](https://git.kayg.org/attachments/a0ac6129-9f3f-470a-8b06-24a4825ad7c2) - [web-820-dark.png](https://git.kayg.org/attachments/6a579adb-630e-4691-ab82-326e6b7e4e77) - [web-1440-light.png](https://git.kayg.org/attachments/1f2d0522-a029-4a39-bef1-d5627c7d9eae) - [web-1440-dark.png](https://git.kayg.org/attachments/931769e9-7943-4dd8-812b-c7b822925bec)
Author
Owner

Deployed to production 2026-10-05 ~04:40 CEST in round 9 (269b1b51b). Includes the mail proxy (CalternalDAV, real Apple Mail acceptance PASS on the Mac VM), provider sync fixes, the stress-round fixes, #1067, #1068, #1078 and the Files upload identity repair. Staging healthy first; production healthy in 18 s; Auth 14 and Mail 17 migrations applied; change events 0/30 s; no expired leases.

Deployed to production 2026-10-05 ~04:40 CEST in round 9 (269b1b51b). Includes the mail proxy (CalternalDAV, real Apple Mail acceptance PASS on the Mac VM), provider sync fixes, the stress-round fixes, #1067, #1068, #1078 and the Files upload identity repair. Staging healthy first; production healthy in 18 s; Auth 14 and Mail 17 migrations applied; change events 0/30 s; no expired leases.
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
kayg/calternal#486
No description provided.