Tags: clicking a tag filters the current view (chip, ⌘-click AND, deep-linkable) #1109

Open
opened 2026-10-05 07:36:49 +00:00 by kayg · 49 comments
Owner

Owner decisions (2026-10-05 grill)

Clicking a tag in the sidebar filters the current view (Calendar Day/Week/Month/Year/Agenda, Tasks, Notes, Files, Photos, Mail) instead of switching to the Tags page. The active filter shows as a removable chip in the header; × or Escape clears it. A plain click replaces the filter; ⌘/Ctrl-click adds a tag with AND (items with all selected tags). The filter is part of the URL (deep link, survives reload, Copy link includes it; DESIGN §33). The Tags page stays for browsing a tag across everything, showing item titles, never file names or paths (today it shows "20260922-dailynote.md" and "Notes/…").

## Owner decisions (2026-10-05 grill) Clicking a tag in the sidebar **filters the current view** (Calendar Day/Week/Month/Year/Agenda, Tasks, Notes, Files, Photos, Mail) instead of switching to the Tags page. The active filter shows as a removable chip in the header; × or Escape clears it. A plain click replaces the filter; ⌘/Ctrl-click adds a tag with AND (items with all selected tags). The filter is part of the URL (deep link, survives reload, Copy link includes it; DESIGN §33). The Tags page stays for browsing a tag across everything, showing item titles, never file names or paths (today it shows "20260922-dailynote.md" and "Notes/…").
Author
Owner

Starting #1109 on branch job/tagfilter-1109, based on dev at 27644444a91dad244073113b0ec8ec7a61f2a212. I’m tracing the shared Tag controls and each Tab’s item projection, then I’ll implement the URL-backed AND filter, shared header chip, and title-only Tag browsing results. No Rust/API change is currently expected.

Starting #1109 on branch `job/tagfilter-1109`, based on dev at `27644444a91dad244073113b0ec8ec7a61f2a212`. I’m tracing the shared Tag controls and each Tab’s item projection, then I’ll implement the URL-backed AND filter, shared header chip, and title-only Tag browsing results. No Rust/API change is currently expected.
Author
Owner

Finding: the Notes list API paginates NoteSummary rows without Tag values, while Files and Photos store Tags in the shared Index and expose a bounded file-assignment read. Filtering the current page from loaded fields would miss matches or make per-item requests. I’m adding repeatable Tag filters to the Notes list query and an exact-path batch lookup to the existing Tags assignment route; both will apply filters before pagination or in bounded batches.

Finding: the Notes list API paginates `NoteSummary` rows without Tag values, while Files and Photos store Tags in the shared Index and expose a bounded file-assignment read. Filtering the current page from loaded fields would miss matches or make per-item requests. I’m adding repeatable Tag filters to the Notes list query and an exact-path batch lookup to the existing Tags assignment route; both will apply filters before pagination or in bounded batches.
Author
Owner

Finding: the incoming Shared Notes list used /api/v1/files/shared-notes without a tag query, while owned Notes used the Notes list endpoint. An active header filter could therefore leave unrelated shared Notes visible. I added bounded repeated-tag AND filtering, nested-tag matching before pagination, and a route regression case for a two-tag match and malformed input.

Finding: the incoming Shared Notes list used `/api/v1/files/shared-notes` without a `tag` query, while owned Notes used the Notes list endpoint. An active header filter could therefore leave unrelated shared Notes visible. I added bounded repeated-tag AND filtering, nested-tag matching before pagination, and a route regression case for a two-tag match and malformed input.
Author
Owner

Resumed #1109 on job/tagfilter-1109 after the host-load pause. I fast-forwarded from the fetched origin/dev base 27644444a to 929a2627f; the paused changes are restored. I resolved the Calendar page conflict by keeping the new preview close action and routing Tag clicks into the current-view filter. I’m continuing with the focused web, Rust, production-build screenshot and E2E checks.

Resumed #1109 on `job/tagfilter-1109` after the host-load pause. I fast-forwarded from the fetched `origin/dev` base `27644444a` to `929a2627f`; the paused changes are restored. I resolved the Calendar page conflict by keeping the new preview close action and routing Tag clicks into the current-view filter. I’m continuing with the focused web, Rust, production-build screenshot and E2E checks.
Author
Owner

#1109 update: the Tags API now supports owner-scoped assignment batches for up to 500 exact Home-relative file paths. RelPath rejects invalid entries, and the SQL uses bound path values. calternal-tags clippy and tests passed before commit 4b443b1cd; the Files plugin clippy gate has also passed. I am running its focused tests now.

#1109 update: the Tags API now supports owner-scoped assignment batches for up to 500 exact Home-relative file paths. `RelPath` rejects invalid entries, and the SQL uses bound path values. `calternal-tags` clippy and tests passed before commit `4b443b1cd`; the Files plugin clippy gate has also passed. I am running its focused tests now.
Author
Owner

#1109 gate finding: calternal-plugin-files clippy passed. The crate suite reported 249 passed, 2 failed, and 4 ignored. public_password_rejection_does_not_wait_for_data_mutation_lock timed out at its existing 2-second bound; the shared-grant test failed while decoding a response as JSON. I am tracing the latter because it covers the new shared Notes Tag filter. The suite also marked two >60-second tests as slow under current host load.

#1109 gate finding: `calternal-plugin-files` clippy passed. The crate suite reported 249 passed, 2 failed, and 4 ignored. `public_password_rejection_does_not_wait_for_data_mutation_lock` timed out at its existing 2-second bound; the shared-grant test failed while decoding a response as JSON. I am tracing the latter because it covers the new shared Notes Tag filter. The suite also marked two >60-second tests as slow under current host load.
Author
Owner

#1109 finding and fix: the initial repeated Tag route test showed Axum's derived Query<Vec<String>> rejected tag=area/work&tag=task/home with HTTP 400 (expected a sequence). I added a shared URL-pair decoder that retains repeated keys and switched the Tags, Notes, Photos and Shared Notes handlers to collect their repeated values before validation. Tags now has a regression test for repeated path values and passes: 19 passed; 0 failed; 0 ignored.

#1109 finding and fix: the initial repeated Tag route test showed Axum's derived `Query<Vec<String>>` rejected `tag=area/work&tag=task/home` with HTTP 400 (`expected a sequence`). I added a shared URL-pair decoder that retains repeated keys and switched the Tags, Notes, Photos and Shared Notes handlers to collect their repeated values before validation. Tags now has a regression test for repeated path values and passes: `19 passed; 0 failed; 0 ignored`.
Author
Owner

#1109 Files gate result: after the repeated-key fix, shared_notes_follow_recursive_grants_and_revoke passed in the full Files suite. cargo clippy -p calternal-plugin-files --all-targets -- -D warnings passed. cargo test -p calternal-plugin-files completed with 250 passed, 1 failed, 4 ignored; the only failure was the existing public_password_rejection_does_not_wait_for_data_mutation_lock two-second timeout (Elapsed(())). It timed out in both full-suite runs. At the second run's end, /proc/loadavg was 16.88 20.30 27.65 15/1079 1278976; the other >60-second filesystem tests passed. I am recording this as a load-sensitive gate gap and will not loop the suite again.

#1109 Files gate result: after the repeated-key fix, `shared_notes_follow_recursive_grants_and_revoke` passed in the full Files suite. `cargo clippy -p calternal-plugin-files --all-targets -- -D warnings` passed. `cargo test -p calternal-plugin-files` completed with 250 passed, 1 failed, 4 ignored; the only failure was the existing `public_password_rejection_does_not_wait_for_data_mutation_lock` two-second timeout (`Elapsed(())`). It timed out in both full-suite runs. At the second run's end, `/proc/loadavg` was `16.88 20.30 27.65 15/1079 1278976`; the other >60-second filesystem tests passed. I am recording this as a load-sensitive gate gap and will not loop the suite again.
Author
Owner

#1109 gate update: Notes and Photos now parse repeated query keys through the shared decoder. The Notes pagination regression test passes with its original expectation unchanged; its Tag fixtures now follow the existing one-row check. The 700-Note reconciliation case passed after limiting this run to four test threads.

  • cargo clippy -p calternal-plugin-notes --all-targets -- -D warnings: passed.
  • cargo test -p calternal-plugin-notes -- --test-threads=4: 284 passed, 0 failed, 2 ignored; apple_replay.rs: 2 passed, 0 failed; doc-tests: 0 passed, 0 failed.
  • cargo clippy -p calternal-plugin-photos --all-targets -- -D warnings: passed.
  • cargo test -p calternal-plugin-photos -- --test-threads=4: 54 passed, 0 failed, 3 ignored; doc-tests: 0 passed, 0 failed.
#1109 gate update: Notes and Photos now parse repeated query keys through the shared decoder. The Notes pagination regression test passes with its original expectation unchanged; its Tag fixtures now follow the existing one-row check. The 700-Note reconciliation case passed after limiting this run to four test threads. - `cargo clippy -p calternal-plugin-notes --all-targets -- -D warnings`: passed. - `cargo test -p calternal-plugin-notes -- --test-threads=4`: 284 passed, 0 failed, 2 ignored; `apple_replay.rs`: 2 passed, 0 failed; doc-tests: 0 passed, 0 failed. - `cargo clippy -p calternal-plugin-photos --all-targets -- -D warnings`: passed. - `cargo test -p calternal-plugin-photos -- --test-threads=4`: 54 passed, 0 failed, 3 ignored; doc-tests: 0 passed, 0 failed.
Author
Owner

#1109 check finding: bun run check stops in scripts/perf-lint --check before Svelte validation. Its exception ledger is already over its ratchet on origin/dev: worktree and origin/dev both have 21,977 ledger entries against 21,964, with the same 13 one-entry rule overages. This is not introduced by #1109. I will keep the perf ratchet unchanged and run the remaining check steps directly.

#1109 check finding: `bun run check` stops in `scripts/perf-lint --check` before Svelte validation. Its exception ledger is already over its ratchet on `origin/dev`: worktree and `origin/dev` both have 21,977 ledger entries against 21,964, with the same 13 one-entry rule overages. This is not introduced by #1109. I will keep the perf ratchet unchanged and run the remaining check steps directly.
Author
Owner

Web type-check follow-up: the production API client was missing the repeated paths query from the generated OpenAPI schema. Direct svelte-check also found a PageChrome handler return-type mismatch and a stale ItemPreview.onhide prop. I regenerated contracts/openapi.json and packages/api-client/src/generated.ts from the Rust route declaration, made the handler await its Promise<void> actions, and removed the unsupported prop. The affected UI and generated contract now compile; I am rerunning the final checker after the filter-state warning cleanup.

Web type-check follow-up: the production API client was missing the repeated `paths` query from the generated OpenAPI schema. Direct `svelte-check` also found a PageChrome handler return-type mismatch and a stale `ItemPreview.onhide` prop. I regenerated `contracts/openapi.json` and `packages/api-client/src/generated.ts` from the Rust route declaration, made the handler await its `Promise<void>` actions, and removed the unsupported prop. The affected UI and generated contract now compile; I am rerunning the final checker after the filter-state warning cleanup.
Author
Owner

OpenAPI generation exposed one contract mismatch: tag was marked required on the Notes and shared Notes list queries even though the server accepts an omitted filter. The Photos and exact-path Tags parameters were already optional. I added required = false to both query declarations and am rerunning the Rust gates before regenerating the client schema.

OpenAPI generation exposed one contract mismatch: `tag` was marked required on the Notes and shared Notes list queries even though the server accepts an omitted filter. The Photos and exact-path Tags parameters were already optional. I added `required = false` to both query declarations and am rerunning the Rust gates before regenerating the client schema.
Author
Owner

Production e2e finding: the first Photos assertion queried the timeline immediately after Tus completion, before the asynchronous index published the upload. I added bounded polling, but used Playwright waitForFunction with an async callback, which treats the returned Promise as truthy; the second run reached the assertion before the tile appeared. I switched to the harness's awaited poll helper. I’m rerunning the complete route and screenshot matrix now.

Production e2e finding: the first Photos assertion queried the timeline immediately after Tus completion, before the asynchronous index published the upload. I added bounded polling, but used Playwright `waitForFunction` with an async callback, which treats the returned Promise as truthy; the second run reached the assertion before the tile appeared. I switched to the harness's awaited `poll` helper. I’m rerunning the complete route and screenshot matrix now.
Author
Owner

Production e2e found a product gap on /tag/area/work: the real Tag API returned the Note title, but the Task row had no indexed title and the page fell back to the generic word “Task”. calternal-tags::items_page currently reads titles only from note_items. I’m adding a bounded batch read of canonical Task titles from the Notes-owned task_items projection, with a regression test, while keeping source paths out of the displayed row.

Production e2e found a product gap on `/tag/area/work`: the real Tag API returned the Note title, but the Task row had no indexed title and the page fell back to the generic word “Task”. `calternal-tags::items_page` currently reads titles only from `note_items`. I’m adding a bounded batch read of canonical Task titles from the Notes-owned `task_items` projection, with a regression test, while keeping source paths out of the displayed row.
Author
Owner

#1109 final report

Branch: job/tagfilter-1109
Head: 6568120fb588876d74fc16c343bb16ba254c28b1

Built

  • Sidebar Tag clicks filter the current Calendar, Tasks, Notes, Files, Photos, or Mail view. The filter stays in repeated tag= URL values, matches with AND semantics, restores on reload, and is preserved by Copy link. A plain click replaces the filter; Command/Ctrl-click adds one; chips can be removed and Escape clears them.
  • The Tags page reads real item titles. Task titles come from the Notes-owned task_items projection in a bounded batch. Rows use the item kind when no title exists and never expose source paths or filenames.
  • Notes and Shared Notes filter before pagination. Files and Photos use bounded exact-path Tag reads. Mail filtering uses user labels and ignores system flags.
  • Added bench/tag-filter-1109.mjs. The profile was not run because this is not a performance issue and the verification policy restricts measurements to performance issues.

Screenshot evidence

All 66 PNG captures are attached to this issue: 11 routes × 3 widths (390, 820, 1440) × 2 themes (paper, tokyo-night), with macOS platform emulation. Filenames follow {route}-{width}-{theme}-mac.png. The final e2e run printed:

PASS #1109 current-view Tag filters; macOS production captures: /home/kayg/Developer/calternal-wt/tagfilter-1109/artifacts/tagfilter-1109

Forgejo's issue asset list confirmed 66 unique attachments. One concurrent upload returned HTTP 500 after the server stored its file; the list confirmed no missing capture.

Commits

  • 4b443b1cd Add exact-path Tags lookup for current-view filters
  • a25bdbd3c Parse repeated exact paths in Tags API
  • 49de75706 Filter shared Notes by repeated Tag keys
  • d7f75df93 Filter Notes by repeated Tag query values
  • 6c5256df5 Parse repeated Photo Tag query values
  • a7c83fc61 Document optional repeated Tag filters in OpenAPI
  • 65c77014f Add shared Tag filter navigation and chips
  • d03f67959 Apply Tag filters across app views
  • 959c81646 Add Tag filter end-to-end coverage and profile
  • 000cc4103 Wait for Photos indexing in Tag filter e2e
  • 08397df49 Include Task titles on Tag pages
  • 6568120fb Wait for responsive Tag sidebar in e2e

Gates

  • cargo fmt --check: exit 0; no output.
  • Clippy passed for calternal-plugin, calternal-plugin-files, calternal-plugin-notes, calternal-plugin-photos, calternal-server, and calternal-tags with -D warnings.
  • cargo test -p calternal-plugin:
test result: ok. 44 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 9.41s
  • cargo test -p calternal-tags:
test result: ok. 20 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 3.51s
  • cargo test -p calternal-plugin-notes -- --test-threads=4:
test result: ok. 284 passed; 0 failed; 2 ignored; 0 measured; 0 filtered out; finished in 292.17s
test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.42s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
  • cargo test -p calternal-plugin-photos -- --test-threads=4:
test result: ok. 54 passed; 0 failed; 3 ignored; 0 measured; 0 filtered out; finished in 22.13s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
  • cargo test -p calternal-plugin-files: one existing two-second lock timing test timed out under host load; the Shared Notes Tag regression passed. Final suite output:
test result: FAILED. 250 passed; 1 failed; 4 ignored; 0 measured; 0 filtered out; finished in 243.19s
  • cargo test -p calternal-server -- --test-threads=4: server unit tests passed, then the inherited deterministic perf guard failed. Unit output:
test result: ok. 255 passed; 0 failed; 10 ignored; 0 measured; 0 filtered out; finished in 171.95s

The guard and bun run check both stop at the same inherited perf-lint ratchet output:

perf-lint: INVALID: exception ratchet: contract.blaze: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; contract.blocked-network: 356 exceptions exceed the ratchet ceiling 355; fix the new violation instead; contract.dom-bound: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; contract.model-bound: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; contract.row-identity: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; contract.snapshot: 356 exceptions exceed the ratchet ceiling 355; fix the new violation instead; coverage.profile: 356 exceptions exceed the ratchet ceiling 355; fix the new violation instead; coverage.readiness: 356 exceptions exceed the ratchet ceiling 355; fix the new violation instead; io.unresolved-call: 16191 exceptions exceed the ratchet ceiling 16190; fix the new violation instead; render.blaze-adapter: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; render.bound: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; render.model_byte_cap: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; render.model_row_cap: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; total: ledger has 21977 exceptions; ratchet total is 21964

Worktree and origin/dev had the same 21,977 ledger entries and 21,964 ratchet ceiling; the shared ratchet was left unchanged.

  • Direct bunx svelte-check --tsconfig ./tsconfig.json:
svelte-check found 0 errors and 2 warnings in 2 files

The two warnings are existing empty CSS rulesets in AttachmentDeck.svelte:1063 and AgendaList.svelte:1274.

  • Focused Vitest:
 Test Files  3 passed (3)
      Tests  9 passed (9)
  • bun run build: passed; output ended with Compressed 883 static variants; saved 20869698 bytes.
  • Generated API client check passed: CALTERNAL_SERVER_BIN="$CARGO_TARGET_DIR/debug/calternal-server" bash packages/api-client/check-generated.sh.
  • cargo clean: Removed 24648 files, 22.7GiB total. Web build output was removed. Worktree is clean.

UX gaps

  • Closed: the Tag page now displays the Task title; Photos waits for its asynchronous index; responsive e2e waits for the route sidebar and selects the visible sidebar row where phone DOM keeps both copies mounted.
  • Left: visual quality review belongs to the orchestrator; the attached production screenshots are ready for that review.

Decisions

  • DESIGN §33 did not define current-view Tag filter semantics. I used the issue's owner decision: repeated tag= values, AND matching, parent Tags include nested Tags, plain click replaces and Command/Ctrl-click adds.
  • Task titles use a bounded Notes-owned projection query. If a projection has no title, the UI uses the truthful kind label rather than a filename or path.

For the merge round

  • bun run test (from apps/web) must prove the complete web unit suite remains green.
  • bun run test:e2e:calendar && bun run test:e2e:tasks && bun run test:e2e:notes && bun run test:e2e:files && bun run test:e2e:photos && bun run test:e2e:mail-layouts (from apps/web) must prove existing adjacent route flows still work with the shared filter.
  • bash tests/adversarial/run.sh (from the repository root) must complete the XUser, authz and API robustness/cross-plugin checks.
  • Recheck the Files timeout and shared perf-lint baseline when the merge round runs the combined suite. Do not change the inherited ratchet in this issue.

READY FOR MERGE: no. The feature e2e and focused tests pass, but the required check is red on the inherited perf-lint ratchet and the Files crate suite has one existing load-sensitive timeout.

Files changed

  • apps/web/e2e/tagfilter-1109.mjs
  • apps/web/src/lib/api/tags.ts
  • apps/web/src/lib/calendar/data.ts
  • apps/web/src/lib/components/app-sidebar.svelte
  • apps/web/src/lib/files/FilesBrowser.svelte
  • apps/web/src/lib/files/InfoPanel.svelte
  • apps/web/src/lib/mail/MailReaderContent.svelte
  • apps/web/src/lib/mail/MailView.svelte
  • apps/web/src/lib/mail/labels.test.ts
  • apps/web/src/lib/mail/labels.ts
  • apps/web/src/lib/notes/api.ts
  • apps/web/src/lib/photos/PhotosView.svelte
  • apps/web/src/lib/photos/api.ts
  • apps/web/src/lib/photos/timeline.svelte.ts
  • apps/web/src/lib/tagFilters.test.ts
  • apps/web/src/lib/tagFilters.ts
  • apps/web/src/lib/tasks/TaskCard.svelte
  • apps/web/src/lib/tasks/TaskList.svelte
  • apps/web/src/lib/tasks/TaskSection.svelte
  • apps/web/src/lib/tasks/TasksSidebar.svelte
  • apps/web/src/lib/tasks/TasksWorkspace.svelte
  • apps/web/src/lib/tasks/views.test.ts
  • apps/web/src/lib/tasks/views.ts
  • apps/web/src/routes/+layout.svelte
  • apps/web/src/routes/calendar/[view]/[date]/+page.svelte
  • apps/web/src/routes/notes/+page.svelte
  • apps/web/src/routes/tag/[tag]/+page.svelte
  • bench/tag-filter-1109.mjs
  • contracts/openapi.json
  • crates/calternal-plugin/src/lib.rs
  • crates/calternal-plugin/src/query.rs
  • crates/calternal-tags/src/index.rs
  • crates/calternal-tags/src/lib.rs
  • crates/plugins/files/src/lib.rs
  • crates/plugins/files/src/shares.rs
  • crates/plugins/notes/src/lib.rs
  • crates/plugins/photos/src/routes.rs
  • docs/DESIGN.md
  • packages/api-client/src/generated.ts
  • packages/ui/src/components/ModeHeader.svelte
  • packages/ui/src/components/TagFilterChips.svelte
  • packages/ui/src/components/TagPill.svelte
  • packages/ui/src/components/calendar/ItemPreview.svelte
#1109 final report Branch: `job/tagfilter-1109` Head: `6568120fb588876d74fc16c343bb16ba254c28b1` ## Built - Sidebar Tag clicks filter the current Calendar, Tasks, Notes, Files, Photos, or Mail view. The filter stays in repeated `tag=` URL values, matches with AND semantics, restores on reload, and is preserved by Copy link. A plain click replaces the filter; Command/Ctrl-click adds one; chips can be removed and Escape clears them. - The Tags page reads real item titles. Task titles come from the Notes-owned `task_items` projection in a bounded batch. Rows use the item kind when no title exists and never expose source paths or filenames. - Notes and Shared Notes filter before pagination. Files and Photos use bounded exact-path Tag reads. Mail filtering uses user labels and ignores system flags. - Added `bench/tag-filter-1109.mjs`. The profile was not run because this is not a performance issue and the verification policy restricts measurements to performance issues. ## Screenshot evidence All 66 PNG captures are attached to this issue: 11 routes × 3 widths (390, 820, 1440) × 2 themes (paper, tokyo-night), with macOS platform emulation. Filenames follow `{route}-{width}-{theme}-mac.png`. The final e2e run printed: ```text PASS #1109 current-view Tag filters; macOS production captures: /home/kayg/Developer/calternal-wt/tagfilter-1109/artifacts/tagfilter-1109 ``` Forgejo's issue asset list confirmed 66 unique attachments. One concurrent upload returned HTTP 500 after the server stored its file; the list confirmed no missing capture. ## Commits - `4b443b1cd` Add exact-path Tags lookup for current-view filters - `a25bdbd3c` Parse repeated exact paths in Tags API - `49de75706` Filter shared Notes by repeated Tag keys - `d7f75df93` Filter Notes by repeated Tag query values - `6c5256df5` Parse repeated Photo Tag query values - `a7c83fc61` Document optional repeated Tag filters in OpenAPI - `65c77014f` Add shared Tag filter navigation and chips - `d03f67959` Apply Tag filters across app views - `959c81646` Add Tag filter end-to-end coverage and profile - `000cc4103` Wait for Photos indexing in Tag filter e2e - `08397df49` Include Task titles on Tag pages - `6568120fb` Wait for responsive Tag sidebar in e2e ## Gates - `cargo fmt --check`: exit 0; no output. - Clippy passed for `calternal-plugin`, `calternal-plugin-files`, `calternal-plugin-notes`, `calternal-plugin-photos`, `calternal-server`, and `calternal-tags` with `-D warnings`. - `cargo test -p calternal-plugin`: ```text test result: ok. 44 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 9.41s ``` - `cargo test -p calternal-tags`: ```text test result: ok. 20 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 3.51s ``` - `cargo test -p calternal-plugin-notes -- --test-threads=4`: ```text test result: ok. 284 passed; 0 failed; 2 ignored; 0 measured; 0 filtered out; finished in 292.17s test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.42s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s ``` - `cargo test -p calternal-plugin-photos -- --test-threads=4`: ```text test result: ok. 54 passed; 0 failed; 3 ignored; 0 measured; 0 filtered out; finished in 22.13s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s ``` - `cargo test -p calternal-plugin-files`: one existing two-second lock timing test timed out under host load; the Shared Notes Tag regression passed. Final suite output: ```text test result: FAILED. 250 passed; 1 failed; 4 ignored; 0 measured; 0 filtered out; finished in 243.19s ``` - `cargo test -p calternal-server -- --test-threads=4`: server unit tests passed, then the inherited deterministic perf guard failed. Unit output: ```text test result: ok. 255 passed; 0 failed; 10 ignored; 0 measured; 0 filtered out; finished in 171.95s ``` The guard and `bun run check` both stop at the same inherited perf-lint ratchet output: ```text perf-lint: INVALID: exception ratchet: contract.blaze: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; contract.blocked-network: 356 exceptions exceed the ratchet ceiling 355; fix the new violation instead; contract.dom-bound: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; contract.model-bound: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; contract.row-identity: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; contract.snapshot: 356 exceptions exceed the ratchet ceiling 355; fix the new violation instead; coverage.profile: 356 exceptions exceed the ratchet ceiling 355; fix the new violation instead; coverage.readiness: 356 exceptions exceed the ratchet ceiling 355; fix the new violation instead; io.unresolved-call: 16191 exceptions exceed the ratchet ceiling 16190; fix the new violation instead; render.blaze-adapter: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; render.bound: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; render.model_byte_cap: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; render.model_row_cap: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; total: ledger has 21977 exceptions; ratchet total is 21964 ``` Worktree and `origin/dev` had the same 21,977 ledger entries and 21,964 ratchet ceiling; the shared ratchet was left unchanged. - Direct `bunx svelte-check --tsconfig ./tsconfig.json`: ```text svelte-check found 0 errors and 2 warnings in 2 files ``` The two warnings are existing empty CSS rulesets in `AttachmentDeck.svelte:1063` and `AgendaList.svelte:1274`. - Focused Vitest: ```text Test Files 3 passed (3) Tests 9 passed (9) ``` - `bun run build`: passed; output ended with `Compressed 883 static variants; saved 20869698 bytes.` - Generated API client check passed: `CALTERNAL_SERVER_BIN="$CARGO_TARGET_DIR/debug/calternal-server" bash packages/api-client/check-generated.sh`. - `cargo clean`: `Removed 24648 files, 22.7GiB total`. Web build output was removed. Worktree is clean. ## UX gaps - Closed: the Tag page now displays the Task title; Photos waits for its asynchronous index; responsive e2e waits for the route sidebar and selects the visible sidebar row where phone DOM keeps both copies mounted. - Left: visual quality review belongs to the orchestrator; the attached production screenshots are ready for that review. ## Decisions - DESIGN §33 did not define current-view Tag filter semantics. I used the issue's owner decision: repeated `tag=` values, AND matching, parent Tags include nested Tags, plain click replaces and Command/Ctrl-click adds. - Task titles use a bounded Notes-owned projection query. If a projection has no title, the UI uses the truthful kind label rather than a filename or path. ## For the merge round - `bun run test` (from `apps/web`) must prove the complete web unit suite remains green. - `bun run test:e2e:calendar && bun run test:e2e:tasks && bun run test:e2e:notes && bun run test:e2e:files && bun run test:e2e:photos && bun run test:e2e:mail-layouts` (from `apps/web`) must prove existing adjacent route flows still work with the shared filter. - `bash tests/adversarial/run.sh` (from the repository root) must complete the XUser, authz and API robustness/cross-plugin checks. - Recheck the Files timeout and shared perf-lint baseline when the merge round runs the combined suite. Do not change the inherited ratchet in this issue. READY FOR MERGE: no. The feature e2e and focused tests pass, but the required check is red on the inherited perf-lint ratchet and the Files crate suite has one existing load-sensitive timeout. ## Files changed - `apps/web/e2e/tagfilter-1109.mjs` - `apps/web/src/lib/api/tags.ts` - `apps/web/src/lib/calendar/data.ts` - `apps/web/src/lib/components/app-sidebar.svelte` - `apps/web/src/lib/files/FilesBrowser.svelte` - `apps/web/src/lib/files/InfoPanel.svelte` - `apps/web/src/lib/mail/MailReaderContent.svelte` - `apps/web/src/lib/mail/MailView.svelte` - `apps/web/src/lib/mail/labels.test.ts` - `apps/web/src/lib/mail/labels.ts` - `apps/web/src/lib/notes/api.ts` - `apps/web/src/lib/photos/PhotosView.svelte` - `apps/web/src/lib/photos/api.ts` - `apps/web/src/lib/photos/timeline.svelte.ts` - `apps/web/src/lib/tagFilters.test.ts` - `apps/web/src/lib/tagFilters.ts` - `apps/web/src/lib/tasks/TaskCard.svelte` - `apps/web/src/lib/tasks/TaskList.svelte` - `apps/web/src/lib/tasks/TaskSection.svelte` - `apps/web/src/lib/tasks/TasksSidebar.svelte` - `apps/web/src/lib/tasks/TasksWorkspace.svelte` - `apps/web/src/lib/tasks/views.test.ts` - `apps/web/src/lib/tasks/views.ts` - `apps/web/src/routes/+layout.svelte` - `apps/web/src/routes/calendar/[view]/[date]/+page.svelte` - `apps/web/src/routes/notes/+page.svelte` - `apps/web/src/routes/tag/[tag]/+page.svelte` - `bench/tag-filter-1109.mjs` - `contracts/openapi.json` - `crates/calternal-plugin/src/lib.rs` - `crates/calternal-plugin/src/query.rs` - `crates/calternal-tags/src/index.rs` - `crates/calternal-tags/src/lib.rs` - `crates/plugins/files/src/lib.rs` - `crates/plugins/files/src/shares.rs` - `crates/plugins/notes/src/lib.rs` - `crates/plugins/photos/src/routes.rs` - `docs/DESIGN.md` - `packages/api-client/src/generated.ts` - `packages/ui/src/components/ModeHeader.svelte` - `packages/ui/src/components/TagFilterChips.svelte` - `packages/ui/src/components/TagPill.svelte` - `packages/ui/src/components/calendar/ItemPreview.svelte`
Author
Owner

Addendum to the merge-round commands: the listed Calendar, Tasks, Notes, Files, Photos and Mail e2e scripts are the existing adjacent-route regression checks; the dedicated bun e2e/tagfilter-1109.mjs run above covers the new Tag-filter state and its screenshot matrix. The merge-round runner should still run its full configured e2e set.

Addendum to the merge-round commands: the listed Calendar, Tasks, Notes, Files, Photos and Mail e2e scripts are the existing adjacent-route regression checks; the dedicated `bun e2e/tagfilter-1109.mjs` run above covers the new Tag-filter state and its screenshot matrix. The merge-round runner should still run its full configured e2e set.
Author
Owner

Orchestrator review of artifacts/tagfilter-1109 (calendar-month-1440-tokyo-night-mac.png): send back.

  1. Merge origin/dev first (batches 6–15 are on dev). The Calendar header changed in #1112: the "‹ Today ›" pager is gone and a centred Agenda/Day/Week/Month/Year segmented control sits in the header; the sidebar no longer lists Calendar views. Resolve conflicts keeping dev's header. perf-lint is being fixed on dev (#1133); do not spend time on ratchet numbers.
  2. Chip placement with the new header: filter chips sit on the left after the page title in the same header row (never colliding with the centred segmented control; keep ≥ one gap token clear). When they do not fit, collapse to one chip "2 tags ▾" that opens a small popover listing them with remove buttons. Same rule on every Tab's header.
  3. Chip design: the remove × lives INSIDE each chip pill (trailing, hit target ≥ 24 px, own tooltip "Remove #area/work"); no loose × glyphs between chips. Remove the separate bare "clear all" ×: Escape clears all (as decided), and when 2+ chips are active the overflow popover / chip menu has "Clear filters". Chips use the shared tag chip style (colour dot/hash from the tag's colour), vertically centred on the title's x-height.
  4. Retake the matrix (Calendar Month/Week/Day/Agenda, Tasks, Notes, Files, Photos, Mail at 390/820/1440, light + dark) with 1 and 2 active tags, plus 4x crops of the chip row. Geometry e2e: chips never intersect the segmented control or toolbar; × inside its chip rect.
    Commit; comment on #1109 with head SHA. Do not push.
Orchestrator review of artifacts/tagfilter-1109 (calendar-month-1440-tokyo-night-mac.png): send back. 1. **Merge origin/dev first** (batches 6–15 are on dev). The Calendar header changed in #1112: the "‹ Today ›" pager is gone and a centred Agenda/Day/Week/Month/Year segmented control sits in the header; the sidebar no longer lists Calendar views. Resolve conflicts keeping dev's header. perf-lint is being fixed on dev (#1133); do not spend time on ratchet numbers. 2. **Chip placement with the new header:** filter chips sit on the left after the page title in the same header row (never colliding with the centred segmented control; keep ≥ one gap token clear). When they do not fit, collapse to one chip "2 tags ▾" that opens a small popover listing them with remove buttons. Same rule on every Tab's header. 3. **Chip design:** the remove × lives INSIDE each chip pill (trailing, hit target ≥ 24 px, own tooltip "Remove #area/work"); no loose × glyphs between chips. Remove the separate bare "clear all" ×: Escape clears all (as decided), and when 2+ chips are active the overflow popover / chip menu has "Clear filters". Chips use the shared tag chip style (colour dot/hash from the tag's colour), vertically centred on the title's x-height. 4. Retake the matrix (Calendar Month/Week/Day/Agenda, Tasks, Notes, Files, Photos, Mail at 390/820/1440, light + dark) with 1 and 2 active tags, plus 4x crops of the chip row. Geometry e2e: chips never intersect the segmented control or toolbar; × inside its chip rect. Commit; comment on #1109 with head SHA. Do not push.
Author
Owner

Starting #1109 on branch job/tagfilter-1109 at base SHA 6568120fb588876d74fc16c343bb16ba254c28b1. I have read CLAUDE.md, docs/DESIGN.md §§33–34 and CONTEXT.md. I am fetching and merging origin/dev before implementing the chip-row fixes and requested verification.

Starting #1109 on branch `job/tagfilter-1109` at base SHA `6568120fb588876d74fc16c343bb16ba254c28b1`. I have read `CLAUDE.md`, `docs/DESIGN.md` §§33–34 and `CONTEXT.md`. I am fetching and merging `origin/dev` before implementing the chip-row fixes and requested verification.
Author
Owner

Merge finding: origin/dev now supplies the centered Calendar segmented control in ModeHeader and removes the Calendar view list from the sidebar (#1112). I resolved the conflicts by keeping that control and sidebar change, placing the shared Tag filter after the title, and preserving repeated Tag filters in Notes links and sidebar navigation. The focused integration also keeps the newer Notes create actions and Tasks Tag loading/error state.

Merge finding: `origin/dev` now supplies the centered Calendar segmented control in `ModeHeader` and removes the Calendar view list from the sidebar (#1112). I resolved the conflicts by keeping that control and sidebar change, placing the shared Tag filter after the title, and preserving repeated Tag filters in Notes links and sidebar navigation. The focused integration also keeps the newer Notes create actions and Tasks Tag loading/error state.
Author
Owner

Verification finding: bun run check currently stops at perf-lint before Svelte validation. Its output says perf-lint: INVALID: exception ratchet: contract.blaze: 290 exceptions exceed the ratchet ceiling 289 and the same one-over condition for the listed ledgers, with total: ledger has 21977 exceptions; ratchet total is 21964. Per the job instruction for #1133, I am not changing ratchet numbers; I am running Svelte validation directly.

Verification finding: `bun run check` currently stops at `perf-lint` before Svelte validation. Its output says `perf-lint: INVALID: exception ratchet: contract.blaze: 290 exceptions exceed the ratchet ceiling 289` and the same one-over condition for the listed ledgers, with `total: ledger has 21977 exceptions; ratchet total is 21964`. Per the job instruction for #1133, I am not changing ratchet numbers; I am running Svelte validation directly.
Author
Owner

Gate finding: cargo test -p calternal-tags passed 17 of 20 tests; three existing recovery tests failed. Their shared reconcile_fixture writes Travel/beach.jpg and XMP sidecars but leaves files_index.mime NULL. Tag reconciliation selects XMP handling from the indexed MIME, so this fixture routes the photo through folder metadata. That makes the folder-corruption cases miss the expected photo Tags and lets the XMP-corruption hash case restore them. I will add the missing image/jpeg fixture metadata and keep all existing expectations unchanged.

Gate finding: `cargo test -p calternal-tags` passed 17 of 20 tests; three existing recovery tests failed. Their shared `reconcile_fixture` writes `Travel/beach.jpg` and XMP sidecars but leaves `files_index.mime` NULL. Tag reconciliation selects XMP handling from the indexed MIME, so this fixture routes the photo through folder metadata. That makes the folder-corruption cases miss the expected photo Tags and lets the XMP-corruption hash case restore them. I will add the missing `image/jpeg` fixture metadata and keep all existing expectations unchanged.
Author
Owner

Gate finding: cargo clippy -p calternal-plugin-notes --all-targets -- -D warnings found an unused user argument in the existing setup_with_user test helper. The helper then generated a different UUID, which contradicted its comment that Canvas fixtures can supply a stable User ID. I will use the supplied ID; no test expectation changes.

Gate finding: `cargo clippy -p calternal-plugin-notes --all-targets -- -D warnings` found an unused `user` argument in the existing `setup_with_user` test helper. The helper then generated a different UUID, which contradicted its comment that Canvas fixtures can supply a stable User ID. I will use the supplied ID; no test expectation changes.
Author
Owner

Rust gate findings:

  • Files ran 257 tests successfully; internal_temp_paths_never_enter_index_during_atomic_write_reconcile_storm hit its five-minute bound under the four-thread full suite and then panicked while cleaning up completed Tokio handles. The same case passed alone: test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 261 filtered out; finished in 218.60s. This is a SLOW load result; no production behavior or test expectation was changed.
  • Server ran 256 tests successfully, then tests/perf_guards.rs::deterministic_performance_guards failed because perf-lint reports the existing ratchet mismatch (ledger 21977, ceiling 21964). As the job instructions say, I did not change the ratchet numbers.
Rust gate findings: - Files ran 257 tests successfully; `internal_temp_paths_never_enter_index_during_atomic_write_reconcile_storm` hit its five-minute bound under the four-thread full suite and then panicked while cleaning up completed Tokio handles. The same case passed alone: `test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 261 filtered out; finished in 218.60s`. This is a SLOW load result; no production behavior or test expectation was changed. - Server ran 256 tests successfully, then `tests/perf_guards.rs::deterministic_performance_guards` failed because perf-lint reports the existing ratchet mismatch (ledger 21977, ceiling 21964). As the job instructions say, I did not change the ratchet numbers.
Author
Owner

Completed #1109 on job/tagfilter-1109.

Head: c41b6dd991c5b4e1be9f3ada545affe7e08ba23b

Merged origin/dev once at the start (c1d5d5dbe), retaining #1112's centered Calendar view control and removing the old pager/sidebar view list. No push.

Built

  • Added URL-backed, repeated tag filters with AND behavior for Calendar, Tasks, Notes, Files, Photos, and Mail. Kept other route state and deep links intact.
  • Added shared header chips after the title, with room reserved for centered controls and toolbar. When the full row does not fit, it becomes one N tags ▾ chip and an anchored menu. Each chip has its own remove button and Remove #tag tooltip; Escape clears all, and the menu offers Clear filters for multiple active tags.
  • Used shared TagPill styling and tag colours. Raised the remove target for touch use. Filter changes stay in the route and therefore update with browser navigation and Copy link.
  • Added generated API contract/client updates, focused URL and view tests, a current-view matcher profile, and a production-build geometry/screenshot E2E.
  • Fixed two test fixture issues found by gates: Files tag recovery now retains MIME metadata for .jpg; Notes fixtures use the supplied User ID. Existing test expectations were not changed.

Main files include packages/ui/src/components/{ModeHeader,TagFilterChips,TagPill}.svelte, apps/web/src/lib/tagFilters.ts, Tasks/Files/Photos/Mail/Notes/Calendar adapters and views, crates/calternal-plugin/src/query.rs, crates/calternal-tags/src/{index,lib}.rs, Files/Notes/Photos plugin routes, contracts/openapi.json, packages/api-client/src/generated.ts, and apps/web/e2e/tagfilter-1109.mjs.

Visual evidence

The archive contains 108 route screenshots (Calendar Month/Week/Day/Agenda, Tasks, Notes, Files, Photos, Mail × 390/820/1440 px × light/dark × one/two active tags) and the four 4× chip-row crops. Playwright emulated macOS. All geometry checks passed: chips did not intersect the centered control or toolbar, and each remove button stayed within its chip.

Download all 112 captures

One Tag, light
Two Tags, light
One Tag, dark
Two Tags, dark

Gates

Passing output excerpts:

  • cargo fmt --check — exit 0, no output.
  • cargo clippy -p calternal-plugin --all-targets -- -D warnings — Finished \dev` profile [unoptimized + debuginfo] target(s) in 3m 30s; tests: 44 passed; 0 failed`.
  • cargo clippy -p calternal-tags --all-targets -- -D warnings — Finished \dev` profile [unoptimized + debuginfo] target(s) in 3.58s; tests: 20 passed; 0 failed`.
  • Files, Notes, Photos, Server clippy passed. Their clippy completion lines were respectively Finished \dev` profile [unoptimized + debuginfo] target(s) in 4m 00s, ... in 24.05s, ... in 2m 37s, and ... in 6m 44s`.
  • Notes tests: 288 passed; 0 failed; 3 ignored; Apple replay integration: 2 passed. Photos tests: 56 passed; 0 failed; 4 ignored. Server unit tests: 256 passed; 0 failed; 10 ignored.
  • Focused Vitest: Test Files 4 passed (4); Tests 27 passed (27).
  • svelte-check found 0 errors and 2 warnings in 2 files (existing empty CSS rulesets in AttachmentDeck.svelte and AgendaList.svelte).
  • bun run build passed; final output: Compressed 885 static variants; saved 20935561 bytes.
  • bun e2e/tagfilter-1109.mjs passed: PASS #1109 current-view Tag filters; macOS production captures: /home/kayg/Developer/calternal-wt/tagfilter-1109/artifacts/tagfilter-1109.

Known gate findings:

  • bun run check and the Server perf_guards integration failed on the same existing perf-lint exception ratchet. Per the instruction for #1133, I did not edit ratchet numbers. Exact output:

    perf-lint: INVALID: exception ratchet: contract.blaze: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; contract.blocked-network: 356 exceptions exceed the ratchet ceiling 355; fix the new violation instead; contract.dom-bound: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; contract.model-bound: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; contract.row-identity: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; contract.snapshot: 356 exceptions exceed the ratchet ceiling 355; fix the new violation instead; coverage.profile: 356 exceptions exceed the ratchet ceiling 355; fix the new violation instead; coverage.readiness: 356 exceptions exceed the ratchet ceiling 355; fix the new violation instead; io.unresolved-call: 16191 exceptions exceed the ratchet ceiling 16190; fix the new violation instead; render.blaze-adapter: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; render.bound: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; render.model_byte_cap: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; render.model_row_cap: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; total: ledger has 21977 exceptions; ratchet total is 21964

  • Files full tests had one shared-host timeout cleanup failure: FAILED. 257 passed; 1 failed; 4 ignored; finished in 398.97s (JoinHandle polled after completion). The isolated rerun passed: test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 261 filtered out; finished in 218.60s. No expectation was changed.

UX gaps closed / left

Closed: direct removal from each chip, keyboard clear with Escape, a discoverable multi-tag clear action, touch-size remove targets, visible overflow recovery, and geometry checks across every requested viewport and theme. Left: none found for this feature in the exercised flows.

Decisions not covered by DESIGN

  • Repeated tag query keys represent an AND filter and preserve the rest of the route.
  • Files and Photos use bounded exact-path assignment reads when filtering loaded rows, avoiding a per-row request.
  • Mail exposes user labels as Tags and omits system/category flags from the filter list.

For the merge round

  • Run bun run test for the combined web unit suite and bun run test:e2e for the standard E2E shell suite.
  • Run tests/adversarial/run.sh against the combined server to check XUser/authz and hostile-input behavior.
  • After the #1133 ratchet fix lands, rerun cargo test -p calternal-server --test perf_guards to confirm the performance guard.
  • The bench/tag-filter-1109.mjs profile was added but not measured, per the current verification policy limiting perf measurements to performance issues.
Completed #1109 on `job/tagfilter-1109`. **Head:** `c41b6dd991c5b4e1be9f3ada545affe7e08ba23b` Merged `origin/dev` once at the start (`c1d5d5dbe`), retaining #1112's centered Calendar view control and removing the old pager/sidebar view list. No push. ### Built - Added URL-backed, repeated `tag` filters with AND behavior for Calendar, Tasks, Notes, Files, Photos, and Mail. Kept other route state and deep links intact. - Added shared header chips after the title, with room reserved for centered controls and toolbar. When the full row does not fit, it becomes one `N tags ▾` chip and an anchored menu. Each chip has its own remove button and `Remove #tag` tooltip; Escape clears all, and the menu offers **Clear filters** for multiple active tags. - Used shared TagPill styling and tag colours. Raised the remove target for touch use. Filter changes stay in the route and therefore update with browser navigation and Copy link. - Added generated API contract/client updates, focused URL and view tests, a current-view matcher profile, and a production-build geometry/screenshot E2E. - Fixed two test fixture issues found by gates: Files tag recovery now retains MIME metadata for `.jpg`; Notes fixtures use the supplied User ID. Existing test expectations were not changed. Main files include `packages/ui/src/components/{ModeHeader,TagFilterChips,TagPill}.svelte`, `apps/web/src/lib/tagFilters.ts`, Tasks/Files/Photos/Mail/Notes/Calendar adapters and views, `crates/calternal-plugin/src/query.rs`, `crates/calternal-tags/src/{index,lib}.rs`, Files/Notes/Photos plugin routes, `contracts/openapi.json`, `packages/api-client/src/generated.ts`, and `apps/web/e2e/tagfilter-1109.mjs`. ### Visual evidence The archive contains 108 route screenshots (Calendar Month/Week/Day/Agenda, Tasks, Notes, Files, Photos, Mail × 390/820/1440 px × light/dark × one/two active tags) and the four 4× chip-row crops. Playwright emulated macOS. All geometry checks passed: chips did not intersect the centered control or toolbar, and each remove button stayed within its chip. [Download all 112 captures](https://git.kayg.org/attachments/1cf51eb4-3652-456b-8950-93a84d3ccbea) ![One Tag, light](https://git.kayg.org/attachments/c34fa719-d4dd-48e5-a07f-3df9a6fc7fe5) ![Two Tags, light](https://git.kayg.org/attachments/4bab85d1-9f7e-4f61-a857-14fc2beca6ef) ![One Tag, dark](https://git.kayg.org/attachments/d5bdad83-627d-48fa-985f-64d5457cadb1) ![Two Tags, dark](https://git.kayg.org/attachments/1214067d-3a74-436b-9f7e-4c212a0b0639) ### Gates Passing output excerpts: - `cargo fmt --check` — exit 0, no output. - `cargo clippy -p calternal-plugin --all-targets -- -D warnings` — `Finished \`dev\` profile [unoptimized + debuginfo] target(s) in 3m 30s`; tests: `44 passed; 0 failed`. - `cargo clippy -p calternal-tags --all-targets -- -D warnings` — `Finished \`dev\` profile [unoptimized + debuginfo] target(s) in 3.58s`; tests: `20 passed; 0 failed`. - Files, Notes, Photos, Server clippy passed. Their clippy completion lines were respectively `Finished \`dev\` profile [unoptimized + debuginfo] target(s) in 4m 00s`, `... in 24.05s`, `... in 2m 37s`, and `... in 6m 44s`. - Notes tests: `288 passed; 0 failed; 3 ignored`; Apple replay integration: `2 passed`. Photos tests: `56 passed; 0 failed; 4 ignored`. Server unit tests: `256 passed; 0 failed; 10 ignored`. - Focused Vitest: `Test Files 4 passed (4)`; `Tests 27 passed (27)`. - `svelte-check found 0 errors and 2 warnings in 2 files` (existing empty CSS rulesets in AttachmentDeck.svelte and AgendaList.svelte). - `bun run build` passed; final output: `Compressed 885 static variants; saved 20935561 bytes.` - `bun e2e/tagfilter-1109.mjs` passed: `PASS #1109 current-view Tag filters; macOS production captures: /home/kayg/Developer/calternal-wt/tagfilter-1109/artifacts/tagfilter-1109`. Known gate findings: - `bun run check` and the Server `perf_guards` integration failed on the same existing perf-lint exception ratchet. Per the instruction for #1133, I did not edit ratchet numbers. Exact output: `perf-lint: INVALID: exception ratchet: contract.blaze: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; contract.blocked-network: 356 exceptions exceed the ratchet ceiling 355; fix the new violation instead; contract.dom-bound: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; contract.model-bound: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; contract.row-identity: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; contract.snapshot: 356 exceptions exceed the ratchet ceiling 355; fix the new violation instead; coverage.profile: 356 exceptions exceed the ratchet ceiling 355; fix the new violation instead; coverage.readiness: 356 exceptions exceed the ratchet ceiling 355; fix the new violation instead; io.unresolved-call: 16191 exceptions exceed the ratchet ceiling 16190; fix the new violation instead; render.blaze-adapter: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; render.bound: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; render.model_byte_cap: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; render.model_row_cap: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; total: ledger has 21977 exceptions; ratchet total is 21964` - Files full tests had one shared-host timeout cleanup failure: `FAILED. 257 passed; 1 failed; 4 ignored; finished in 398.97s` (`JoinHandle polled after completion`). The isolated rerun passed: `test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 261 filtered out; finished in 218.60s`. No expectation was changed. ### UX gaps closed / left Closed: direct removal from each chip, keyboard clear with Escape, a discoverable multi-tag clear action, touch-size remove targets, visible overflow recovery, and geometry checks across every requested viewport and theme. Left: none found for this feature in the exercised flows. ### Decisions not covered by DESIGN - Repeated `tag` query keys represent an AND filter and preserve the rest of the route. - Files and Photos use bounded exact-path assignment reads when filtering loaded rows, avoiding a per-row request. - Mail exposes user labels as Tags and omits system/category flags from the filter list. ### For the merge round - Run `bun run test` for the combined web unit suite and `bun run test:e2e` for the standard E2E shell suite. - Run `tests/adversarial/run.sh` against the combined server to check XUser/authz and hostile-input behavior. - After the #1133 ratchet fix lands, rerun `cargo test -p calternal-server --test perf_guards` to confirm the performance guard. - The `bench/tag-filter-1109.mjs` profile was added but not measured, per the current verification policy limiting perf measurements to performance issues.
Author
Owner

Started merge27j on job/merge27, base/head 869653b19c93d0c1320ffcc608919c8bf4ab35df. Resolve #1142 and #1136 with both intents, fix the six reported web failures and exact performance pin, fetch and merge origin/dev once, then run the requested clean-install web and per-crate Rust gates. No push or deploy.

Started merge27j on `job/merge27`, base/head `869653b19c93d0c1320ffcc608919c8bf4ab35df`. Resolve #1142 and #1136 with both intents, fix the six reported web failures and exact performance pin, fetch and merge origin/dev once, then run the requested clean-install web and per-crate Rust gates. No push or deploy.
Author
Owner

Resolved #1142 conflicts by retaining filtered Photos URLs from #1109 and inline Copy link announcements plus background-result classification from #1142. MonthGrid fixture kept its existing noteId: null; no expectations changed. #1136 conflict retained caller-supplied unique User IDs and the updated comment.

The six reported failures were reproduced by the existing test contracts: static TagPill markup introduces whitespace around its label, and #1109 passes an empty fifth argument to the previously four-argument burst page refresh. Code fixes preserve exact static labels and the unfiltered call while passing active Tags. Added a filtered-burst regression. Focused verification: Test Files 3 passed (3) / Tests 32 passed (32).

Fetched origin and merged origin/dev once: Already up to date. Full gates are now running.

Resolved #1142 conflicts by retaining filtered Photos URLs from #1109 and inline Copy link announcements plus background-result classification from #1142. MonthGrid fixture kept its existing `noteId: null`; no expectations changed. #1136 conflict retained caller-supplied unique User IDs and the updated comment. The six reported failures were reproduced by the existing test contracts: static TagPill markup introduces whitespace around its label, and #1109 passes an empty fifth argument to the previously four-argument burst page refresh. Code fixes preserve exact static labels and the unfiltered call while passing active Tags. Added a filtered-burst regression. Focused verification: `Test Files 3 passed (3)` / `Tests 32 passed (32)`. Fetched origin and merged origin/dev once: `Already up to date.` Full gates are now running.
Author
Owner

The first full check found #1109 CSS that fails the shared style guards: TagPill has two literal border-radius: 50% declarations, and TagPill/TagFilterChips add local focus-ring declarations. Replaced the radii with --radius-circle and removed local focus CSS so the shared global ring owns focus. The type-token guard now passes.

The full web suite also found a SettingsCard double-tap test that still expects a toast after #1142 removed that callback. #1142 explicitly changes this behavior: confirmation is inline and announced by LinkedHeading. Updated only that obsolete expectation to require its polite live-region copy and zero toasts; the clipboard, touch-feedback and copied-class assertions remain. Removed the now-unused toast import and documented the owner of this feedback. This changed expectation is called out for review.

The first full check found #1109 CSS that fails the shared style guards: TagPill has two literal `border-radius: 50%` declarations, and TagPill/TagFilterChips add local focus-ring declarations. Replaced the radii with `--radius-circle` and removed local focus CSS so the shared global ring owns focus. The type-token guard now passes. The full web suite also found a SettingsCard double-tap test that still expects a toast after #1142 removed that callback. #1142 explicitly changes this behavior: confirmation is inline and announced by LinkedHeading. Updated only that obsolete expectation to require its polite live-region copy and zero toasts; the clipboard, touch-feedback and copied-class assertions remain. Removed the now-unused toast import and documented the owner of this feedback. This changed expectation is called out for review.
Author
Owner

First full web run finished: Test Files 4 failed | 265 passed (269) / Tests 7 failed | 1833 passed (1840). The original six reported failures are fixed. New failures: one Settings heading confirmation expectation, five Note/Canvas toast-object expectations, and a policy source-scan timeout (Error: Test timed out in 5000ms.).

#1142 explicitly changes confirmation and error-toast behavior. Updated the six obsolete expectations, retaining their clipboard, route, identity and focus assertions. The creation tests now also invoke all five recovery callbacks and verify the exact destination. Focused runs pass: Settings/ItemPreview 21 tests, Note/Canvas creation 10 tests, policy 1 test. The source scan has a scoped 30-second timeout because it scans repository files, not a User interaction. No toast classification or performance rule was relaxed.

After shared-style cleanup, refreshed only six exact TagFilterChips pin identities; the ratchet is unchanged at 22,369. Ordinary final check and full tests are running on the corrected source. Head so far: 2240078ad.

First full web run finished: `Test Files 4 failed | 265 passed (269)` / `Tests 7 failed | 1833 passed (1840)`. The original six reported failures are fixed. New failures: one Settings heading confirmation expectation, five Note/Canvas toast-object expectations, and a policy source-scan timeout (`Error: Test timed out in 5000ms.`). #1142 explicitly changes confirmation and error-toast behavior. Updated the six obsolete expectations, retaining their clipboard, route, identity and focus assertions. The creation tests now also invoke all five recovery callbacks and verify the exact destination. Focused runs pass: Settings/ItemPreview 21 tests, Note/Canvas creation 10 tests, policy 1 test. The source scan has a scoped 30-second timeout because it scans repository files, not a User interaction. No toast classification or performance rule was relaxed. After shared-style cleanup, refreshed only six exact TagFilterChips pin identities; the ratchet is unchanged at 22,369. Ordinary final check and full tests are running on the corrected source. Head so far: `2240078ad`.
Author
Owner

Head 2240078ad89a1b4a09c7e63f2ebcf1dfedd5a18e. The replacement full web check exited 0. Verbatim summary:

perf-lint: PASS; 0 violations; 22369 scoped exceptions
svelte-check found 0 errors and 2 warnings in 2 files

Both warnings are existing empty CSS rules in AttachmentDeck and AgendaList. The production web build also exited 0. Notes and Server all-target clippy exited 0:

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 23m 10s

The full web suite and required Rust tests are still running. No new web failure has been reported in the corrected run.

Head `2240078ad89a1b4a09c7e63f2ebcf1dfedd5a18e`. The replacement full web check exited 0. Verbatim summary: ``` perf-lint: PASS; 0 violations; 22369 scoped exceptions svelte-check found 0 errors and 2 warnings in 2 files ``` Both warnings are existing empty CSS rules in AttachmentDeck and AgendaList. The production web build also exited 0. Notes and Server all-target clippy exited 0: ``` Finished `dev` profile [unoptimized + debuginfo] target(s) in 23m 10s ``` The full web suite and required Rust tests are still running. No new web failure has been reported in the corrected run.
Author
Owner

The full web gate exited 0 from the frozen-lockfile install on head 2240078ad89a1b4a09c7e63f2ebcf1dfedd5a18e:

 Test Files  269 passed (269)
      Tests  1840 passed (1840)
   Start at  02:46:03
   Duration  933.73s (transform 33%, environment 24%, import 20%, tests 18%, setup 5%)

bun run check also exited 0 with svelte-check found 0 errors and 2 warnings in 2 files. The original six failures and all integration failures found in this round are resolved. Rust tests remain in progress. No pushes or deploys.

The full web gate exited 0 from the frozen-lockfile install on head `2240078ad89a1b4a09c7e63f2ebcf1dfedd5a18e`: ``` Test Files 269 passed (269) Tests 1840 passed (1840) Start at 02:46:03 Duration 933.73s (transform 33%, environment 24%, import 20%, tests 18%, setup 5%) ``` `bun run check` also exited 0 with `svelte-check found 0 errors and 2 warnings in 2 files`. The original six failures and all integration failures found in this round are resolved. Rust tests remain in progress. No pushes or deploys.
Author
Owner

The required Notes gate reproduced #1136 even though every test passed. The 700-Note reconciliation case passed. This is a native shutdown failure, not SLOW-only load. Verbatim:

test tests::unicode_titles::random_unicode_task_titles_survive_create_read_rename_and_caldav ... ok
test voice::tests::voice_backfill_scan_is_paged_low_priority_and_cancellable ... ok
test tests::seven_hundred_notes_reconcile_without_feedback ... ok

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

error: test failed, to rerun pass `-p calternal-plugin-notes --lib`

Caused by:
  process didn't exit successfully: `/home/kayg/build/targets/merge27j/debug/deps/calternal_plugin_notes-2e1e6d4f020c6819 --test-threads=4` (signal: 11, SIGSEGV: invalid memory reference)

Investigating native process cleanup; the Server build continues. All web gates and all changed-crate clippy gates have passed. This branch is not ready while the native exit remains.

The required Notes gate reproduced #1136 even though every test passed. The 700-Note reconciliation case passed. This is a native shutdown failure, not SLOW-only load. Verbatim: ``` test tests::unicode_titles::random_unicode_task_titles_survive_create_read_rename_and_caldav ... ok test voice::tests::voice_backfill_scan_is_paged_low_priority_and_cancellable ... ok test tests::seven_hundred_notes_reconcile_without_feedback ... ok test result: ok. 288 passed; 0 failed; 3 ignored; 0 measured; 0 filtered out; finished in 586.49s error: test failed, to rerun pass `-p calternal-plugin-notes --lib` Caused by: process didn't exit successfully: `/home/kayg/build/targets/merge27j/debug/deps/calternal_plugin_notes-2e1e6d4f020c6819 --test-threads=4` (signal: 11, SIGSEGV: invalid memory reference) ``` Investigating native process cleanup; the Server build continues. All web gates and all changed-crate clippy gates have passed. This branch is not ready while the native exit remains.
Author
Owner

Native staging finding for #1136: sherpa-onnx-sys 1.13.8 copy_unix_runtime_libs uses fs::copy onto existing shared-library destinations. A fixture invoking the actual compiled build script confirms that the destination inode remains the same, an already-open descriptor sees replacement bytes, and a private mapping sees replacement bytes in an untouched page. The new regression fails in all four Linux/macOS profile/examples cases before the fix. It passes after using the existing atomic-copy helper.

A small, Apache-2.0-compatible vendored patch changes Unix staging only; FFI and native runtime version stay unchanged. The dependency version was verified with cargo search. This fixes an observed build-artifact race that can affect live mappings when Cargo builds overlap test execution. It does not yet establish the root cause of the earlier SIGSEGV. Gates will run without concurrent Rust builds.

The independent direct Notes run exited normally with one pre-existing transient Index is busy; retry shortly failure in daily_log_projection_rebuild_resumes_without_markdown_writes. Its assertions remain unchanged.

Native staging finding for #1136: sherpa-onnx-sys 1.13.8 `copy_unix_runtime_libs` uses `fs::copy` onto existing shared-library destinations. A fixture invoking the actual compiled build script confirms that the destination inode remains the same, an already-open descriptor sees replacement bytes, and a private mapping sees replacement bytes in an untouched page. The new regression fails in all four Linux/macOS profile/examples cases before the fix. It passes after using the existing atomic-copy helper. A small, Apache-2.0-compatible vendored patch changes Unix staging only; FFI and native runtime version stay unchanged. The dependency version was verified with cargo search. This fixes an observed build-artifact race that can affect live mappings when Cargo builds overlap test execution. It does not yet establish the root cause of the earlier SIGSEGV. Gates will run without concurrent Rust builds. The independent direct Notes run exited normally with one pre-existing transient `Index is busy; retry shortly` failure in daily_log_projection_rebuild_resumes_without_markdown_writes. Its assertions remain unchanged.
Author
Owner

The real production Tag filter walkthrough found a first-frame overlap after Command-click added the second Tag. At 1440px, the Tag list right edge was 642.17px while the toolbar lane started at 511.02px. The initial full list painted before ResizeObserver delivered its size.

Commit fixes this in CODE: show the bounded count control until the current Tag list has a known fit, and invalidate the previous fit before painting changed route Tags. The existing observer still restores full pills when they fit. Focused regression tests pass (2 files / 19 tests); the production build passes. Exact TagFilterChips perf pin hashes were refreshed; the exception count remains 22369 and no rule or ratchet was weakened. The existing browser geometry assertions are unchanged.

The first Server gate failed only startup_serves_http_while_upgrade_backfills_wait at its unchanged 15-second deadline (child elapsed 112.95s). All other non-ignored tests passed. The final gate will run after the native patch with no concurrent Rust build.

The real production Tag filter walkthrough found a first-frame overlap after Command-click added the second Tag. At 1440px, the Tag list right edge was 642.17px while the toolbar lane started at 511.02px. The initial full list painted before ResizeObserver delivered its size. Commit fixes this in CODE: show the bounded count control until the current Tag list has a known fit, and invalidate the previous fit before painting changed route Tags. The existing observer still restores full pills when they fit. Focused regression tests pass (2 files / 19 tests); the production build passes. Exact TagFilterChips perf pin hashes were refreshed; the exception count remains 22369 and no rule or ratchet was weakened. The existing browser geometry assertions are unchanged. The first Server gate failed only startup_serves_http_while_upgrade_backfills_wait at its unchanged 15-second deadline (child elapsed 112.95s). All other non-ignored tests passed. The final gate will run after the native patch with no concurrent Rust build.
Author
Owner

The 4× Tag crop showed the dot/remove icon slightly below the label cap centre. Commit 5e6837121 applies the existing optical-caps helper to removable Tag labels and the overflow count. It adds no runtime layout measurement or observer. Focused Tag/ItemPreview tests pass (2 files, 17 tests); perf-lint passes with the unchanged 22369 exact exceptions.

The first toast walkthrough failed to observe the completed upload while an update toast appeared. The server build output reports CALTERNAL_BUILD_ID=2240078ad89a1b4a09c7e63f2ebcf1dfedd5a18e, while the separately built SPA was newer. This fixture mismatch triggers the real app update flow. The final server and SPA will be rebuilt at the same HEAD before capturing again. The upload visibility assertion remains unchanged; no upload timer behavior was changed.

The full single-thread Notes run has now passed both the 650-Daily-note rebuild and the 700-Note reconcile cases that were slow under the shared-host run. Remaining tests are still running.

The 4× Tag crop showed the dot/remove icon slightly below the label cap centre. Commit 5e6837121 applies the existing optical-caps helper to removable Tag labels and the overflow count. It adds no runtime layout measurement or observer. Focused Tag/ItemPreview tests pass (2 files, 17 tests); perf-lint passes with the unchanged 22369 exact exceptions. The first toast walkthrough failed to observe the completed upload while an update toast appeared. The server build output reports CALTERNAL_BUILD_ID=2240078ad89a1b4a09c7e63f2ebcf1dfedd5a18e, while the separately built SPA was newer. This fixture mismatch triggers the real app update flow. The final server and SPA will be rebuilt at the same HEAD before capturing again. The upload visibility assertion remains unchanged; no upload timer behavior was changed. The full single-thread Notes run has now passed both the 650-Daily-note rebuild and the 700-Note reconcile cases that were slow under the shared-host run. Remaining tests are still running.
Author
Owner

Production evidence at 5e683712155e6f93941f6e8331a5f62d46112d5e.

Tag filter walkthrough: PASS, 112 captures. Toast walkthrough: PASS, 24 captures. Both use the real production build and matching server metadata, macOS emulation, 390/820/1440 px, and paper/tokyo-night themes. The shared cap-height trim fixes the observed icon/label offset. The orchestrator must review visual quality.

Full web gates exited 0:


perf-lint: PASS; 0 violations; 22369 scoped exceptions

svelte-check found 0 errors and 2 warnings in 2 files

Test Files  270 passed (270)

Tests  1841 passed (1841)

The two warnings are existing empty CSS rules in AttachmentDeck and AgendaList. The live serial Notes suite has passed both large reconstruction cases; remaining tests and the final server suite are still running. No gate assertions were weakened.

Evidence:

merge27-review.zip

chip-row-1-tag-paper-4x-mac.png

chip-row-1-tag-tokyo-night-4x-mac.png

chip-row-2-tags-paper-4x-mac.png

chip-row-2-tags-tokyo-night-4x-mac.png

Production evidence at `5e683712155e6f93941f6e8331a5f62d46112d5e`. Tag filter walkthrough: PASS, 112 captures. Toast walkthrough: PASS, 24 captures. Both use the real production build and matching server metadata, macOS emulation, 390/820/1440 px, and paper/tokyo-night themes. The shared cap-height trim fixes the observed icon/label offset. The orchestrator must review visual quality. Full web gates exited 0: ```text perf-lint: PASS; 0 violations; 22369 scoped exceptions svelte-check found 0 errors and 2 warnings in 2 files Test Files 270 passed (270) Tests 1841 passed (1841) ``` The two warnings are existing empty CSS rules in AttachmentDeck and AgendaList. The live serial Notes suite has passed both large reconstruction cases; remaining tests and the final server suite are still running. No gate assertions were weakened. Evidence: [merge27-review.zip](https://git.kayg.org/attachments/2d0330d4-2214-4798-a895-6dbb2421de91) ![chip-row-1-tag-paper-4x-mac.png](https://git.kayg.org/attachments/24121c74-02bf-419e-aee0-e545241320b0) ![chip-row-1-tag-tokyo-night-4x-mac.png](https://git.kayg.org/attachments/0158cdf8-f99a-4923-84e6-aa173163309d) ![chip-row-2-tags-paper-4x-mac.png](https://git.kayg.org/attachments/474df7cf-5420-405f-a2be-09f386bf14f7) ![chip-row-2-tags-tokyo-night-4x-mac.png](https://git.kayg.org/attachments/41f08eb0-192b-4eb0-ab0f-55777522a0c0)
Author
Owner

Notes and focused toast API gates now pass at 5e683712155e6f93941f6e8331a5f62d46112d5e.

cargo test -p calternal-plugin-notes -- --test-threads=1 exited 0. Serial dispatch keeps the existing assertions and bounded waits intact on this shared host.

test result: ok. 288 passed; 0 failed; 3 ignored; 0 measured; 0 filtered out; finished in 909.22s
test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.24s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
Notes gate exit: 0

Focused toast API round exited 0:

PASS #1142 toast route auth, validation, idempotency, User isolation and concurrent writes

The final server and remaining changed-crate suites are running serially. The original native crash has no captured stack. The mapped-library overwrite race is independently reproduced and covered by the new regression.

Notes and focused toast API gates now pass at `5e683712155e6f93941f6e8331a5f62d46112d5e`. `cargo test -p calternal-plugin-notes -- --test-threads=1` exited 0. Serial dispatch keeps the existing assertions and bounded waits intact on this shared host. ```text test result: ok. 288 passed; 0 failed; 3 ignored; 0 measured; 0 filtered out; finished in 909.22s test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.24s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s Notes gate exit: 0 ``` Focused toast API round exited 0: ```text PASS #1142 toast route auth, validation, idempotency, User isolation and concurrent writes ``` The final server and remaining changed-crate suites are running serially. The original native crash has no captured stack. The mapped-library overwrite race is independently reproduced and covered by the new regression.
Author
Owner

The required server gate is not green. At 5e683712155e6f93941f6e8331a5f62d46112d5e, serial dispatch passed the startup-lock child but failed the unchanged #965 Search-rebuild latency assertion. All 32 writes returned HTTP 201; p95 was 14.586 seconds against 10 seconds. The owner rule treats SLOW-only local findings as host load, but the CLI result remains exit 101. No assertion or budget was changed.

search_reconcile_calendar_write_profile files=20000 writes=32 p50_ms=14233 p95_ms=14586 p95_budget_ms=10000
test result: FAILED. 262 passed; 1 failed; 10 ignored; 0 measured; 0 filtered out; finished in 123.98s

The standard shell E2E also stops at the four-versus-five visible Tab geometry assertion after opening Ask at 1440 px. It preserves the selected Tab and scrolling. Filed as #1172; its assertion is unchanged. This is a cosmetic finding under the owner rule.

The remaining five changed-crate test suites are still running. Web, Notes, all changed-crate Clippy gates, both feature screenshot matrices, and the focused toast API round pass. The final report will state the server and shell failures explicitly.

The required server gate is not green. At `5e683712155e6f93941f6e8331a5f62d46112d5e`, serial dispatch passed the startup-lock child but failed the unchanged #965 Search-rebuild latency assertion. All 32 writes returned HTTP 201; p95 was 14.586 seconds against 10 seconds. The owner rule treats SLOW-only local findings as host load, but the CLI result remains exit 101. No assertion or budget was changed. ```text search_reconcile_calendar_write_profile files=20000 writes=32 p50_ms=14233 p95_ms=14586 p95_budget_ms=10000 test result: FAILED. 262 passed; 1 failed; 10 ignored; 0 measured; 0 filtered out; finished in 123.98s ``` The standard shell E2E also stops at the four-versus-five visible Tab geometry assertion after opening Ask at 1440 px. It preserves the selected Tab and scrolling. Filed as #1172; its assertion is unchanged. This is a cosmetic finding under the owner rule. The remaining five changed-crate test suites are still running. Web, Notes, all changed-crate Clippy gates, both feature screenshot matrices, and the focused toast API round pass. The final report will state the server and shell failures explicitly.
Author
Owner

Documentation review complete: c798666dc adds the required doc comment at copy_unix_runtime_libs. It states that Cargo releases its target lock before tests and that atomic staging must preserve loaded code and private relocation pages. Workspace formatting and the actual build-script regression both exit 0. No behavior changed after the production screenshot matrices at 5e6837121; UI source is identical.

Files now passes: 258 tests, four intentional ignores, exit 0. Photos and Notifications are the last running suites. The server latency gate failure is filed as #1173; the shell Tab Bar geometry failure is #1172. Both assertions remain unchanged.

Documentation review complete: `c798666dc` adds the required doc comment at `copy_unix_runtime_libs`. It states that Cargo releases its target lock before tests and that atomic staging must preserve loaded code and private relocation pages. Workspace formatting and the actual build-script regression both exit 0. No behavior changed after the production screenshot matrices at `5e6837121`; UI source is identical. Files now passes: 258 tests, four intentional ignores, exit 0. Photos and Notifications are the last running suites. The server latency gate failure is filed as #1173; the shell Tab Bar geometry failure is #1172. Both assertions remain unchanged.
Author
Owner

Merge27j final report: code committed; not all required gates are green.

Head SHA: d71c6cb0c2. Branch: job/merge27. Base origin/dev: d0061ec3df. Supplied integration head: 869653b19. No push or deployment was performed by this job.

Built

  • Merged job/toast-1142 and job/segv-1136. Calendar keeps noteId: null in the fixture. Photos keeps stable Tag-aware links, background-toast classification and inline announcement. Notes keeps caller-supplied unique User IDs and the incoming bounded SQLite-busy retry.
  • Fixed static Tag chip text and accessible-name whitespace without changing ItemPreview assertions. Removable filters keep their design.
  • Fixed the Photos refresh regression introduced by d03f67959 (#1109). Unfiltered burst refresh keeps the four-argument page contract; active AND filters use the fifth Tags argument. Existing later-page assertions remain intact; added active-filter coverage.
  • Refreshed exact live perf pins, including the sidebar. Final count: 22369. No rule or latency budget was weakened. Shared shape/focus styles replace local duplication.
  • Closed first-frame and route-change Tag overlap. Show a bounded count until the existing fit observer delivers, and reschedule when a route preserves its Tags. Labels use the existing cap-height trim.
  • Fixed the confirmed native staging race. Vendored verified sherpa-onnx-sys 1.13.8, preserved its Apache-2.0 license/source, and reused its atomic-copy helper for Unix runtime libraries. FFI, runtime version and Windows behavior are unchanged. The actual build-script regression covers both Unix filename branches and output directories, old descriptors and private dirty relocation pages.
  • Updated Settings/Notes/Canvas toast assertions only where #1142 explicitly changes behavior. Clipboard checks remain; five recovery callbacks are invoked and their destinations checked. The static source-policy scan has a scoped 30-second timeout with unchanged assertions.
  • Re-read module and local change comments; added the native staging invariant at its owning function in the final documentation-only commit.

Files

Main conflict/fix files: apps/web/src/lib/calendar/MonthGrid.svelte.test.ts; apps/web/src/lib/photos/PhotosView.svelte; crates/plugins/notes/src/lib.rs; packages/ui/src/components/TagPill.svelte and TagFilterChips.svelte; Photos timeline and its tests; tagFilterChips.svelte.test.ts; SettingsCard and its tests; Notes/Canvas creation tests; toast-policy tests; contracts/perf/exceptions.json and adoption-1058.json; root Cargo.toml/Cargo.lock; vendor/sherpa-onnx-sys; tests/adversarial/test_native_runtime_copy.py.
Full local integration list (200 paths): artifacts/merged-files-final.txt. Changes after the supplied head: artifacts/changed-files-final.txt.

Gates — output quoted verbatim

A clean bun install --frozen-lockfile exited 0 before web gates. Cargo used line-tables-only, incremental=0, jobs=4, the preset target directory and worktree TMPDIR. Crate suites ran sequentially. Serial dispatch preserves existing waits and assertions; a four-thread Notes run had a transient busy failure.

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

cd apps/web && bun run check: exit 0

perf-lint: PASS; 0 violations; 22369 scoped exceptions
svelte-check found 0 errors and 2 warnings in 2 files

cd apps/web && bun run test (two workers): exit 0

 Test Files  270 passed (270)
      Tests  1841 passed (1841)
   Duration  423.36s (environment 29%, transform 25%, import 25%, tests 14%, setup 5%)

Clippy --all-targets -- -D warnings, calternal-plugin-notes and calternal-server: exit 0.

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

Clippy --all-targets -- -D warnings, calternal-plugin: exit 0.

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 18m 51s

Clippy --all-targets -- -D warnings, calternal-tags: exit 0.

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

Clippy --all-targets -- -D warnings, calternal-plugin-files: exit 0.

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

Clippy --all-targets -- -D warnings, calternal-plugin-photos: exit 0.

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

Clippy --all-targets -- -D warnings, calternal-plugin-notifications: exit 0.

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

cargo test -p calternal-plugin-notes -- --test-threads=1: exit 0.

test result: ok. 288 passed; 0 failed; 3 ignored; 0 measured; 0 filtered out; finished in 909.22s
test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.24s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

cargo test -p calternal-server -- --test-threads=1: exit 101.

test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 272 filtered out; finished in 26.80s
test result: FAILED. 262 passed; 1 failed; 10 ignored; 0 measured; 0 filtered out; finished in 123.98s

cargo test -p calternal-plugin -- --test-threads=1: exit 0.

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

cargo test -p calternal-tags -- --test-threads=1: exit 0.

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

cargo test -p calternal-plugin-files -- --test-threads=1: exit 0.

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

cargo test -p calternal-plugin-photos -- --test-threads=1: exit 0.

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

cargo test -p calternal-plugin-notifications -- --test-threads=1: exit 0.

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

Actual SDK build-script regression: exit 0; four subcases. Unpatched staging fails this invariant.

.
----------------------------------------------------------------------
Ran 1 test in 0.172s

OK

python3 -m unittest bench.test_record: exit 0.

..............
----------------------------------------------------------------------
Ran 14 tests in 0.169s

OK

toast-api-final.log: exit 0.

PASS #1142 toast route auth, validation, idempotency, User isolation and concurrent writes

tagfilter-e2e-cap-final.log: exit 0.

PASS #1109 current-view Tag filters; macOS production captures: /home/kayg/Developer/calternal-wt/merge27/artifacts/tagfilter-cap-final

toast-e2e-matched-final.log: exit 0.

PASS captured twenty-four production screenshots in /home/kayg/Developer/calternal-wt/merge27/artifacts/toast-1142

Known gaps and failed verification

  • Required server gate exits 101. All 32 Calendar writes returned HTTP 201 within the 20-second client deadline during the 20,000-file Search rebuild, but p95 exceeds the unchanged 10-second budget. Filed #1173. The owner rule treats SLOW-only local findings as host load; this does not make the CLI gate green.
search_reconcile_calendar_write_profile files=20000 writes=32 p50_ms=14233 p95_ms=14586 p95_budget_ms=10000
  • Standard cd apps/web && bun run test:e2e exits 1 at the desktop Tab Bar geometry assertion: Ask leaves four complete Tabs in a five-Tab window. Selection remains visible and scrolling works. Both Tab Bar source files match origin/dev. Filed #1172; expectation unchanged. First-owner setup, passkey/recovery handoff and real Daily note/Note creation passed; CSP reports were zero.
  • Two existing web warnings: empty CSS rules in AttachmentDeck and AgendaList.
  • The original SIGSEGV has no captured native stack. The overwrite race is independently proven and fixed; the full Notes suite exits cleanly. Attribution of that original crash remains an inference.
  • Upstream vendor formatting is retained. Workspace formatting passes; standalone rustfmt reports upstream formatting differences.
  • Broad cross-plugin API matrices, real Mac interop, deployment checks and perf-VM measurements were not run. The focused new-route contract/isolation round and both production feature matrices did run.

UX gaps closed

Exact Tag labels/accessible names; safe first-frame and route-change fit; icon/label cap-height alignment through shared CSS; preserved loaded Photos pages and active AND filters; polite inline heading Copy link feedback; working Note/Canvas recovery actions.

UX gaps left

Desktop Tab Bar geometry (#1172). Search-rebuild timing needs follow-up (#1173); the local debug observation does not establish a release regression.

Decisions

  • Start changed Tag rows as a count control until fit is known, then expand through the existing observer. Content and actions stay available immediately.
  • Use the existing optical cap trim; add no runtime text measurement or layout observer for alignment.
  • Keep the verified SDK version and carry the minimal atomic-staging dependency patch with its original compatible license.
  • Give the static source-policy scan 30 seconds, preserving assertions and all interaction/performance budgets.
  • Use serial Rust dispatch after observed SQLite contention. Do not weaken assertions or rerun in a loop to wait for a quiet host.

Evidence

Production matrices use macOS emulation, 390/820/1440 px, paper/tokyo-night. 112 Tag captures and 24 toast captures. Capture revision: 5e6837121. The final commit changes only SDK documentation; UI source is identical. The orchestrator reviews visual quality.

merge27-review.zip

chip-row-1-tag-paper-4x-mac.png

chip-row-1-tag-tokyo-night-4x-mac.png

chip-row-2-tags-paper-4x-mac.png

chip-row-2-tags-tokyo-night-4x-mac.png

Remaining verification

After investigating #1173, cargo test -p calternal-server -- --test-threads=1 must exit 0 without changing budgets. After fixing #1172, cd apps/web && bun run test:e2e must retain and pass the configured visible-Tab count assertion.

Cleanup

cargo clean: exit 0.

     Removed 25123 files, 25.4GiB total

Removed known generated web build directories and worktree test temporary directory with path checks. Artifacts remain untracked. Source worktree is clean.

Merge27j final report: code committed; not all required gates are green. Head SHA: d71c6cb0c242aa5b039f24c23480eada37704a96. Branch: job/merge27. Base origin/dev: d0061ec3df127d81c86729d07d899b0bf2b6de91. Supplied integration head: 869653b19. No push or deployment was performed by this job. **Built** - Merged job/toast-1142 and job/segv-1136. Calendar keeps noteId: null in the fixture. Photos keeps stable Tag-aware links, background-toast classification and inline announcement. Notes keeps caller-supplied unique User IDs and the incoming bounded SQLite-busy retry. - Fixed static Tag chip text and accessible-name whitespace without changing ItemPreview assertions. Removable filters keep their design. - Fixed the Photos refresh regression introduced by d03f67959 (#1109). Unfiltered burst refresh keeps the four-argument page contract; active AND filters use the fifth Tags argument. Existing later-page assertions remain intact; added active-filter coverage. - Refreshed exact live perf pins, including the sidebar. Final count: 22369. No rule or latency budget was weakened. Shared shape/focus styles replace local duplication. - Closed first-frame and route-change Tag overlap. Show a bounded count until the existing fit observer delivers, and reschedule when a route preserves its Tags. Labels use the existing cap-height trim. - Fixed the confirmed native staging race. Vendored verified sherpa-onnx-sys 1.13.8, preserved its Apache-2.0 license/source, and reused its atomic-copy helper for Unix runtime libraries. FFI, runtime version and Windows behavior are unchanged. The actual build-script regression covers both Unix filename branches and output directories, old descriptors and private dirty relocation pages. - Updated Settings/Notes/Canvas toast assertions only where #1142 explicitly changes behavior. Clipboard checks remain; five recovery callbacks are invoked and their destinations checked. The static source-policy scan has a scoped 30-second timeout with unchanged assertions. - Re-read module and local change comments; added the native staging invariant at its owning function in the final documentation-only commit. **Files** Main conflict/fix files: apps/web/src/lib/calendar/MonthGrid.svelte.test.ts; apps/web/src/lib/photos/PhotosView.svelte; crates/plugins/notes/src/lib.rs; packages/ui/src/components/TagPill.svelte and TagFilterChips.svelte; Photos timeline and its tests; tagFilterChips.svelte.test.ts; SettingsCard and its tests; Notes/Canvas creation tests; toast-policy tests; contracts/perf/exceptions.json and adoption-1058.json; root Cargo.toml/Cargo.lock; vendor/sherpa-onnx-sys; tests/adversarial/test_native_runtime_copy.py. Full local integration list (200 paths): artifacts/merged-files-final.txt. Changes after the supplied head: artifacts/changed-files-final.txt. **Gates — output quoted verbatim** A clean bun install --frozen-lockfile exited 0 before web gates. Cargo used line-tables-only, incremental=0, jobs=4, the preset target directory and worktree TMPDIR. Crate suites ran sequentially. Serial dispatch preserves existing waits and assertions; a four-thread Notes run had a transient busy failure. cargo fmt --check: exit 0, no output. cd apps/web && bun run check: exit 0 ```text perf-lint: PASS; 0 violations; 22369 scoped exceptions svelte-check found 0 errors and 2 warnings in 2 files ``` cd apps/web && bun run test (two workers): exit 0 ```text Test Files 270 passed (270) Tests 1841 passed (1841) Duration 423.36s (environment 29%, transform 25%, import 25%, tests 14%, setup 5%) ``` Clippy --all-targets -- -D warnings, calternal-plugin-notes and calternal-server: exit 0. ```text Finished `dev` profile [unoptimized + debuginfo] target(s) in 3m 08s ``` Clippy --all-targets -- -D warnings, calternal-plugin: exit 0. ```text Finished `dev` profile [unoptimized + debuginfo] target(s) in 18m 51s ``` Clippy --all-targets -- -D warnings, calternal-tags: exit 0. ```text Finished `dev` profile [unoptimized + debuginfo] target(s) in 46.28s ``` Clippy --all-targets -- -D warnings, calternal-plugin-files: exit 0. ```text Finished `dev` profile [unoptimized + debuginfo] target(s) in 1m 51s ``` Clippy --all-targets -- -D warnings, calternal-plugin-photos: exit 0. ```text Finished `dev` profile [unoptimized + debuginfo] target(s) in 1m 36s ``` Clippy --all-targets -- -D warnings, calternal-plugin-notifications: exit 0. ```text Finished `dev` profile [unoptimized + debuginfo] target(s) in 1m 52s ``` cargo test -p calternal-plugin-notes -- --test-threads=1: exit 0. ```text test result: ok. 288 passed; 0 failed; 3 ignored; 0 measured; 0 filtered out; finished in 909.22s test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.24s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s ``` cargo test -p calternal-server -- --test-threads=1: exit 101. ```text test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 272 filtered out; finished in 26.80s test result: FAILED. 262 passed; 1 failed; 10 ignored; 0 measured; 0 filtered out; finished in 123.98s ``` cargo test -p calternal-plugin -- --test-threads=1: exit 0. ```text test result: ok. 44 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 9.21s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s ``` cargo test -p calternal-tags -- --test-threads=1: exit 0. ```text test result: ok. 20 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 15.44s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s ``` cargo test -p calternal-plugin-files -- --test-threads=1: exit 0. ```text test result: ok. 258 passed; 0 failed; 4 ignored; 0 measured; 0 filtered out; finished in 532.54s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s ``` cargo test -p calternal-plugin-photos -- --test-threads=1: exit 0. ```text test result: ok. 56 passed; 0 failed; 4 ignored; 0 measured; 0 filtered out; finished in 63.71s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s ``` cargo test -p calternal-plugin-notifications -- --test-threads=1: exit 0. ```text test result: ok. 37 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 11.96s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s ``` Actual SDK build-script regression: exit 0; four subcases. Unpatched staging fails this invariant. ```text . ---------------------------------------------------------------------- Ran 1 test in 0.172s OK ``` python3 -m unittest bench.test_record: exit 0. ```text .............. ---------------------------------------------------------------------- Ran 14 tests in 0.169s OK ``` toast-api-final.log: exit 0. ```text PASS #1142 toast route auth, validation, idempotency, User isolation and concurrent writes ``` tagfilter-e2e-cap-final.log: exit 0. ```text PASS #1109 current-view Tag filters; macOS production captures: /home/kayg/Developer/calternal-wt/merge27/artifacts/tagfilter-cap-final ``` toast-e2e-matched-final.log: exit 0. ```text PASS captured twenty-four production screenshots in /home/kayg/Developer/calternal-wt/merge27/artifacts/toast-1142 ``` **Known gaps and failed verification** - Required server gate exits 101. All 32 Calendar writes returned HTTP 201 within the 20-second client deadline during the 20,000-file Search rebuild, but p95 exceeds the unchanged 10-second budget. Filed #1173. The owner rule treats SLOW-only local findings as host load; this does not make the CLI gate green. ```text search_reconcile_calendar_write_profile files=20000 writes=32 p50_ms=14233 p95_ms=14586 p95_budget_ms=10000 ``` - Standard cd apps/web && bun run test:e2e exits 1 at the desktop Tab Bar geometry assertion: Ask leaves four complete Tabs in a five-Tab window. Selection remains visible and scrolling works. Both Tab Bar source files match origin/dev. Filed #1172; expectation unchanged. First-owner setup, passkey/recovery handoff and real Daily note/Note creation passed; CSP reports were zero. - Two existing web warnings: empty CSS rules in AttachmentDeck and AgendaList. - The original SIGSEGV has no captured native stack. The overwrite race is independently proven and fixed; the full Notes suite exits cleanly. Attribution of that original crash remains an inference. - Upstream vendor formatting is retained. Workspace formatting passes; standalone rustfmt reports upstream formatting differences. - Broad cross-plugin API matrices, real Mac interop, deployment checks and perf-VM measurements were not run. The focused new-route contract/isolation round and both production feature matrices did run. **UX gaps closed** Exact Tag labels/accessible names; safe first-frame and route-change fit; icon/label cap-height alignment through shared CSS; preserved loaded Photos pages and active AND filters; polite inline heading Copy link feedback; working Note/Canvas recovery actions. **UX gaps left** Desktop Tab Bar geometry (#1172). Search-rebuild timing needs follow-up (#1173); the local debug observation does not establish a release regression. **Decisions** - Start changed Tag rows as a count control until fit is known, then expand through the existing observer. Content and actions stay available immediately. - Use the existing optical cap trim; add no runtime text measurement or layout observer for alignment. - Keep the verified SDK version and carry the minimal atomic-staging dependency patch with its original compatible license. - Give the static source-policy scan 30 seconds, preserving assertions and all interaction/performance budgets. - Use serial Rust dispatch after observed SQLite contention. Do not weaken assertions or rerun in a loop to wait for a quiet host. **Evidence** Production matrices use macOS emulation, 390/820/1440 px, paper/tokyo-night. 112 Tag captures and 24 toast captures. Capture revision: 5e6837121. The final commit changes only SDK documentation; UI source is identical. The orchestrator reviews visual quality. [merge27-review.zip](https://git.kayg.org/attachments/2d0330d4-2214-4798-a895-6dbb2421de91) [chip-row-1-tag-paper-4x-mac.png](https://git.kayg.org/attachments/24121c74-02bf-419e-aee0-e545241320b0) [chip-row-1-tag-tokyo-night-4x-mac.png](https://git.kayg.org/attachments/0158cdf8-f99a-4923-84e6-aa173163309d) [chip-row-2-tags-paper-4x-mac.png](https://git.kayg.org/attachments/474df7cf-5420-405f-a2be-09f386bf14f7) [chip-row-2-tags-tokyo-night-4x-mac.png](https://git.kayg.org/attachments/41f08eb0-192b-4eb0-ab0f-55777522a0c0) **Remaining verification** After investigating #1173, cargo test -p calternal-server -- --test-threads=1 must exit 0 without changing budgets. After fixing #1172, cd apps/web && bun run test:e2e must retain and pass the configured visible-Tab count assertion. **Cleanup** cargo clean: exit 0. ```text Removed 25123 files, 25.4GiB total ``` Removed known generated web build directories and worktree test temporary directory with path checks. Artifacts remain untracked. Source worktree is clean.
Author
Owner

Correction to the base field in the preceding final report: I read the shared remote-tracking tip after it advanced. The tested base is 41bf97fb28, not d0061ec3df. Gate results and final head d71c6cb0c2 are unchanged. The source worktree is clean. Cargo cleanup freed 25.4 GiB; web build output and test temporary data are removed. No second merge was run, per the once-per-round rule.

Correction to the base field in the preceding final report: I read the shared remote-tracking tip after it advanced. The tested base is 41bf97fb2861ea6e4ea70aab7d3b15a1c9aa278d, not d0061ec3df127d81c86729d07d899b0bf2b6de91. Gate results and final head d71c6cb0c242aa5b039f24c23480eada37704a96 are unchanged. The source worktree is clean. Cargo cleanup freed 25.4 GiB; web build output and test temporary data are removed. No second merge was run, per the once-per-round rule.
Author
Owner

Starting merge28j on job/merge28, base 46c185487 (merge27 plus minihover, Drawing, tray date). I will merge #1148, #1110, #1129, #1152, #1151 in order, preserve both sides of each conflict, reconcile exact perf contracts, and run the requested web and per-crate gates. No push or deploy.

Starting merge28j on `job/merge28`, base `46c185487` (merge27 plus minihover, Drawing, tray date). I will merge #1148, #1110, #1129, #1152, #1151 in order, preserve both sides of each conflict, reconcile exact perf contracts, and run the requested web and per-crate gates. No push or deploy.
Author
Owner

Merged reviewed branches in order: #1148 7f8f0b11b, #1110 5b3609aef, #1129 54aca22e7, #1152 3aff0c7bd, #1151 8b9752b60.

Resolutions retain created-date projection plus repeated AND Tag predicates, TagRow rename/merge plus modifier navigation, both Inspector test/mock sets and harness helpers, multi-block Copy links/Undo plus URL-card actions, and #1142 copy-feedback behavior. Notes migration 34 collided: date recovery stays 34; later link previews use 35. Upgrade pins now require both. git fetch origin && git merge --no-ff origin/dev returned Already up to date.; origin/dev registers Notes through 33.

Exact perf reconciliation initially reported missing base allowance for Tag metadata-read and mutation scopes. Restored 100 prior branch adoption entries only where their full entry exactly equals the live ledger. No guard rule or per-site limit changed. Frozen install passed: 911 packages installed [9.33s]. Rust and web gates are running.

Merged reviewed branches in order: #1148 `7f8f0b11b`, #1110 `5b3609aef`, #1129 `54aca22e7`, #1152 `3aff0c7bd`, #1151 `8b9752b60`. Resolutions retain created-date projection plus repeated AND Tag predicates, TagRow rename/merge plus modifier navigation, both Inspector test/mock sets and harness helpers, multi-block Copy links/Undo plus URL-card actions, and #1142 copy-feedback behavior. Notes migration 34 collided: date recovery stays 34; later link previews use 35. Upgrade pins now require both. `git fetch origin && git merge --no-ff origin/dev` returned `Already up to date.`; origin/dev registers Notes through 33. Exact perf reconciliation initially reported missing base allowance for Tag metadata-read and mutation scopes. Restored 100 prior branch adoption entries only where their full entry exactly equals the live ledger. No guard rule or per-site limit changed. Frozen install passed: `911 packages installed [9.33s]`. Rust and web gates are running.
Author
Owner

Combined-branch gates found three integration defects and the fixes are in progress:

  1. Svelte: Cannot find name eventTags in app-sidebar. Restored the existing Event-Tag ancestry set used only to restrict rewrites; all Tags still filter Calendar. Recheck reports svelte-check found 0 errors and 2 warnings in 2 files.
  2. Notes test compilation: automatic merge removed the fixture unique-User binding. Restored uuid::Uuid::new_v4() and updated its comment for the shared Notes/Tag writer registry. Notes clippy now passes.
  3. Full web tests: Test Files 1 failed | 272 passed (273) / Tests 1 failed | 1904 passed (1905). Only the #1142 toast-policy test failed on twelve incoming Drawing/Tag/link-card call sites. Adapted failures to named background results, preserved Undo and no-action completion expectations, kept progress actionable through Background Work, and reused shared Copy feedback. Focused toast-policy + Tag-receipt tests now pass: Test Files 2 passed (2) / Tests 6 passed (6). Test expectations were not changed. The final full web rerun and remaining Rust gates are running.
Combined-branch gates found three integration defects and the fixes are in progress: 1. Svelte: `Cannot find name eventTags` in app-sidebar. Restored the existing Event-Tag ancestry set used only to restrict rewrites; all Tags still filter Calendar. Recheck reports `svelte-check found 0 errors and 2 warnings in 2 files`. 2. Notes test compilation: automatic merge removed the fixture unique-User binding. Restored `uuid::Uuid::new_v4()` and updated its comment for the shared Notes/Tag writer registry. Notes clippy now passes. 3. Full web tests: `Test Files 1 failed | 272 passed (273)` / `Tests 1 failed | 1904 passed (1905)`. Only the #1142 toast-policy test failed on twelve incoming Drawing/Tag/link-card call sites. Adapted failures to named background results, preserved Undo and no-action completion expectations, kept progress actionable through Background Work, and reused shared Copy feedback. Focused toast-policy + Tag-receipt tests now pass: `Test Files 2 passed (2)` / `Tests 6 passed (6)`. Test expectations were not changed. The final full web rerun and remaining Rust gates are running.
Author
Owner

Frontend integration fixes committed as f1d705cb2. All requested clippy gates now pass. Final web gates pass after the origin/dev refresh and exact perf reconciliation:

perf-lint: PASS; 0 violations; 22359 scoped exceptions
svelte-check found 0 errors and 2 warnings in 2 files
 Test Files  273 passed (273)
      Tests  1905 passed (1905)
   Duration  299.81s (environment 28%, transform 26%, import 22%, tests 17%, setup 6%)

The two warnings are existing empty CSS rules in AttachmentDeck and AgendaList. No guard rule or test expectation was weakened. Per-crate Rust tests and current-build local browser checks remain.

Frontend integration fixes committed as `f1d705cb2`. All requested clippy gates now pass. Final web gates pass after the origin/dev refresh and exact perf reconciliation: ```text perf-lint: PASS; 0 violations; 22359 scoped exceptions svelte-check found 0 errors and 2 warnings in 2 files Test Files 273 passed (273) Tests 1905 passed (1905) Duration 299.81s (environment 28%, transform 26%, import 22%, tests 17%, setup 6%) ``` The two warnings are existing empty CSS rules in AttachmentDeck and AgendaList. No guard rule or test expectation was weakened. Per-crate Rust tests and current-build local browser checks remain.
Author
Owner

Local verification uses one current-branch server binary and one browser at a time. The browser scripts are tagfilter-1109, tags-1110-1111, notes-dates-1148, info-inspector, notes (BLOCK_ACTIONS_ONLY), and linkcards-1151. The live API round uses the existing XUser and Admin matrices on disposable local state, with a fixed 15-minute deadline. No staging deployment or push.

Local verification uses one current-branch server binary and one browser at a time. The browser scripts are tagfilter-1109, tags-1110-1111, notes-dates-1148, info-inspector, notes (BLOCK_ACTIONS_ONLY), and linkcards-1151. The live API round uses the existing XUser and Admin matrices on disposable local state, with a fixed 15-minute deadline. No staging deployment or push.
Author
Owner

The first Notes test run found one stale migration maximum after merging #1148 and #1151: headingless_projection_migration_restarts_old_cursors still pinned 34, while the merged migration list correctly ends at 35. The explicit migration-pin change is committed in b7d535129; the cursor-reset assertions remain unchanged. The same commit restores the unique User binding that the automatic merge had dropped from the shared writer fixture.

First Notes run, verbatim:

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

Tag tests, verbatim:

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

The server and filesystem test runs are in progress. Notes will run again with the corrected pin. No existing behavioral expectation was changed.

The first Notes test run found one stale migration maximum after merging #1148 and #1151: `headingless_projection_migration_restarts_old_cursors` still pinned 34, while the merged migration list correctly ends at 35. The explicit migration-pin change is committed in `b7d535129`; the cursor-reset assertions remain unchanged. The same commit restores the unique User binding that the automatic merge had dropped from the shared writer fixture. First Notes run, verbatim: ``` test result: FAILED. 303 passed; 1 failed; 4 ignored; 0 measured; 0 filtered out; finished in 370.74s ``` Tag tests, verbatim: ``` test result: ok. 44 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 39.88s ``` The server and filesystem test runs are in progress. Notes will run again with the corrected pin. No existing behavioral expectation was changed.
Author
Owner

Final merged head so far: a7f0c391796a630c5840d117206c8300eb8d2967.

The 7c production fixture ends at Notifications 6. It needs six pending receipts on this branch: Files 26/27, Search 5, Notifications 7, Notes 34/35. Commit a7f0c3917 pins all six and explicitly checks Notifications 7. All existing receipt-preservation and source-data assertions remain unchanged. All four upgrade tests now pass.

The final perf check found four stale NoteView scope pins after the last toast repair. Commit 9cf20e996 refreshes their exact symbols and hashes. The exact ratchet remains 22359 total, raw reads 375, Blaze 277. No rule or scope limit changed.

Final web check, verbatim:

perf-lint: PASS; 0 violations; 22359 scoped exceptions
svelte-check found 0 errors and 2 warnings in 2 files

Final Notes tests, verbatim:

test result: ok. 304 passed; 0 failed; 4 ignored; 0 measured; 0 filtered out; finished in 374.57s
test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.18s

Final server tests, verbatim:

HTTP startup waited for an upgrade backfill: Elapsed(())
test result: FAILED. 262 passed; 1 failed; 10 ignored; 0 measured; 0 filtered out; finished in 93.21s

The only final server failure is live_apps_run_in_separate_processes, which reports startup_serves_http_while_upgrade_backfills_wait failing at wire.rs:8443. This is the known #1161 case. Its timeout and assertions remain unchanged. All four required crate clippy runs, Notes/Tags/FS tests, fmt and the full web suite pass. The current-branch executable is building for the local browser and API round.

Final merged head so far: `a7f0c391796a630c5840d117206c8300eb8d2967`. The 7c production fixture ends at Notifications 6. It needs six pending receipts on this branch: Files 26/27, Search 5, Notifications 7, Notes 34/35. Commit `a7f0c3917` pins all six and explicitly checks Notifications 7. All existing receipt-preservation and source-data assertions remain unchanged. All four upgrade tests now pass. The final perf check found four stale NoteView scope pins after the last toast repair. Commit `9cf20e996` refreshes their exact symbols and hashes. The exact ratchet remains 22359 total, raw reads 375, Blaze 277. No rule or scope limit changed. Final web check, verbatim: ``` perf-lint: PASS; 0 violations; 22359 scoped exceptions svelte-check found 0 errors and 2 warnings in 2 files ``` Final Notes tests, verbatim: ``` test result: ok. 304 passed; 0 failed; 4 ignored; 0 measured; 0 filtered out; finished in 374.57s test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.18s ``` Final server tests, verbatim: ``` HTTP startup waited for an upgrade backfill: Elapsed(()) test result: FAILED. 262 passed; 1 failed; 10 ignored; 0 measured; 0 filtered out; finished in 93.21s ``` The only final server failure is `live_apps_run_in_separate_processes`, which reports `startup_serves_http_while_upgrade_backfills_wait` failing at wire.rs:8443. This is the known #1161 case. Its timeout and assertions remain unchanged. All four required crate clippy runs, Notes/Tags/FS tests, fmt and the full web suite pass. The current-branch executable is building for the local browser and API round.
Author
Owner

The production browser run found a merged Tag-filter timing regression: shared TagRow postponed pointer navigation by 250 ms for full-route double-click rename. The Calendar filter assertion saw no active Tag immediately after a click. Current-view callbacks now run immediately; full-route rows still retain the original rename window. The Tasks row also retains its task-tag-link identity. New regression tests cover immediate modifier handling, cancellation of full-route navigation on double-click, and immediate keyboard activation. All three runtime tests pass. Full web check/test are in progress with the corrected strict TypeScript mock access.

The full Tag rewrite browser flow passes, including rename, merge, exact-byte Undo and touch. The date review fixture edited a Blob-backed inode directly. That changed the Blob without updating its content hash, and the existing hard-link provenance guard refused the later backfill. The fixture now replaces the inode with a fresh imported source and leaves the Blob intact; no filesystem protection or assertion is weakened. The rerun is pending the final production build.

Inspector, block actions and link-card capture needed the installed Nix C++ runtime library path for sharp. The runtime now loads successfully with libvips 8.18.7. This is a host prerequisite, not a product change.

The local API round passes its media, Calendar subscription and Photos Share prechecks. Cross-User reached the CLI Search proof and found that the server-only build had not built calternal. The required clients are building. Admin is continuing; the remaining Cross-User scenarios will run after that prerequisite is fixed.

The production browser run found a merged Tag-filter timing regression: shared TagRow postponed pointer navigation by 250 ms for full-route double-click rename. The Calendar filter assertion saw no active Tag immediately after a click. Current-view callbacks now run immediately; full-route rows still retain the original rename window. The Tasks row also retains its `task-tag-link` identity. New regression tests cover immediate modifier handling, cancellation of full-route navigation on double-click, and immediate keyboard activation. All three runtime tests pass. Full web check/test are in progress with the corrected strict TypeScript mock access. The full Tag rewrite browser flow passes, including rename, merge, exact-byte Undo and touch. The date review fixture edited a Blob-backed inode directly. That changed the Blob without updating its content hash, and the existing hard-link provenance guard refused the later backfill. The fixture now replaces the inode with a fresh imported source and leaves the Blob intact; no filesystem protection or assertion is weakened. The rerun is pending the final production build. Inspector, block actions and link-card capture needed the installed Nix C++ runtime library path for sharp. The runtime now loads successfully with libvips 8.18.7. This is a host prerequisite, not a product change. The local API round passes its media, Calendar subscription and Photos Share prechecks. Cross-User reached the CLI Search proof and found that the server-only build had not built `calternal`. The required clients are building. Admin is continuing; the remaining Cross-User scenarios will run after that prerequisite is fixed.
Author
Owner

merge28j final report — #1109

Head: f5fbced3c7 (job/merge28). Working tree is clean. No push or deploy. origin/dev was fetched and merged once before final gates; it was already included.

All five requested branches are merged and committed. Required gates pass except the unchanged startup-timeout test tracked in #1161. This report does not claim an all-green server gate.

Per-branch merge summary

Branch Merge commit Reconciled behavior
job/dates-1148 7f8f0b11b Note created-date backfill and existing Tag filters both remain. Upgrade receipts include Notes and Notifications backfills.
job/tags-1110 5b3609aef Durable Tag rename/merge and Undo coexist with #1109 AND/Meta/Ctrl filters. Both Notes writer and MIME upsert changes remain.
job/inspector-1129 54aca22e7 Inspector and collaborative-history harness coexist with Files metadata spacing. Date and version mocks remain.
job/blockpill-1152 3aff0c7bd Block actions, multi-selection, scoped delete Undo and Copy links retain shared action feedback.
job/linkcards-1151 8b9752b60 Rich link cards coexist with block actions and shared editor props. Notes preview migration is 0035; date migration stays 0034.

Follow-up atomic commits fix upgrade receipt pins, exact performance contract pins, shared action feedback, Tag filter timing, missing eventTags wiring, Cross-User classification/fixtures, and browser fixture integration. The final Inspector commit changes test helpers only. Production UI was last changed in 4df4593c5 and was verified with a production build.

Files

The full 131-file manifest is included in the verification attachment as files.txt. Main integration files: crates/plugins/notes/src/lib.rs and its store/migrations/tests; crates/calternal-tags/src/lib.rs; crates/calternal-server/src/upgrade_tests.rs; apps/web/src/lib/components/app-sidebar.svelte; TasksSidebar.svelte; TagRow.svelte and its regression tests; apps/web/src/lib/notes/NoteView.svelte and api.ts; apps/web/e2e/harness.mjs and reviewed browser scenarios; tests/adversarial classification/fixtures; scripts/perf_guards contract files. Incoming reviewed branch files are included in the manifest.

Decisions

  • Keep Notes date migration 0034 and assign link previews 0035. Update all affected store and upgrade pins; do not reuse deployed numbers.
  • Apply current-view Tag filter callbacks immediately. Keep the existing double-click rename arbitration window for full-route Tag browsing. Keep Meta/Ctrl filter modifiers.
  • Use shared #1142 actionable feedback for incoming actions. Do not retry uncertain writes from an error toast.
  • Reconcile exact live performance entries and ratchet counts without weakening any rule or per-site allowance. Final ledger has 22359 scoped exceptions; cache.raw-read is 375 and contract.blaze is 277.
  • No other new product decisions were needed. Conflict resolutions keep both reviewed branches' behavior.

UX gaps closed

Current-view Tag filters respond immediately; Tasks keep their Tag row selector; Calendar keeps event Tag filtering; Tag rename/merge/Undo and filter modifiers coexist. Block actions and rich link cards retain their primary actions and Copy link feedback. Browser fixtures preserve imported Note body/mtime without mutating a shared Blob. Inspector verification waits for the current ready view and checks durable collaborative history without relying on a framework editor class.

UX gaps left: none found in the covered flows. Claude must review the attached visual evidence; these runtime and geometry checks do not replace that review.

Required gate output (verbatim)

Commands: bun install --frozen-lockfile; cargo fmt --check; cargo clippy -p --all-targets -- -D warnings; cargo test -p ; cd apps/web && bun run check; bun run test --maxWorkers=2.

cargo fmt --check exited 0 with no output. All four clippy commands exited 0. Cargo used the prescribed debug, incremental, jobs and TMPDIR settings and the preset target directory.

Frozen install

bun install v1.4.2 (744846f84)
911 packages installed [9.33s]

Clippy: calternal-plugin-notes

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

Clippy: calternal-tags

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

Clippy: calternal-fs

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

Clippy: calternal-server

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

Tests: calternal-plugin-notes

test result: ok. 304 passed; 0 failed; 4 ignored; 0 measured; 0 filtered out; finished in 374.57s
test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.18s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

Tests: calternal-tags

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

Tests: calternal-fs

test result: ok. 95 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out; finished in 16.72s
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.10s
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.17s
test result: ok. 52 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 18.93s
test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.05s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

Tests: calternal-server (known #1161 failure)

HTTP startup waited for an upgrade backfill: Elapsed(())
test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 272 filtered out; finished in 24.76s
test result: FAILED. 262 passed; 1 failed; 10 ignored; 0 measured; 0 filtered out; finished in 93.21s
error: test failed, to rerun pass `-p calternal-server --bin calternal-server`

Web check

perf-lint: PASS; 0 violations; 22359 scoped exceptions
svelte-check found 0 errors and 2 warnings in 2 files

Full web tests

 Test Files  274 passed (274)
      Tests  1908 passed (1908)
   Duration  507.96s (transform 30%, environment 26%, import 22%, tests 17%, setup 5%)

The two Svelte warnings are existing empty CSS rules in AttachmentDeck and AgendaList. The server failure is startup_serves_http_while_upgrade_backfills_wait, reported through live_apps_run_in_separate_processes. Its expectation and implementation were not changed. All four focused upgrade tests pass after the receipt reconciliation.

Live API verification

The completed Admin matrix reports:

Authorization matrix: 415 OpenAPI operations; 2848 requests across 4 base identities plus invalid/stale session probes and 21 App Password scope classes; valid/malformed session bodies on 17 privileged body routes; App Passwords use valid bodies; policy classes {'public': 20, 'public_link': 12, 'user': 335, 'admin': 48}
Two-User OpenAPI matrix: 415 operations classified; 197 operations replayed; 913 A-ID vs missing-ID comparisons across B, C, D and anonymous; 37 identifier routes classified with no local fixture factory; median absolute timing delta 0.5 ms
Job/Mail/quota ownership checks: 117 comparisons; 0 denial failures
Revoked Share timing control: identical HTTP 404 profiles; median delta 3.2 ms across 12 alternating pairs

The first combined runner stopped at a missing local CLI fixture prerequisite after Admin completed. The CLI/sync clients were built and Cross-User was resumed on a fresh fixture. Cross-User completed, including Tag job/Undo ownership and CLI Search isolation. The resumed wrapper then started a duplicate Admin phase; that duplicate was intentionally stopped. The combined wrapper exits are not presented as all-green runs. The completed Admin and Cross-User phases above found no denial failures. There are 37 inherited identifier routes without a seeded local object factory; this remains a coverage gap. New Tag job and Undo receipts are seeded and checked. The focused classification regression has 16 passing tests.

Production browser evidence

One browser at a time. All six final scenario sets pass at phone 390 px, tablet 820 px and desktop 1440 px, in light and dark, with macOS platform emulation. Screenshots are not committed. Attachments include crops where required:

Coverage: #1109 current-view Tag filters; #1110/#1111 rename/merge/Undo, keyboard and touch; #1148 date backfill and exact body/mtime preservation; #1129 Inspector/history/alignment; #1152/#1125 block actions and multi-selection; #1151 rich link cards, Copy link, reload, live rename, retry/Undo and offline behavior. Final captures: Tag filters 112, Tags 54 plus manifest, dates 18, Inspector 50 including crops, block actions 83, link cards 25.

Known gaps and merge-round status

  • Required server gate remains red only on the known #1161 startup-timeout test. Do not treat this report as an all-green gate result.
  • Claude visual review of attached screenshots remains external to this job.
  • 37 Cross-User identifier routes have no seeded local object factory.
  • No performance measurement was run: this is integration verification, and current policy reserves perf VM measurements for performance issues. Exact performance contracts pass.
  • No push, deploy or Mac interop was performed. No secrets were printed.

Cleanup

cargo clean completed:

     Removed 22353 files, 17.9GiB total

Ignored apps/web/build and apps/web/.svelte-kit output was deleted with guarded directory checks. Review artifacts remain ignored in the worktree. Git status is clean.

Full gate logs, this report and the complete file manifest: merge28 verification archive.

merge28j final report — #1109 Head: f5fbced3c733370b5b37544d7816732628be2fd0 (job/merge28). Working tree is clean. No push or deploy. origin/dev was fetched and merged once before final gates; it was already included. All five requested branches are merged and committed. Required gates pass except the unchanged startup-timeout test tracked in #1161. This report does not claim an all-green server gate. ## Per-branch merge summary | Branch | Merge commit | Reconciled behavior | | --- | --- | --- | | job/dates-1148 | 7f8f0b11b | Note created-date backfill and existing Tag filters both remain. Upgrade receipts include Notes and Notifications backfills. | | job/tags-1110 | 5b3609aef | Durable Tag rename/merge and Undo coexist with #1109 AND/Meta/Ctrl filters. Both Notes writer and MIME upsert changes remain. | | job/inspector-1129 | 54aca22e7 | Inspector and collaborative-history harness coexist with Files metadata spacing. Date and version mocks remain. | | job/blockpill-1152 | 3aff0c7bd | Block actions, multi-selection, scoped delete Undo and Copy links retain shared action feedback. | | job/linkcards-1151 | 8b9752b60 | Rich link cards coexist with block actions and shared editor props. Notes preview migration is 0035; date migration stays 0034. | Follow-up atomic commits fix upgrade receipt pins, exact performance contract pins, shared action feedback, Tag filter timing, missing eventTags wiring, Cross-User classification/fixtures, and browser fixture integration. The final Inspector commit changes test helpers only. Production UI was last changed in 4df4593c5 and was verified with a production build. ## Files The full 131-file manifest is included in the verification attachment as files.txt. Main integration files: crates/plugins/notes/src/lib.rs and its store/migrations/tests; crates/calternal-tags/src/lib.rs; crates/calternal-server/src/upgrade_tests.rs; apps/web/src/lib/components/app-sidebar.svelte; TasksSidebar.svelte; TagRow.svelte and its regression tests; apps/web/src/lib/notes/NoteView.svelte and api.ts; apps/web/e2e/harness.mjs and reviewed browser scenarios; tests/adversarial classification/fixtures; scripts/perf_guards contract files. Incoming reviewed branch files are included in the manifest. ## Decisions - Keep Notes date migration 0034 and assign link previews 0035. Update all affected store and upgrade pins; do not reuse deployed numbers. - Apply current-view Tag filter callbacks immediately. Keep the existing double-click rename arbitration window for full-route Tag browsing. Keep Meta/Ctrl filter modifiers. - Use shared #1142 actionable feedback for incoming actions. Do not retry uncertain writes from an error toast. - Reconcile exact live performance entries and ratchet counts without weakening any rule or per-site allowance. Final ledger has 22359 scoped exceptions; cache.raw-read is 375 and contract.blaze is 277. - No other new product decisions were needed. Conflict resolutions keep both reviewed branches' behavior. ## UX gaps closed Current-view Tag filters respond immediately; Tasks keep their Tag row selector; Calendar keeps event Tag filtering; Tag rename/merge/Undo and filter modifiers coexist. Block actions and rich link cards retain their primary actions and Copy link feedback. Browser fixtures preserve imported Note body/mtime without mutating a shared Blob. Inspector verification waits for the current ready view and checks durable collaborative history without relying on a framework editor class. UX gaps left: none found in the covered flows. Claude must review the attached visual evidence; these runtime and geometry checks do not replace that review. ## Required gate output (verbatim) Commands: bun install --frozen-lockfile; cargo fmt --check; cargo clippy -p <crate> --all-targets -- -D warnings; cargo test -p <crate>; cd apps/web && bun run check; bun run test --maxWorkers=2. cargo fmt --check exited 0 with no output. All four clippy commands exited 0. Cargo used the prescribed debug, incremental, jobs and TMPDIR settings and the preset target directory. Frozen install ```text bun install v1.4.2 (744846f84) 911 packages installed [9.33s] ``` Clippy: calternal-plugin-notes ```text Finished `dev` profile [unoptimized + debuginfo] target(s) in 26.40s ``` Clippy: calternal-tags ```text Finished `dev` profile [unoptimized + debuginfo] target(s) in 1m 16s ``` Clippy: calternal-fs ```text Finished `dev` profile [unoptimized + debuginfo] target(s) in 14.90s ``` Clippy: calternal-server ```text Finished `dev` profile [unoptimized + debuginfo] target(s) in 1m 10s ``` Tests: calternal-plugin-notes ```text test result: ok. 304 passed; 0 failed; 4 ignored; 0 measured; 0 filtered out; finished in 374.57s test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.18s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s ``` Tests: calternal-tags ```text test result: ok. 44 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 39.88s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s ``` Tests: calternal-fs ```text test result: ok. 95 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out; finished in 16.72s test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.10s test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.17s test result: ok. 52 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 18.93s test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.05s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s ``` Tests: calternal-server (known #1161 failure) ```text HTTP startup waited for an upgrade backfill: Elapsed(()) test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 272 filtered out; finished in 24.76s test result: FAILED. 262 passed; 1 failed; 10 ignored; 0 measured; 0 filtered out; finished in 93.21s error: test failed, to rerun pass `-p calternal-server --bin calternal-server` ``` Web check ```text perf-lint: PASS; 0 violations; 22359 scoped exceptions svelte-check found 0 errors and 2 warnings in 2 files ``` Full web tests ```text Test Files 274 passed (274) Tests 1908 passed (1908) Duration 507.96s (transform 30%, environment 26%, import 22%, tests 17%, setup 5%) ``` The two Svelte warnings are existing empty CSS rules in AttachmentDeck and AgendaList. The server failure is startup_serves_http_while_upgrade_backfills_wait, reported through live_apps_run_in_separate_processes. Its expectation and implementation were not changed. All four focused upgrade tests pass after the receipt reconciliation. ## Live API verification The completed Admin matrix reports: ```text Authorization matrix: 415 OpenAPI operations; 2848 requests across 4 base identities plus invalid/stale session probes and 21 App Password scope classes; valid/malformed session bodies on 17 privileged body routes; App Passwords use valid bodies; policy classes {'public': 20, 'public_link': 12, 'user': 335, 'admin': 48} Two-User OpenAPI matrix: 415 operations classified; 197 operations replayed; 913 A-ID vs missing-ID comparisons across B, C, D and anonymous; 37 identifier routes classified with no local fixture factory; median absolute timing delta 0.5 ms Job/Mail/quota ownership checks: 117 comparisons; 0 denial failures Revoked Share timing control: identical HTTP 404 profiles; median delta 3.2 ms across 12 alternating pairs ``` The first combined runner stopped at a missing local CLI fixture prerequisite after Admin completed. The CLI/sync clients were built and Cross-User was resumed on a fresh fixture. Cross-User completed, including Tag job/Undo ownership and CLI Search isolation. The resumed wrapper then started a duplicate Admin phase; that duplicate was intentionally stopped. The combined wrapper exits are not presented as all-green runs. The completed Admin and Cross-User phases above found no denial failures. There are 37 inherited identifier routes without a seeded local object factory; this remains a coverage gap. New Tag job and Undo receipts are seeded and checked. The focused classification regression has 16 passing tests. ## Production browser evidence One browser at a time. All six final scenario sets pass at phone 390 px, tablet 820 px and desktop 1440 px, in light and dark, with macOS platform emulation. Screenshots are not committed. Attachments include crops where required: - [merge28-tagfilters.zip](https://git.kayg.org/attachments/a3748504-e925-4015-bae2-e51c39dcc981) - [merge28-tags.zip](https://git.kayg.org/attachments/a8c4cb53-09d6-4072-923e-4e7834c7dc32) - [merge28-dates.zip](https://git.kayg.org/attachments/bbce17af-7fe3-4e91-800f-3b168a4e0722) - [merge28-block-actions.zip](https://git.kayg.org/attachments/b5097b08-b997-4d5a-9c36-a64dbb9544d5) - [merge28-linkcards.zip](https://git.kayg.org/attachments/4728f08a-aa00-49a8-bffc-1957e6673621) - [merge28-inspector.zip](https://git.kayg.org/attachments/fb549bc7-ee07-45fe-a45e-881f44f6395d) Coverage: #1109 current-view Tag filters; #1110/#1111 rename/merge/Undo, keyboard and touch; #1148 date backfill and exact body/mtime preservation; #1129 Inspector/history/alignment; #1152/#1125 block actions and multi-selection; #1151 rich link cards, Copy link, reload, live rename, retry/Undo and offline behavior. Final captures: Tag filters 112, Tags 54 plus manifest, dates 18, Inspector 50 including crops, block actions 83, link cards 25. ## Known gaps and merge-round status - Required server gate remains red only on the known #1161 startup-timeout test. Do not treat this report as an all-green gate result. - Claude visual review of attached screenshots remains external to this job. - 37 Cross-User identifier routes have no seeded local object factory. - No performance measurement was run: this is integration verification, and current policy reserves perf VM measurements for performance issues. Exact performance contracts pass. - No push, deploy or Mac interop was performed. No secrets were printed. ## Cleanup cargo clean completed: ```text Removed 22353 files, 17.9GiB total ``` Ignored apps/web/build and apps/web/.svelte-kit output was deleted with guarded directory checks. Review artifacts remain ignored in the worktree. Git status is clean. Full gate logs, this report and the complete file manifest: [merge28 verification archive](https://git.kayg.org/attachments/e07036d5-dc3b-4f73-831e-927367521477).
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#1109
No description provided.