CalDAV: normal 100-resource multiget exceeds the 16 KiB REPORT cap #500

Closed
opened 2026-09-30 08:22:24 +00:00 by kayg · 8 comments
Owner

A normal 100-href CalDAV cache refill returns HTTP 413 on the supplied dev release 0dc772c3697ea9bd01822c26440c32206d472715. This is a nonblocking client-batch limitation found in #457. No 5xx, crash or accepted-write loss was observed.

Reproduction: run tests/perf/caldav_scale.py on an isolated release server with its default 50,000 Log entries across twenty area calendars, 5,000 Tasks and --request-timeout 120. After all 55,000 resources are verified, area:multiget-1 returns 207 with the expected ETag and VEVENT. area:multiget-100 requests the first 100 existing hrefs from the same area listing and returns 413. Expected in the normal cache-refill check: 207 with those 100 ETags and VEVENTs. No hostile payload is needed; it is a standard calendar-multiget XML body.

area_report in crates/calternal-dav/src/protocol.rs reads at most 16 KiB. Stable User and area identities make each href long, so a 100-resource XML request exceeds that cap. The request includes only href, getetag and calendar-data selections. Keep the cap's protection; decide whether normal-client batching should be documented, supported with a negotiated limit, or given a larger bounded cap. The stress job will keep 207 as the expected result, record 413 as a finding and continue the separate sync/convergence checks.

Evidence: perf VM under /root/perf.lock, supplied binary SHA-256 7f98931bde5141750b4eee9e8053dcce6cc90b0841d1208601d5bf0dd84d1bc8. Twenty-sample one-href multiget: p50 163.639 ms, p95 185.504 ms, p99 195.269 ms. The full result is retained by #457. No credentials or response bodies are in this report.

A normal 100-href CalDAV cache refill returns HTTP 413 on the supplied dev release `0dc772c3697ea9bd01822c26440c32206d472715`. This is a nonblocking client-batch limitation found in #457. No 5xx, crash or accepted-write loss was observed. Reproduction: run `tests/perf/caldav_scale.py` on an isolated release server with its default 50,000 Log entries across twenty area calendars, 5,000 Tasks and `--request-timeout 120`. After all 55,000 resources are verified, `area:multiget-1` returns 207 with the expected ETag and VEVENT. `area:multiget-100` requests the first 100 existing hrefs from the same area listing and returns 413. Expected in the normal cache-refill check: 207 with those 100 ETags and VEVENTs. No hostile payload is needed; it is a standard calendar-multiget XML body. `area_report` in `crates/calternal-dav/src/protocol.rs` reads at most 16 KiB. Stable User and area identities make each href long, so a 100-resource XML request exceeds that cap. The request includes only href, getetag and calendar-data selections. Keep the cap's protection; decide whether normal-client batching should be documented, supported with a negotiated limit, or given a larger bounded cap. The stress job will keep 207 as the expected result, record 413 as a finding and continue the separate sync/convergence checks. Evidence: perf VM under `/root/perf.lock`, supplied binary SHA-256 `7f98931bde5141750b4eee9e8053dcce6cc90b0841d1208601d5bf0dd84d1bc8`. Twenty-sample one-href multiget: p50 163.639 ms, p95 185.504 ms, p99 195.269 ms. The full result is retained by #457. No credentials or response bodies are in this report.
Author
Owner

Started work on job/multiget-500, based on origin/dev at 6c87f5ff9442cd658572139bc536d018fd5222a4.

The reported failure is reproducible from the implementation: area_report buffers a REPORT body with a 16 KiB limit, so a standard 100-href calendar-multiget can be rejected before XML parsing. I am checking real Apple and DAVx5 batch sizes and will keep an explicit upper bound with adversarial coverage.

Started work on `job/multiget-500`, based on `origin/dev` at `6c87f5ff9442cd658572139bc536d018fd5222a4`. The reported failure is reproducible from the implementation: `area_report` buffers a REPORT body with a 16 KiB limit, so a standard 100-href calendar-multiget can be rejected before XML parsing. I am checking real Apple and DAVx5 batch sizes and will keep an explicit upper bound with adversarial coverage.
Author
Owner

Test-first reproduction confirms the failure in the current handler. cargo test -p calternal-dav --test apple_replay apple_calendar_multiget_accepts_100_hrefs_over_legacy_report_cap fails at the response assertion: actual status is 413, expected 207. The request contains 100 existing hrefs and exceeds 16 KiB using a UUID-length User ID and the stable 69-character area collection ID.

Test-first reproduction confirms the failure in the current handler. `cargo test -p calternal-dav --test apple_replay apple_calendar_multiget_accepts_100_hrefs_over_legacy_report_cap` fails at the response assertion: actual status is 413, expected 207. The request contains 100 existing hrefs and exceeds 16 KiB using a UUID-length User ID and the stable 69-character area collection ID.
Author
Owner

Decision for the cap, which DESIGN does not define: REPORT XML is limited to 512 KiB. The Apple replay request shape measures 18,045 bytes for 100 hrefs and 179,145 bytes for 1,000 hrefs when using the current stable path lengths (36-byte User ID, 69-byte area collection ID, 36-byte resource ID). The cap is 2.9x the calculated 1,000-href body and is applied before xmltree parses the body. tests/adversarial/attack.py now sends 650,098-byte multiget XML and 614,513-byte sync-token XML; both must return 413, including on Reminders.

Live Apple Calendar and DAVx5 payload sizes were not captured: the required macOS VM lock was held by another job, and no Android/DAVx5 capture device was available in this session. The byte counts above come from the Apple replay URL shape, not live-client network traces. I am keeping this measurement gap visible for review.

Decision for the cap, which DESIGN does not define: REPORT XML is limited to 512 KiB. The Apple replay request shape measures 18,045 bytes for 100 hrefs and 179,145 bytes for 1,000 hrefs when using the current stable path lengths (36-byte User ID, 69-byte area collection ID, 36-byte resource ID). The cap is 2.9x the calculated 1,000-href body and is applied before `xmltree` parses the body. `tests/adversarial/attack.py` now sends 650,098-byte multiget XML and 614,513-byte sync-token XML; both must return 413, including on Reminders. Live Apple Calendar and DAVx5 payload sizes were not captured: the required macOS VM lock was held by another job, and no Android/DAVx5 capture device was available in this session. The byte counts above come from the Apple replay URL shape, not live-client network traces. I am keeping this measurement gap visible for review.
Author
Owner

#500 implementation report

Head: c5508ed118f535f07087f47316ecda87a67c9bc3 (job/multiget-500). The functional fix is 067df161016ce0d7fedda9140ae9afa38bdec09c; the final commit updates the adversarial probe docstring. git fetch origin && git merge origin/dev reported Already up to date.

Change

  • Set a hard 512 KiB input cap for Log-area, Journal and Reminders REPORT bodies before XML parsing. Requests over the cap return 413.
  • Added an apple_replay test with 100 calendar hrefs. Its 18,045-byte body exceeds the old 16 KiB cap. Before the fix, the regression test returned 413 instead of 207; after the fix it returns 207 with 100 responses and all 100 event summaries.
  • Updated the live-server adversarial probes to require 413 for a 650,098-byte multiget body and 614,513-byte sync-token bodies, including Reminders.

The local DAV adversarial run exited 0 and printed these lines:

DAV Apple property, write-capability, MKCALENDAR and adversarial probes completed
WebDAV scripted probes passed

It reported SLOW-only load observations: SQLx acquisition warnings around 2.33–2.47 s and app-password verifier timings around 0.4–5.5 s during concurrent DAV requests. No blocking adversarial finding was reported.

Decisions and gap

DESIGN does not set a REPORT body cap. I chose 512 KiB so a 1,000-href replay shape with a 36-byte User ID, 69-byte area collection ID and 36-byte resource ID is about 179,145 bytes while keeping buffered XML input bounded below 512 KiB. These are calculated replay-shape sizes, not client captures. I could not capture the largest actual Apple Calendar or DAVx5 1,000-item request: the required Mac VM lock was busy, and no Android DAVx5 capture device was available. Please treat actual client-size validation as a known gap. #500 is a batch compatibility fix; no latency benchmark was run.

Files

  • crates/calternal-dav/src/protocol.rs
  • crates/calternal-dav/tests/apple_replay.rs
  • tests/adversarial/attack.py

Gates

The Rust gates passed after the merge and before the final docstring-only commit. Verbatim success output captured:

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

cargo clippy -p calternal-dav --all-targets -- -D warnings
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 37.35s

cargo test -p calternal-dav
    test result: ok. 40 passed; 0 failed
    test result: ok. 34 passed; 0 failed
    test result: ok. 0 passed; 0 failed

cargo clippy -p calternal-server --all-targets -- -D warnings
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 1m 51s

cargo test -p calternal-server
    test result: ok. 85 passed; 0 failed; 2 ignored; 0 measured; 0 filtered out; finished in 50.52s

After the final docstring-only commit, ast.parse and git diff --check passed. No web source changed, so web check/test gates were not run. cargo clean removed 16,500 files (9.3 GiB); generated apps/web/build, apps/web/.svelte-kit and adversarial output were removed.

#500 implementation report Head: `c5508ed118f535f07087f47316ecda87a67c9bc3` (`job/multiget-500`). The functional fix is `067df161016ce0d7fedda9140ae9afa38bdec09c`; the final commit updates the adversarial probe docstring. `git fetch origin && git merge origin/dev` reported `Already up to date.` ## Change - Set a hard 512 KiB input cap for Log-area, Journal and Reminders REPORT bodies before XML parsing. Requests over the cap return 413. - Added an `apple_replay` test with 100 calendar hrefs. Its 18,045-byte body exceeds the old 16 KiB cap. Before the fix, the regression test returned 413 instead of 207; after the fix it returns 207 with 100 responses and all 100 event summaries. - Updated the live-server adversarial probes to require 413 for a 650,098-byte multiget body and 614,513-byte sync-token bodies, including Reminders. The local DAV adversarial run exited 0 and printed these lines: ```text DAV Apple property, write-capability, MKCALENDAR and adversarial probes completed WebDAV scripted probes passed ``` It reported SLOW-only load observations: SQLx acquisition warnings around 2.33–2.47 s and app-password verifier timings around 0.4–5.5 s during concurrent DAV requests. No blocking adversarial finding was reported. ## Decisions and gap DESIGN does not set a REPORT body cap. I chose 512 KiB so a 1,000-href replay shape with a 36-byte User ID, 69-byte area collection ID and 36-byte resource ID is about 179,145 bytes while keeping buffered XML input bounded below 512 KiB. These are calculated replay-shape sizes, not client captures. I could not capture the largest actual Apple Calendar or DAVx5 1,000-item request: the required Mac VM lock was busy, and no Android DAVx5 capture device was available. Please treat actual client-size validation as a known gap. #500 is a batch compatibility fix; no latency benchmark was run. ## Files - `crates/calternal-dav/src/protocol.rs` - `crates/calternal-dav/tests/apple_replay.rs` - `tests/adversarial/attack.py` ## Gates The Rust gates passed after the merge and before the final docstring-only commit. Verbatim success output captured: ```text cargo fmt --check (no output; exit 0) cargo clippy -p calternal-dav --all-targets -- -D warnings Finished `dev` profile [unoptimized + debuginfo] target(s) in 37.35s cargo test -p calternal-dav test result: ok. 40 passed; 0 failed test result: ok. 34 passed; 0 failed test result: ok. 0 passed; 0 failed cargo clippy -p calternal-server --all-targets -- -D warnings Finished `dev` profile [unoptimized + debuginfo] target(s) in 1m 51s cargo test -p calternal-server test result: ok. 85 passed; 0 failed; 2 ignored; 0 measured; 0 filtered out; finished in 50.52s ``` After the final docstring-only commit, `ast.parse` and `git diff --check` passed. No web source changed, so web check/test gates were not run. `cargo clean` removed 16,500 files (9.3 GiB); generated `apps/web/build`, `apps/web/.svelte-kit` and adversarial output were removed.
Author
Owner

Coverage finding: the Rust Apple replay in crates/calternal-dav/tests/apple_replay.rs covers 100 hrefs, but ADVERSARIAL_DAV_ONLY=1 only had a one-href REPORT plus an oversized rejection. I added a real-server replay that imports 100 Log rows, discovers their stable CalDAV hrefs, verifies the REPORT is over 16 KiB, then checks for 100 matching multistatus responses and removes the fixture. python3 -m py_compile tests/adversarial/attack.py and bash -n tests/adversarial/run.sh pass; the live replay is pending the final adversarial round.

Coverage finding: the Rust Apple replay in `crates/calternal-dav/tests/apple_replay.rs` covers 100 hrefs, but `ADVERSARIAL_DAV_ONLY=1` only had a one-href REPORT plus an oversized rejection. I added a real-server replay that imports 100 Log rows, discovers their stable CalDAV hrefs, verifies the REPORT is over 16 KiB, then checks for 100 matching multistatus responses and removes the fixture. `python3 -m py_compile tests/adversarial/attack.py` and `bash -n tests/adversarial/run.sh` pass; the live replay is pending the final adversarial round.
Author
Owner

Merge round 3 integration report

State: incomplete; do not fast-forward this snapshot to dev yet. The four-hour job limit ended while CLI Clippy was compiling. No completed final-tree gate failed. No source branch was dropped because the completed gates showed no failing branch.

  • Branch: job/merge-round-3
  • Head: 3e5056d485e9021d2d1f708613e783b0b901b447
  • Included in order: job/multiget-500, job/dav-delete-471, job/iso-435, job/admin-deny-483, job/attach-427, job/hidden-420, job/files-sel-keys, job/small-bugs-3, job/sweep-478.
  • Additional commits: 92f5803f3, 3ea69e317, 26b986bc4, 0948cffa1, 99c088193, df6b07a5a, 3e5056d48.

Completed gate output (verbatim excerpts)

cargo fmt --check exited 0 with no output.

  • DAV clippy: Finished \dev` profile [unoptimized + debuginfo] target(s) in 56.92s`
  • DAV tests:
    test result: ok. 40 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.37s
    test result: ok. 36 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.09s
    test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.31s
  • Notes Core clippy: Finished \dev` profile [unoptimized + debuginfo] target(s) in 14.97s`
  • Notes Core tests:
    test result: ok. 512 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.21s
    test result: ok. 19 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 8.21s
    test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.06s
    test result: ok. 7 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.35s
    test result: ok. 12 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s
  • Notes plugin clippy: Finished \dev` profile [unoptimized + debuginfo] target(s) in 2m 55s`
  • Notes plugin tests: test result: ok. 127 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 151.26s
  • Files clippy (after comment fix): Finished \dev` profile [unoptimized + debuginfo] target(s) in 48.77s`
  • Files tests: test result: ok. 144 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out; finished in 178.62s
    The dev-version migration test passed: test tests::dev_files_schema_upgrades_through_share_log_and_sidecar_migrations ... ok
  • Calendar clippy: Finished \dev` profile [unoptimized + debuginfo] target(s) in 1m 53s`
  • Calendar tests:
    test result: ok. 52 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 7.01s
    test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.12s
    test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.22s
  • Photos clippy: Finished \dev` profile [unoptimized + debuginfo] target(s) in 1m 13s`
  • Photos tests: test result: ok. 45 passed; 0 failed; 2 ignored; 0 measured; 0 filtered out; finished in 11.10s
  • Search clippy: Finished \dev` profile [unoptimized + debuginfo] target(s) in 55.79s`
  • Search tests:
    test result: ok. 36 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out; finished in 46.71s
    test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 2.38s
    test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.09s
    test result: ok. 21 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 10.44s
    test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.05s
    test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.02s
    test result: ok. 1 passed; 0 failed; 2 ignored; 0 measured; 0 filtered out; finished in 5.66s
    test result: ok. 4 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s
  • Embed clippy: Finished \dev` profile [unoptimized + debuginfo] target(s) in 27.32s`
  • Embed tests: test result: ok. 31 passed; 0 failed; 4 ignored; 0 measured; 0 filtered out; finished in 1.93s
  • Filesystem clippy: Finished \dev` profile [unoptimized + debuginfo] target(s) in 10.78s`
  • Filesystem tests:
    test result: ok. 50 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 9.04s
    test result: ok. 42 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 3.56s
  • Server clippy: Finished \dev` profile [unoptimized + debuginfo] target(s) in 1m 48s`
  • Server tests: test result: ok. 85 passed; 0 failed; 2 ignored; 0 measured; 0 filtered out; finished in 19.67s

Other completed checks:

  • Parity matrix: 190 web API actions, 122 shortcuts, 2 static commands, 136 menu actions, 31 settings groups, 172 actions with adapter gaps
  • Cross-User classification gate: 311 operations classified; its test suite printed Ran 5 tests in 0.246s and OK.
  • Admin coverage: 39 reviewed operations; contract and Rust guards agree; its test suite printed Ran 14 tests in 2.404s and OK.
  • Migration audit: ai: 4 migrations, no duplicate numbers; analytics: 2 migrations, no duplicate numbers; calendar: 3 migrations, no duplicate numbers; files: 18 migrations, no duplicate numbers; mail: 8 migrations, no duplicate numbers; notes: 19 migrations, no duplicate numbers; notifications: 4 migrations, no duplicate numbers; photos: 6 migrations, no duplicate numbers; video: 1 migrations, no duplicate numbers.

Remaining work

  • CLI Clippy was interrupted at the four-hour limit while checking dependencies; CLI tests and both Auth gates did not run.
  • The generated contract check, web bun run check, bun run test, and bun run build are pending.
  • The live two-User matrix, authz matrix, DAV round (including Apple’s 100-href and DELETE re-parent replays), sidecar probe, and attachment e2e are pending.
  • Production-browser screenshots for each affected screen at 390/820/1440 px in light/dark mode are pending. No visual review artifacts were produced.
  • The new benchmark profile was added, but its local run and comparison with docs/perf/baseline.json are pending.
  • cargo clean is running but has not returned yet; apps/web/build was removed.

Decisions

  • Files migration IDs follow merge order after dev’s 0015: 0016 share_search_invalidations, 0017 log_attachment_trash, 0018 sidecar_pairs. The populated dev-schema upgrade test passed.
  • Hidden-file Settings copy leads with the User-visible result and uses “Photo edit files (.xmp, .aae)”.
  • The parity exception snapshot was regenerated and reviewed for the newly merged API and Files UI actions.

The branch contains the merged code and commits, but the listed pending gates mean this is not a green merge candidate yet.

## Merge round 3 integration report **State: incomplete; do not fast-forward this snapshot to `dev` yet.** The four-hour job limit ended while CLI Clippy was compiling. No completed final-tree gate failed. No source branch was dropped because the completed gates showed no failing branch. - Branch: `job/merge-round-3` - Head: `3e5056d485e9021d2d1f708613e783b0b901b447` - Included in order: `job/multiget-500`, `job/dav-delete-471`, `job/iso-435`, `job/admin-deny-483`, `job/attach-427`, `job/hidden-420`, `job/files-sel-keys`, `job/small-bugs-3`, `job/sweep-478`. - Additional commits: `92f5803f3`, `3ea69e317`, `26b986bc4`, `0948cffa1`, `99c088193`, `df6b07a5a`, `3e5056d48`. ### Completed gate output (verbatim excerpts) `cargo fmt --check` exited 0 with no output. - DAV clippy: `Finished \`dev\` profile [unoptimized + debuginfo] target(s) in 56.92s` - DAV tests: `test result: ok. 40 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.37s` `test result: ok. 36 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.09s` `test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.31s` - Notes Core clippy: `Finished \`dev\` profile [unoptimized + debuginfo] target(s) in 14.97s` - Notes Core tests: `test result: ok. 512 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.21s` `test result: ok. 19 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 8.21s` `test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.06s` `test result: ok. 7 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.35s` `test result: ok. 12 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s` - Notes plugin clippy: `Finished \`dev\` profile [unoptimized + debuginfo] target(s) in 2m 55s` - Notes plugin tests: `test result: ok. 127 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 151.26s` - Files clippy (after comment fix): `Finished \`dev\` profile [unoptimized + debuginfo] target(s) in 48.77s` - Files tests: `test result: ok. 144 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out; finished in 178.62s` The dev-version migration test passed: `test tests::dev_files_schema_upgrades_through_share_log_and_sidecar_migrations ... ok` - Calendar clippy: `Finished \`dev\` profile [unoptimized + debuginfo] target(s) in 1m 53s` - Calendar tests: `test result: ok. 52 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 7.01s` `test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.12s` `test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.22s` - Photos clippy: `Finished \`dev\` profile [unoptimized + debuginfo] target(s) in 1m 13s` - Photos tests: `test result: ok. 45 passed; 0 failed; 2 ignored; 0 measured; 0 filtered out; finished in 11.10s` - Search clippy: `Finished \`dev\` profile [unoptimized + debuginfo] target(s) in 55.79s` - Search tests: `test result: ok. 36 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out; finished in 46.71s` `test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 2.38s` `test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.09s` `test result: ok. 21 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 10.44s` `test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.05s` `test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.02s` `test result: ok. 1 passed; 0 failed; 2 ignored; 0 measured; 0 filtered out; finished in 5.66s` `test result: ok. 4 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s` - Embed clippy: `Finished \`dev\` profile [unoptimized + debuginfo] target(s) in 27.32s` - Embed tests: `test result: ok. 31 passed; 0 failed; 4 ignored; 0 measured; 0 filtered out; finished in 1.93s` - Filesystem clippy: `Finished \`dev\` profile [unoptimized + debuginfo] target(s) in 10.78s` - Filesystem tests: `test result: ok. 50 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 9.04s` `test result: ok. 42 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 3.56s` - Server clippy: `Finished \`dev\` profile [unoptimized + debuginfo] target(s) in 1m 48s` - Server tests: `test result: ok. 85 passed; 0 failed; 2 ignored; 0 measured; 0 filtered out; finished in 19.67s` Other completed checks: - `Parity matrix: 190 web API actions, 122 shortcuts, 2 static commands, 136 menu actions, 31 settings groups, 172 actions with adapter gaps` - `Cross-User classification gate: 311 operations classified`; its test suite printed `Ran 5 tests in 0.246s` and `OK`. - `Admin coverage: 39 reviewed operations; contract and Rust guards agree`; its test suite printed `Ran 14 tests in 2.404s` and `OK`. - Migration audit: `ai: 4 migrations, no duplicate numbers`; `analytics: 2 migrations, no duplicate numbers`; `calendar: 3 migrations, no duplicate numbers`; `files: 18 migrations, no duplicate numbers`; `mail: 8 migrations, no duplicate numbers`; `notes: 19 migrations, no duplicate numbers`; `notifications: 4 migrations, no duplicate numbers`; `photos: 6 migrations, no duplicate numbers`; `video: 1 migrations, no duplicate numbers`. ### Remaining work - CLI Clippy was interrupted at the four-hour limit while checking dependencies; CLI tests and both Auth gates did not run. - The generated contract check, web `bun run check`, `bun run test`, and `bun run build` are pending. - The live two-User matrix, authz matrix, DAV round (including Apple’s 100-href and DELETE re-parent replays), sidecar probe, and attachment e2e are pending. - Production-browser screenshots for each affected screen at 390/820/1440 px in light/dark mode are pending. No visual review artifacts were produced. - The new benchmark profile was added, but its local run and comparison with `docs/perf/baseline.json` are pending. - `cargo clean` is running but has not returned yet; `apps/web/build` was removed. ### Decisions - Files migration IDs follow merge order after dev’s 0015: 0016 `share_search_invalidations`, 0017 `log_attachment_trash`, 0018 `sidecar_pairs`. The populated dev-schema upgrade test passed. - Hidden-file Settings copy leads with the User-visible result and uses “Photo edit files (.xmp, .aae)”. - The parity exception snapshot was regenerated and reviewed for the newly merged API and Files UI actions. The branch contains the merged code and commits, but the listed pending gates mean this is not a green merge candidate yet.
Author
Owner

Merge round 3 report addendum

Branch job/merge-round-3, HEAD 3e5056d485e9021d2d1f708613e783b0b901b447.

  • Cleanup completed after the main report: Removed 25367 files, 17.5GiB total.
  • apps/web/build removal check: web build output removed: True.
  • git diff --check exited 0 with no output; the worktree has no modified or untracked files.
  • The 4-hour cutoff also prevented a full re-read of documentation comments across all 234 changed files. This remains an audit gap alongside the pending gates listed in the main report.

The branch is still not a green merge candidate.

## Merge round 3 report addendum Branch `job/merge-round-3`, HEAD `3e5056d485e9021d2d1f708613e783b0b901b447`. - Cleanup completed after the main report: `Removed 25367 files, 17.5GiB total`. - `apps/web/build` removal check: `web build output removed: True`. - `git diff --check` exited 0 with no output; the worktree has no modified or untracked files. - The 4-hour cutoff also prevented a full re-read of documentation comments across all 234 changed files. This remains an audit gap alongside the pending gates listed in the main report. The branch is still not a green merge candidate.
Author
Owner

Merged in merge round 3 and deployed to calternal.cloud in cc25c441b (healthy).

Merged in merge round 3 and deployed to calternal.cloud in cc25c441b (healthy).
kayg closed this issue 2026-09-30 23:22:34 +00:00
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#500
No description provided.