Heading deep links: hover squiggle + link icon copies (kayg.org/blog style), double-tap on touch; remove header link icons #184

Closed
opened 2026-09-26 14:49:46 +00:00 by kayg · 21 comments
Owner

Owner grill 2026-09-26 (rounds 1-2, all answered). Reference implementation: the owner's website git.kayg.org/kayg/website.git (blog heading anchors: hovering a heading shows an accent squiggly underline and a link icon; clicking copies the heading's deep link and shows a toast). Read its source and port the idea to our design system.

  • One shared component. Used for: Settings section and group titles, headings inside notes (H1-H6, DESIGN §33 heading links), page titles that are real headings. Titles that are menus (e.g. 'Sep 2026 ⌄') are not headings and do not get it. Every existing standalone header link icon (the blue link glyphs in Settings) is removed.
  • Colour: the theme accent (per theme).
  • Desktop: hover or keyboard focus reveals the icon (a real button, Tab reaches it, Enter copies). Squiggle draws in left→right ~180ms, icon fades/slides 4px, on copy the icon swaps to a check briefly. Reduced motion: instant, no draw.
  • Toast (shared toaster): Link to “” copied.
  • Touch: double-tap a NON-editable heading copies (touch-action: manipulation; no 300ms wait on elements whose single tap does something: those get no double-tap). The squiggle draws for ~400ms as feedback plus the toast.
  • Notes (editable headings): double-tap edits text (Craft modes, #182), so on touch a note heading's Copy link lives in the block toolbar of the selected block; on desktop the hover icon click copies and must not change the editor mode (no block select, no text edit). Wait for #182 to land on dev before the notes part (merge dev).
    Screenshots/recording of hover, copy and toast, light and dark, 1440 and 390, for Claude's review.
Owner grill 2026-09-26 (rounds 1-2, all answered). Reference implementation: the owner's website git.kayg.org/kayg/website.git (blog heading anchors: hovering a heading shows an accent squiggly underline and a link icon; clicking copies the heading's deep link and shows a toast). Read its source and port the idea to our design system. - One shared <LinkedHeading> component. Used for: Settings section and group titles, headings inside notes (H1-H6, DESIGN §33 heading links), page titles that are real headings. Titles that are menus (e.g. 'Sep 2026 ⌄') are not headings and do not get it. Every existing standalone header link icon (the blue link glyphs in Settings) is removed. - Colour: the theme accent (per theme). - Desktop: hover or keyboard focus reveals the icon (a real button, Tab reaches it, Enter copies). Squiggle draws in left→right ~180ms, icon fades/slides 4px, on copy the icon swaps to a check briefly. Reduced motion: instant, no draw. - Toast (shared toaster): Link to “<heading>” copied. - Touch: double-tap a NON-editable heading copies (touch-action: manipulation; no 300ms wait on elements whose single tap does something: those get no double-tap). The squiggle draws for ~400ms as feedback plus the toast. - Notes (editable headings): double-tap edits text (Craft modes, #182), so on touch a note heading's Copy link lives in the block toolbar of the selected block; on desktop the hover icon click copies and must not change the editor mode (no block select, no text edit). Wait for #182 to land on dev before the notes part (merge dev). Screenshots/recording of hover, copy and toast, light and dark, 1440 and 390, for Claude's review.
Author
Owner

Starting Forgejo #184 on branch job/heading-links, based on dev at 6e1e565603. I will build the shared heading component and Settings/page headings first, then merge dev to pick up #182 before implementing the notes behavior.

Starting Forgejo #184 on branch job/heading-links, based on dev at 6e1e5656036eaeb060df3089043519aab2066376. I will build the shared heading component and Settings/page headings first, then merge dev to pick up #182 before implementing the notes behavior.
Author
Owner

Read-only website reference reviewed at 036508c74073fe3676b4f7529aa8361129102519: src/layouts/MarkdownLayout.astro builds heading URLs from the current path and heading id, copies through its clipboard helper, and shows a toast; src/styles/global.css supplies the accent squiggle and hover icon. calternal keeps the stable route URLs and shared CopyLink clipboard path. For the unspecified touch gesture tolerance, LinkedHeading recognizes taps within 320 ms and 20 px; it ignores nested controls so their single-tap action stays intact.

Read-only website reference reviewed at 036508c74073fe3676b4f7529aa8361129102519: `src/layouts/MarkdownLayout.astro` builds heading URLs from the current path and heading id, copies through its clipboard helper, and shows a toast; `src/styles/global.css` supplies the accent squiggle and hover icon. calternal keeps the stable route URLs and shared `CopyLink` clipboard path. For the unspecified touch gesture tolerance, `LinkedHeading` recognizes taps within 320 ms and 20 px; it ignores nested controls so their single-tap action stays intact.
Author
Owner

The shared component and the Settings section/group and Journal page headings are committed in d68006a5. The focused web tests, bun run check, and production web build pass. I fetched origin/dev; it is still 6e1e5656, and #182 is still open, so I am waiting to merge dev before starting Notes as the issue directs.

The shared component and the Settings section/group and Journal page headings are committed in d68006a5. The focused web tests, `bun run check`, and production web build pass. I fetched origin/dev; it is still 6e1e5656, and #182 is still open, so I am waiting to merge dev before starting Notes as the issue directs.
Author
Owner

Resuming Forgejo #184 after the VM restart on branch job/heading-links at 6fbba90a8e. The worktree is clean; this checkpoint adds the Notes heading interaction assertions. The existing feature commit is d68006a5, and the prior dev merge includes #182. Current dev is 8b8e5cc9; I will integrate it before final gates, then finish the Notes desktop and touch actions and review screenshots.

Resuming Forgejo #184 after the VM restart on branch job/heading-links at 6fbba90a8e591ea575312af4947fb8a4756412e4. The worktree is clean; this checkpoint adds the Notes heading interaction assertions. The existing feature commit is d68006a5, and the prior dev merge includes #182. Current dev is 8b8e5cc9; I will integrate it before final gates, then finish the Notes desktop and touch actions and review screenshots.
Author
Owner

Finding and fix: the live Note editor and its fallback editor rendered H1–H6 as headings but exposed Copy link only from the editor block menu. That made the DESIGN §33 /n/<id>#<heading-slug> action unavailable at the heading itself. The new shared LinkedHeading control uses the existing stable note ID and slug route; the block-menu path already used the same slug helper and remains unchanged. The heading action is an editor decoration, so it does not change Markdown or collaboration content.

Finding and fix: the live Note editor and its fallback editor rendered H1–H6 as headings but exposed Copy link only from the editor block menu. That made the DESIGN §33 `/n/<id>#<heading-slug>` action unavailable at the heading itself. The new shared LinkedHeading control uses the existing stable note ID and slug route; the block-menu path already used the same slug helper and remains unchanged. The heading action is an editor decoration, so it does not change Markdown or collaboration content.
Author
Owner

Merge integration decision: current dev adds public Note editing at /s/<slug>, but DESIGN §33 defines no public heading fragment. I kept Copy link actions out of that guest editor instead of emitting a private /n/<id>#<heading-slug> link that the guest cannot open. The deep-link inventory now records this rule. Owned Note editors still expose H1–H6 links. bun run check passed with zero errors and warnings after the merge resolution.

Merge integration decision: current `dev` adds public Note editing at `/s/<slug>`, but DESIGN §33 defines no public heading fragment. I kept Copy link actions out of that guest editor instead of emitting a private `/n/<id>#<heading-slug>` link that the guest cannot open. The deep-link inventory now records this rule. Owned Note editors still expose H1–H6 links. `bun run check` passed with zero errors and warnings after the merge resolution.
Author
Owner

Adversarial probe finding: round 1 reported Journal fix stale line: SLOW 6.2s status 412 in tests/adversarial/attack.py. This is a SLOW-only result, so I am treating it as shared-host load under this job's rule. The full probe is still running; I will report any non-SLOW finding separately.

Adversarial probe finding: round 1 reported `Journal fix stale line: SLOW 6.2s status 412` in `tests/adversarial/attack.py`. This is a SLOW-only result, so I am treating it as shared-host load under this job's rule. The full probe is still running; I will report any non-SLOW finding separately.
Author
Owner

Adversarial finding under triage: tests/adversarial/attack2.py reported collab embeds: SERVER DIED after the embed-input cases. The probe had created Notes for malformed and Unicode embed bodies, then checked /readyz; it could no longer reach the server. The follow-on restart probe completed with 0 findings. I am checking whether this was a process crash or shared-host termination before closing out the finding.

Adversarial finding under triage: `tests/adversarial/attack2.py` reported `collab embeds: SERVER DIED` after the embed-input cases. The probe had created Notes for malformed and Unicode embed bodies, then checked `/readyz`; it could no longer reach the server. The follow-on restart probe completed with `0 findings`. I am checking whether this was a process crash or shared-host termination before closing out the finding.
Author
Owner

Adversarial triage update: I reran with ROUND2_SECTIONS=collab. The malformed and Unicode embed cases and socket-cap probe completed; the server was alive at the end, and the collaboration section reported ROUND 2 FINDINGS 0. The restart probe also reported 0 findings. The original full run's collab embeds: SERVER DIED did not reproduce. Its private server log was removed by the runner cleanup, so the original process exit cause is unknown. I recorded it here for follow-up; no heading-link change was implicated. Other findings in the focused run were SLOW-only API latency under concurrent host load.

Adversarial triage update: I reran with `ROUND2_SECTIONS=collab`. The malformed and Unicode embed cases and socket-cap probe completed; the server was alive at the end, and the collaboration section reported `ROUND 2 FINDINGS 0`. The restart probe also reported `0 findings`. The original full run's `collab embeds: SERVER DIED` did not reproduce. Its private server log was removed by the runner cleanup, so the original process exit cause is unknown. I recorded it here for follow-up; no heading-link change was implicated. Other findings in the focused run were SLOW-only API latency under concurrent host load.
Author
Owner

Completed

Built heading-level Copy link actions for H1–H6 in Note editors. Links use the Note identity and current heading slug. The editor tracks mapped heading ranges and scans the full Note only when transaction mapping is unavailable. Escape returns from heading text editing to block selection after a copy action.

The heading control uses the selected block toolbar on touch. The fallback editor shows its control without block selection. The public /s/<slug> guest editor has no heading fragments because DESIGN §33 does not define them; it does not produce a private /n/<id>#... link.

Files: packages/ui/src/components/LinkedHeading.svelte, packages/ui/src/index.ts, apps/web/src/lib/notes/headingLinks.ts, apps/web/src/lib/notes/NoteEditorSurface.svelte, apps/web/src/lib/notes/NoteView.svelte, apps/web/src/lib/notes/editorHost.ts, apps/web/e2e/notes.mjs, docs/deep-links.md, and four production screenshots in apps/web/e2e/review/heading-links/.

Commits: 8fbb5670, f4b71e9e, 7ed26940, merge of dev at e9f18804, screenshot commits 2dc4ca1d and 9136cc7f.

Head: 9136cc7f3781dba15d69c7fa4de263eff4e1519e.

Gates

  • cargo fmt --check: exit 0; no output.
  • cargo clippy --all-targets -- -D warnings: exit 0. Output: Finished \dev` profile [unoptimized + debuginfo] target(s) in 7m 30s`.
  • cargo test: exit 0; 69 emitted result lines sum to 1236 passed, 0 failed, 12 ignored. Example output: test result: ok. 45 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.08s.
  • bun run check: svelte-check found 0 errors and 0 warnings.
  • bun run test: Test Files 71 passed (71); Tests 542 passed (542).
  • bun run build: ✓ built in 36.44s; ✔ done.
  • Production Notes E2E: notes e2e: ok.
  • cargo clean: Removed 17072 files, 14.5GiB total.

Adversarial probe

The full probe reported SLOW 6.2s status 412 for the journal stale-line case and HOSTILE BYTES FINDINGS 0. It also reported collab embeds: SERVER DIED once. A scoped ROUND2_SECTIONS=collab replay completed with server alive at end: True and ROUND 2 FINDINGS 0; the restart probe reported 0 findings. The original private server log was removed by runner cleanup, so the first process exit cause is unknown. I filed this intermittent finding for investigation in #221. No heading-link code was implicated.

Decisions and known gaps

  • Public guest Note headings have no heading fragments because the deep-link grammar does not define them.
  • The one-time collaboration server loss did not reproduce in the scoped replay. Its cause remains unknown and is tracked in #221.
  • The visual review screenshots are attached for the orchestrator to review.
## Completed Built heading-level Copy link actions for H1–H6 in Note editors. Links use the Note identity and current heading slug. The editor tracks mapped heading ranges and scans the full Note only when transaction mapping is unavailable. Escape returns from heading text editing to block selection after a copy action. The heading control uses the selected block toolbar on touch. The fallback editor shows its control without block selection. The public `/s/<slug>` guest editor has no heading fragments because DESIGN §33 does not define them; it does not produce a private `/n/<id>#...` link. Files: `packages/ui/src/components/LinkedHeading.svelte`, `packages/ui/src/index.ts`, `apps/web/src/lib/notes/headingLinks.ts`, `apps/web/src/lib/notes/NoteEditorSurface.svelte`, `apps/web/src/lib/notes/NoteView.svelte`, `apps/web/src/lib/notes/editorHost.ts`, `apps/web/e2e/notes.mjs`, `docs/deep-links.md`, and four production screenshots in `apps/web/e2e/review/heading-links/`. Commits: `8fbb5670`, `f4b71e9e`, `7ed26940`, merge of `dev` at `e9f18804`, screenshot commits `2dc4ca1d` and `9136cc7f`. Head: `9136cc7f3781dba15d69c7fa4de263eff4e1519e`. ## Gates - `cargo fmt --check`: exit 0; no output. - `cargo clippy --all-targets -- -D warnings`: exit 0. Output: `Finished \`dev\` profile [unoptimized + debuginfo] target(s) in 7m 30s`. - `cargo test`: exit 0; 69 emitted result lines sum to 1236 passed, 0 failed, 12 ignored. Example output: `test result: ok. 45 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.08s`. - `bun run check`: `svelte-check found 0 errors and 0 warnings`. - `bun run test`: `Test Files 71 passed (71)`; `Tests 542 passed (542)`. - `bun run build`: `✓ built in 36.44s`; `✔ done`. - Production Notes E2E: `notes e2e: ok`. - `cargo clean`: `Removed 17072 files, 14.5GiB total`. ## Adversarial probe The full probe reported `SLOW 6.2s status 412` for the journal stale-line case and `HOSTILE BYTES FINDINGS 0`. It also reported `collab embeds: SERVER DIED` once. A scoped `ROUND2_SECTIONS=collab` replay completed with `server alive at end: True` and `ROUND 2 FINDINGS 0`; the restart probe reported `0 findings`. The original private server log was removed by runner cleanup, so the first process exit cause is unknown. I filed this intermittent finding for investigation in #221. No heading-link code was implicated. ## Decisions and known gaps - Public guest Note headings have no heading fragments because the deep-link grammar does not define them. - The one-time collaboration server loss did not reproduce in the scoped replay. Its cause remains unknown and is tracked in #221. - The visual review screenshots are attached for the orchestrator to review.
Author
Owner

Claude review (heading-copy-1440-paper-white.png): the squiggle + accent link icon look right. BUG before merge: consecutive headings render SIDE BY SIDE on one line ('Milestones Delivery plan Regional pilot Field teams First site' are five headings H2-H6 in one row). The LinkedHeading wrapper changed heading display (inline/inline-flex) or its container. Headings must stay block-level with their normal vertical rhythm; the icon sits inline at the end of the heading text only. Add a layout-sweep check that consecutive headings stack vertically. (The bordered selection ring on the 390 shot belongs to #191, which switches selection to a tint.) Re-take the screenshots.

Claude review (heading-copy-1440-paper-white.png): the squiggle + accent link icon look right. BUG before merge: consecutive headings render SIDE BY SIDE on one line ('Milestones Delivery plan Regional pilot Field teams First site' are five headings H2-H6 in one row). The LinkedHeading wrapper changed heading display (inline/inline-flex) or its container. Headings must stay block-level with their normal vertical rhythm; the icon sits inline at the end of the heading text only. Add a layout-sweep check that consecutive headings stack vertically. (The bordered selection ring on the 390 shot belongs to #191, which switches selection to a tint.) Re-take the screenshots.
Author
Owner

Resuming Forgejo #184 on branch job/heading-links at 9136cc7f3781dba15d69c7fa4de263eff4e1519e. The branch and dev currently share merge-base 21ee397d5c3d24f6355d90b17c2e36b2cf76615a; local dev is 32b115dc6338b262d7c5a313a24d25f24d3c2637. Latest review finding: consecutive Note headings render side by side. I will keep semantic headings block-level, put the icon inline after heading text, add a layout-sweep regression check, and retake the production screenshots.

Resuming Forgejo #184 on branch `job/heading-links` at `9136cc7f3781dba15d69c7fa4de263eff4e1519e`. The branch and `dev` currently share merge-base `21ee397d5c3d24f6355d90b17c2e36b2cf76615a`; local `dev` is `32b115dc6338b262d7c5a313a24d25f24d3c2637`. Latest review finding: consecutive Note headings render side by side. I will keep semantic headings block-level, put the icon inline after heading text, add a layout-sweep regression check, and retake the production screenshots.
Author
Owner

Finding from the first focused layout run: bun e2e/layout-sweep.mjs --only note checked 12 screens and reported CLS note: 0.036; it also ran the separate Agenda adversarial cases despite the Notes filter. Those unrelated cases timed out at agenda 320 and agenda zoom200 after 30 seconds. I am narrowing the --only run to the selected test group, then I will rerun the Note check.

Finding from the first focused layout run: `bun e2e/layout-sweep.mjs --only note` checked 12 screens and reported `CLS note: 0.036`; it also ran the separate Agenda adversarial cases despite the Notes filter. Those unrelated cases timed out at `agenda 320` and `agenda zoom200` after 30 seconds. I am narrowing the `--only` run to the selected test group, then I will rerun the Note check.
Author
Owner

Finding from refreshed Notes E2E: the existing heading.hover() steps now land at the centre of the full-width block heading, which can be outside its text. The Copy link stays hidden there, and Playwright reports the toolbar intercepting the hidden button. The new behavior reveals the action from the heading text or keyboard focus, so I am updating the E2E hover targets to the rendered text span before rerunning.

Finding from refreshed Notes E2E: the existing `heading.hover()` steps now land at the centre of the full-width block heading, which can be outside its text. The Copy link stays hidden there, and Playwright reports the toolbar intercepting the hidden button. The new behavior reveals the action from the heading text or keyboard focus, so I am updating the E2E hover targets to the rendered text span before rerunning.
Author
Owner

Post-merge finding on dev integration commit 38979440: the Notes E2E completes the H1–H6 copy-link checks and then times out at apps/web/e2e/notes.mjs:444 waiting for #unlinked-mentions-panel .mention-link after 15 seconds. The same Notes E2E passed before the merge. The fixture has a Meeting notes Note that mentions Project Atlas as plain text. I am recording this as an upstream Notes/search follow-up; it is separate from the heading layout fix.

Post-merge finding on `dev` integration commit `38979440`: the Notes E2E completes the H1–H6 copy-link checks and then times out at `apps/web/e2e/notes.mjs:444` waiting for `#unlinked-mentions-panel .mention-link` after 15 seconds. The same Notes E2E passed before the merge. The fixture has a `Meeting notes` Note that mentions `Project Atlas` as plain text. I am recording this as an upstream Notes/search follow-up; it is separate from the heading layout fix.
Author
Owner

Adversarial finding to triage on the merged local server: attack.py's bookmark capture storm reported statuses [201 x 11, -1 x 5] for 16 concurrent requests and 11/16 unique IDs. The five -1 values are no-response outcomes and are not tagged SLOW, so I am checking the probe timeout and replaying this case after the current round. No server crash was reported at this point.

Adversarial finding to triage on the merged local server: `attack.py`'s bookmark capture storm reported statuses `[201 x 11, -1 x 5]` for 16 concurrent requests and `11/16 unique IDs`. The five `-1` values are no-response outcomes and are not tagged `SLOW`, so I am checking the probe timeout and replaying this case after the current round. No server crash was reported at this point.
Author
Owner

Round-two adversarial results to triage on the merged local server (server alive at end):

  • Photos shared timeline returned 200 with {"days":[]}; the active shared photo did not appear.
  • Analytics storm produced three no-response timeouts, and two reads after the storm disagreed.
  • Public collaboration frame 301 did not close the socket at the configured rate limit.

These results are not tagged SLOW. I am checking the probe contracts and will replay them once the runner's collaboration restart checks finish.

Round-two adversarial results to triage on the merged local server (server alive at end): - Photos shared timeline returned `200` with `{"days":[]}`; the active shared photo did not appear. - Analytics storm produced three no-response timeouts, and two reads after the storm disagreed. - Public collaboration frame 301 did not close the socket at the configured rate limit. These results are not tagged `SLOW`. I am checking the probe contracts and will replay them once the runner's collaboration restart checks finish.
Author
Owner

Adversarial round against the merged dev snapshot at cc2a42b007b350989af5496b70e9eb86d151704b:

  • The editor probe reported three non-SLOW findings: “10,000 top-level blocks sync timed out”; “browser editor paste, Unicode, and history storm” timed out at 15 seconds; and the live-editor server restart did not complete.
  • Round 1 reported 33 findings, all labeled SLOW except the editor findings above. Hostile-byte checks reported 0 findings. The restart probe reported 0 findings.
  • Round 2 did not produce its summary within the 30-minute time box. I stopped it while it was still active. During this run, the server also logged multi-second API requests and an analytics connection reset, which is consistent with the shared host being under load, but the three editor results remain filed for follow-up and are not claimed as fixed.

This run was inconclusive for round 2. No code change was made for these editor/server findings because they concern shared collaboration behavior outside the heading layout fix.

Adversarial round against the merged `dev` snapshot at `cc2a42b007b350989af5496b70e9eb86d151704b`: - The editor probe reported three non-SLOW findings: “10,000 top-level blocks sync timed out”; “browser editor paste, Unicode, and history storm” timed out at 15 seconds; and the live-editor server restart did not complete. - Round 1 reported 33 findings, all labeled SLOW except the editor findings above. Hostile-byte checks reported 0 findings. The restart probe reported 0 findings. - Round 2 did not produce its summary within the 30-minute time box. I stopped it while it was still active. During this run, the server also logged multi-second API requests and an analytics connection reset, which is consistent with the shared host being under load, but the three editor results remain filed for follow-up and are not claimed as fixed. This run was inconclusive for round 2. No code change was made for these editor/server findings because they concern shared collaboration behavior outside the heading layout fix.
Author
Owner

Photos API adversarial round after merging dev (HEAD f012706d): the 15-minute timebox ended before attack.py reached the Photos search section, so this run does not verify the Photos search endpoint. The runner completed its hostile-byte stage with HOSTILE BYTES FINDINGS 0 and ROUND 2 FINDINGS 0; it printed repeated no-response timeouts during saved-search create/rename storms while the shared host had several concurrent builds and adversarial probes. I stopped the runner at the cap. These timeout results are inconclusive under load and are recorded as load findings; no Photos search fix is claimed from this round.

Photos API adversarial round after merging dev (HEAD f012706d): the 15-minute timebox ended before `attack.py` reached the Photos search section, so this run does not verify the Photos search endpoint. The runner completed its hostile-byte stage with `HOSTILE BYTES FINDINGS 0` and `ROUND 2 FINDINGS 0`; it printed repeated no-response timeouts during saved-search create/rename storms while the shared host had several concurrent builds and adversarial probes. I stopped the runner at the cap. These timeout results are inconclusive under load and are recorded as load findings; no Photos search fix is claimed from this round.
Author
Owner

Completed

Fixed the review bug. Linked headings now remain block-level, and the Copy link control stays inline after the heading text. The layout sweep checks consecutive H1–H6 boxes in the real Notes fixture. Retook the Notes screenshots after the final dev merge.

Files in this branch: packages/ui/src/components/LinkedHeading.svelte, packages/ui/src/index.ts, apps/web/src/lib/notes/headingLinks.ts, apps/web/src/lib/notes/NoteEditorSurface.svelte, apps/web/src/lib/notes/NoteView.svelte, apps/web/src/lib/notes/editorHost.ts, apps/web/e2e/notes.mjs, apps/web/e2e/layout-sweep.mjs, apps/web/e2e/review/heading-links/heading-copy-{1440,390}-{paper-white,tokyo-night}.png, apps/web/src/routes/journal/+page.svelte, apps/web/src/routes/journal/JournalPage.svelte.test.ts, apps/web/src/routes/settings/[...path]/+page.svelte, apps/web/src/routes/settings/parts/SettingsGroup.svelte, apps/web/src/routes/settings/parts/SettingsGroup.svelte.test.ts, and docs/deep-links.md.

Final branch head: 65c34a0ad61211ea5d8c0ebf303ef720b61cf2d4. dev at f1c0766907d5d1a0a3a7ea0ae807e43dd2caf9f0 is an ancestor.

Gates and local E2E

  • cargo fmt --check: exit 0, no output.
  • cargo clippy --all-targets -- -D warnings:
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 30.20s
    
  • cargo test: all emitted result groups passed. Parsed from the run output:
    groups=140 passed=2482 failed=0 ignored=24
    
  • bun run check:
    svelte-check found 0 errors and 0 warnings
    
  • bun run test:
     Test Files  80 passed (80)
          Tests  582 passed (582)
    
  • bun e2e/search.mjs: search e2e: ok
  • bun e2e/notes.mjs --screenshots e2e/review/heading-links: notes e2e: ok
  • bun e2e/layout-sweep.mjs --only note:
    checked 12 screens
    CLS note: 0.037
    LAYOUT SWEEP PASSED
    

Adversarial status and decisions

The capped Photos adversarial attempt did not reach the Photos search section. Its 15-minute limit expired during saved-search create/rename storms, which produced no-response timeouts while the shared host was saturated. Hostile-byte findings were 0. The reported ROUND 2 FINDINGS 0 came from explicitly skipped Round 2 sections and is not a passing result. The Photos search route itself passed the focused real-server search E2E, but hostile-query and request-storm coverage remains unverified on this run. Earlier editor probe timeouts (large block sync, paste/history storm, and restart) are in the prior issue comments and still need a lower-load rerun.

Design decision: keep the semantic H1–H6 element block-level; render its toolbar inline after .linked-heading-text, and scope pointer feedback to the text and toolbar. This preserves heading flow while keeping the action next to the heading label.

## Completed Fixed the review bug. Linked headings now remain block-level, and the Copy link control stays inline after the heading text. The layout sweep checks consecutive H1–H6 boxes in the real Notes fixture. Retook the Notes screenshots after the final `dev` merge. Files in this branch: `packages/ui/src/components/LinkedHeading.svelte`, `packages/ui/src/index.ts`, `apps/web/src/lib/notes/headingLinks.ts`, `apps/web/src/lib/notes/NoteEditorSurface.svelte`, `apps/web/src/lib/notes/NoteView.svelte`, `apps/web/src/lib/notes/editorHost.ts`, `apps/web/e2e/notes.mjs`, `apps/web/e2e/layout-sweep.mjs`, `apps/web/e2e/review/heading-links/heading-copy-{1440,390}-{paper-white,tokyo-night}.png`, `apps/web/src/routes/journal/+page.svelte`, `apps/web/src/routes/journal/JournalPage.svelte.test.ts`, `apps/web/src/routes/settings/[...path]/+page.svelte`, `apps/web/src/routes/settings/parts/SettingsGroup.svelte`, `apps/web/src/routes/settings/parts/SettingsGroup.svelte.test.ts`, and `docs/deep-links.md`. Final branch head: `65c34a0ad61211ea5d8c0ebf303ef720b61cf2d4`. `dev` at `f1c0766907d5d1a0a3a7ea0ae807e43dd2caf9f0` is an ancestor. ## Gates and local E2E - `cargo fmt --check`: exit 0, no output. - `cargo clippy --all-targets -- -D warnings`: ```text Finished `dev` profile [unoptimized + debuginfo] target(s) in 30.20s ``` - `cargo test`: all emitted result groups passed. Parsed from the run output: ```text groups=140 passed=2482 failed=0 ignored=24 ``` - `bun run check`: ```text svelte-check found 0 errors and 0 warnings ``` - `bun run test`: ```text Test Files 80 passed (80) Tests 582 passed (582) ``` - `bun e2e/search.mjs`: `search e2e: ok` - `bun e2e/notes.mjs --screenshots e2e/review/heading-links`: `notes e2e: ok` - `bun e2e/layout-sweep.mjs --only note`: ```text checked 12 screens CLS note: 0.037 LAYOUT SWEEP PASSED ``` ## Adversarial status and decisions The capped Photos adversarial attempt did not reach the Photos search section. Its 15-minute limit expired during saved-search create/rename storms, which produced no-response timeouts while the shared host was saturated. Hostile-byte findings were 0. The reported `ROUND 2 FINDINGS 0` came from explicitly skipped Round 2 sections and is not a passing result. The Photos search route itself passed the focused real-server search E2E, but hostile-query and request-storm coverage remains unverified on this run. Earlier editor probe timeouts (large block sync, paste/history storm, and restart) are in the prior issue comments and still need a lower-load rerun. Design decision: keep the semantic H1–H6 element block-level; render its toolbar inline after `.linked-heading-text`, and scope pointer feedback to the text and toolbar. This preserves heading flow while keeping the action next to the heading label.
Author
Owner

Merged in 6f31788b. Headings are block-level with the inline Copy link after the text.

Merged in 6f31788b. Headings are block-level with the inline Copy link after the text.
kayg closed this issue 2026-09-27 12:44:39 +00:00
kayg referenced this issue from a commit 2026-09-27 12:44:40 +00:00
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#184
No description provided.