port: hidden blocks, the editor UI (#611, approved mockup) #904

Open
kayg wants to merge 70 commits from port/hidden-blocks into dev
Owner

The editor side of hidden blocks (#611, ADR 0056). Stacked on #887 (notes-archive-hide): this branch is based on #887's head c8afa867, so the first commits here are #887's. Review range: c8afa867..port/hidden-blocks. Gate numbers and screenshots are added as comments below.

#887 only has the server side: hidden blocks: frontmatter and search skipping them. It has no block-level action, so the client writes the list itself through the normal edit path, in the same change as the block's id.

What it does

  • Hide in the block menu (and the block bar): the block gets its id (^id, on its last line, if it has none) and the frontmatter gets hidden blocks: ["^id", …], in ONE change, so one Undo takes it all back; a toast offers Undo. The block's words never change. An older hidden: list moves into hidden blocks: in that same edit (hidden: true is the note flag and is left alone).
  • The block disappears from the reading view with no placeholder line: the block and one blank line beside it are replaced, so the gap closes too (ADR 0056). Source mode shows the file as it is.
  • Show hidden blocks (a toggle in the note tools and a Composer command, only when the note has hidden blocks): every hidden block comes back faded (42 %) with the mockup's 36 px unhide button, centred on the block. Hide hidden blocks again puts them away. Unhide takes the id out of the list.
  • A direct link to a hidden block (?block=<id>) opens the note with only that block shown faded, for that visit: the list is unchanged, so it is hidden again after leaving.
  • Undo (⌘Z or the toast) restores the block and the list.

Cost on the typing path

None for a note without hidden blocks (the field returns its value untouched; the test proves it). With hidden blocks: a change touches the frontmatter or a marker line → rebuild; anything else only maps the existing decorations through the change.

Decisions

  • Menu word is Hide (the mockup's), not "Hide block"; the menu is already "Block actions".
  • The caret leaves the hidden lines in the hide change itself; otherwise the leftover selection turned into "words selected", swapped the bar and dismissed the Undo toast (flaky under --repeat-each).
  • Faded blocks fade by their own text colour and background (an opacity on the line would fade the unhide button too), with an opacity only on inline pieces that have a colour of their own.
  • No duplicate open PR found for this work.

Tests

packages/editor/test/hidden-blocks.test.ts (list read/write incl. both keys, the reading view, peeking, zero cost), apps/web/e2e/hidden-blocks.spec.ts (4 cases: hide with no placeholder, Undo, Show hidden + unhide, link to a hidden block).

🤖 Generated with Claude Code

Budget (kayg approved, 2026-11-08 08:20 IST): kayg approved raising the lazy budget total, up to 543.9 KiB. perf/budgets.json in this PR sets each named lazy line to the largest size measured over the 17 approved ports after trimming (rounded up to 0.01 KiB) and the total to the sum of the lines (543.25 KiB). The same file is in the first PR of every stack, so whichever merges first carries it. First paint is judged separately and has not been raised.

The editor side of hidden blocks (#611, ADR 0056). **Stacked on #887** (`notes-archive-hide`): this branch is based on #887's head `c8afa867`, so the first commits here are #887's. Review range: `c8afa867..port/hidden-blocks`. Gate numbers and screenshots are added as comments below. #887 only has the server side: `hidden blocks:` frontmatter and search skipping them. It has no block-level action, so the client writes the list itself through the normal edit path, in the same change as the block's id. ## What it does - **Hide** in the block menu (and the block bar): the block gets its id (`^id`, on its last line, if it has none) and the frontmatter gets `hidden blocks: ["^id", …]`, in ONE change, so one Undo takes it all back; a toast offers Undo. The block's words never change. An older `hidden:` list moves into `hidden blocks:` in that same edit (`hidden: true` is the note flag and is left alone). - The block disappears from the reading view with **no placeholder line**: the block and one blank line beside it are replaced, so the gap closes too (ADR 0056). Source mode shows the file as it is. - **Show hidden blocks** (a toggle in the note tools and a Composer command, only when the note has hidden blocks): every hidden block comes back faded (42 %) with the mockup's 36 px unhide button, centred on the block. **Hide hidden blocks again** puts them away. Unhide takes the id out of the list. - A **direct link** to a hidden block (`?block=<id>`) opens the note with only that block shown faded, for that visit: the list is unchanged, so it is hidden again after leaving. - Undo (⌘Z or the toast) restores the block and the list. ## Cost on the typing path None for a note without hidden blocks (the field returns its value untouched; the test proves it). With hidden blocks: a change touches the frontmatter or a marker line → rebuild; anything else only maps the existing decorations through the change. ## Decisions - Menu word is **Hide** (the mockup's), not "Hide block"; the menu is already "Block actions". - The caret leaves the hidden lines in the hide change itself; otherwise the leftover selection turned into "words selected", swapped the bar and dismissed the Undo toast (flaky under `--repeat-each`). - Faded blocks fade by their own text colour and background (an opacity on the line would fade the unhide button too), with an opacity only on inline pieces that have a colour of their own. - No duplicate open PR found for this work. ## Tests `packages/editor/test/hidden-blocks.test.ts` (list read/write incl. both keys, the reading view, peeking, zero cost), `apps/web/e2e/hidden-blocks.spec.ts` (4 cases: hide with no placeholder, Undo, Show hidden + unhide, link to a hidden block). 🤖 Generated with [Claude Code](https://claude.com/claude-code) **Budget (kayg approved, 2026-11-08 08:20 IST):** kayg approved raising the lazy budget total, up to 543.9 KiB. `perf/budgets.json` in this PR sets each named lazy line to the largest size measured over the 17 approved ports after trimming (rounded up to 0.01 KiB) and the total to the sum of the lines (543.25 KiB). The same file is in the first PR of every stack, so whichever merges first carries it. First paint is judged separately and has not been raised.
kayg added 70 commits 2026-11-03 18:02:27 +00:00
test: specify note hide and archive actions
Some checks failed
CI / server (pull_request) Has been cancelled
CI / rust (pull_request) Has been cancelled
CI / web (pull_request) Has been cancelled
Markdown extraction contract / markdown-native-contract (pull_request) Has been cancelled
Markdown extraction contract / markdown-editor-contract (pull_request) Has been cancelled
7306f64e10
Hide/Unhide/Archive/Unarchive only change a key that is absent or a plain
true/false. Lists (ADR 0056 hidden blocks), yes, True, strings, CRLF or BOM
metadata and comments skip that note with a reason and leave it byte-exact.
The reader counts a flag only where the planner reads a plain true, so no
note can be archived but impossible to unarchive. Bulk actions return
per-note results and plan again when another edit lands mid-action.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A changed room, a rename, a trash or a consumed undo now returns
BlockChanged (another author: Forbidden) instead of an internal error.
Tests cover undo after rename and trash, an edit from another device or a
file sync landing between planning and commit, and notes without metadata.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A publishing executor write now pauses search updates only for its own
notes; a full reconcile still waits because it marks every entry done.
The Archived place drives from the sparse archived index and looks notes
up by id, so its cost follows archived notes only. Tests cover the scoped
pause, the Archived query plan and the upgrade path for notes archived
before visibility existed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Tasks in hidden or archived notes give no task rows, so Tasks lists,
counts, Untracked and task tag counts leave them out. The backlinks panel
leaves them out too; rename and Trash relinking still see them. The web
store follows the visibility in notes.saved: a hidden or archived row
leaves open lists on every device, and an unhidden or unarchived one
comes back.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A hidden note that links the target left the linked list, then came back
as an unlinked mention through search.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Hidden and archived notes were left out with NOT IN over a subquery, so
every page built a b-tree of all flagged ids, and the total counted that
set again. Pages now anti-join the sparse table by primary key for the
rows they return, and the total is the stats count minus the flagged rows.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
A key of lowercase words (like 'hidden blocks' or 'last edited') is
written without quotes. Value words (true, no, null...) and ids stay
quoted. A quoted key already in a file is read, and kept byte for byte
unless its own value is rewritten.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
decide_all is crate-visible for the cross-module test.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
A state field hides the blocks listed under hidden blocks: with no placeholder, shows them faded
while peeking (all, or just one a link names) and costs nothing for notes without any. Hide and
Show hidden are wired in the block menu, block bar and note tools; Undo is the normal edit undo.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
A selection left inside the hidden block turned into 'words selected' and swapped the bar, which
dismissed the Undo toast.
test(web): give saves and the file 15 s on a slow browser
Some checks failed
CI / server (pull_request) Has been cancelled
CI / rust (pull_request) Has been cancelled
CI / web (pull_request) Has been cancelled
Markdown extraction contract / markdown-native-contract (pull_request) Has been cancelled
Markdown extraction contract / markdown-editor-contract (pull_request) Has been cancelled
c3de0d2cc7
Author
Owner

Product (left) vs approved mockup (right), 1440x900 and 390x844, light and dark. Taken by me and checked; the mockup is review/calendar-2 on its own page, so its surroundings differ.

state product mockup
hidden-blocks-hidden-1440-dark
hidden-blocks-hidden-1440-light
hidden-blocks-hidden-390-dark
hidden-blocks-hidden-390-light
hidden-blocks-menu-1440-dark
hidden-blocks-menu-1440-light
hidden-blocks-menu-390-dark
hidden-blocks-menu-390-light
hidden-blocks-shown-1440-dark
hidden-blocks-shown-1440-light
hidden-blocks-shown-390-dark
hidden-blocks-shown-390-light
Product (left) vs approved mockup (right), 1440x900 and 390x844, light and dark. Taken by me and checked; the mockup is `review/calendar-2` on its own page, so its surroundings differ. | state | product | mockup | |---|---|---| | hidden-blocks-hidden-1440-dark | ![](https://git.kayg.org/attachments/354b88f5-37ed-4a04-9e1f-c33397b57b90) | ![](https://git.kayg.org/attachments/0e18de44-3f61-4bd6-858e-54c01c3ffabd) | | hidden-blocks-hidden-1440-light | ![](https://git.kayg.org/attachments/70d675f8-16d7-42fa-95b6-cdbfd438cf9b) | ![](https://git.kayg.org/attachments/834a4674-4604-4643-aa01-71557dfd3c3b) | | hidden-blocks-hidden-390-dark | ![](https://git.kayg.org/attachments/55b660ee-e4e3-4ddf-abcc-a91d2f3eb4c1) | ![](https://git.kayg.org/attachments/6145e009-f341-4d90-92ca-f4f149b58528) | | hidden-blocks-hidden-390-light | ![](https://git.kayg.org/attachments/96157fe5-8d02-43f0-9d62-ad8d68945d91) | ![](https://git.kayg.org/attachments/6597da92-7744-4887-9fc0-589899fb7bc6) | | hidden-blocks-menu-1440-dark | ![](https://git.kayg.org/attachments/9729fb53-b88a-4bd0-b3f7-e3a3b42d66e2) | ![](https://git.kayg.org/attachments/418b44bf-4567-4e9f-86be-90e4a70fe8eb) | | hidden-blocks-menu-1440-light | ![](https://git.kayg.org/attachments/e921af72-7358-48cb-b98b-7a05a1415673) | ![](https://git.kayg.org/attachments/fd67e35a-5208-45ad-b01a-1725992a982a) | | hidden-blocks-menu-390-dark | ![](https://git.kayg.org/attachments/eb1f8ee5-8b46-4c24-ae29-bd1cf234e9ae) | ![](https://git.kayg.org/attachments/97d12720-108a-4b90-9aa5-65a21c029ec8) | | hidden-blocks-menu-390-light | ![](https://git.kayg.org/attachments/36abcb57-988a-46a7-a2f9-514e3f3bb337) | ![](https://git.kayg.org/attachments/5a977de7-c28d-4298-a218-0c567d6ed66f) | | hidden-blocks-shown-1440-dark | ![](https://git.kayg.org/attachments/f09c3ceb-a46a-45f3-aa92-976bb62ca54e) | ![](https://git.kayg.org/attachments/7decc9f5-6c94-4a5b-be54-4ef11d41f060) | | hidden-blocks-shown-1440-light | ![](https://git.kayg.org/attachments/5c64f454-e63e-4a24-a5bc-7fa32b8c83e3) | ![](https://git.kayg.org/attachments/ca01648f-2ef4-4470-b557-df41b1809056) | | hidden-blocks-shown-390-dark | ![](https://git.kayg.org/attachments/5cddecb8-9b72-4721-a1bb-939024a778a0) | ![](https://git.kayg.org/attachments/92a42660-af1c-43e6-997e-09fe2a7dbad6) | | hidden-blocks-shown-390-light | ![](https://git.kayg.org/attachments/69d019c4-71cc-4f64-9694-0b3a410c62e7) | ![](https://git.kayg.org/attachments/dcb52ccc-3bc3-4461-be61-0c6ac41585f6) |
Author
Owner

First paint, exact bytes (brotli, index chunk; #887 head c8afa867 vs this head 68f30a78)

  • #887 head: 239,276; this PR: 239,510; delta +234 B (0.23 KiB). dev (41f2efa3) is 238,797 for reference. First-paint CSS: 19,250 vs 19,250 (identical).
  • It cannot be exactly zero: what stays in first paint is lib/lazy-hidden.ts (one view plugin that looks at the properties when the note opens and when they change), the "Hide" menu entry, the Show hidden toggle (note tools and Composer) and two fields in the editing store. The editor piece, its stylesheet and the hide/unhide/peek actions are one lazy chunk (hidden-ui, 2.3 KiB), fetched only for a note whose properties list hidden blocks, when Hide is used, or when a link names a hidden block. editor.ts, index.ts, syntax/mode.ts and cm.css are byte-identical to #887's.
  • The block bar's Hide button was dropped (not asked for) to save bytes; Hide is in the block menu.

Gates at 68f30a78

  • hidden-blocks.spec.ts (4 cases), --repeat-each=5, CI=1 --retries=0 --workers=1: chromium-1440 20/20, chromium-390 20/20 (dev-01), webkit-1440 20/20, webkit-390 20/20 (dev-02).
  • editor unit tests 520 pass, web 103 pass, tsc --noEmit clean, svelte-check only the existing review4-signout errors.
  • Two things the lazy split broke and the repeat runs caught: a block decoration may not come from a function of the view, so the reading/source switch now lives in the field; and the unhide button's block was found from the wrong line.

Typing latency on the perf VMs (ABAB, dev-vs-dev control, both locks)

Taken 11-03 on perf-01 with perf-lock held on BOTH perf VMs for the whole run. Chromium at 4x CPU slowdown, 10k Home, 4 rounds, order reversed every other round. Cases: dev (41f2efa3), dev2 (the same dist again: the dev-vs-dev control), cb (#903 head), h887 (#887 head c8afa867), hb (#904 head). Each cell is the median over the 4 rounds of that run's p50 (or p95, or CPU per key), ms:

20
metric (median over rounds of per-run value; ms)   dev dev2 cb h887 hb
type.code_block                       59.8(4)    62.7(4)    64.7(4)    65.1(4)    63.5(4)
type.code_block_cpu                   24.6(4)    27.9(4)    29.9(4)    27.5(4)    27.5(4)
type.code_block|p95                  147.4(4)   151.1(4)   155.7(4)   153.2(4)   151.2(4)
type.code_note_prose                  62.1(4)    68.1(4)    67.0(4)    67.7(4)    69.0(4)
type.code_note_prose_cpu              30.0(4)    33.3(4)    33.2(4)    33.1(4)    32.9(4)
type.code_note_prose|p95             156.1(4)   160.1(4)   161.7(4)   160.8(4)   160.2(4)
type.long_note                        61.6(4)    63.2(4)    61.9(4)    63.5(4)    65.7(4)
type.long_note_cpu                    26.9(4)    28.8(4)    28.6(4)    29.0(4)    29.2(4)
type.long_note|p95                   149.9(4)   152.4(4)   153.1(4)   153.1(4)   154.6(4)

Reading it: dev and dev2 are identical bits and differ by up to 6 ms (code_note_prose), so that is the resolution. #903 against dev2: within -1.1 to +2.0 ms p50 and -0.4 to +2.0 ms CPU per key; #904 against #887: within +0.4 to +2.2 ms p50 and about +0.2 to +0.4 ms... see the table; no row separates a PR from its base by more than the control does. The earlier +10 ms (one run, perf-01 under load 9, no control) is not reproduced. The per-keystroke work was also cut: the #903 gate now looks only at typed backticks/tildes, and #904 does nothing on a keystroke until a hidden list exists.

## First paint, exact bytes (brotli, `index` chunk; #887 head c8afa867 vs this head 68f30a78) - #887 head: **239,276**; this PR: **239,510**; delta **+234 B** (0.23 KiB). dev (41f2efa3) is 238,797 for reference. First-paint CSS: 19,250 vs 19,250 (identical). - It cannot be exactly zero: what stays in first paint is `lib/lazy-hidden.ts` (one view plugin that looks at the properties when the note opens and when they change), the "Hide" menu entry, the Show hidden toggle (note tools and Composer) and two fields in the editing store. The editor piece, its stylesheet and the hide/unhide/peek actions are one lazy chunk (`hidden-ui`, 2.3 KiB), fetched only for a note whose properties list hidden blocks, when Hide is used, or when a link names a hidden block. `editor.ts`, `index.ts`, `syntax/mode.ts` and `cm.css` are byte-identical to #887's. - The block bar's Hide button was dropped (not asked for) to save bytes; Hide is in the block menu. ## Gates at 68f30a78 - `hidden-blocks.spec.ts` (4 cases), `--repeat-each=5`, `CI=1 --retries=0 --workers=1`: chromium-1440 20/20, chromium-390 20/20 (dev-01), webkit-1440 20/20, webkit-390 20/20 (dev-02). - editor unit tests 520 pass, web 103 pass, `tsc --noEmit` clean, svelte-check only the existing `review4-signout` errors. - Two things the lazy split broke and the repeat runs caught: a block decoration may not come from a function of the view, so the reading/source switch now lives in the field; and the unhide button's block was found from the wrong line. ## Typing latency on the perf VMs (ABAB, dev-vs-dev control, both locks) Taken 11-03 on perf-01 with `perf-lock` held on BOTH perf VMs for the whole run. Chromium at 4x CPU slowdown, 10k Home, 4 rounds, order reversed every other round. Cases: `dev` (41f2efa3), `dev2` (the same dist again: the dev-vs-dev control), `cb` (#903 head), `h887` (#887 head c8afa867), `hb` (#904 head). Each cell is the median over the 4 rounds of that run's p50 (or p95, or CPU per key), ms: ``` 20 metric (median over rounds of per-run value; ms) dev dev2 cb h887 hb type.code_block 59.8(4) 62.7(4) 64.7(4) 65.1(4) 63.5(4) type.code_block_cpu 24.6(4) 27.9(4) 29.9(4) 27.5(4) 27.5(4) type.code_block|p95 147.4(4) 151.1(4) 155.7(4) 153.2(4) 151.2(4) type.code_note_prose 62.1(4) 68.1(4) 67.0(4) 67.7(4) 69.0(4) type.code_note_prose_cpu 30.0(4) 33.3(4) 33.2(4) 33.1(4) 32.9(4) type.code_note_prose|p95 156.1(4) 160.1(4) 161.7(4) 160.8(4) 160.2(4) type.long_note 61.6(4) 63.2(4) 61.9(4) 63.5(4) 65.7(4) type.long_note_cpu 26.9(4) 28.8(4) 28.6(4) 29.0(4) 29.2(4) type.long_note|p95 149.9(4) 152.4(4) 153.1(4) 153.1(4) 154.6(4) ``` Reading it: dev and dev2 are identical bits and differ by up to 6 ms (code_note_prose), so that is the resolution. #903 against dev2: within -1.1 to +2.0 ms p50 and -0.4 to +2.0 ms CPU per key; #904 against #887: within +0.4 to +2.2 ms p50 and about +0.2 to +0.4 ms... see the table; no row separates a PR from its base by more than the control does. The earlier +10 ms (one run, perf-01 under load 9, no control) is not reproduced. The per-keystroke work was also cut: the #903 gate now looks only at typed backticks/tildes, and #904 does nothing on a keystroke until a hidden list exists.
Author
Owner

Exact deltas for the table above (this PR minus its base h887, ms): p50 code_block -1.6, code_note_prose +1.3, long_note +2.2; CPU per key 0.0, -0.2, +0.2. The same-bits dev-vs-dev control differs by +2.9, +6.0, +1.6 p50, so none of this separates the PR from noise; the first run's +10 ms is not reproduced.

Exact deltas for the table above (this PR minus its base `h887`, ms): p50 code_block -1.6, code_note_prose +1.3, long_note +2.2; CPU per key 0.0, -0.2, +0.2. The same-bits dev-vs-dev control differs by +2.9, +6.0, +1.6 p50, so none of this separates the PR from noise; the first run's +10 ms is not reproduced.
kayg changed target branch from dev to notes-archive-hide 2026-11-04 20:00:42 +00:00
Author
Owner

First-paint diet (BM15, #947). Head 7443f392 (cherry-picked onto the #887 diet; base notes-archive-hide).

First-paint bytes are brotli q11 from apps/web/scripts/bundle-size.mjs (JS of the first-paint closure = the index chunk; CSS of the first stylesheet). Dev baseline 41f2efa3: 238,797 B JS, 19,250 B CSS. A second figure, "hash-normalised", is the same chunk with the 8-character chunk-file hashes replaced by a fixed string: the hashes are random, and they move the real brotli number by ±300 B between two builds of identical code, so a few-hundred-byte claim is only meaningful in the normalised figure (dev: 238,804). Chunk budgets: every new lazy chunk's line is taken from the first-script line or the idle-screens line so the total stays 404.2; perf/web.sh --bundle-only --gate passes on this head.

first JS first CSS lazy JS
#887 head 239,130 19,250 123,424
this PR 239,391 (+261 over #887, +594 over dev; normalised 239,342 = +689 over #887, +538 over dev) 19,250 (0) 126,166

The Hide block action's body (select, undo toast) moved into hidden-ui.ts (it was in actions.ts); everything else already loaded on demand (lazy-hidden.ts is the one trigger). What is left on the first screen is the trigger plugin, the Show-hidden-blocks button in Tools.svelte and its count in editing. This PR is not ≤ 0 on its own; it is paid for by #875's offset (see #947 for the running total in merge order).

hidden-blocks.spec: 16 passed (all four projects). Lint ok, svelte-check = baseline, units ok.

Budgets: hidden-ui 2.5 from index (240 → 237.5) and the notes-visibility-apply line from idle-screens; total 404.2 (the +2.5 bump is reverted).

**First-paint diet (BM15, #947).** Head `7443f392` (cherry-picked onto the #887 diet; base `notes-archive-hide`). First-paint bytes are brotli q11 from `apps/web/scripts/bundle-size.mjs` (JS of the first-paint closure = the `index` chunk; CSS of the first stylesheet). Dev baseline `41f2efa3`: **238,797 B JS, 19,250 B CSS**. A second figure, "hash-normalised", is the same chunk with the 8-character chunk-file hashes replaced by a fixed string: the hashes are random, and they move the real brotli number by ±300 B between two builds of identical code, so a few-hundred-byte claim is only meaningful in the normalised figure (dev: 238,804). Chunk budgets: every new lazy chunk's line is taken from the first-script line or the idle-screens line so the total stays 404.2; `perf/web.sh --bundle-only --gate` passes on this head. | | first JS | first CSS | lazy JS | |---|---|---|---| | #887 head | 239,130 | 19,250 | 123,424 | | this PR | 239,391 (**+261 over #887**, +594 over dev; normalised 239,342 = **+689 over #887**, +538 over dev) | 19,250 (0) | 126,166 | The Hide block action's body (select, undo toast) moved into `hidden-ui.ts` (it was in `actions.ts`); everything else already loaded on demand (`lazy-hidden.ts` is the one trigger). What is left on the first screen is the trigger plugin, the Show-hidden-blocks button in `Tools.svelte` and its count in `editing`. This PR is **not ≤ 0 on its own**; it is paid for by #875's offset (see #947 for the running total in merge order). `hidden-blocks.spec`: **16 passed** (all four projects). Lint ok, svelte-check = baseline, units ok. Budgets: `hidden-ui` 2.5 from `index` (240 → 237.5) and the `notes-visibility-apply` line from `idle-screens`; total 404.2 (the +2.5 bump is reverted).
Author
Owner

Not gated yet: carries #887

This branch contains a merge of #887 (notes-archive-hide: the hide/archive/restore Rust and the contracts/actions.json changes). #887's write-path regression is being fixed by a separate lane, so gating this branch now would measure that regression, and merging it would land #887 through the back door. Once #887 is in dev, I merge dev here and run the full per-PR gates (I already merged origin/dev b5e8dcb2 into #875 and #904; #877 and #878 follow #875 as a stack). Also needs then: backend perf ABAB on the perf VMs (Rust), and for #904 the unchanged phone-bar fix f30e0bb7.

## Not gated yet: carries #887 This branch contains a merge of #887 (`notes-archive-hide`: the hide/archive/restore Rust and the `contracts/actions.json` changes). #887's write-path regression is being fixed by a separate lane, so gating this branch now would measure that regression, and merging it would land #887 through the back door. Once #887 is in dev, I merge dev here and run the full per-PR gates (I already merged origin/dev `b5e8dcb2` into #875 and #904; #877 and #878 follow #875 as a stack). Also needs then: backend perf ABAB on the perf VMs (Rust), and for #904 the unchanged phone-bar fix `f30e0bb7`.
kayg changed target branch from notes-archive-hide to dev 2026-11-07 20:33:21 +00:00
Author
Owner

housekeeping #1009: rebased+failing, left open for review.

rebased hidden blocks with its missing backend dependency. kept dev code/picker lazy chunks, current toolbar and phone Attach behavior; restored lazy hidden UI and editing.peeking.

head: 2b98bf3af49165cf2196e4939e7e34ad5e6f8392; based on dev cd7f84432febfc63b788fbb9b9f9950452982d74, pushed with the original exact force-with-lease.

frontend frozen install, check, lint, build and unit tests passed. bundle gate failed. first-paint brotli vs dev: JS 231250 B (+473 B), CSS 18386 B (+0 B).

Rust gate results (Mac VM):

exit command
0 cargo fmt -p calternal-core -p calternal-engine -p calternal-notes -p calternal-perf -p calternal-search -p calternal-tasks -- --check
0 cargo check -j4 --locked -p calternal-core -p calternal-engine -p calternal-notes -p calternal-perf -p calternal-search -p calternal-tasks --all-targets
0 cargo clippy -j4 --locked -p calternal-core -p calternal-engine -p calternal-notes -p calternal-perf -p calternal-search -p calternal-tasks --all-targets -- -D warnings
101 cargo test -j4 --locked -p calternal-core -p calternal-engine -p calternal-notes -p calternal-perf -p calternal-search -p calternal-tasks

Engine idle-user fixture fails with missing file; the same failure reproduces on dev. targeted Chromium and WebKit specs at 1440 and 390 never started. the audit waited more than three hours behind the live daily-train-1107 locks (first queue at 23:45 IST, 7 November; final queue cleanup after 02:46 IST, 8 November). browser validation and UI captures are unrun. only this audit’s exact queued units were stopped; the train locks and owners were left intact. hot-path perf qualification is unrun.

all executed gates used the VM Nix environment, shared Mac lock and slot. exact commands, source heads, logs and dev baseline. frontend inputs are identical to the tested frontend tree when a Rust-only repair changed the head.

original-head cherry/patch inventory, pr-904.md; unmatched entries are missing-patch candidates, with semantic overlap/replacements noted above.

final queue, cleanup and source-verification evidence.

housekeeping #1009: rebased+failing, left open for review. rebased hidden blocks with its missing backend dependency. kept dev code/picker lazy chunks, current toolbar and phone Attach behavior; restored lazy hidden UI and editing.peeking. head: `2b98bf3af49165cf2196e4939e7e34ad5e6f8392`; based on dev `cd7f84432febfc63b788fbb9b9f9950452982d74`, pushed with the original exact force-with-lease. frontend frozen install, check, lint, build and unit tests passed. bundle gate failed. first-paint brotli vs dev: JS 231250 B (+473 B), CSS 18386 B (+0 B). Rust gate results (Mac VM): | exit | command | |---|---| | 0 | `cargo fmt -p calternal-core -p calternal-engine -p calternal-notes -p calternal-perf -p calternal-search -p calternal-tasks -- --check` | | 0 | `cargo check -j4 --locked -p calternal-core -p calternal-engine -p calternal-notes -p calternal-perf -p calternal-search -p calternal-tasks --all-targets` | | 0 | `cargo clippy -j4 --locked -p calternal-core -p calternal-engine -p calternal-notes -p calternal-perf -p calternal-search -p calternal-tasks --all-targets -- -D warnings` | | 101 | `cargo test -j4 --locked -p calternal-core -p calternal-engine -p calternal-notes -p calternal-perf -p calternal-search -p calternal-tasks` | Engine idle-user fixture fails with missing file; the same failure reproduces on dev. targeted Chromium and WebKit specs at 1440 and 390 never started. the audit waited more than three hours behind the live daily-train-1107 locks (first queue at 23:45 IST, 7 November; final queue cleanup after 02:46 IST, 8 November). browser validation and UI captures are unrun. only this audit’s exact queued units were stopped; the train locks and owners were left intact. hot-path perf qualification is unrun. all executed gates used the VM Nix environment, shared Mac lock and slot. [exact commands, source heads, logs and dev baseline](https://git.kayg.org/attachments/870a0fef-2e31-425c-aea6-eb87a66d365a). frontend inputs are identical to the tested frontend tree when a Rust-only repair changed the head. [original-head cherry/patch inventory](https://git.kayg.org/attachments/e05a38dc-c028-4d77-8655-efa9d5c8ea50), `pr-904.md`; unmatched entries are missing-patch candidates, with semantic overlap/replacements noted above. [final queue, cleanup and source-verification evidence](https://git.kayg.org/attachments/7ab315a5-4b6c-4af1-971b-cdae2637adae).
Author
Owner

Final-port test pass (issue #1009), READY: no: fixed 3 real failures, specs now pass; bundle gate fails.

head 0e601928a307dff6a414660e8c140ae71a88165f

Targeted specs, CI=1 --retries=0 --workers=1, dev-01 Chromium and dev-02 WebKit (through ~/bin/slot), against a dev-head backend (cd7f84432).

spec Chromium 1440 Chromium 390 WebKit 1440 WebKit 390
hidden-blocks (before fix) 1/4 1/4 1/4 1/4
hidden-blocks (after 0e601928a) 4/4 4/4 4/4 4/4

Bundle gate: perf/web.sh --bundle-only --gate (the 17 failures from the housekeeping audit). Per the gate's own rule (total_js_brotli budget must equal the sum of the named chunk budgets) a cap can only move between named chunks; there is no donor chunk inside this PR, so a fix is a code cut or a decision by kayg. I raised nothing and moved nothing.

  • Fix pushed (0e601928a): Hide and Unhide dispatched with userEvent: "input". Dev's editor refuses every frontmatter edit that isn't tagged input.properties (packages/editor/src/syntax/hidden.ts), so Hide did nothing on the page. Both dispatches now use input.properties.
  • Gate: idle-screens 51.75 vs 51.2, index 225.83 vs 223.75 (caps were set tight by the PR itself). No donor chunk; needs a cut.

Not done: Not run yet: Mac VM Safari blur/frame check and perf ABAB x5 on the perf VMs (they need a ready PR first); light/dark 2x screenshots against the mockup are only done for #888 (see its comment).

Not marked READY FOR MERGE.

**Final-port test pass (issue #1009), READY: no: fixed 3 real failures, specs now pass; bundle gate fails.** head `0e601928a307dff6a414660e8c140ae71a88165f` Targeted specs, `CI=1 --retries=0 --workers=1`, dev-01 Chromium and dev-02 WebKit (through `~/bin/slot`), against a dev-head backend (`cd7f84432`). | spec | Chromium 1440 | Chromium 390 | WebKit 1440 | WebKit 390 | |---|---|---|---|---| | hidden-blocks (before fix) | 1/4 | 1/4 | 1/4 | 1/4 | | hidden-blocks (after `0e601928a`) | 4/4 | 4/4 | 4/4 | 4/4 | **Bundle gate:** `perf/web.sh --bundle-only --gate` (the 17 failures from the housekeeping audit). Per the gate's own rule (`total_js_brotli` budget must equal the sum of the named chunk budgets) a cap can only move between named chunks; there is no donor chunk inside this PR, so a fix is a code cut or a decision by kayg. I raised nothing and moved nothing. - **Fix pushed (`0e601928a`):** Hide and Unhide dispatched with `userEvent: "input"`. Dev's editor refuses every frontmatter edit that isn't tagged `input.properties` (`packages/editor/src/syntax/hidden.ts`), so Hide did nothing on the page. Both dispatches now use `input.properties`. - Gate: `idle-screens` 51.75 vs 51.2, `index` 225.83 vs 223.75 (caps were set tight by the PR itself). No donor chunk; needs a cut. **Not done:** Not run yet: Mac VM Safari blur/frame check and perf ABAB x5 on the perf VMs (they need a ready PR first); light/dark 2x screenshots against the mockup are only done for #888 (see its comment). Not marked READY FOR MERGE.
Author
Owner

Screenshots and state (issue #1009), e84b29d0bb

Product (this PR, Chromium, 2x) next to the approved mockup (review/calendar-2, 2x), light and dark, 1440x900 and 390x844. Real Safari (glass) for these states is not taken yet. Not READY: first paint is over dev (see the #1009 table).
Differences from the mockup: the desktop has no note-level button in dev today, so Show hidden blocks is reached through the command palette there (the phone's Page actions menu has it, between Show source and Pin); the block menu has dev's own items (Move up/down, Delete note) and Hide now sits after Select with the eye-slash icon, as in the mockup; the sample note in the mockup has a fenced code block that the product cannot hide in these shots (the product's hidden wifi block is a plain line).

Screenshots (2x; light and dark; 1440x900 and 390x844). Left: the approved mockup (review/calendar-2). Right: this PR.

menu

mockup this PR
1440 light
1440 dark
390 light
390 dark

shown

mockup this PR
1440 light
1440 dark
390 light
390 dark

blockmenu

mockup this PR
1440 light
1440 dark
390 light
390 dark

hidden

mockup this PR
1440 light
1440 dark
390 light
390 dark

Real Safari (Mac VM, safaridriver, 1x: the VM reports devicePixelRatio 1)

menu

light dark
1440
390

shown

light dark
1440
390

blockmenu

light dark
1440
390

hidden

light dark
1440
390
**Screenshots and state (issue #1009), e84b29d0bb01dd90014c6a642f226e332b79e63e** Product (this PR, Chromium, 2x) next to the approved mockup (review/calendar-2, 2x), light and dark, 1440x900 and 390x844. Real Safari (glass) for these states is not taken yet. **Not READY: first paint is over dev (see the #1009 table).** Differences from the mockup: the desktop has no note-level button in dev today, so *Show hidden blocks* is reached through the command palette there (the phone's *Page actions* menu has it, between Show source and Pin); the block menu has dev's own items (Move up/down, Delete note) and *Hide* now sits after *Select* with the eye-slash icon, as in the mockup; the sample note in the mockup has a fenced code block that the product cannot hide in these shots (the product's hidden wifi block is a plain line). ### Screenshots (2x; light and dark; 1440x900 and 390x844). Left: the approved mockup (review/calendar-2). Right: this PR. **menu** | | mockup | this PR | |---|---|---| | 1440 light | ![](https://git.kayg.org/attachments/50c79857-599a-493b-80d3-af4063055bd2) | ![](https://git.kayg.org/attachments/98656f2e-d5d7-4697-9582-a6d5f65f0f2d) | | 1440 dark | ![](https://git.kayg.org/attachments/72467c40-d2f9-4658-9d45-5c1db0ddd2af) | ![](https://git.kayg.org/attachments/9dbd4080-8092-447a-b2d6-52af54e0eacc) | | 390 light | ![](https://git.kayg.org/attachments/63e6c749-d8e7-4303-a491-67abe6513673) | ![](https://git.kayg.org/attachments/953f8c8b-0bb9-46a2-88d4-269d84cdb130) | | 390 dark | ![](https://git.kayg.org/attachments/62bcc85c-7655-47ba-8b32-979d3e7dc5d4) | ![](https://git.kayg.org/attachments/9112fad4-0dbb-4eca-bb24-e800e7bad31f) | **shown** | | mockup | this PR | |---|---|---| | 1440 light | ![](https://git.kayg.org/attachments/c4cfae67-a4d1-4f0f-9350-d79b98d147c5) | ![](https://git.kayg.org/attachments/cb653ad5-895d-482a-9811-15057af1a602) | | 1440 dark | ![](https://git.kayg.org/attachments/2d49b1f8-7ea8-4945-9366-000b9f22b0c7) | ![](https://git.kayg.org/attachments/1fdd4b2d-035d-4f9f-b6a5-98bc08dfbca7) | | 390 light | ![](https://git.kayg.org/attachments/5f2914d1-6ba3-4726-b0aa-83bc194cae5b) | ![](https://git.kayg.org/attachments/770e00e6-6b84-49d7-99fa-cfa2a7e9dd98) | | 390 dark | ![](https://git.kayg.org/attachments/7150e6bb-589d-4328-b942-fe8e6db981f3) | ![](https://git.kayg.org/attachments/460664d1-959e-40d7-ae7a-bb0609b5060c) | **blockmenu** | | mockup | this PR | |---|---|---| | 1440 light | ![](https://git.kayg.org/attachments/4609157d-16d6-40e0-9a53-9477c5b80539) | ![](https://git.kayg.org/attachments/6eb976a8-80f1-471a-baa0-be4dffd71630) | | 1440 dark | ![](https://git.kayg.org/attachments/c234057a-ded6-4a76-a5fa-cb6ec2522cc0) | ![](https://git.kayg.org/attachments/0aefb081-bc32-4c0a-8a79-3668e9ec5c37) | | 390 light | ![](https://git.kayg.org/attachments/01558b5a-2082-47ae-bb31-5e6818f19917) | ![](https://git.kayg.org/attachments/40992e05-87ea-45b1-8c7d-ab86dc328761) | | 390 dark | ![](https://git.kayg.org/attachments/5a338c52-975c-4cd0-867b-ea40368455e7) | ![](https://git.kayg.org/attachments/3ab2b434-fa01-4641-8e6f-b468a9670189) | **hidden** | | mockup | this PR | |---|---|---| | 1440 light | ![](https://git.kayg.org/attachments/f7eeea1e-f966-4264-afb8-74ab0ffc0a23) | ![](https://git.kayg.org/attachments/5f2dad7a-da0f-4328-93d4-be09f989fc04) | | 1440 dark | ![](https://git.kayg.org/attachments/2661ddc2-a611-43a3-946b-6babd3016165) | ![](https://git.kayg.org/attachments/7766072a-45b0-4ad9-8eab-ed63d2e19ce9) | | 390 light | ![](https://git.kayg.org/attachments/d689ea9c-2345-4772-a288-cf4d5c7b81b5) | ![](https://git.kayg.org/attachments/8636fc0c-13fc-466f-9694-e94eacc2190b) | | 390 dark | ![](https://git.kayg.org/attachments/37e8f221-7acd-4527-b5f5-431722136272) | ![](https://git.kayg.org/attachments/d7170660-3dfd-4187-8188-01c0ac77d0ab) | ### Real Safari (Mac VM, safaridriver, 1x: the VM reports devicePixelRatio 1) **menu** | | light | dark | |---|---|---| | 1440 | ![](https://git.kayg.org/attachments/d414c5c0-1651-42af-83fb-32894e8e2e31) | ![](https://git.kayg.org/attachments/957a68fd-e922-471a-a946-631fae462169) | | 390 | ![](https://git.kayg.org/attachments/88641331-98c5-4e25-9d83-bef6fcda65d1) | ![](https://git.kayg.org/attachments/4033d781-62a8-454b-8ce5-daa475a17ef3) | **shown** | | light | dark | |---|---|---| | 1440 | ![](https://git.kayg.org/attachments/fddeaaad-d476-4b5b-b713-8f36ee647494) | ![](https://git.kayg.org/attachments/5e0a81b5-6883-4e53-8acb-24f7d7a587ed) | | 390 | ![](https://git.kayg.org/attachments/aa6baf82-93d9-4e4c-a1f9-ad3703da3c4f) | ![](https://git.kayg.org/attachments/a1434855-4b2b-4b62-a8ce-eb2a448da86b) | **blockmenu** | | light | dark | |---|---|---| | 1440 | ![](https://git.kayg.org/attachments/914a9ba4-fa5a-46e3-bc31-8b896ae97143) | ![](https://git.kayg.org/attachments/375b64bd-fdae-4105-a1b1-653e363cdba6) | | 390 | ![](https://git.kayg.org/attachments/c20dfcc7-4954-4207-9b25-f015f4bf9435) | ![](https://git.kayg.org/attachments/6837dfe6-bcf2-49f1-bf5d-abb02090ebb9) | **hidden** | | light | dark | |---|---|---| | 1440 | ![](https://git.kayg.org/attachments/9f19f92f-511a-48cb-83ff-565fa52ed571) | ![](https://git.kayg.org/attachments/50177306-0cb4-4121-9c67-225015815a59) | | 390 | ![](https://git.kayg.org/attachments/1a33f7b7-a358-4dc6-8ac0-39797ad8a316) | ![](https://git.kayg.org/attachments/e6d7aa6a-b0f5-4a20-8850-fe2556c6406f) |
Author
Owner

Restacked on dev d4b32af94, head e30958527. Not READY: first paint is over dev.

First paint JS vs dev (plain 228525 B / normalised 228128 B): 228903 B: +378 B / 228614 B: +486 B; CSS +0. Specs: hidden-blocks 8 passed, Chromium and WebKit (1440 + 390). Bundle gate passes; budget regenerated (total 516.0 KiB). Dev d4b32af94 itself fails 9 specs (palette preload:118 at 1440 and 390, glass:76, lazy-ui:70, preload:89 x3 at 390), on Chromium and WebKit; the same ones fail on this head and none is new.

**Restacked on dev `d4b32af94`, head `e30958527`. Not READY: first paint is over dev.** First paint JS vs dev (plain 228525 B / normalised 228128 B): **228903 B: +378 B** / 228614 B: +486 B; CSS +0. Specs: hidden-blocks 8 passed, Chromium and WebKit (1440 + 390). Bundle gate passes; budget regenerated (total 516.0 KiB). Dev `d4b32af94` itself fails 9 specs (palette `preload:118` at 1440 and 390, `glass:76`, `lazy-ui:70`, `preload:89` x3 at 390), on Chromium and WebKit; the same ones fail on this head and none is new.
Author
Owner

Restacked on dev 661123e94, head 569feffc61987560fd0960ae3d9b4c2e9588f1da. Not READY: first paint +361 B plain (normalised +110 B), CSS +0. Specs: hidden-blocks 8 passed, both engines; gate passes (total 510.1 KiB). The stubs are the note menu entry, the block menu's Hide, the visibility flags and the Hide icon in the shared icon table (the block menu is drawn before the hidden-blocks chunk is there). Dev 661123e94 itself fails the same nine specs as before (palette preload:118 at 1440 and 390, glass:76, lazy-ui:70, preload:89 x3), on both engines; none is new on this head.

**Restacked on dev `661123e94`, head `569feffc61987560fd0960ae3d9b4c2e9588f1da`. Not READY: first paint +361 B plain (normalised +110 B), CSS +0.** Specs: hidden-blocks 8 passed, both engines; gate passes (total 510.1 KiB). The stubs are the note menu entry, the block menu's Hide, the visibility flags and the Hide icon in the shared icon table (the block menu is drawn before the hidden-blocks chunk is there). Dev `661123e94` itself fails the same nine specs as before (palette `preload:118` at 1440 and 390, `glass:76`, `lazy-ui:70`, `preload:89` x3), on both engines; none is new on this head.
Author
Owner

READY FOR MERGE: hidden blocks (head 1cb0233f6, on the rows base)

Design merge with Sharing (#842/#876) and dev 4274dafb4 (rusqlite 0.41, restore detection, #1044 frame fixes, #1048 lifecycle ids). Done once in the rows base (#875), carried up by merges:

  • write_executor/home.rs: run_note_write(plan, undo_of, caller) takes both the rows undo key and Sharing's caller; plain writes pass (None, None), execute_note_write_for passes the caller, undo passes its key.
  • crates/notes/src/actions.rs: shared::actions and visibility::actions are both chained. contracts/actions.json is the union (notes.hide/archive/unarchive/unhide and notes.hide-shared side by side; actions.gen.ts regenerated with action-types.mjs --check).
  • crates/search/src/index.rs: dev's hand-opened read snapshot (rusqlite 0.41) plus the foreground gauge.
  • Web: NoteList, lists.ts, sidebar.svelte.ts, actions.ts keep both the Archived and the Shared with me lists; Show hidden does not add your own hidden notes to Shared with me; lists.ts reads store.list(key) (#1030) for Archived/Pinned/tags.
  • #904: its duplicated copy of the backend is replaced by the rows branch's, so there is one backend; its own web commits are untouched.

Checks on dev-02 (aarch64), PR-built backend: cargo test -p calternal-notes 623 passed (one run had typing_during_a_tag_rename_is_kept fail while WebKit specs loaded the host; it passes 3/3 alone on this head and on dev), calternal-auth isolation 3, calternal isolation 40, calternal-server access 1, admin-sharing 11 passed in both chromium projects on #878 and #904 (including the new trash/restore test). Specs, 4 projects: preload, lazy-ui, lazy-offline, glass, shortcuts, keys-no-motion, press, bulk-tag, visibility, sidebar-drop, hidden-blocks, slash-menu: 0 failures except keys-no-motion webkit-1440 settings (Control+,), a flake (fails on 845/877/904 runs and passes on rerun, also on #854/#861).

First paint vs dev: +283 / +341 B, CSS 0. Budget total 535.36 KiB. Gate clean. Merging #904 after #877 needs one small fix: both put an show icon in a table (Icon.svelte in #877, hidden-ui.ts registerIcons in #904), which icons.test rejects as a duplicate; drop the one in hidden-ui.ts then.

## READY FOR MERGE: hidden blocks (head `1cb0233f6`, on the rows base) **Design merge with Sharing (#842/#876) and dev `4274dafb4` (rusqlite 0.41, restore detection, #1044 frame fixes, #1048 lifecycle ids).** Done once in the rows base (#875), carried up by merges: - `write_executor/home.rs`: `run_note_write(plan, undo_of, caller)` takes both the rows undo key and Sharing's caller; plain writes pass `(None, None)`, `execute_note_write_for` passes the caller, undo passes its key. - `crates/notes/src/actions.rs`: `shared::actions` and `visibility::actions` are both chained. `contracts/actions.json` is the union (`notes.hide`/`archive`/`unarchive`/`unhide` and `notes.hide-shared` side by side; `actions.gen.ts` regenerated with `action-types.mjs --check`). - `crates/search/src/index.rs`: dev's hand-opened read snapshot (rusqlite 0.41) plus the foreground gauge. - Web: `NoteList`, `lists.ts`, `sidebar.svelte.ts`, `actions.ts` keep both the Archived and the Shared with me lists; Show hidden does not add your own hidden notes to Shared with me; `lists.ts` reads `store.list(key)` (#1030) for Archived/Pinned/tags. - #904: its duplicated copy of the backend is replaced by the rows branch's, so there is one backend; its own web commits are untouched. **Checks on dev-02 (aarch64), PR-built backend:** `cargo test -p calternal-notes` 623 passed (one run had `typing_during_a_tag_rename_is_kept` fail while WebKit specs loaded the host; it passes 3/3 alone on this head and on dev), `calternal-auth` isolation 3, `calternal` isolation 40, `calternal-server` access 1, **admin-sharing 11 passed in both chromium projects on #878 and #904** (including the new trash/restore test). Specs, 4 projects: preload, lazy-ui, lazy-offline, glass, shortcuts, keys-no-motion, press, bulk-tag, visibility, sidebar-drop, hidden-blocks, slash-menu: 0 failures except `keys-no-motion` webkit-1440 `settings (Control+,)`, a flake (fails on 845/877/904 runs and passes on rerun, also on #854/#861). First paint vs dev: **+283 / +341 B**, CSS 0. Budget total 535.36 KiB. Gate clean. Merging #904 after #877 needs one small fix: both put an `show` icon in a table (`Icon.svelte` in #877, `hidden-ui.ts` registerIcons in #904), which `icons.test` rejects as a duplicate; drop the one in `hidden-ui.ts` then.
Some checks failed
CI / server (pull_request) Has been cancelled
CI / rust (pull_request) Has been cancelled
CI / web (pull_request) Has been cancelled
Markdown extraction contract / markdown-native-contract (pull_request) Has been cancelled
Markdown extraction contract / markdown-editor-contract (pull_request) Has been cancelled
Merge conflict checking is in progress. Try again in few moments.
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u origin port/hidden-blocks:port/hidden-blocks
git switch port/hidden-blocks

Merge

Merge the changes and update on Forgejo.

Warning: The "Autodetect manual merge" setting is not enabled for this repository, you will have to mark this pull request as manually merged afterwards.

git switch dev
git merge --no-ff port/hidden-blocks
git switch port/hidden-blocks
git rebase dev
git switch dev
git merge --ff-only port/hidden-blocks
git switch port/hidden-blocks
git rebase dev
git switch dev
git merge --no-ff port/hidden-blocks
git switch dev
git merge --squash port/hidden-blocks
git switch dev
git merge --ff-only port/hidden-blocks
git switch dev
git merge port/hidden-blocks
git push origin dev
Sign in to join this conversation.
No reviewers
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!904
No description provided.