Contextual + button: always present; New note on Notes, New task on Tasks, Upload on Files/Photos #1128

Open
opened 2026-10-05 08:38:44 +00:00 by kayg · 15 comments
Owner

Owner report (2026-10-05)

"The + button disappears in the Notes view? When I just want a new note and not the Composer, I can't get it."

On the Notes Tab the + button next to the mode tray is gone. Make the + contextual and always present next to the tray, with the same position, look and motion:

  • Calendar: opens the Composer (as today).
  • Notes: creates a new Note and opens it with the title focused. Long-press/right-click offers New Canvas and New folder.
  • Tasks: new Task in the current view/column.
  • Files: menu with Upload files, New folder, New Note here.
  • Photos: Upload photos.
  • Mail: Compose.
  • Money: Add transaction.
    The tooltip names the action ("New note · ⌘N" etc.) with its shortcut. Keyboard ⌘/Ctrl+N does the same per Tab. The Composer stays reachable everywhere via its shortcut.
## Owner report (2026-10-05) "The + button disappears in the Notes view? When I just want a new note and not the Composer, I can't get it." On the Notes Tab the + button next to the mode tray is gone. Make the + contextual and always present next to the tray, with the same position, look and motion: - Calendar: opens the Composer (as today). - Notes: creates a new Note and opens it with the title focused. Long-press/right-click offers New Canvas and New folder. - Tasks: new Task in the current view/column. - Files: menu with Upload files, New folder, New Note here. - Photos: Upload photos. - Mail: Compose. - Money: Add transaction. The tooltip names the action ("New note · ⌘N" etc.) with its shortcut. Keyboard ⌘/Ctrl+N does the same per Tab. The Composer stays reachable everywhere via its shortcut.
Author
Owner

Started #1128 on job/plus-1128, based at origin/dev / 98584d6f78510a4c72b2d2b9193c46581db04742. I’m tracing the shared primary pill and existing Tab create actions before editing.

Started #1128 on `job/plus-1128`, based at `origin/dev` / `98584d6f78510a4c72b2d2b9193c46581db04742`. I’m tracing the shared primary pill and existing Tab create actions before editing.
Author
Owner

Finding for #1128: docs/DESIGN.md §34 and apps/web/src/lib/shortcuts/registry.ts explicitly reject Mod+N because browsers use it for a new window; the issue explicitly requests ⌘/Ctrl+N. I will implement the issue shortcut as a documented exception in the shortcut registry and its reserved-shortcut test. docs/DESIGN.md §40 says calternal does not create subfolders in Notes/; the issue asks for New folder in the Notes menu, so I will follow the issue and create it under Notes/ through the existing Files API. MailView.svelte has no compose action, and §53 says sending is not supported; I am checking for another existing compose flow before changing that Tab.

Finding for #1128: `docs/DESIGN.md` §34 and `apps/web/src/lib/shortcuts/registry.ts` explicitly reject Mod+N because browsers use it for a new window; the issue explicitly requests ⌘/Ctrl+N. I will implement the issue shortcut as a documented exception in the shortcut registry and its reserved-shortcut test. `docs/DESIGN.md` §40 says calternal does not create subfolders in `Notes/`; the issue asks for New folder in the Notes menu, so I will follow the issue and create it under `Notes/` through the existing Files API. `MailView.svelte` has no compose action, and §53 says sending is not supported; I am checking for another existing compose flow before changing that Tab.
Author
Owner

Post-merge finding for #1128: MailView.svelte has no in-app compose flow. DESIGN §53 says calternal Mail does not send, so I will make the requested Compose primary action open the User's configured mailto: client. This keeps the Mail action usable and leaves the server's no-send behavior unchanged. I will record the handoff as a decision in the final report.

Post-merge finding for #1128: `MailView.svelte` has no in-app compose flow. DESIGN §53 says calternal Mail does not send, so I will make the requested Compose primary action open the User's configured `mailto:` client. This keeps the Mail action usable and leaves the server's no-send behavior unchanged. I will record the handoff as a decision in the final report.
Author
Owner

Finding for #1128: the shell's Mod+N handler only clicked .primary-pill; page-owned selection bars unmount that pill, so the shortcut had no action in those states. I will add a page-owned fallback for direct actions and let Files open the existing New menu from the bottom chrome when its pill is hidden.

Finding for #1128: the shell's `Mod+N` handler only clicked `.primary-pill`; page-owned selection bars unmount that pill, so the shortcut had no action in those states. I will add a page-owned fallback for direct actions and let Files open the existing New menu from the bottom chrome when its pill is hidden.
Author
Owner

Finding for #1128: the Notes API intentionally creates regular Notes only in Notes/ (crates/plugins/notes/src/lib.rs, validate_template_folder), while Files must offer “New Note here” in the open folder. I will create through the Notes writer, then use the existing Files move API to place the Note in the current folder. The Files move path already preserves calternal-id and rewrites references, so this needs no server route change.

Finding for #1128: the Notes API intentionally creates regular Notes only in `Notes/` (`crates/plugins/notes/src/lib.rs`, `validate_template_folder`), while Files must offer “New Note here” in the open folder. I will create through the Notes writer, then use the existing Files move API to place the Note in the current folder. The Files move path already preserves `calternal-id` and rewrites references, so this needs no server route change.
Author
Owner

Verification finding: the first bun run check stopped in perf-lint because the exact source hash for apps/web/src/lib/canvas/CanvasView.svelte#each:3a4cbef6167607e4:1 no longer matched the #1058 ledger after the merged origin/dev source changes. The guard hashes each Svelte list with its full file. I ran the repository's explicit scripts/perf-lint --adopt-7c workflow. It reported Adopted 4036 exact #1058 sites; ordinary future ratchet remains active. This refresh changes only contracts/perf/adoption-1058.json, contracts/perf/exceptions.json and contracts/perf/ratchet.json; I will keep it in a separate generated-files commit. The rerun reports perf-lint: PASS; 0 violations; 21969 scoped exceptions and svelte-check found 0 errors and 4 warnings in 3 files.

Verification finding: the first `bun run check` stopped in `perf-lint` because the exact source hash for `apps/web/src/lib/canvas/CanvasView.svelte#each:3a4cbef6167607e4:1` no longer matched the #1058 ledger after the merged `origin/dev` source changes. The guard hashes each Svelte list with its full file. I ran the repository's explicit `scripts/perf-lint --adopt-7c` workflow. It reported `Adopted 4036 exact #1058 sites; ordinary future ratchet remains active`. This refresh changes only `contracts/perf/adoption-1058.json`, `contracts/perf/exceptions.json` and `contracts/perf/ratchet.json`; I will keep it in a separate generated-files commit. The rerun reports `perf-lint: PASS; 0 violations; 21969 scoped exceptions` and `svelte-check found 0 errors and 4 warnings in 3 files`.
Author
Owner

The Notes list route clamps each page to 100 (crates/plugins/notes/src/lib.rs, list), so a limit=500 check would only inspect the first page. I updated the #1128 local production profile to follow next_cursor until all 500 real Notes are counted, and kept the measured Mod+N burst separate from the verification reads.

The Notes list route clamps each page to 100 (`crates/plugins/notes/src/lib.rs`, `list`), so a `limit=500` check would only inspect the first page. I updated the #1128 local production profile to follow `next_cursor` until all 500 real Notes are counted, and kept the measured Mod+N burst separate from the verification reads.
Author
Owner

The real local production profile reproduced a Notes open error at an average Mod+N sample (sample 3 of 15). The app reached the new stable /n/<id> route, but NoteView showed “This note could not be opened”; the follow-up direct Notes API read for that same ID returned HTTP 200. This points to the bounded detail cache’s 16-pending-read limit under Notes index prefetch, before NoteView issues its own GET. I am fixing create navigation to fetch the exact Note representation and seed the same cache before opening the route.

The real local production profile reproduced a Notes open error at an average Mod+N sample (sample 3 of 15). The app reached the new stable `/n/<id>` route, but NoteView showed “This note could not be opened”; the follow-up direct Notes API read for that same ID returned HTTP 200. This points to the bounded detail cache’s 16-pending-read limit under Notes index prefetch, before NoteView issues its own GET. I am fixing create navigation to fetch the exact Note representation and seed the same cache before opening the route.
Author
Owner

bun run check stopped in scripts/perf-lint --check before Svelte diagnostics. It reported the exact existing CanvasView site CanvasView.svelte#each:3a4cbef6167607e4:1 as an unused or changed exception. The #1128 CanvasView edit changed that file hash; I am refreshing the exact #7c adoption record so future unrelated violations remain caught by the normal ratchet.

`bun run check` stopped in `scripts/perf-lint --check` before Svelte diagnostics. It reported the exact existing CanvasView site `CanvasView.svelte#each:3a4cbef6167607e4:1` as an unused or changed exception. The #1128 CanvasView edit changed that file hash; I am refreshing the exact #7c adoption record so future unrelated violations remain caught by the normal ratchet.
Author
Owner

The second profile run confirmed the cache race. The network trace showed the exact new Note GET returned 200 with a strong ETag, then NoteView failed without issuing its own GET; a post-error GET returned the same 200 representation. The Notes event stream emits kind=created for that action, and noteIndex.#apply invalidated every Note revision for every event. I changed it to retain existing exact revisions for created events only; modified, moved, trash and other changes keep the existing invalidation path. Added a change-feed regression test.

The second profile run confirmed the cache race. The network trace showed the exact new Note GET returned 200 with a strong ETag, then NoteView failed without issuing its own GET; a post-error GET returned the same 200 representation. The Notes event stream emits `kind=created` for that action, and `noteIndex.#apply` invalidated every Note revision for every event. I changed it to retain existing exact revisions for `created` events only; `modified`, moved, trash and other changes keep the existing invalidation path. Added a change-feed regression test.
Author
Owner

Production E2E finding: New Canvas created a real Note but its /notes/<id> route showed “This note could not be opened”; the browser had no page errors. The shared Canvas creator navigates after createNote without priming the exact Note revision cache, while the Notes primary action now uses loadNoteViewForNavigation to avoid the bounded preview-read queue. I am applying that handoff to Canvas creation and retaining a list entry plus direct route fallback if the exact read fails.

Production E2E finding: New Canvas created a real Note but its `/notes/<id>` route showed “This note could not be opened”; the browser had no page errors. The shared Canvas creator navigates after `createNote` without priming the exact Note revision cache, while the Notes primary action now uses `loadNoteViewForNavigation` to avoid the bounded preview-read queue. I am applying that handoff to Canvas creation and retaining a list entry plus direct route fallback if the exact read fails.
Author
Owner

#1128 implementation report

READY FOR MERGE: yes — implementation gates and the production walkthrough pass. The 66 production screenshots are attached to this issue for the required orchestrator visual review.

Built

  • Added the shared primary action pill beside the mode tray. It follows the active Tab and supports click, right-click, touch long-press, shortcut hints and Mod+N. Files keeps its shortcut fallback while selection controls replace the pill.
  • Added the contextual create actions across Calendar, Notes, Tasks, Files, Photos, Mail and Money. Files “New Note here” uses the Notes writer, then the existing Files move so the Note keeps its identity.
  • Fixed Note and Canvas route opens under Notes preview-cache pressure. Create flows read and retain the exact Note revision before navigation. A Note’s own created change event no longer invalidates that revision. Failed Canvas reads keep a real list entry and route fallback.
  • Added real-server E2E coverage, a create-action performance profile and the first local reference in docs/perf/baseline.json.

Screenshots

Attached 66 macOS production screenshots: 11 affected surfaces × phone (390 px), tablet (820 px), desktop (1440 px) × light and dark themes. Example: calendar-390-light-mac.png. The set is also in the ignored local directory artifacts/plus-1128/; no screenshots are committed.

Commits

  • 552afae7e — add per-Tab primary create actions
  • 74036787a — refresh exact performance exception records
  • d7f528fcd — open created Notes past cache pressure
  • e44ad3fa8 — retain new Note revisions on create events
  • b594cf7bc — prime Canvas revision before opening
  • 5298cc8f4fb8572ed8fb06e1747e5e25bfee78b4 — capture primary-create review evidence

Head: 5298cc8f4fb8572ed8fb06e1747e5e25bfee78b4.

Gate output (verbatim)

bun run check from apps/web:

perf-lint: PASS; 0 violations; 21969 scoped exceptions
User browser caches use userStorage; only documented device/public-link exceptions remain.
Glass alpha, blur and backdrop-filter roles use packages/ui/src/tokens.css.
Text sizes and UI shape values use shared role tokens.
Keyboard focus rings use the shared focus tokens.
UI transitions and animation options use shared motion tokens or documented exceptions.
svelte-check found 0 errors and 4 warnings in 3 files

Focused Vitest:

 Test Files  4 passed (4)
      Tests  26 passed (26)
   Start at  14:22:06
   Duration  2.26s (transform 69%, import 19%, tests 11%, worker 1%)

Production E2E:

PASS #1128 primary actions and 66 macOS production screenshots

node --check on the E2E and bench scripts, JSON parsing, and git diff --check exited 0. No Rust files changed, so Rust crate gates were not run. Cleanup: cargo clean removed 8,626 files / 7.2 GiB; apps/web/build was removed.

Performance profile

Local production web build and debug server; first #1128 reference (baseline: null). Average: 50 Notes, 15 activations, p50 4,318.75 ms, p95 14,234.13 ms, server CPU 16.83 s, peak RSS 318,238,720 B. Worst: 500 Notes, eight same-turn Mod+N events, 2,652.89 ms, exactly one new Note (501 total), server CPU 1.15 s, peak RSS 348,409,856 B. Host load average was 36.91 before and 26.86 after. These local numbers ran under high shared-host load; use them as a reference only and compare later runs on the perf-test VM.

UX gaps closed

  • The Notes and Canvas create routes now open while the Notes preview queue is full; create events keep the exact cached revision.
  • Files can create a Note in the open folder without adding a second Note writer. Selection mode still reaches the create menu with Mod+N.
  • The walkthrough covers pointer, keyboard and touch paths, Mail’s external Compose handoff, and every affected surface at the required widths and themes.

UX gaps left

No functional gap remained in the walkthrough. Visual quality and cap-height alignment are left to the orchestrator’s review of the attached screenshots. svelte-check still reports four existing warnings: two empty CSS rulesets in AttachmentDeck.svelte and AgendaList.svelte, and unused .note-page-lede and .note-state selectors in notes/+page.svelte.

Decisions

  • Mod+N creates the active Tab’s primary item. Plain N remains Composer.
  • Mail Compose hands off to the system mailto: client until calternal Mail can send.
  • “New Note here” uses the Notes writer, then the existing Files move. A new Notes folder action uses Files’ folder flow.

For the merge round

  • cd apps/web && bun run test — run the full web test suite.
  • cd apps/web && bun run test:e2e — run the production shell E2E suite.
  • bash tests/adversarial/run.sh — run the real-server XUser, authorization and robustness matrices.
#1128 implementation report **READY FOR MERGE: yes** — implementation gates and the production walkthrough pass. The 66 production screenshots are attached to this issue for the required orchestrator visual review. ## Built - Added the shared primary action pill beside the mode tray. It follows the active Tab and supports click, right-click, touch long-press, shortcut hints and Mod+N. Files keeps its shortcut fallback while selection controls replace the pill. - Added the contextual create actions across Calendar, Notes, Tasks, Files, Photos, Mail and Money. Files “New Note here” uses the Notes writer, then the existing Files move so the Note keeps its identity. - Fixed Note and Canvas route opens under Notes preview-cache pressure. Create flows read and retain the exact Note revision before navigation. A Note’s own `created` change event no longer invalidates that revision. Failed Canvas reads keep a real list entry and route fallback. - Added real-server E2E coverage, a create-action performance profile and the first local reference in `docs/perf/baseline.json`. ## Screenshots Attached 66 macOS production screenshots: 11 affected surfaces × phone (390 px), tablet (820 px), desktop (1440 px) × light and dark themes. Example: [calendar-390-light-mac.png](https://git.kayg.org/attachments/7b2eb2b8-c0fa-429b-91ed-54612e416f65). The set is also in the ignored local directory `artifacts/plus-1128/`; no screenshots are committed. ## Commits - `552afae7e` — add per-Tab primary create actions - `74036787a` — refresh exact performance exception records - `d7f528fcd` — open created Notes past cache pressure - `e44ad3fa8` — retain new Note revisions on create events - `b594cf7bc` — prime Canvas revision before opening - `5298cc8f4fb8572ed8fb06e1747e5e25bfee78b4` — capture primary-create review evidence Head: `5298cc8f4fb8572ed8fb06e1747e5e25bfee78b4`. ## Gate output (verbatim) `bun run check` from `apps/web`: ```text perf-lint: PASS; 0 violations; 21969 scoped exceptions User browser caches use userStorage; only documented device/public-link exceptions remain. Glass alpha, blur and backdrop-filter roles use packages/ui/src/tokens.css. Text sizes and UI shape values use shared role tokens. Keyboard focus rings use the shared focus tokens. UI transitions and animation options use shared motion tokens or documented exceptions. svelte-check found 0 errors and 4 warnings in 3 files ``` Focused Vitest: ```text Test Files 4 passed (4) Tests 26 passed (26) Start at 14:22:06 Duration 2.26s (transform 69%, import 19%, tests 11%, worker 1%) ``` Production E2E: ```text PASS #1128 primary actions and 66 macOS production screenshots ``` `node --check` on the E2E and bench scripts, JSON parsing, and `git diff --check` exited 0. No Rust files changed, so Rust crate gates were not run. Cleanup: `cargo clean` removed 8,626 files / 7.2 GiB; `apps/web/build` was removed. ## Performance profile Local production web build and debug server; first #1128 reference (`baseline: null`). Average: 50 Notes, 15 activations, p50 4,318.75 ms, p95 14,234.13 ms, server CPU 16.83 s, peak RSS 318,238,720 B. Worst: 500 Notes, eight same-turn Mod+N events, 2,652.89 ms, exactly one new Note (501 total), server CPU 1.15 s, peak RSS 348,409,856 B. Host load average was 36.91 before and 26.86 after. These local numbers ran under high shared-host load; use them as a reference only and compare later runs on the perf-test VM. ## UX gaps closed - The Notes and Canvas create routes now open while the Notes preview queue is full; create events keep the exact cached revision. - Files can create a Note in the open folder without adding a second Note writer. Selection mode still reaches the create menu with Mod+N. - The walkthrough covers pointer, keyboard and touch paths, Mail’s external Compose handoff, and every affected surface at the required widths and themes. ## UX gaps left No functional gap remained in the walkthrough. Visual quality and cap-height alignment are left to the orchestrator’s review of the attached screenshots. `svelte-check` still reports four existing warnings: two empty CSS rulesets in `AttachmentDeck.svelte` and `AgendaList.svelte`, and unused `.note-page-lede` and `.note-state` selectors in `notes/+page.svelte`. ## Decisions - Mod+N creates the active Tab’s primary item. Plain N remains Composer. - Mail Compose hands off to the system `mailto:` client until calternal Mail can send. - “New Note here” uses the Notes writer, then the existing Files move. A new Notes folder action uses Files’ folder flow. ## For the merge round - `cd apps/web && bun run test` — run the full web test suite. - `cd apps/web && bun run test:e2e` — run the production shell E2E suite. - `bash tests/adversarial/run.sh` — run the real-server XUser, authorization and robustness matrices.
Author
Owner

Finish pass for #1128 in this worktree (head 5298cc8f4). Orchestrator review:

  1. git merge origin/dev (dev now has batches 6–11: Delete/Undo menus, Draw fixes, tray icons, palette, Calendar header, reconnect, NLP chip). Resolve apps/web/src/lib/canvas/CanvasView.svelte by keeping BOTH sides' behaviour (dev's Draw/Delete changes and your revision priming b594cf7bc). Resolve contracts/perf/* and docs/perf/baseline.json with dev's side, then regenerate only your own entries; perf-lint is non-gating (#1133), do not spend long on it.
  2. Same look on every Tab: Notes shows a file-plus glyph while Files/Calendar show a plain "+". Use the one "+" glyph everywhere; the tooltip names the action with its shortcut ("New note · ⌘N", "Upload · ⌘N" …). Same size, position and motion as the Calendar Composer button.
  3. After the merge, Notes list rows must keep dev's Share + ⋯ actions (your screenshots show a link icon instead of ⋯ because your base predates batch 6). Do not reintroduce the old row actions.
  4. Rerun your e2e and retake the screenshot matrix (390/820/1440, light + dark) on the merged head; 4x crops of the + button next to the tray on each Tab (alignment with the tray's vertical centre within 1 px).
    Commit; comment on #1128 with head SHA and gate output verbatim. Do not push.
Finish pass for #1128 in this worktree (head 5298cc8f4). Orchestrator review: 1. `git merge origin/dev` (dev now has batches 6–11: Delete/Undo menus, Draw fixes, tray icons, palette, Calendar header, reconnect, NLP chip). Resolve apps/web/src/lib/canvas/CanvasView.svelte by keeping BOTH sides' behaviour (dev's Draw/Delete changes and your revision priming b594cf7bc). Resolve contracts/perf/* and docs/perf/baseline.json with dev's side, then regenerate only your own entries; perf-lint is non-gating (#1133), do not spend long on it. 2. Same look on every Tab: Notes shows a file-plus glyph while Files/Calendar show a plain "+". Use the one "+" glyph everywhere; the tooltip names the action with its shortcut ("New note · ⌘N", "Upload · ⌘N" …). Same size, position and motion as the Calendar Composer button. 3. After the merge, Notes list rows must keep dev's Share + ⋯ actions (your screenshots show a link icon instead of ⋯ because your base predates batch 6). Do not reintroduce the old row actions. 4. Rerun your e2e and retake the screenshot matrix (390/820/1440, light + dark) on the merged head; 4x crops of the + button next to the tray on each Tab (alignment with the tray's vertical centre within 1 px). Commit; comment on #1128 with head SHA and gate output verbatim. Do not push.
Author
Owner

Starting #1128 in job/plus-1128 at 5298cc8f4fb8572ed8fb06e1747e5e25bfee78b4. Branch base: 570e084c8691a76b9bec904f47151f4ff5701298. I have read CLAUDE.md, docs/DESIGN.md and CONTEXT.md; I am fetching and merging current origin/dev before finishing the contextual create action and review evidence.

Starting #1128 in `job/plus-1128` at `5298cc8f4fb8572ed8fb06e1747e5e25bfee78b4`. Branch base: `570e084c8691a76b9bec904f47151f4ff5701298`. I have read `CLAUDE.md`, `docs/DESIGN.md` and `CONTEXT.md`; I am fetching and merging current `origin/dev` before finishing the contextual create action and review evidence.
Author
Owner

#1128 finish pass

Branch: job/plus-1128
Head: d5e78faf771cdb48cc95f145e434d04c0fa6de62
Commits: a98bc0882 merged current origin/dev; d5e78faf7 unified the primary actions.

Built

  • All seven Tab primary actions use the same plain + glyph. Files names its action Upload, with the action and ⌘N in its tooltip.
  • The Files menu puts Upload files, New folder and New Note here first, while retaining New Canvas and Upload a folder.
  • The merged Notes row Share and ⋯ actions remain present; E2E verifies Share and Copy link in the menu.
  • The E2E pass checks the glyph, shortcut tooltip, and button-to-Tab-Bar vertical centre within 1 px. It captures 66 production screenshots and 14 4× crops with macOS platform emulation.

UX gaps closed

  • Primary actions were checked on pointer, shortcut and touch paths. Notes Share and row-menu actions were checked after the merge.
  • Captured all touched routes at 390, 820 and 1440 px in light and dark themes. All 7 Tab plus-to-tray crops are attached below.

UX gaps left

Decisions

  • DESIGN §60 requires New Canvas in the Files menu but does not set action order. The issue's three common actions come first; New Canvas stays before Upload a folder.
  • The Files primary label is Upload because that is the first action its shared plus button opens.

Performance

The #1128 feature profile is the first local reference (baseline: null), measured with a local production web build and local debug server under high shared-host load (36.91 before, 26.86 after). Average: 50 Notes, p50 4318.75 ms, p95 14234.13 ms, 16.83 server CPU seconds, RSS 185217024 → 318238720 bytes. Worst case: 500 Notes, 8-key burst, activation latency 2652.89 ms, 1.15 server CPU seconds, RSS 348168192 → 348409856 bytes. The profile is in docs/perf/baseline.json; treat it as a reference, not a stable comparison.

Verification

cargo fmt --check exited 0 with no output.

Focused Vitest:

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

Production E2E:

PASS #1128 primary actions, aligned create pills, 66 macOS production screenshots and 14 4x Tab Bar crops

bun run build succeeded. svelte-check reported:

svelte-check found 0 errors and 4 warnings in 3 files

bun run check stopped at its first perf-lint step. The merged origin/dev exception ledger exceeds its ratchet; this is non-gating #1133 work, so I did not regenerate the ledger:

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

Rust clippy and tests were not run because this pass changes no Rust files. The separate storage check found four direct sessionStorage accesses in merged dev file apps/web/src/lib/navigation/clientRouteStatus.svelte.ts; the Svelte warnings are two empty Calendar CSS rules and two unused selectors in the merged Notes page. These are outside #1128.

Screenshot attachments

Build output was cleaned with cargo clean (Removed 8626 files, 7.2GiB total) and the web build output was deleted. No push performed.

## #1128 finish pass Branch: `job/plus-1128` Head: `d5e78faf771cdb48cc95f145e434d04c0fa6de62` Commits: `a98bc0882` merged current `origin/dev`; `d5e78faf7` unified the primary actions. ### Built - All seven Tab primary actions use the same plain `+` glyph. Files names its action `Upload`, with the action and `⌘N` in its tooltip. - The Files menu puts Upload files, New folder and New Note here first, while retaining New Canvas and Upload a folder. - The merged Notes row Share and ⋯ actions remain present; E2E verifies Share and Copy link in the menu. - The E2E pass checks the glyph, shortcut tooltip, and button-to-Tab-Bar vertical centre within 1 px. It captures 66 production screenshots and 14 4× crops with macOS platform emulation. ### UX gaps closed - Primary actions were checked on pointer, shortcut and touch paths. Notes Share and row-menu actions were checked after the merge. - Captured all touched routes at 390, 820 and 1440 px in light and dark themes. All 7 Tab plus-to-tray crops are attached below. ### UX gaps left - None found for #1128. ### Decisions - DESIGN §60 requires New Canvas in the Files menu but does not set action order. The issue's three common actions come first; New Canvas stays before Upload a folder. - The Files primary label is `Upload` because that is the first action its shared plus button opens. ### Performance The #1128 feature profile is the first local reference (`baseline: null`), measured with a local production web build and local debug server under high shared-host load (36.91 before, 26.86 after). Average: 50 Notes, p50 4318.75 ms, p95 14234.13 ms, 16.83 server CPU seconds, RSS 185217024 → 318238720 bytes. Worst case: 500 Notes, 8-key burst, activation latency 2652.89 ms, 1.15 server CPU seconds, RSS 348168192 → 348409856 bytes. The profile is in `docs/perf/baseline.json`; treat it as a reference, not a stable comparison. ### Verification `cargo fmt --check` exited 0 with no output. Focused Vitest: ```text Test Files 2 passed (2) Tests 9 passed (9) ``` Production E2E: ```text PASS #1128 primary actions, aligned create pills, 66 macOS production screenshots and 14 4x Tab Bar crops ``` `bun run build` succeeded. `svelte-check` reported: ```text svelte-check found 0 errors and 4 warnings in 3 files ``` `bun run check` stopped at its first perf-lint step. The merged `origin/dev` exception ledger exceeds its ratchet; this is non-gating #1133 work, so I did not regenerate the ledger: ```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 ``` Rust clippy and tests were not run because this pass changes no Rust files. The separate storage check found four direct `sessionStorage` accesses in merged dev file `apps/web/src/lib/navigation/clientRouteStatus.svelte.ts`; the Svelte warnings are two empty Calendar CSS rules and two unused selectors in the merged Notes page. These are outside #1128. ### Screenshot attachments - [390 px, light](https://git.kayg.org/attachments/a805b687-2a50-4353-b34d-70512c6a8ac3) · [390 px, dark](https://git.kayg.org/attachments/37b2898e-f91c-4c7f-b215-51e9ca54e6c4) - [820 px, light](https://git.kayg.org/attachments/92559637-4399-4243-b00f-037633dbbce1) · [820 px, dark](https://git.kayg.org/attachments/d58acae6-71ec-43b4-9011-39482db9e82b) - [1440 px, light](https://git.kayg.org/attachments/e6214d6f-25d9-4d95-8641-3f85257823cf) · [1440 px, dark](https://git.kayg.org/attachments/6e71ec6b-de94-4130-bc04-41d0ab65c4be) - [Tab Bar crops at 4×](https://git.kayg.org/attachments/860d137a-e699-4164-99d2-33c10f2809e4) Build output was cleaned with `cargo clean` (`Removed 8626 files, 7.2GiB total`) and the web build output was deleted. No push performed.
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#1128
No description provided.