Photos shows a voice recording as a blank video tile; audio never belongs in Photos #720

Open
opened 2026-10-02 11:42:10 +00:00 by kayg · 11 comments
Owner

Owner report (2026-10-02, calternal.cloud c4a61e8cf)

The Photos timeline (Thu, Oct 1) shows a voice recording as a blank grey video tile with a play badge.

Expected

Photos shows only images and videos. Audio files (voice memos and any audio MIME type: webm/ogg/m4a/mp3/wav, including audio-only WebM/MP4 containers that #620 now sniffs correctly) never appear in the Photos timeline, albums, memories or Calendar photo decks. They live in Documents → Voice Memos and appear on the Calendar as audio attachments. The fix belongs in the shared media-kind classifier (one source of truth: #620's sniffing on job/voicefiles-620) used by the Photos index. Existing mis-indexed audio items are removed from the Photos index (projection only, never the files).

Tests

Upload a voice memo (audio-only WebM) and an audio-only MP4. Neither appears in Photos; both appear in Documents/Voice Memos and on the Calendar day. A reindex removes the existing wrong Photos entries.

## Owner report (2026-10-02, calternal.cloud `c4a61e8cf`) The Photos timeline (Thu, Oct 1) shows a voice recording as a blank grey video tile with a play badge. ## Expected Photos shows only images and videos. Audio files (voice memos and any audio MIME type: webm/ogg/m4a/mp3/wav, including audio-only WebM/MP4 containers that #620 now sniffs correctly) never appear in the Photos timeline, albums, memories or Calendar photo decks. They live in Documents → Voice Memos and appear on the Calendar as audio attachments. The fix belongs in the shared media-kind classifier (one source of truth: #620's sniffing on job/voicefiles-620) used by the Photos index. Existing mis-indexed audio items are removed from the Photos index (projection only, never the files). ## Tests Upload a voice memo (audio-only WebM) and an audio-only MP4. Neither appears in Photos; both appear in Documents/Voice Memos and on the Calendar day. A reindex removes the existing wrong Photos entries.
Author
Owner

Started #720 on branch job/audiophotos-720, based on c4a61e8cf090170f35b1bed3350d9de20c83ecd5. I’m merging origin/job/voicefiles-620 first so the Photos projection can use its shared media-kind classifier and sniffing, then I’ll add the projection fix, regression coverage, and requested UI evidence.

Started #720 on branch `job/audiophotos-720`, based on `c4a61e8cf090170f35b1bed3350d9de20c83ecd5`. I’m merging `origin/job/voicefiles-620` first so the Photos projection can use its shared media-kind classifier and sniffing, then I’ll add the projection fix, regression coverage, and requested UI evidence.
Author
Owner

Root cause found at crates/plugins/photos/src/index.rs: is_photo_path admits .webm and .mp4 from mime_guess (video/*) and never checks the Files Index MIME, while parse_media treats every EXIF Track as Photos media. After #620, Files stores a sniffed audio/* MIME for audio-only containers. refresh_user_if_changed already diffs prior and rebuilt item IDs, then removes missing rows and their groups; using the shared media-kind classifier at admission will remove stale Photos projections without changing Files rows.

Root cause found at `crates/plugins/photos/src/index.rs`: `is_photo_path` admits `.webm` and `.mp4` from `mime_guess` (`video/*`) and never checks the Files Index MIME, while `parse_media` treats every EXIF `Track` as Photos media. After #620, Files stores a sniffed `audio/*` MIME for audio-only containers. `refresh_user_if_changed` already diffs prior and rebuilt item IDs, then removes missing rows and their groups; using the shared media-kind classifier at admission will remove stale Photos projections without changing Files rows.
Author
Owner

#720 report

Implemented and committed on job/audiophotos-720. Head SHA: 0668a70f2540cb1bd37477ac6201a63e51116ede (includes one clean merge of origin/dev). Feature commits: d5958737d, 47b2590a8, df8912a2f.

Built

  • Added calternal_media::classify_mime as the shared MIME-family classifier, following the #620 Files MIME sniffer.
  • Photos full rebuild and targeted refresh paths now filter audio/* before metadata parsing. Existing full rebuild removes stale audio rows from Photos media, groups, group members and days; it leaves Files rows intact.
  • Added a regression test that seeds legacy video MIME rows, changes their Files MIME to audio and verifies only the Photos projection is cleaned.
  • Added bench/audiophotos-720.sh for 100k indexed paths over 31 repeated scans. It reports p50/p95 filter time and process CPU/RSS.
  • Added production e2e coverage for real audio WebM/MP4 Files entries, Photos exclusion, Quick Look audio playback, Calendar attachments, and macOS rendering at 390/820/1440 px in light/dark.

Files

Cargo.lock, crates/calternal-media/src/lib.rs, crates/plugins/photos/Cargo.toml, crates/plugins/photos/src/index.rs, apps/web/package.json, apps/web/e2e/audiophotos-720.mjs, bench/audiophotos-720.sh.

Gate output

cargo fmt --check passed after the merge; stdout/stderr were empty (exit 0).

cargo test --offline -p calternal-media passed:

running 5 tests
test tests::audio_only_webm_is_audio ... ok
test tests::classifies_media_by_mime_family ... ok
test tests::webm_with_a_video_track_stays_video ... ok
test tests::ogg_opus_is_audio ... ok
test tests::audio_only_mp4_is_audio ... ok

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

bun run check passed:

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.
Loading svelte-check in workspace: /home/kayg/Developer/calternal-wt/audiophotos-720/apps/web
Getting Svelte diagnostics...
svelte-check found 0 errors and 0 warnings

bun run build passed and produced the production SPA. The build emitted existing MODULE_LEVEL_DIRECTIVE warnings for vendor use client directives.

bun run test exited 1 under host load. Vitest reported 940 tests passed and nine worker-start timeouts:

Test Files  144 passed (144)
      Tests  940 passed (940)
     Errors  9 errors
   Duration  329.78s (transform 62%, environment 17%, import 12%, setup 6%, tests 3%)
error: script "test" exited with code 1

The Photos regression test was still compiling after 69 minutes and was interrupted at the two-hour job limit (exit 130). The host load average was 137.18, 136.50, 131.28. Therefore Photos cargo test, both touched-crate clippy gates, the 100k benchmark, the production server e2e, screenshots, and the local adversarial round are not verified. node --check apps/web/e2e/audiophotos-720.mjs passed with no output. cargo clean removed 1125 files (563.9 MiB); apps/web/build and apps/web/.svelte-kit were deleted. The worktree is clean.

UX gaps

  • Coverage added for keeping audio in Files and Calendar, excluding it from Photos, and previewing both WebM and MP4 as audio across the macOS screenshot matrix.
  • These browser checks did not run because the local server binary was not built before the time limit. No screenshots are attached.
  • No playback, screen-reader or touch result is claimed as verified by this run.

Decisions not stated in DESIGN

  • Use the Files Index MIME value as the authoritative media family. audio/* wins over a video-looking extension; known RAW suffixes stay eligible when MIME is generic. The filter applies only to derived Photos tables.
  • The new benchmark isolates the per-row Photos admission filter at 100k candidates. For context, docs/perf/baseline.json records photos.timeline_buckets at p50 1.4 ms and p95 3.4 ms; these are different measurements, and the new profile was not run.
## #720 report Implemented and committed on `job/audiophotos-720`. Head SHA: `0668a70f2540cb1bd37477ac6201a63e51116ede` (includes one clean merge of `origin/dev`). Feature commits: `d5958737d`, `47b2590a8`, `df8912a2f`. ### Built - Added `calternal_media::classify_mime` as the shared MIME-family classifier, following the #620 Files MIME sniffer. - Photos full rebuild and targeted refresh paths now filter `audio/*` before metadata parsing. Existing full rebuild removes stale audio rows from Photos media, groups, group members and days; it leaves Files rows intact. - Added a regression test that seeds legacy video MIME rows, changes their Files MIME to audio and verifies only the Photos projection is cleaned. - Added `bench/audiophotos-720.sh` for 100k indexed paths over 31 repeated scans. It reports p50/p95 filter time and process CPU/RSS. - Added production e2e coverage for real audio WebM/MP4 Files entries, Photos exclusion, Quick Look audio playback, Calendar attachments, and macOS rendering at 390/820/1440 px in light/dark. ### Files `Cargo.lock`, `crates/calternal-media/src/lib.rs`, `crates/plugins/photos/Cargo.toml`, `crates/plugins/photos/src/index.rs`, `apps/web/package.json`, `apps/web/e2e/audiophotos-720.mjs`, `bench/audiophotos-720.sh`. ### Gate output `cargo fmt --check` passed after the merge; stdout/stderr were empty (exit 0). `cargo test --offline -p calternal-media` passed: ```text running 5 tests test tests::audio_only_webm_is_audio ... ok test tests::classifies_media_by_mime_family ... ok test tests::webm_with_a_video_track_stays_video ... ok test tests::ogg_opus_is_audio ... ok test tests::audio_only_mp4_is_audio ... ok 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 ``` `bun run check` passed: ```text 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. Loading svelte-check in workspace: /home/kayg/Developer/calternal-wt/audiophotos-720/apps/web Getting Svelte diagnostics... svelte-check found 0 errors and 0 warnings ``` `bun run build` passed and produced the production SPA. The build emitted existing `MODULE_LEVEL_DIRECTIVE` warnings for vendor `use client` directives. `bun run test` exited 1 under host load. Vitest reported 940 tests passed and nine worker-start timeouts: ```text Test Files 144 passed (144) Tests 940 passed (940) Errors 9 errors Duration 329.78s (transform 62%, environment 17%, import 12%, setup 6%, tests 3%) error: script "test" exited with code 1 ``` The Photos regression test was still compiling after 69 minutes and was interrupted at the two-hour job limit (exit 130). The host load average was `137.18, 136.50, 131.28`. Therefore Photos `cargo test`, both touched-crate clippy gates, the 100k benchmark, the production server e2e, screenshots, and the local adversarial round are not verified. `node --check apps/web/e2e/audiophotos-720.mjs` passed with no output. `cargo clean` removed 1125 files (563.9 MiB); `apps/web/build` and `apps/web/.svelte-kit` were deleted. The worktree is clean. ### UX gaps - Coverage added for keeping audio in Files and Calendar, excluding it from Photos, and previewing both WebM and MP4 as audio across the macOS screenshot matrix. - These browser checks did not run because the local server binary was not built before the time limit. No screenshots are attached. - No playback, screen-reader or touch result is claimed as verified by this run. ### Decisions not stated in DESIGN - Use the Files Index MIME value as the authoritative media family. `audio/*` wins over a video-looking extension; known RAW suffixes stay eligible when MIME is generic. The filter applies only to derived Photos tables. - The new benchmark isolates the per-row Photos admission filter at 100k candidates. For context, `docs/perf/baseline.json` records `photos.timeline_buckets` at p50 1.4 ms and p95 3.4 ms; these are different measurements, and the new profile was not run.
Author
Owner

Correction to the build note in my final report: I did not compare against a pre-change build, so I cannot confirm those warnings were pre-existing. The observed MODULE_LEVEL_DIRECTIVE warnings referenced vendor use client directives; they did not reference files changed by this job.

Correction to the build note in my final report: I did not compare against a pre-change build, so I cannot confirm those warnings were pre-existing. The observed `MODULE_LEVEL_DIRECTIVE` warnings referenced vendor `use client` directives; they did not reference files changed by this job.
Author
Owner

Independent read-only review started. Review branch: job/rev2-audiophotos-720. Base SHA: 440e19dce2. Target SHA: 0668a70f2. I will inspect code and tests. LIGHT rules prohibit builds, tests, servers and browsers.

Independent read-only review started. Review branch: job/rev2-audiophotos-720. Base SHA: 440e19dce23040ac8ebaae88f0469b6535b1afcb. Target SHA: 0668a70f2. I will inspect code and tests. LIGHT rules prohibit builds, tests, servers and browsers.
Author
Owner

Independent read-only review complete. Result: changes required.

Review head: 2feee261d0d86cd9224f5883257bed4a2848501d.
Target reviewed: 0668a70f2. Base: 440e19dce23040ac8ebaae88f0469b6535b1afcb.
Committed files: review-audiophotos-720.md, audit-findings.md.

P1 findings and repair issues:

  1. crates/plugins/photos/src/index.rs:2204-2205: #[test] now decorates an async function that awaits file writes. The Photos test target cannot compile. Restore #[tokio::test] and retain all assertions. New repair issue: #894.
  2. crates/calternal-media/src/lib.rs:398-399: recursive container traversal still has no depth limit or shared node budget. This inherited #620 risk can exhaust the server stack during indexing. Use a finite grammar or an iterative traversal with explicit depth and node limits. Evidence added to the existing repair issue: #816. No duplicate issue was created.

No P2 or P3 defect was confirmed in the scoped Photos filter. The full and targeted refresh paths use the shared MIME classifier before metadata parsing. Audio exclusion keeps Files rows and content files intact. Existing owner, viewer and active Share checks remain. The full reindex test would fail with the old filter. The e2e uses Home as the default library root, so Documents uploads do exercise Photos exclusion.

Gate output: none. LIGHT rules prohibit builds, tests, servers, browsers and benchmarks. No compiler diagnostic or live crash is claimed. git diff --check exited 0 with no output.

Known gaps: targeted MIME-only refresh and downstream album/Memories behavior have no focused new regression tests. Runtime behavior and screenshots were not independently verified. The checkout has no DESIGN §58; available performance rules were used. This review does not certify unrelated #620 routes in the aggregate diff.

For the merge round, after repair:

  • cargo fmt --check
  • cargo clippy -p calternal-plugin-photos --all-targets -- -D warnings
  • cargo test -p calternal-plugin-photos
  • cargo clippy -p calternal-media --all-targets -- -D warnings
  • cargo test -p calternal-media
  • From apps/web: bun e2e/audiophotos-720.mjs

Use the required Cargo environment. Prove that the existing Sidecar test and new reindex test execute, parser limits reject excess nesting safely, both audio formats remain in Files and Calendar, and neither enters Photos. Add focused targeted-refresh and downstream-view coverage.

Decisions: no product decision. The specific LIGHT contract takes precedence over shared build and merge steps. No product code or author-worktree file was changed. No push, deploy or merge was done.

UX gaps closed: none; read-only review. UX gaps left: runtime and visual checks belong to the merge round.

Independent read-only review complete. Result: changes required. Review head: `2feee261d0d86cd9224f5883257bed4a2848501d`. Target reviewed: `0668a70f2`. Base: `440e19dce23040ac8ebaae88f0469b6535b1afcb`. Committed files: `review-audiophotos-720.md`, `audit-findings.md`. P1 findings and repair issues: 1. `crates/plugins/photos/src/index.rs:2204-2205`: `#[test]` now decorates an async function that awaits file writes. The Photos test target cannot compile. Restore `#[tokio::test]` and retain all assertions. New repair issue: https://git.kayg.org/kayg/calternal/issues/894. 2. `crates/calternal-media/src/lib.rs:398-399`: recursive container traversal still has no depth limit or shared node budget. This inherited #620 risk can exhaust the server stack during indexing. Use a finite grammar or an iterative traversal with explicit depth and node limits. Evidence added to the existing repair issue: https://git.kayg.org/kayg/calternal/issues/816. No duplicate issue was created. No P2 or P3 defect was confirmed in the scoped Photos filter. The full and targeted refresh paths use the shared MIME classifier before metadata parsing. Audio exclusion keeps Files rows and content files intact. Existing owner, viewer and active Share checks remain. The full reindex test would fail with the old filter. The e2e uses Home as the default library root, so Documents uploads do exercise Photos exclusion. Gate output: none. LIGHT rules prohibit builds, tests, servers, browsers and benchmarks. No compiler diagnostic or live crash is claimed. `git diff --check` exited 0 with no output. Known gaps: targeted MIME-only refresh and downstream album/Memories behavior have no focused new regression tests. Runtime behavior and screenshots were not independently verified. The checkout has no DESIGN §58; available performance rules were used. This review does not certify unrelated #620 routes in the aggregate diff. For the merge round, after repair: - `cargo fmt --check` - `cargo clippy -p calternal-plugin-photos --all-targets -- -D warnings` - `cargo test -p calternal-plugin-photos` - `cargo clippy -p calternal-media --all-targets -- -D warnings` - `cargo test -p calternal-media` - From `apps/web`: `bun e2e/audiophotos-720.mjs` Use the required Cargo environment. Prove that the existing Sidecar test and new reindex test execute, parser limits reject excess nesting safely, both audio formats remain in Files and Calendar, and neither enters Photos. Add focused targeted-refresh and downstream-view coverage. Decisions: no product decision. The specific LIGHT contract takes precedence over shared build and merge steps. No product code or author-worktree file was changed. No push, deploy or merge was done. UX gaps closed: none; read-only review. UX gaps left: runtime and visual checks belong to the merge round.
Author
Owner

Starting review repairs and merge-round verification on job/audiophotos-720. HEAD is 0668a70f25; base is 440e19dce2. The independent review reports two P1s: an async Photos test has the wrong attribute, and the shared media parser has unbounded recursive nesting. I will fix both with regression coverage, then merge origin/dev once before final gates.

Starting review repairs and merge-round verification on job/audiophotos-720. HEAD is 0668a70f2540cb1bd37477ac6201a63e51116ede; base is 440e19dce23040ac8ebaae88f0469b6535b1afcb. The independent review reports two P1s: an async Photos test has the wrong attribute, and the shared media parser has unbounded recursive nesting. I will fix both with regression coverage, then merge origin/dev once before final gates.
Author
Owner

Review finding #2 repaired and committed as f1f56b9e7. now enforces an 8-level ISO container depth and one 4,096-box budget shared across the top-level scan and nested / boxes; byte-size caps remain. Boundary regressions accept the exact limits and reject one level/box over.
running 7 tests
test tests::audio_only_mp4_is_audio ... ok
test tests::iso_parser_bounds_container_depth ... ok
test tests::classifies_media_by_mime_family ... ok
test tests::audio_only_webm_is_audio ... ok
test tests::ogg_opus_is_audio ... ok
test tests::webm_with_a_video_track_stays_video ... ok
test tests::iso_parser_shares_a_finite_box_budget ... ok

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

running 0 tests

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

Review finding #2 repaired and committed as f1f56b9e7. now enforces an 8-level ISO container depth and one 4,096-box budget shared across the top-level scan and nested / boxes; byte-size caps remain. Boundary regressions accept the exact limits and reject one level/box over. running 7 tests test tests::audio_only_mp4_is_audio ... ok test tests::iso_parser_bounds_container_depth ... ok test tests::classifies_media_by_mime_family ... ok test tests::audio_only_webm_is_audio ... ok test tests::ogg_opus_is_audio ... ok test tests::webm_with_a_video_track_stays_video ... ok test tests::iso_parser_shares_a_finite_box_budget ... ok test result: ok. 7 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s running 0 tests test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s passed (7 tests); passed.
Author
Owner

Correction to my prior issue comment: the shell expanded inline-code tokens in that comment. The implementation and gate results are intact. Commit f1f56b9e7 updates crates/calternal-media/src/lib.rs: the ISO track probe now shares a 4,096-box budget across the file scan and nested trak/mdia boxes, and rejects nesting beyond eight levels. The existing 1 MiB prefix and 16 MiB movie-header limits remain. New tests accept the exact depth and node limits and reject one over each limit.

Evidence: cargo test -p calternal-media passed with 7 tests; cargo clippy -p calternal-media --all-targets -- -D warnings exited 0.

Correction to my prior issue comment: the shell expanded inline-code tokens in that comment. The implementation and gate results are intact. Commit f1f56b9e7 updates crates/calternal-media/src/lib.rs: the ISO track probe now shares a 4,096-box budget across the file scan and nested trak/mdia boxes, and rejects nesting beyond eight levels. The existing 1 MiB prefix and 16 MiB movie-header limits remain. New tests accept the exact depth and node limits and reject one over each limit. Evidence: cargo test -p calternal-media passed with 7 tests; cargo clippy -p calternal-media --all-targets -- -D warnings exited 0.
Author
Owner

The final Photos clippy pass exposed two test-compilation errors in the reindex regression: it built SQL with format! for three fixed projection table names, and SQLx 0.9 rejects those dynamic strings. I replaced both the existing full-refresh loop and the new targeted-refresh loop with fixed SQL literals and bound viewer IDs. Assertions are unchanged. The Photos clippy pass is rerunning against this correction.

The final Photos clippy pass exposed two test-compilation errors in the reindex regression: it built SQL with format! for three fixed projection table names, and SQLx 0.9 rejects those dynamic strings. I replaced both the existing full-refresh loop and the new targeted-refresh loop with fixed SQL literals and bound viewer IDs. Assertions are unchanged. The Photos clippy pass is rerunning against this correction.
Author
Owner

#720 verification round report

Head SHA: 046dc6591ecfbc19d688f7c446ee2cb139eb1c25.
Merged origin/dev once before final gates as 1c2ed4f72. No push, deploy or merge to dev was done.

Built and repaired

  • Bounded ISO container parsing with one 4,096-box budget shared across the file scan and nested containers, plus an eight-level recursion limit. The existing 1 MiB prefix and 16 MiB movie-header caps remain.
  • Restored #[tokio::test] on the asynchronous Photos Sidecar test without changing its assertions.
  • Extended the Photos reindex regression to cover MIME-only targeted refresh. It checks removal from media, group, group-member and day projections while Files rows remain.
  • Changed test count queries to fixed SQL literals with bound viewer IDs. SQLx 0.9 rejected the prior formatted SQL strings.

Files

  • crates/calternal-media/src/lib.rs
  • crates/plugins/photos/src/index.rs

Gate output

cargo fmt --check exited 0 with no stdout.

cargo clippy --offline --locked -p calternal-plugin-photos --all-targets -- -D warnings:

    Checking calternal-plugin-photos v0.0.1 (/home/kayg/Developer/calternal-wt/audiophotos-720/crates/plugins/photos)
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 27m 27s

cargo test --offline --locked -p calternal-plugin-photos printed this while compiling:

   Compiling calternal-plugin-photos v0.0.1 (/home/kayg/Developer/calternal-wt/audiophotos-720/crates/plugins/photos)

I interrupted it with SIGINT (exit 130) after the rustc process made no CPU progress for 11 minutes under shared-host load. No test results were produced. The passing all-targets clippy run compiled the Photos test targets but did not execute them.

cargo clippy --offline --locked -p calternal-media --all-targets -- -D warnings:

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

cargo test --offline --locked -p calternal-media:

    Finished `test` profile [unoptimized + debuginfo] target(s) in 14.28s
     Running unittests src/lib.rs (/mnt/hdd/targets/jobs/audiophotos-720/debug/deps/calternal_media-174a7de072ae1534)

running 7 tests
test tests::audio_only_mp4_is_audio ... ok
test tests::webm_with_a_video_track_stays_video ... ok
test tests::iso_parser_bounds_container_depth ... ok
test tests::audio_only_webm_is_audio ... ok
test tests::ogg_opus_is_audio ... ok
test tests::iso_parser_shares_a_finite_box_budget ... ok
test tests::classifies_media_by_mime_family ... ok

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

   Doc-tests calternal_media

running 0 tests

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

cargo clean output:

     Removed 10245 files, 3.7GiB total

UX gaps closed

The new regression covers the targeted MIME-only removal path and verifies that the Photos projection changes while Files entries remain.

UX gaps left

The Photos test assertions were not executed. The production upload and playback flow, Calendar audio attachments, touch and screen-reader behavior, and the visual screenshot matrix remain unverified in this round. No screenshots were captured or attached. Albums and Memories do not have a separate focused regression in this change.

For the merge round

  • cargo test --offline --locked -p calternal-plugin-photos — execute the Sidecar and full/targeted audio-projection regressions.
  • From the repository root: cd apps/web && bun e2e/audiophotos-720.mjs --screenshots ../../artifacts/audiophotos-720 — prove audio-only WebM and MP4 remain in Files and Calendar attachments and stay out of Photos; capture the macOS-emulated light/dark screenshots at 390, 820 and 1440 px, then attach them to #720.
  • From the repository root: tests/adversarial/run.sh — run the real-server Photos roots, timeline, stack and upload probes with malformed and hostile inputs.
  • bench/audiophotos-720.sh — the profile exists. I did not measure it because this issue is not a performance issue under the current verification policy. If the merge round requires it, run on the perf VM as flock /root/perf.lock bench/audiophotos-720.sh; record p50/p95 filter time and process CPU/RSS for the 100k-path workload.

Decisions not stated in DESIGN

Use an eight-level ISO container nesting cap and one 4,096-box budget across the file scan and nested boxes. These limits bound stack and parsing work after review finding #816. The existing byte caps stay in place; malformed or over-limit containers keep their existing MIME guess.

## #720 verification round report Head SHA: `046dc6591ecfbc19d688f7c446ee2cb139eb1c25`. Merged `origin/dev` once before final gates as `1c2ed4f72`. No push, deploy or merge to `dev` was done. ### Built and repaired - Bounded ISO container parsing with one 4,096-box budget shared across the file scan and nested containers, plus an eight-level recursion limit. The existing 1 MiB prefix and 16 MiB movie-header caps remain. - Restored `#[tokio::test]` on the asynchronous Photos Sidecar test without changing its assertions. - Extended the Photos reindex regression to cover MIME-only targeted refresh. It checks removal from media, group, group-member and day projections while Files rows remain. - Changed test count queries to fixed SQL literals with bound viewer IDs. SQLx 0.9 rejected the prior formatted SQL strings. ### Files - `crates/calternal-media/src/lib.rs` - `crates/plugins/photos/src/index.rs` ### Gate output `cargo fmt --check` exited 0 with no stdout. `cargo clippy --offline --locked -p calternal-plugin-photos --all-targets -- -D warnings`: ```text Checking calternal-plugin-photos v0.0.1 (/home/kayg/Developer/calternal-wt/audiophotos-720/crates/plugins/photos) Finished `dev` profile [unoptimized + debuginfo] target(s) in 27m 27s ``` `cargo test --offline --locked -p calternal-plugin-photos` printed this while compiling: ```text Compiling calternal-plugin-photos v0.0.1 (/home/kayg/Developer/calternal-wt/audiophotos-720/crates/plugins/photos) ``` I interrupted it with SIGINT (exit 130) after the rustc process made no CPU progress for 11 minutes under shared-host load. No test results were produced. The passing all-targets clippy run compiled the Photos test targets but did not execute them. `cargo clippy --offline --locked -p calternal-media --all-targets -- -D warnings`: ```text Finished `dev` profile [unoptimized + debuginfo] target(s) in 1.68s ``` `cargo test --offline --locked -p calternal-media`: ```text Finished `test` profile [unoptimized + debuginfo] target(s) in 14.28s Running unittests src/lib.rs (/mnt/hdd/targets/jobs/audiophotos-720/debug/deps/calternal_media-174a7de072ae1534) running 7 tests test tests::audio_only_mp4_is_audio ... ok test tests::webm_with_a_video_track_stays_video ... ok test tests::iso_parser_bounds_container_depth ... ok test tests::audio_only_webm_is_audio ... ok test tests::ogg_opus_is_audio ... ok test tests::iso_parser_shares_a_finite_box_budget ... ok test tests::classifies_media_by_mime_family ... ok test result: ok. 7 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.02s Doc-tests calternal_media running 0 tests test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s ``` `cargo clean` output: ```text Removed 10245 files, 3.7GiB total ``` ### UX gaps closed The new regression covers the targeted MIME-only removal path and verifies that the Photos projection changes while Files entries remain. ### UX gaps left The Photos test assertions were not executed. The production upload and playback flow, Calendar audio attachments, touch and screen-reader behavior, and the visual screenshot matrix remain unverified in this round. No screenshots were captured or attached. Albums and Memories do not have a separate focused regression in this change. ### For the merge round - `cargo test --offline --locked -p calternal-plugin-photos` — execute the Sidecar and full/targeted audio-projection regressions. - From the repository root: `cd apps/web && bun e2e/audiophotos-720.mjs --screenshots ../../artifacts/audiophotos-720` — prove audio-only WebM and MP4 remain in Files and Calendar attachments and stay out of Photos; capture the macOS-emulated light/dark screenshots at 390, 820 and 1440 px, then attach them to #720. - From the repository root: `tests/adversarial/run.sh` — run the real-server Photos roots, timeline, stack and upload probes with malformed and hostile inputs. - `bench/audiophotos-720.sh` — the profile exists. I did not measure it because this issue is not a performance issue under the current verification policy. If the merge round requires it, run on the perf VM as `flock /root/perf.lock bench/audiophotos-720.sh`; record p50/p95 filter time and process CPU/RSS for the 100k-path workload. ### Decisions not stated in DESIGN Use an eight-level ISO container nesting cap and one 4,096-box budget across the file scan and nested boxes. These limits bound stack and parsing work after review finding #816. The existing byte caps stay in place; malformed or over-limit containers keep their existing MIME guess.
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#720
No description provided.