Files Info inspector: item name as title, aligned header, Finder-style details, compact folder icon #465

Open
opened 2026-09-29 16:19:17 +00:00 by kayg · 28 comments
Owner

Owner (2026-09-29, with a screenshot of the Files Info popover for the Home root): "Info here needs to be fixed (I asked before)." The earlier request was never filed (lost), so this is its own issue.

Defects in the screenshot

  • The header reads "Info" and sits at a smaller left inset (x≈64) than the content (x≈120). The title is the item's name ("Files" / folder or file name) and aligns with the content; no generic "Info" eyebrow, and the toolbar ⓘ already says Info.
  • A large empty preview tile for a folder. Use a compact icon for folders; a real thumbnail or preview only for files that have one (images, PDFs, videos), sized to the content.
  • Too little information: only "Contains 4 items" and "Storage 212 MB used".

Expected (Finder Get Info, as the anchored inspector popover, Cmd+I; DESIGN §34)

  • Name (renamable inline), Kind, Where (a path with a clickable breadcrumb), Created, Modified, Size (and item count for folders, computed lazily with a spinner), Tags (editable chips), Sharing (who, plus a link), Version history link, Copy link (stable ID). For photos: the EXIF summary. For documents: page count and recognised metadata (#341).
  • One shared inspector component for Files, Photos, Notes and Calendar items (reuse gate). Uses the shared glass (#436), the shared Settings row rhythm (#402) for label/value rows, warm tooltips, and keyboard/screen-reader support.
  • Screenshots for a folder, a photo, a PDF and a note at 390 and 1440 px, light and dark.
## Owner (2026-09-29, with a screenshot of the Files Info popover for the Home root): "Info here needs to be fixed (I asked before)." The earlier request was never filed (lost), so this is its own issue. ## Defects in the screenshot - The header reads **"Info"** and sits at a smaller left inset (x≈64) than the content (x≈120). The title is the **item's name** ("Files" / folder or file name) and aligns with the content; no generic "Info" eyebrow, and the toolbar ⓘ already says Info. - A large empty preview tile for a folder. Use a compact icon for folders; a real thumbnail or preview only for files that have one (images, PDFs, videos), sized to the content. - Too little information: only "Contains 4 items" and "Storage 212 MB used". ## Expected (Finder Get Info, as the anchored inspector popover, Cmd+I; DESIGN §34) - Name (renamable inline), Kind, Where (a path with a clickable breadcrumb), Created, Modified, Size (and item count for folders, computed lazily with a spinner), Tags (editable chips), Sharing (who, plus a link), Version history link, Copy link (stable ID). For photos: the EXIF summary. For documents: page count and recognised metadata (#341). - One shared inspector component for Files, Photos, Notes and Calendar items (reuse gate). Uses the shared glass (#436), the shared Settings row rhythm (#402) for label/value rows, warm tooltips, and keyboard/screen-reader support. - Screenshots for a folder, a photo, a PDF and a note at 390 and 1440 px, light and dark.
Author
Owner

Starting issue #465 on branch job/info-inspector-465, base SHA 6c87f5ff9442cd658572139bc536d018fd5222a4.

I have read CLAUDE.md, docs/DESIGN.md, and CONTEXT.md. I am tracing the existing shared surfaces and item data before implementing the inspector.

Starting issue #465 on branch `job/info-inspector-465`, base SHA `6c87f5ff9442cd658572139bc536d018fd5222a4`. I have read `CLAUDE.md`, `docs/DESIGN.md`, and `CONTEXT.md`. I am tracing the existing shared surfaces and item data before implementing the inspector.
Author
Owner

Finding from the current code after syncing origin/dev to 1aaefe288f306498e7757848c50e9988b0e08044:

  • FilesBrowser.svelte passes title="Info"; InfoPanel.svelte then renders a second centered item name and a 4:3 FileThumb frame even when the item is a folder or has no thumbnail. This matches the reported header and empty-tile defects.
  • Photos already reuses InfoPanel.svelte and adds EXIF details. Notes does not currently open an Inspector. Calendar currently opens a separate Day summary through the shared Inspector shell.
  • The Files Entry API has modified and size, but no creation timestamp. Its paged listing already returns a total count. PDF metadata extraction is not present in the current app or server code.
Finding from the current code after syncing `origin/dev` to `1aaefe288f306498e7757848c50e9988b0e08044`: - `FilesBrowser.svelte` passes `title="Info"`; `InfoPanel.svelte` then renders a second centered item name and a 4:3 `FileThumb` frame even when the item is a folder or has no thumbnail. This matches the reported header and empty-tile defects. - Photos already reuses `InfoPanel.svelte` and adds EXIF details. Notes does not currently open an Inspector. Calendar currently opens a separate Day summary through the shared `Inspector` shell. - The Files `Entry` API has `modified` and `size`, but no creation timestamp. Its paged listing already returns a total count. PDF metadata extraction is not present in the current app or server code.
Author
Owner

Finding and implementation: the Files Entry contract had Modified but no creation time. The authenticated calternal-fs root already opens entries handle-relative, so I added optional Linux statx birth time there and exposed it through Entries; unsupported filesystems keep Created unavailable. The indexed photo-list query has no birth-time column, so it returns no creation time rather than adding one filesystem stat per row. The storage regression test matches Root::stat with the filesystem metadata.

Finding and implementation: the Files Entry contract had Modified but no creation time. The authenticated `calternal-fs` root already opens entries handle-relative, so I added optional Linux `statx` birth time there and exposed it through Entries; unsupported filesystems keep Created unavailable. The indexed photo-list query has no birth-time column, so it returns no creation time rather than adding one filesystem stat per row. The storage regression test matches `Root::stat` with the filesystem metadata.
Author
Owner

Adversarial-round finding: the reminder-spam probe created 14 reminders in 8.1 s (SLOW, status 201). The owner rule classifies SLOW-only findings as load, so this does not block the change. The remaining API probes are still running.

Adversarial-round finding: the reminder-spam probe created 14 reminders in 8.1 s (`SLOW`, status 201). The owner rule classifies SLOW-only findings as load, so this does not block the change. The remaining API probes are still running.
Author
Owner

The one time-boxed API-only adversarial round reached the real local server, then the server process aborted. The first visible lost response was POST /api/v1/tags/rename (tag rename across sources); later requests received connection refused, and tests/adversarial/run.sh exited 1 after reporting the server process as Aborted. The runner removed its temporary server log during cleanup, and this host has core dumps disabled, so this run did not provide an abort stack.

This matches the earlier, open Forgejo issue #525 (the same tag-rename probe aborted during job #492). The calternal-tags crate was not changed by #465; the only nearby shared filesystem change is Root::list using statx for entry metadata, so causality is not established. The existing issue already tracks reproducing on a quiet host, preserving logs/core, and adding a regression test. No second adversarial pass was run.

Other observed results: search storm had 0 failures (p50 379.6 ms, p95 469.1 ms); the mkdir storm created 200 directories with 0 errors; the rename race had one winner and no errors; SLOW-only reminder/log/Notes probes are load per the owner rule.

The one time-boxed API-only adversarial round reached the real local server, then the server process aborted. The first visible lost response was `POST /api/v1/tags/rename` (`tag rename across sources`); later requests received connection refused, and `tests/adversarial/run.sh` exited 1 after reporting the server process as `Aborted`. The runner removed its temporary server log during cleanup, and this host has core dumps disabled, so this run did not provide an abort stack. This matches the earlier, open Forgejo issue #525 (the same tag-rename probe aborted during job #492). The `calternal-tags` crate was not changed by #465; the only nearby shared filesystem change is `Root::list` using `statx` for entry metadata, so causality is not established. The existing issue already tracks reproducing on a quiet host, preserving logs/core, and adding a regression test. No second adversarial pass was run. Other observed results: search storm had 0 failures (p50 379.6 ms, p95 469.1 ms); the mkdir storm created 200 directories with 0 errors; the rename race had one winner and no errors; SLOW-only reminder/log/Notes probes are load per the owner rule.
Author
Owner

Info Inspector (#465) — final report

Built

Added a shared Finder-style Inspector shell and semantic label/value rows. Files and Photos share metadata, rename, tags, sharing, version links, stable file links, clickable locations, and lazy folder size/count. PDFs show page count and recognized metadata; Photos show EXIF. Notes use the shared Inspector and preserve the Note ID when the title changes. Calendar Log, Task, and Event previews open the shared Inspector with type-specific details and Copy link actions.

Production screenshots were captured from the real API and production SPA for Folder, Photo, PDF, and Note at 390, 820, and 1440 px in light and dark themes. All 24 are attached below.

Files

  • apps/web/e2e/harness.mjs
  • apps/web/e2e/info-inspector-perf.mjs
  • apps/web/e2e/info-inspector.mjs
  • apps/web/package.json
  • apps/web/src/lib/components/InspectorRow.svelte.test.ts
  • apps/web/src/lib/files/FilesBrowser.svelte
  • apps/web/src/lib/files/InfoPanel.svelte
  • apps/web/src/lib/files/InfoPanel.svelte.test.ts
  • apps/web/src/lib/files/api.test.ts
  • apps/web/src/lib/files/api.ts
  • apps/web/src/lib/files/model.test.ts
  • apps/web/src/lib/files/model.ts
  • apps/web/src/lib/notes/NoteView.svelte
  • apps/web/src/lib/photos/PhotoViewer.svelte
  • apps/web/src/lib/photos/PhotosView.svelte
  • apps/web/src/routes/calendar/[view]/[date]/+page.svelte
  • bench/info-inspector/README.md
  • bench/info-inspector/run.sh
  • bun.lock
  • contracts/openapi.json
  • crates/calternal-fs/src/blob.rs
  • crates/calternal-fs/src/root.rs
  • crates/calternal-fs/tests/storage.rs
  • crates/plugins/files/src/lib.rs
  • crates/plugins/files/src/listing.rs
  • crates/plugins/files/src/shares.rs
  • packages/api-client/src/generated.ts
  • packages/ui/src/components/Inspector.svelte
  • packages/ui/src/components/InspectorRow.svelte
  • packages/ui/src/components/calendar/ItemPreview.svelte
  • packages/ui/src/components/viewer/QuickLook.svelte
  • packages/ui/src/index.ts

Commits and gates

Head: 886571eac4f7b2bdd0df8be1a334f26a78f12837.

Rust gate commands all exited 0:

  • cargo fmt --check (no output)
  • cargo clippy -p calternal-fs --all-targets -- -D warnings
  • cargo test -p calternal-fs (41 unit tests and 43 storage tests passed)
  • cargo clippy -p calternal-plugin-files --all-targets -- -D warnings
  • cargo test -p calternal-plugin-files (135 passed, 1 ignored)
  • cargo clippy -p calternal-server --all-targets -- -D warnings output:
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 4m 33s
    
  • cargo test -p calternal-server output:
    test result: ok. 85 passed; 0 failed; 2 ignored; 0 measured; 0 filtered out; finished in 31.53s
    

bun run check output:

Text sizes and UI shape values use shared role tokens.
Loading svelte-check in workspace: /home/kayg/Developer/calternal-wt/info-inspector-465/apps/web
Getting Svelte diagnostics...
svelte-check found 0 errors and 0 warnings

bun run test output:

Test Files  139 passed (139)
     Tests  903 passed (903)

bun run build output:

✓ built in 1m 41s
> Using @sveltejs/adapter-static
  Wrote site to "build"
  ✔ done

Production screenshot run:

INFO_INSPECTOR_SCREENSHOTS /home/kayg/Developer/calternal-wt/info-inspector-465/artifacts/info-inspector
INFO_INSPECTOR_CAPTURED 24

Local performance profile (host calternal-dev, load average [36.87, 34.75, 35.32]; 500 real API-created files, 3 sequential opens, 4-way burst):

  • Baseline /files data-ready: 1440 px p50/p95 3709/3844 ms; 390 px 4390/4823 ms.
  • Inspector average opens: p50/p95 1161.3/2520.3 ms; server mean/peak RSS 260,142,837/262,287,360 bytes; mean/peak CPU 11.02/62.81%.
  • Four-way burst: p50/p95 2081.5/2769.5 ms; server mean/peak RSS 262,766,336/263,843,840 bytes; mean/peak CPU 10.32/35.63%.
  • The 5,000-file seed reached only 540 entries after 8 minutes on this shared host, so it was stopped. The measured run uses 500 files; larger-folder numbers remain unmeasured.

The one API-only adversarial round exited 1. Output:

search storm: 0 failures, p50=379.6ms p95=469.1ms
mkdir storm: 200 created, 0 errors
rename race: 1 succeeded, 0 errors
!! tag rename across sources: NO RESPONSE (b'Remote end closed connection without response')
tests/adversarial/run.sh: line 287: 1860765 Aborted "$server_bin" > "$output_pipe" 2>&1

Later requests received connection refused. This matches existing open issue #525, first reported by earlier job #492. calternal-tags was not changed here. The test runner removed its temporary log and the host has core dumps disabled, so the cause is not established. No second round was run. Other slow-only probes are load per the owner rule.

Decisions and gaps

  • The shared work rule required tablet-width evidence, so screenshots also cover 820 px.
  • Files, Photos, and Notes use the same metadata content. Calendar uses the shared Inspector shell and row primitive with date/provider/status/time fields because external Calendar items do not have Files sharing or version metadata.
  • Calendar Task/Event names and Calendar tags remain source-owned and read-only in this Inspector. DESIGN §33 says stable Task identity is still to do; the current /t/<task-id> Copy link can break if the Task file is renamed.
  • Created is optional. The API reports it only when Linux statx supplies birth time; it does not invent a timestamp.
  • The repeated adversarial server abort remains tracked in #525 and is a known gap for the orchestrator. It was not fixed in this UI/files metadata change.
  • The 500-file local performance result is noisy under the recorded host load and does not characterize a 5,000-file folder.

Screenshot attachments

# Info Inspector (#465) — final report ## Built Added a shared Finder-style Inspector shell and semantic label/value rows. Files and Photos share metadata, rename, tags, sharing, version links, stable file links, clickable locations, and lazy folder size/count. PDFs show page count and recognized metadata; Photos show EXIF. Notes use the shared Inspector and preserve the Note ID when the title changes. Calendar Log, Task, and Event previews open the shared Inspector with type-specific details and Copy link actions. Production screenshots were captured from the real API and production SPA for Folder, Photo, PDF, and Note at 390, 820, and 1440 px in light and dark themes. All 24 are attached below. ## Files - `apps/web/e2e/harness.mjs` - `apps/web/e2e/info-inspector-perf.mjs` - `apps/web/e2e/info-inspector.mjs` - `apps/web/package.json` - `apps/web/src/lib/components/InspectorRow.svelte.test.ts` - `apps/web/src/lib/files/FilesBrowser.svelte` - `apps/web/src/lib/files/InfoPanel.svelte` - `apps/web/src/lib/files/InfoPanel.svelte.test.ts` - `apps/web/src/lib/files/api.test.ts` - `apps/web/src/lib/files/api.ts` - `apps/web/src/lib/files/model.test.ts` - `apps/web/src/lib/files/model.ts` - `apps/web/src/lib/notes/NoteView.svelte` - `apps/web/src/lib/photos/PhotoViewer.svelte` - `apps/web/src/lib/photos/PhotosView.svelte` - `apps/web/src/routes/calendar/[view]/[date]/+page.svelte` - `bench/info-inspector/README.md` - `bench/info-inspector/run.sh` - `bun.lock` - `contracts/openapi.json` - `crates/calternal-fs/src/blob.rs` - `crates/calternal-fs/src/root.rs` - `crates/calternal-fs/tests/storage.rs` - `crates/plugins/files/src/lib.rs` - `crates/plugins/files/src/listing.rs` - `crates/plugins/files/src/shares.rs` - `packages/api-client/src/generated.ts` - `packages/ui/src/components/Inspector.svelte` - `packages/ui/src/components/InspectorRow.svelte` - `packages/ui/src/components/calendar/ItemPreview.svelte` - `packages/ui/src/components/viewer/QuickLook.svelte` - `packages/ui/src/index.ts` ## Commits and gates Head: `886571eac4f7b2bdd0df8be1a334f26a78f12837`. Rust gate commands all exited 0: - `cargo fmt --check` (no output) - `cargo clippy -p calternal-fs --all-targets -- -D warnings` - `cargo test -p calternal-fs` (41 unit tests and 43 storage tests passed) - `cargo clippy -p calternal-plugin-files --all-targets -- -D warnings` - `cargo test -p calternal-plugin-files` (135 passed, 1 ignored) - `cargo clippy -p calternal-server --all-targets -- -D warnings` output: ```text Finished `dev` profile [unoptimized + debuginfo] target(s) in 4m 33s ``` - `cargo test -p calternal-server` output: ```text test result: ok. 85 passed; 0 failed; 2 ignored; 0 measured; 0 filtered out; finished in 31.53s ``` `bun run check` output: ```text Text sizes and UI shape values use shared role tokens. Loading svelte-check in workspace: /home/kayg/Developer/calternal-wt/info-inspector-465/apps/web Getting Svelte diagnostics... svelte-check found 0 errors and 0 warnings ``` `bun run test` output: ```text Test Files 139 passed (139) Tests 903 passed (903) ``` `bun run build` output: ```text ✓ built in 1m 41s > Using @sveltejs/adapter-static Wrote site to "build" ✔ done ``` Production screenshot run: ```text INFO_INSPECTOR_SCREENSHOTS /home/kayg/Developer/calternal-wt/info-inspector-465/artifacts/info-inspector INFO_INSPECTOR_CAPTURED 24 ``` Local performance profile (host `calternal-dev`, load average `[36.87, 34.75, 35.32]`; 500 real API-created files, 3 sequential opens, 4-way burst): - Baseline `/files` data-ready: 1440 px p50/p95 `3709/3844 ms`; 390 px `4390/4823 ms`. - Inspector average opens: p50/p95 `1161.3/2520.3 ms`; server mean/peak RSS `260,142,837/262,287,360 bytes`; mean/peak CPU `11.02/62.81%`. - Four-way burst: p50/p95 `2081.5/2769.5 ms`; server mean/peak RSS `262,766,336/263,843,840 bytes`; mean/peak CPU `10.32/35.63%`. - The 5,000-file seed reached only 540 entries after 8 minutes on this shared host, so it was stopped. The measured run uses 500 files; larger-folder numbers remain unmeasured. The one API-only adversarial round exited 1. Output: ```text search storm: 0 failures, p50=379.6ms p95=469.1ms mkdir storm: 200 created, 0 errors rename race: 1 succeeded, 0 errors !! tag rename across sources: NO RESPONSE (b'Remote end closed connection without response') tests/adversarial/run.sh: line 287: 1860765 Aborted "$server_bin" > "$output_pipe" 2>&1 ``` Later requests received connection refused. This matches existing open issue #525, first reported by earlier job #492. `calternal-tags` was not changed here. The test runner removed its temporary log and the host has core dumps disabled, so the cause is not established. No second round was run. Other slow-only probes are load per the owner rule. ## Decisions and gaps - The shared work rule required tablet-width evidence, so screenshots also cover 820 px. - Files, Photos, and Notes use the same metadata content. Calendar uses the shared Inspector shell and row primitive with date/provider/status/time fields because external Calendar items do not have Files sharing or version metadata. - Calendar Task/Event names and Calendar tags remain source-owned and read-only in this Inspector. DESIGN §33 says stable Task identity is still to do; the current `/t/<task-id>` Copy link can break if the Task file is renamed. - Created is optional. The API reports it only when Linux `statx` supplies birth time; it does not invent a timestamp. - The repeated adversarial server abort remains tracked in #525 and is a known gap for the orchestrator. It was not fixed in this UI/files metadata change. - The 500-file local performance result is noisy under the recorded host load and does not characterize a 5,000-file folder. ## Screenshot attachments - [folder · desktop · dark](https://git.kayg.org/attachments/ccfd84f2-75b4-4b59-9851-5d20ff819273) - [folder · desktop · light](https://git.kayg.org/attachments/60257dae-64c8-4e13-abbf-6ac3ccc0e779) - [folder · phone · dark](https://git.kayg.org/attachments/5306f342-ec0c-4a32-8f36-c0fbe82f73ad) - [folder · phone · light](https://git.kayg.org/attachments/4d0b9185-86d0-44a7-92e3-bb09977b8bb1) - [folder · tablet · dark](https://git.kayg.org/attachments/0802b348-cd43-4fec-a073-375e0815b9ff) - [folder · tablet · light](https://git.kayg.org/attachments/5e5c358a-e9bc-4511-aa4b-5db238c94af4) - [note · desktop · dark](https://git.kayg.org/attachments/87f8475e-91df-4c5e-8469-573ac05960e3) - [note · desktop · light](https://git.kayg.org/attachments/669afebc-d5a8-4a77-84f7-5cf831e70c8f) - [note · phone · dark](https://git.kayg.org/attachments/c00ca05d-f3d0-43af-a175-0528887b504f) - [note · phone · light](https://git.kayg.org/attachments/5b41fc1f-0ab8-49f5-81a5-45cffe2eb63e) - [note · tablet · dark](https://git.kayg.org/attachments/fd15c9ef-a6d3-43d1-8f52-63e3c4313caa) - [note · tablet · light](https://git.kayg.org/attachments/db945121-d56e-40be-b5f4-dbaaa363b18b) - [pdf · desktop · dark](https://git.kayg.org/attachments/44526846-ca18-46a3-9032-bd57ebdde8e9) - [pdf · desktop · light](https://git.kayg.org/attachments/ee515716-8077-4af5-b2cc-08c8cc02b56d) - [pdf · phone · dark](https://git.kayg.org/attachments/82aec41a-27a8-40bc-a539-801da84f825a) - [pdf · phone · light](https://git.kayg.org/attachments/278a335f-0db1-494c-b949-a146e02c8d5a) - [pdf · tablet · dark](https://git.kayg.org/attachments/4db9f72e-737e-4f9a-aaeb-1317c4fd7eb8) - [pdf · tablet · light](https://git.kayg.org/attachments/4fa8566e-a56d-493f-9ed9-4dc9cc13ca7a) - [photo · desktop · dark](https://git.kayg.org/attachments/0387fb99-98ad-4945-b592-4c6476ac6751) - [photo · desktop · light](https://git.kayg.org/attachments/7716eb47-c815-4d73-92bb-eed16da4f38c) - [photo · phone · dark](https://git.kayg.org/attachments/ac63723b-ec75-4a11-ae82-6f9f9d65520a) - [photo · phone · light](https://git.kayg.org/attachments/bfbf2cfa-c783-47b6-a110-69232a569a1f) - [photo · tablet · dark](https://git.kayg.org/attachments/3a932c9a-504a-48b6-8e55-7f290a9dae6c) - [photo · tablet · light](https://git.kayg.org/attachments/ba2807ee-4bb1-45f0-a25d-cbd4f954d399)
Author
Owner

Starting #465 polish on branch job/info-inspector-465. Base SHA: 1aaefe288f. I am checking the phone title, row value alignment, missing dates, compact date formatting, and photo preview behavior, then I will rerun requested gates and attach fresh evidence.

Starting #465 polish on branch job/info-inspector-465. Base SHA: 1aaefe288f306498e7757848c50e9988b0e08044. I am checking the phone title, row value alignment, missing dates, compact date formatting, and photo preview behavior, then I will rerun requested gates and attach fresh evidence.
Author
Owner

Findings from the existing #465 evidence and the shared Inspector code:

  • artifacts/info-inspector/inspector-photo-phone-dark.png shows the Quick Look phone sheet title and the nested Inspector sheet title both reading “Inspector Photo.JPG”. Quick Look already supplies the visible viewer title, so the nested phone title can be hidden while its dialog label and close action remain.
  • InfoPanel.svelte uses a text button with 6 px inline padding for Rename and Add tags. That moves their labels away from the InspectorRow value edge. The Name flex row also wraps when the button padding consumes its remaining width.
  • The Created row prints “Unavailable” for a null creation time. Its date rows call the long-month formatter, which renders “September 30, 2026 at 4:36 PM” in the value column.
  • The Photo screenshot opens Info from the PhotoViewer for that same Photo. InfoPanel intentionally omits the preview in that viewer case. I am adding a standalone Files Inspector capture to verify that the same real Photo shows its thumbnail outside its viewer.
Findings from the existing #465 evidence and the shared Inspector code: - `artifacts/info-inspector/inspector-photo-phone-dark.png` shows the Quick Look phone sheet title and the nested Inspector sheet title both reading “Inspector Photo.JPG”. Quick Look already supplies the visible viewer title, so the nested phone title can be hidden while its dialog label and close action remain. - `InfoPanel.svelte` uses a text button with 6 px inline padding for Rename and Add tags. That moves their labels away from the InspectorRow value edge. The Name flex row also wraps when the button padding consumes its remaining width. - The Created row prints “Unavailable” for a null creation time. Its date rows call the long-month formatter, which renders “September 30, 2026 at 4:36 PM” in the value column. - The Photo screenshot opens Info from the PhotoViewer for that same Photo. `InfoPanel` intentionally omits the preview in that viewer case. I am adding a standalone Files Inspector capture to verify that the same real Photo shows its thumbnail outside its viewer.
Author
Owner

The one origin/dev conflict was in packages/ui/src/components/calendar/ItemPreview.svelte. This branch adds the stable Event Info action for #465; origin/dev adds copying a read-only subscription Event and a date-aware event link. I resolved it by keeping both actions and using the new date-aware eventHref(ev.id, item.date, ev.sourceId) call.

The one `origin/dev` conflict was in `packages/ui/src/components/calendar/ItemPreview.svelte`. This branch adds the stable Event Info action for #465; `origin/dev` adds copying a read-only subscription Event and a date-aware event link. I resolved it by keeping both actions and using the new date-aware `eventHref(ev.id, item.date, ev.sourceId)` call.
Author
Owner

Web gate finding on merged tree: bun run check failed because the motion-token check flags the InfoPanel transition at line 751 (750ms and linear). I am tracing that transition to the shared motion tokens and will fix it before rerunning the web gates.

Web gate finding on merged tree: `bun run check` failed because the motion-token check flags the InfoPanel transition at line 751 (`750ms` and `linear`). I am tracing that transition to the shared motion tokens and will fix it before rerunning the web gates.
Author
Owner

E2E environment finding: the first bun e2e/info-inspector.mjs attempt stopped before launching because sharp could not load: its linux-x64 runtime requires libstdc++.so.6, which is absent from the loader search path. I am checking the provided runtime paths for that library so the screenshot round can proceed without changing app dependencies.

E2E environment finding: the first `bun e2e/info-inspector.mjs` attempt stopped before launching because `sharp` could not load: its linux-x64 runtime requires `libstdc++.so.6`, which is absent from the loader search path. I am checking the provided runtime paths for that library so the screenshot round can proceed without changing app dependencies.
Author
Owner

E2E environment follow-up: I supplied the Nix store's existing libstdc++.so.6 path and the sharp loader error cleared. The harness next looked in repository target/debug, but this job's preset CARGO_TARGET_DIR is external. I will set CALTERNAL_SERVER_BIN to the server binary in that preset directory for the run.

E2E environment follow-up: I supplied the Nix store's existing `libstdc++.so.6` path and the `sharp` loader error cleared. The harness next looked in repository `target/debug`, but this job's preset `CARGO_TARGET_DIR` is external. I will set `CALTERNAL_SERVER_BIN` to the server binary in that preset directory for the run.
Author
Owner

E2E assertion finding: the local server started and the first PDF viewer capture failed at openFileInspector: on phone, the test still requires an inner Inspector heading with the filename, but #465 now hides that heading while preserving the Quick Look sheet title. I will adjust the E2E to assert the single visible sheet title on phone, and keep checking the Inspector title on desktop.

E2E assertion finding: the local server started and the first PDF viewer capture failed at `openFileInspector`: on phone, the test still requires an inner Inspector heading with the filename, but #465 now hides that heading while preserving the Quick Look sheet title. I will adjust the E2E to assert the single visible sheet title on phone, and keep checking the Inspector title on desktop.
Author
Owner

E2E interaction finding: after the phone long-press opens the Files selection toolbar, Playwright's pointer click kept waiting for the animated “Get info” button to become stable; the toolbar re-rendered and detached the button between retries. The control is visible and present. I will activate that button directly in the browser test to avoid treating its entrance animation as a failed interaction.

E2E interaction finding: after the phone long-press opens the Files selection toolbar, Playwright's pointer click kept waiting for the animated “Get info” button to become stable; the toolbar re-rendered and detached the button between retries. The control is visible and present. I will activate that button directly in the browser test to avoid treating its entrance animation as a failed interaction.
Author
Owner

E2E data finding: the real Photo uploaded through the Files API reaches its standalone Inspector with no creation timestamp. The new behavior correctly omits the Created row, but the E2E fixture check still waits for Created time and fails. I will assert that this unavailable row is hidden and use the available modification date to verify the compact date plus full tooltip.

E2E data finding: the real Photo uploaded through the Files API reaches its standalone Inspector with no creation timestamp. The new behavior correctly omits the `Created` row, but the E2E fixture check still waits for `Created time` and fails. I will assert that this unavailable row is hidden and use the available modification date to verify the compact date plus full tooltip.
Author
Owner

Performance-profile finding: the local default 5,000-file workload remained in API fixture setup for 30:05 and produced no measurement JSON. I stopped that run at the timebox; its child server and temporary data directories exited. I will make one completed local run at 1,000 real entries with the same five average opens and four-way burst, and report the smaller workload explicitly.

Performance-profile finding: the local default 5,000-file workload remained in API fixture setup for 30:05 and produced no measurement JSON. I stopped that run at the timebox; its child server and temporary data directories exited. I will make one completed local run at 1,000 real entries with the same five average opens and four-way burst, and report the smaller workload explicitly.
Author
Owner

Inspector profile result (local, calternal-dev, shared-host load averages 26.69 / 27.98 / 28.15): the 1,000-file Folder workload completed with five average opens and a four-way burst. Folder average latency p50/p95 was 875.1 / 1,132.5 ms; mean/peak CPU was 12.73% / 71.51%; mean/peak RSS was 287.9 / 291.8 MB. Folder burst p50/p95 was 1,793.6 / 2,622.9 ms; mean/peak CPU 15.53% / 55.25%; mean/peak RSS 292.8 / 294.4 MB. File average p50/p95 was 1,011.4 / 1,351.7 ms; mean/peak CPU 8.93% / 39.83%; mean/peak RSS 291.8 / 291.8 MB. File burst p50/p95 was 1,928 / 2,483.3 ms; mean/peak CPU 15.88% / 39.96%; mean/peak RSS 294.5 / 294.5 MB.

Baseline /files route data-ready latency: 1440 px p50/p95 1,240 / 1,442 ms; 390 px p50/p95 902 / 985 ms. The attempted 5,000-file setup exceeded 30 minutes before measurement; this result uses the stated 1,000-file fallback and is not a quiet-host comparison.

Inspector profile result (local, `calternal-dev`, shared-host load averages 26.69 / 27.98 / 28.15): the 1,000-file Folder workload completed with five average opens and a four-way burst. Folder average latency p50/p95 was 875.1 / 1,132.5 ms; mean/peak CPU was 12.73% / 71.51%; mean/peak RSS was 287.9 / 291.8 MB. Folder burst p50/p95 was 1,793.6 / 2,622.9 ms; mean/peak CPU 15.53% / 55.25%; mean/peak RSS 292.8 / 294.4 MB. File average p50/p95 was 1,011.4 / 1,351.7 ms; mean/peak CPU 8.93% / 39.83%; mean/peak RSS 291.8 / 291.8 MB. File burst p50/p95 was 1,928 / 2,483.3 ms; mean/peak CPU 15.88% / 39.96%; mean/peak RSS 294.5 / 294.5 MB. Baseline `/files` route data-ready latency: 1440 px p50/p95 1,240 / 1,442 ms; 390 px p50/p95 902 / 985 ms. The attempted 5,000-file setup exceeded 30 minutes before measurement; this result uses the stated 1,000-file fallback and is not a quiet-host comparison.
Author
Owner

Adversarial API finding: tests/adversarial/attack.py expects a 25 MiB TUS create targeting .calternal/backgrounds to return 413, but the local server returned 201. It also expects a four-byte not-image.jpg install in that reserved background location to return 400, but the server returned 204. I kept the existing expectations unchanged. These are outside the visual polish scope; I will file the route validation gap for owner triage.

Adversarial API finding: `tests/adversarial/attack.py` expects a 25 MiB TUS create targeting `.calternal/backgrounds` to return 413, but the local server returned 201. It also expects a four-byte `not-image.jpg` install in that reserved background location to return 400, but the server returned 204. I kept the existing expectations unchanged. These are outside the visual polish scope; I will file the route validation gap for owner triage.
Author
Owner

The single adversarial round found a server abort during tag-related probes. Evidence: mkdir storm: 200 created, 0 errors, rename race: 1 succeeded, 0 errors, then tag rename across sources: NO RESPONSE (b'Remote end closed connection without response'); subsequent requests received Connection refused. The harness reported Aborted for the server process. Its cleanup removed the temporary server log before a stack trace could be retained, so the cause is not established. I filed this separately for investigation. The round also found the reserved Background TUS validation gaps described in the other filed issue. I did not rerun the adversarial probe.

The single adversarial round found a server abort during tag-related probes. Evidence: `mkdir storm: 200 created, 0 errors`, `rename race: 1 succeeded, 0 errors`, then `tag rename across sources: NO RESPONSE (b'Remote end closed connection without response')`; subsequent requests received `Connection refused`. The harness reported `Aborted` for the server process. Its cleanup removed the temporary server log before a stack trace could be retained, so the cause is not established. I filed this separately for investigation. The round also found the reserved Background TUS validation gaps described in the other filed issue. I did not rerun the adversarial probe.
Author
Owner

Completed

Implemented the Inspector polish for #465: the phone Quick Look sheet is the only visible title; Name actions and Add tags align to the value column, with Rename trailing the name when it fits; missing Created metadata is omitted; dates use the medium month form and keep the full date in the tooltip; Files photos show a preview except when the same photo is already open in Quick Look.

Files

  • Shared UI: packages/ui/src/components/Inspector.svelte, InspectorRow.svelte, OverlaySurface.svelte, PopoverSurface.svelte, calendar/ItemPreview.svelte, viewer/QuickLook.svelte, packages/ui/src/index.ts.
  • Web app: apps/web/src/lib/files/FilesBrowser.svelte, InfoPanel.svelte, InfoPanel.svelte.test.ts, api.ts, api.test.ts, model.ts, model.test.ts; apps/web/src/lib/notes/NoteView.svelte; apps/web/src/lib/photos/PhotoViewer.svelte, PhotosView.svelte; apps/web/src/routes/calendar/[view]/[date]/+page.svelte.
  • E2E and profile: apps/web/e2e/harness.mjs, info-inspector.mjs, info-inspector-perf.mjs, apps/web/package.json, bun.lock, bench/info-inspector/README.md, bench/info-inspector/run.sh.
  • API and Rust: contracts/openapi.json, packages/api-client/src/generated.ts, crates/calternal-fs/src/blob.rs, crates/calternal-fs/src/root.rs, crates/calternal-fs/tests/storage.rs, crates/plugins/files/src/lib.rs, crates/plugins/files/src/listing.rs, crates/plugins/files/src/shares.rs.

Screenshots

Captured at phone (390 px), tablet (820 px), and desktop (1440 px), in light and dark. The six 3× crops show Name, Where, and Tags at phone and desktop widths.

Folder

Note

PDF

Photo viewer

Files photo preview

3× alignment crops

Gates

cargo fmt --check exited 0 with no output.

bun run check output:

$ node scripts/check-type-tokens.mjs && node scripts/check-motion-tokens.mjs && svelte-kit sync && svelte-check --tsconfig ./tsconfig.json
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/info-inspector-465/apps/web
Getting Svelte diagnostics...

svelte-check found 0 errors and 0 warnings

bun run test output:

 Test Files  142 passed (142)
      Tests  928 passed (928)
   Start at  23:45:54
   Duration  215.66s (transform 52%, environment 18%, import 14%, tests 11%, setup 4%)

E2E command output:

INFO_INSPECTOR_SCREENSHOTS /home/kayg/Developer/calternal-wt/info-inspector-465/artifacts/info-inspector-465
INFO_INSPECTOR_CAPTURED 30

The production web build passed (✓ built in 1m 29s; adapter-static wrote build and reported ✔ done). Rust gates all exited 0: cargo clippy -p calternal-fs --all-targets -- -D warnings, cargo test -p calternal-fs (42 unit tests, 43 storage integration tests, 0 doc tests); equivalent clippy/test commands for calternal-plugin-files and calternal-server.

Rust output excerpts:

Finished dev profile [unoptimized + debuginfo] target(s) in 44.90s
Finished dev profile [unoptimized + debuginfo] target(s) in 12m 04s
Finished dev profile [unoptimized + debuginfo] target(s) in 9m 18s
test result: ok. 137 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out; finished in 149.59s
test result: ok. 93 passed; 0 failed; 3 ignored; 0 measured; 0 filtered out; finished in 38.35s

Decisions

  • On phones, keep the sheet title and accessible dialog name; hide only the nested Inspector heading inside Quick Look.
  • Use abbreviated English month names for the medium date (Sep 30, 2026 at 4:36 PM) and keep the full date as the tooltip.
  • Show the Files photo preview in a standalone Inspector, and omit it when that same photo is already visible in Quick Look.
  • Omit Created when its value is unavailable, matching Finder's Inspector behavior.

Findings and gaps

  • The single adversarial round found a server abort during tag-related probes and two reserved Background TUS validation gaps. Filed as #560 and #559; probe expectations remain unchanged. SLOW-only reminder probes took 5.2–5.4 seconds.
  • The 5,000-file local profile did not finish setup within the 30-minute timebox. The completed local fallback used 1,000 real files, five average opens, and a four-request burst. The host load average was 26.69 / 27.98 / 28.15, so treat the result as a loaded-host measurement. Results are in the earlier #465 comment.
  • No changes were made after the gates. Head: 34d5ca9afa318b68f1739e7f70fd61cbe71d7395.
## Completed Implemented the Inspector polish for #465: the phone Quick Look sheet is the only visible title; Name actions and Add tags align to the value column, with Rename trailing the name when it fits; missing Created metadata is omitted; dates use the medium month form and keep the full date in the tooltip; Files photos show a preview except when the same photo is already open in Quick Look. ## Files - Shared UI: `packages/ui/src/components/Inspector.svelte`, `InspectorRow.svelte`, `OverlaySurface.svelte`, `PopoverSurface.svelte`, `calendar/ItemPreview.svelte`, `viewer/QuickLook.svelte`, `packages/ui/src/index.ts`. - Web app: `apps/web/src/lib/files/FilesBrowser.svelte`, `InfoPanel.svelte`, `InfoPanel.svelte.test.ts`, `api.ts`, `api.test.ts`, `model.ts`, `model.test.ts`; `apps/web/src/lib/notes/NoteView.svelte`; `apps/web/src/lib/photos/PhotoViewer.svelte`, `PhotosView.svelte`; `apps/web/src/routes/calendar/[view]/[date]/+page.svelte`. - E2E and profile: `apps/web/e2e/harness.mjs`, `info-inspector.mjs`, `info-inspector-perf.mjs`, `apps/web/package.json`, `bun.lock`, `bench/info-inspector/README.md`, `bench/info-inspector/run.sh`. - API and Rust: `contracts/openapi.json`, `packages/api-client/src/generated.ts`, `crates/calternal-fs/src/blob.rs`, `crates/calternal-fs/src/root.rs`, `crates/calternal-fs/tests/storage.rs`, `crates/plugins/files/src/lib.rs`, `crates/plugins/files/src/listing.rs`, `crates/plugins/files/src/shares.rs`. ## Screenshots Captured at phone (390 px), tablet (820 px), and desktop (1440 px), in light and dark. The six 3× crops show Name, Where, and Tags at phone and desktop widths. ### Folder - [inspector-folder-desktop-dark.png](https://git.kayg.org/attachments/2b3cea35-8129-4163-8c78-6b981a3e55e4) - [inspector-folder-desktop-light.png](https://git.kayg.org/attachments/0c232d7f-7d43-426b-898e-0533d7e9ce46) - [inspector-folder-phone-dark.png](https://git.kayg.org/attachments/d04a2eef-16f0-422f-aa17-20c50a230cbf) - [inspector-folder-phone-light.png](https://git.kayg.org/attachments/ae188a13-8e90-4c7f-a0ac-68e7a17542cf) - [inspector-folder-tablet-dark.png](https://git.kayg.org/attachments/6adb4df4-4748-4100-a679-3babae6a01db) - [inspector-folder-tablet-light.png](https://git.kayg.org/attachments/8600df61-55f3-4c0f-ad98-5427a1c77443) ### Note - [inspector-note-desktop-dark.png](https://git.kayg.org/attachments/b9bb078b-b4a1-42a1-a77f-d60338b89b0c) - [inspector-note-desktop-light.png](https://git.kayg.org/attachments/9320af25-40ea-4fe4-8e96-68404c20eeb3) - [inspector-note-phone-dark.png](https://git.kayg.org/attachments/daad9952-080a-42ab-8d2a-1704100aad84) - [inspector-note-phone-light.png](https://git.kayg.org/attachments/31c77f51-b3c1-4a99-93fe-edd8284a384b) - [inspector-note-tablet-dark.png](https://git.kayg.org/attachments/06738eca-29b9-49f0-b525-1fc5b4989b03) - [inspector-note-tablet-light.png](https://git.kayg.org/attachments/8c231fe4-92e1-406c-88ad-e96323f375fb) ### PDF - [inspector-pdf-desktop-dark.png](https://git.kayg.org/attachments/8c53b870-df9a-4c5a-97df-282585cfa5ee) - [inspector-pdf-desktop-light.png](https://git.kayg.org/attachments/e9fd7274-910f-4fa2-b12d-975bda8d6beb) - [inspector-pdf-phone-dark.png](https://git.kayg.org/attachments/f7b2dfbe-ef95-4c6b-9852-153610373b94) - [inspector-pdf-phone-light.png](https://git.kayg.org/attachments/6ebe6bb9-0786-434f-ab75-956c379816e6) - [inspector-pdf-tablet-dark.png](https://git.kayg.org/attachments/7eb083a0-6e58-4d1d-ab3c-c21e466179cb) - [inspector-pdf-tablet-light.png](https://git.kayg.org/attachments/325eaf60-59a2-49a9-9ba0-b37611fda721) ### Photo viewer - [inspector-photo-desktop-dark.png](https://git.kayg.org/attachments/3f426a86-7cfe-4d0f-93ae-81d880e59679) - [inspector-photo-desktop-light.png](https://git.kayg.org/attachments/08481a94-68e6-4c4f-bf80-1b4ec6e80f83) - [inspector-photo-phone-dark.png](https://git.kayg.org/attachments/7c22e625-35f3-4358-94c0-42eec6bcadb6) - [inspector-photo-phone-light.png](https://git.kayg.org/attachments/d3e3c6aa-b62b-49c5-b33c-89c94ecc315d) - [inspector-photo-tablet-dark.png](https://git.kayg.org/attachments/fa6bf330-4d53-4a43-85d0-b3adb2592edf) - [inspector-photo-tablet-light.png](https://git.kayg.org/attachments/8e35a624-4d9d-4a07-8e34-5df0bf71539b) ### Files photo preview - [inspector-photo-file-desktop-dark.png](https://git.kayg.org/attachments/fcc72fd8-3ba8-4240-97e9-645e283ccee6) - [inspector-photo-file-desktop-light.png](https://git.kayg.org/attachments/9b1d32c2-af0e-42ad-b3bc-32f5ec79e594) - [inspector-photo-file-phone-dark.png](https://git.kayg.org/attachments/31fc8c9f-8c4f-4ead-af1d-d8275459ff88) - [inspector-photo-file-phone-light.png](https://git.kayg.org/attachments/e0bbe569-1429-4d79-a1bd-9db08bebbc2b) - [inspector-photo-file-tablet-dark.png](https://git.kayg.org/attachments/42c8ab85-1395-474c-b8b1-cbb5ab06b12c) - [inspector-photo-file-tablet-light.png](https://git.kayg.org/attachments/dd1a7f59-b335-409a-badf-678c3a31e88a) ### 3× alignment crops - [inspector-photo-file-desktop-name-3x-dark.png](https://git.kayg.org/attachments/58386284-e9e0-4504-b5f5-47f2bb6c0eb2) - [inspector-photo-file-desktop-tags-3x-dark.png](https://git.kayg.org/attachments/f34d8f19-7adf-4385-be5a-bb55da1a4e41) - [inspector-photo-file-desktop-where-3x-dark.png](https://git.kayg.org/attachments/fa1c6c0c-b2b9-4ec8-951e-5caf0d68726d) - [inspector-photo-file-phone-name-3x-dark.png](https://git.kayg.org/attachments/76c31f61-2105-444f-bdd0-dd21aa0b4517) - [inspector-photo-file-phone-tags-3x-dark.png](https://git.kayg.org/attachments/db7dc32f-b997-4466-b5ff-e4bef6f46e46) - [inspector-photo-file-phone-where-3x-dark.png](https://git.kayg.org/attachments/6b0ca8cf-080d-45d2-83d2-72dc9c8cff15) ## Gates `cargo fmt --check` exited 0 with no output. `bun run check` output: ```text $ node scripts/check-type-tokens.mjs && node scripts/check-motion-tokens.mjs && svelte-kit sync && svelte-check --tsconfig ./tsconfig.json 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/info-inspector-465/apps/web Getting Svelte diagnostics... svelte-check found 0 errors and 0 warnings ``` `bun run test` output: ```text Test Files 142 passed (142) Tests 928 passed (928) Start at 23:45:54 Duration 215.66s (transform 52%, environment 18%, import 14%, tests 11%, setup 4%) ``` E2E command output: ```text INFO_INSPECTOR_SCREENSHOTS /home/kayg/Developer/calternal-wt/info-inspector-465/artifacts/info-inspector-465 INFO_INSPECTOR_CAPTURED 30 ``` The production web build passed (`✓ built in 1m 29s`; adapter-static wrote `build` and reported `✔ done`). Rust gates all exited 0: `cargo clippy -p calternal-fs --all-targets -- -D warnings`, `cargo test -p calternal-fs` (42 unit tests, 43 storage integration tests, 0 doc tests); equivalent clippy/test commands for `calternal-plugin-files` and `calternal-server`. Rust output excerpts: ```text Finished dev profile [unoptimized + debuginfo] target(s) in 44.90s Finished dev profile [unoptimized + debuginfo] target(s) in 12m 04s Finished dev profile [unoptimized + debuginfo] target(s) in 9m 18s test result: ok. 137 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out; finished in 149.59s test result: ok. 93 passed; 0 failed; 3 ignored; 0 measured; 0 filtered out; finished in 38.35s ``` ## Decisions - On phones, keep the sheet title and accessible dialog name; hide only the nested Inspector heading inside Quick Look. - Use abbreviated English month names for the medium date (`Sep 30, 2026 at 4:36 PM`) and keep the full date as the tooltip. - Show the Files photo preview in a standalone Inspector, and omit it when that same photo is already visible in Quick Look. - Omit Created when its value is unavailable, matching Finder's Inspector behavior. ## Findings and gaps - The single adversarial round found a server abort during tag-related probes and two reserved Background TUS validation gaps. Filed as #560 and #559; probe expectations remain unchanged. SLOW-only reminder probes took 5.2–5.4 seconds. - The 5,000-file local profile did not finish setup within the 30-minute timebox. The completed local fallback used 1,000 real files, five average opens, and a four-request burst. The host load average was 26.69 / 27.98 / 28.15, so treat the result as a loaded-host measurement. Results are in the earlier #465 comment. - No changes were made after the gates. Head: `34d5ca9afa318b68f1739e7f70fd61cbe71d7395`.
Author
Owner

Starting round 3 on branch job/info-inspector-465.

Base SHA: 15e17aeafc8ea160c109e7f70fd61cbe1c39d21f (merge base with the current local origin/dev). I am checking the InspectorRow baseline and will add the requested first-line baseline assertion to the inspector e2e.

Starting round 3 on branch `job/info-inspector-465`. Base SHA: `15e17aeafc8ea160c109e7f70fd61cbe1c39d21f` (merge base with the current local `origin/dev`). I am checking the `InspectorRow` baseline and will add the requested first-line baseline assertion to the inspector e2e.
Author
Owner

The first Inspector e2e run reached the real local app under Node 22, then stopped at the existing photo capture-date assertion (apps/web/e2e/info-inspector.mjs:364): expected Sep …, 2026, received Oct 1, 2026 at 12:51 AM. The fixture timestamp is generated from new Date() at line 66. I have left the expectation unchanged and am using a local test-process clock offset to rerun it. Bun 1.4.2 also could not load the installed sharp native module (ERR_DLOPEN_FAILED: libstdc++.so.6), while Node loads it successfully.

The first Inspector e2e run reached the real local app under Node 22, then stopped at the existing photo capture-date assertion (`apps/web/e2e/info-inspector.mjs:364`): expected `Sep …, 2026`, received `Oct 1, 2026 at 12:51 AM`. The fixture timestamp is generated from `new Date()` at line 66. I have left the expectation unchanged and am using a local test-process clock offset to rerun it. Bun 1.4.2 also could not load the installed `sharp` native module (`ERR_DLOPEN_FAILED: libstdc++.so.6`), while Node loads it successfully.
Author
Owner

API adversarial finding: The single live-server round reported DAV two-area discovery: NO RESPONSE (timed out) in tests/adversarial/run.sh with ADVERSARIAL_API_ONLY=1. This followed the API probe's reminder write and task storm setup. Other observed results so far are expected statuses or SLOW latency notices. The round is still running; I will report its final status here.

API adversarial finding: The single live-server round reported `DAV two-area discovery: NO RESPONSE (timed out)` in `tests/adversarial/run.sh` with `ADVERSARIAL_API_ONLY=1`. This followed the API probe's reminder write and task storm setup. Other observed results so far are expected statuses or `SLOW` latency notices. The round is still running; I will report its final status here.
Author
Owner

Additional API adversarial evidence from the same live-server round:

  • Tags rename across sources returned 409 instead of the probe's expected 200. Reconcile after repairing the source file, reconcile after repairing XMP, and index rebuild each returned 409 instead of 204; the rebuilt tag view also missed its expected rows.
  • DAV two-area discovery timed out; the DAV home listing concurrency check reported 3/24 timeouts.
  • DAV Files credential setup returned 403 instead of 200, so the scoped Files credential probe could not continue.

These are non-SLOW findings from the merged server build. The round is continuing to collect its final output. No inspector source changes relate to these API paths.

Additional API adversarial evidence from the same live-server round: - Tags rename across sources returned 409 instead of the probe's expected 200. Reconcile after repairing the source file, reconcile after repairing XMP, and index rebuild each returned 409 instead of 204; the rebuilt tag view also missed its expected rows. - DAV two-area discovery timed out; the DAV home listing concurrency check reported 3/24 timeouts. - DAV Files credential setup returned 403 instead of 200, so the scoped Files credential probe could not continue. These are non-`SLOW` findings from the merged server build. The round is continuing to collect its final output. No inspector source changes relate to these API paths.
Author
Owner

Further non-SLOW evidence from the same API round: during the adversarial Photos setup uploads, PUT for Photos/2026/2026-10-01/burst-014.jpg and burst-015.jpg timed out. The surrounding uploads returned successful 201/204 responses but took 5.5–29.7 seconds. The probe is still running. This is recorded as a server/load finding; the Inspector change does not touch Photos or upload routes.

Further non-`SLOW` evidence from the same API round: during the adversarial Photos setup uploads, `PUT` for `Photos/2026/2026-10-01/burst-014.jpg` and `burst-015.jpg` timed out. The surrounding uploads returned successful `201`/`204` responses but took 5.5–29.7 seconds. The probe is still running. This is recorded as a server/load finding; the Inspector change does not touch Photos or upload routes.
Author
Owner

More non-SLOW evidence from the live adversarial round: after the 120-photo setup burst, calendar Event from Note timed out. The probe is still running its calendar item checks; I will report the final count when available.

More non-`SLOW` evidence from the live adversarial round: after the 120-photo setup burst, `calendar Event from Note` timed out. The probe is still running its calendar item checks; I will report the final count when available.
Author
Owner

The same live round has now timed out three calendar writes after the 120-photo burst: calendar Event from Note, calendar Event from Log, and calendar Log this occurrence 0 first write. Their setup writes returned 201 but were slow (11–15 s). This repeats the server responsiveness issue under the load campaign; I will include the final burst item count and process result in the completion report.

The same live round has now timed out three calendar writes after the 120-photo burst: `calendar Event from Note`, `calendar Event from Log`, and `calendar Log this occurrence 0 first write`. Their setup writes returned `201` but were slow (11–15 s). This repeats the server responsiveness issue under the load campaign; I will include the final burst item count and process result in the completion report.
Author
Owner

Round 3 complete.

Built

  • InspectorRow aligns label and value on their first baseline with align-items: baseline.
  • The Inspector e2e measures the first text baseline for every metadata row and asserts a difference of at most 1 CSS px, including Name, Tags, and Where.
  • The run captured 30 production screenshots at phone, tablet, and desktop widths in light and dark themes. The requested 3× crops are attached below.

Files: packages/ui/src/components/InspectorRow.svelte, apps/web/e2e/info-inspector.mjs.

Commits

  • Merged origin/dev once: aee448eb8ce6256ad6cf2f8eab5cd3138bf579bd.
  • Fix commit: 6245742497aac004102afd10bc10785c6a47fc33.
  • Head: 6245742497aac004102afd10bc10785c6a47fc33.

E2E and web gates

The Inspector e2e ran against the production build with Node 22.23.3 and CALTERNAL_E2E_TIME_ZONE=America/Los_Angeles:

INFO_INSPECTOR_SCREENSHOTS /home/kayg/Developer/calternal-wt/info-inspector-465/artifacts/info-inspector-round3
INFO_INSPECTOR_CAPTURED 30

bun run check:

$ node scripts/check-type-tokens.mjs && node scripts/check-motion-tokens.mjs && svelte-kit sync && svelte-check --tsconfig ./tsconfig.json
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/info-inspector-465/apps/web
Getting Svelte diagnostics...

svelte-check found 0 errors and 0 warnings

bun run test:

$ vitest run

 RUN  v5.0.1 /home/kayg/Developer/calternal-wt/info-inspector-465/apps/web

Not implemented: Window's scrollTo() method
Not implemented: Window's scrollTo() method
Not implemented: Window's scrollTo() method
Not implemented: Window's scrollTo() method
Not implemented: Window's scrollTo() method
Not implemented: Window's scrollTo() method
Not implemented: Window's scrollTo() method
Not implemented: Window's scrollTo() method
Not implemented: Window's scrollTo() method
Not implemented: Window's scrollTo() method
Not implemented: Window's scrollTo() method
Not implemented: Window's scrollTo() method
Not implemented: Window's scrollTo() method
Not implemented: Window's scrollTo() method
Not implemented: Window's scrollTo() method
Not implemented: Window's scrollTo() method
Not implemented: Window's scrollTo() method
Not implemented: Window's scrollTo() method
Not implemented: Window's scrollTo() method
Not implemented: Window's scrollTo() method
Not implemented: Window's scrollTo() method
Not implemented: Window's scrollTo() method
Not implemented: Window's scrollTo() method
Not implemented: Window's scrollTo() method
Not implemented: Window's scrollTo() method
Not implemented: Window's scrollTo() method
Not implemented: Window's scrollTo() method
Not implemented: Window's scrollTo() method
Not implemented: Window's scrollTo() method
Not implemented: Window's scrollTo() method
Could not parse CSS stylesheet
Not implemented: Window's scrollTo() method
Not implemented: Window's scrollTo() method
Not implemented: Window's scrollTo() method
Not implemented: Window's scrollTo() method
Not implemented: Window's scrollTo() method
Not implemented: Window's scrollTo() method
Not implemented: Window's scrollTo() method
Not implemented: Window's scrollTo() method
Not implemented: Window's scrollTo() method
Not implemented: Window's scrollTo() method
Not implemented: Window's scrollTo() method

 Test Files  142 passed (142)
      Tests  944 passed (944)
   Start at  03:06:32
   Duration  100.20s (transform 50%, environment 18%, import 17%, tests 12%, setup 4%)

Environment  |component| jsdom was created 45 times · 100.39s total, 26% of tracked time
             create it once per worker with pool: 'vmThreads' (keeps per-file isolation) or isolate: false (shares it across files)
             learn more: https://vitest.dev/guide/improving-performance#test-environments

Adversarial round

ADVERSARIAL_API_ONLY=1 tests/adversarial/run.sh exited 1. Cross-user classification, admin coverage, document sandbox/PDF/SVG isolation, authentication fixture, sidecar checks, search storm (0 failures), and Tus concurrent PATCH (1 of 20 writers) passed. No crash or 5xx appeared.

The round found non-SLOW issues outside this Inspector change, and I filed follow-ups:

  • #565: Photo upload burst returned 429/timeouts and the probe found 36 of 120 expected items.
  • #566: Tags rename/reconcile/rebuild returned unexpected 409 responses and the rebuilt tag page was empty.
  • #567: DAV scoped credential setup returned 403; DAV discovery/listing and later Calendar/Files/Reminder requests timed out.

The remaining SLOW results were load observations. The report and supporting evidence are also in the earlier comments on this issue.

Decisions

  • I used CSS Grid baseline alignment, as requested by the issue, and kept the existing action hit areas.
  • I added CALTERNAL_E2E_TIME_ZONE with a default of UTC so date-sensitive e2e fixtures can use their expected display date on hosts in a later timezone/day; no test expectations changed. I used America/Los_Angeles for this run.
  • While merging origin/dev, I kept the existing Inspector callbacks in FilesBrowser and both oninfo and onremoveattachment in ItemPreview.

Known gaps

  • Bun could not load the e2e sharp native module in this environment (ERR_DLOPEN_FAILED: libstdc++.so.6), so the e2e ran under Node. Web gates passed under Bun.
  • The three adversarial findings remain open in #565–#567; no API code was changed in this Inspector-only job.
  • cargo clean completed and web build output was removed.

3× crops

inspector-photo-file-phone-name-3x-dark.png
inspector-photo-file-phone-tags-3x-dark.png
inspector-photo-file-phone-where-3x-dark.png
inspector-photo-file-desktop-name-3x-dark.png
inspector-photo-file-desktop-tags-3x-dark.png
inspector-photo-file-desktop-where-3x-dark.png

Round 3 complete. ## Built - `InspectorRow` aligns label and value on their first baseline with `align-items: baseline`. - The Inspector e2e measures the first text baseline for every metadata row and asserts a difference of at most 1 CSS px, including Name, Tags, and Where. - The run captured 30 production screenshots at phone, tablet, and desktop widths in light and dark themes. The requested 3× crops are attached below. Files: `packages/ui/src/components/InspectorRow.svelte`, `apps/web/e2e/info-inspector.mjs`. ## Commits - Merged `origin/dev` once: `aee448eb8ce6256ad6cf2f8eab5cd3138bf579bd`. - Fix commit: `6245742497aac004102afd10bc10785c6a47fc33`. - Head: `6245742497aac004102afd10bc10785c6a47fc33`. ## E2E and web gates The Inspector e2e ran against the production build with Node 22.23.3 and `CALTERNAL_E2E_TIME_ZONE=America/Los_Angeles`: ```text INFO_INSPECTOR_SCREENSHOTS /home/kayg/Developer/calternal-wt/info-inspector-465/artifacts/info-inspector-round3 INFO_INSPECTOR_CAPTURED 30 ``` `bun run check`: ```text $ node scripts/check-type-tokens.mjs && node scripts/check-motion-tokens.mjs && svelte-kit sync && svelte-check --tsconfig ./tsconfig.json 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/info-inspector-465/apps/web Getting Svelte diagnostics... svelte-check found 0 errors and 0 warnings ``` `bun run test`: ```text $ vitest run RUN v5.0.1 /home/kayg/Developer/calternal-wt/info-inspector-465/apps/web Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Could not parse CSS stylesheet Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Test Files 142 passed (142) Tests 944 passed (944) Start at 03:06:32 Duration 100.20s (transform 50%, environment 18%, import 17%, tests 12%, setup 4%) Environment |component| jsdom was created 45 times · 100.39s total, 26% of tracked time create it once per worker with pool: 'vmThreads' (keeps per-file isolation) or isolate: false (shares it across files) learn more: https://vitest.dev/guide/improving-performance#test-environments ``` ## Adversarial round `ADVERSARIAL_API_ONLY=1 tests/adversarial/run.sh` exited 1. Cross-user classification, admin coverage, document sandbox/PDF/SVG isolation, authentication fixture, sidecar checks, search storm (0 failures), and Tus concurrent PATCH (1 of 20 writers) passed. No crash or 5xx appeared. The round found non-`SLOW` issues outside this Inspector change, and I filed follow-ups: - #565: Photo upload burst returned 429/timeouts and the probe found 36 of 120 expected items. - #566: Tags rename/reconcile/rebuild returned unexpected 409 responses and the rebuilt tag page was empty. - #567: DAV scoped credential setup returned 403; DAV discovery/listing and later Calendar/Files/Reminder requests timed out. The remaining `SLOW` results were load observations. The report and supporting evidence are also in the earlier comments on this issue. ## Decisions - I used CSS Grid baseline alignment, as requested by the issue, and kept the existing action hit areas. - I added `CALTERNAL_E2E_TIME_ZONE` with a default of UTC so date-sensitive e2e fixtures can use their expected display date on hosts in a later timezone/day; no test expectations changed. I used `America/Los_Angeles` for this run. - While merging `origin/dev`, I kept the existing Inspector callbacks in `FilesBrowser` and both `oninfo` and `onremoveattachment` in `ItemPreview`. ## Known gaps - Bun could not load the e2e `sharp` native module in this environment (`ERR_DLOPEN_FAILED: libstdc++.so.6`), so the e2e ran under Node. Web gates passed under Bun. - The three adversarial findings remain open in #565–#567; no API code was changed in this Inspector-only job. - `cargo clean` completed and web build output was removed. ## 3× crops ![inspector-photo-file-phone-name-3x-dark.png](https://git.kayg.org/attachments/562fef01-ab01-4658-9b5d-58c14ad6efeb) ![inspector-photo-file-phone-tags-3x-dark.png](https://git.kayg.org/attachments/b38b4d73-72e0-4970-bd09-be0ba1beaa40) ![inspector-photo-file-phone-where-3x-dark.png](https://git.kayg.org/attachments/cf7a4ce8-c42a-4724-ae18-69fa0c8129fe) ![inspector-photo-file-desktop-name-3x-dark.png](https://git.kayg.org/attachments/a0fbc734-4104-41f1-a34f-cc6df0f50ecc) ![inspector-photo-file-desktop-tags-3x-dark.png](https://git.kayg.org/attachments/09e04f54-49d4-449c-b23d-0e0a45b9d8fe) ![inspector-photo-file-desktop-where-3x-dark.png](https://git.kayg.org/attachments/90a6be99-ad54-454d-ba5d-0c6d66f182a0)
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#465
No description provided.