Break the block editor: adversarial sweep of the note editor (web + collab + sync) #186

Closed
opened 2026-09-26 15:02:27 +00:00 by kayg · 32 comments
Owner

Owner 2026-09-26: 'I want an agent trying to break our block editor in various ways.' Scope: packages/editor, apps/web/src/lib/notes, the collab room (crates/calternal-collab) and the notes routes. Build a scripted, seeded, repeatable attack harness (Playwright + direct collab clients) in tests/ and run it on a real local server:

  • Structure: deep nesting (50 levels), 10k blocks, huge single block (1 MB), empty/whitespace blocks, mixed lists/tasks/headings/code/tables/images/embeds, block ids missing/duplicated/malformed (^ids), frontmatter edge cases.
  • Interaction: rapid click/double-click (Craft block vs text modes, #182), drag-and-drop to every position including into itself/its children, multi-select + move/delete, undo/redo storms (⌘Z/⌘⇧Z 500x), paste of hostile HTML/Markdown/RTF/images/huge text, IME composition (Japanese, Korean), RTL/bidi, emoji ZWJ sequences, Unicode normalisation, zero-width chars.
  • Concurrency: 2-5 collab clients editing the same block, one deleting what another edits, offline edits reconciled later, the sync client rewriting the same .md file on disk while the editor is open, server restart mid-edit (collab epochs).
  • Features in flight: reminders on blocks (calternal-reminders), → make-note-from-block (atomic, undoable), copy link to block, heading links (#184).
    Invariants: no crash/exception, no data loss (every byte written by any client is in the final file or a conflict copy), no duplicated or lost blocks, file stays valid Markdown that round-trips byte-for-byte where untouched (#95), ^ids unique, undo restores exactly. Every failure: minimal seeded repro as a regression test, fix, commit atomically. Report seeds run and bugs fixed/filed.
Owner 2026-09-26: 'I want an agent trying to break our block editor in various ways.' Scope: packages/editor, apps/web/src/lib/notes, the collab room (crates/calternal-collab) and the notes routes. Build a scripted, seeded, repeatable attack harness (Playwright + direct collab clients) in tests/ and run it on a real local server: - Structure: deep nesting (50 levels), 10k blocks, huge single block (1 MB), empty/whitespace blocks, mixed lists/tasks/headings/code/tables/images/embeds, block ids missing/duplicated/malformed (^ids), frontmatter edge cases. - Interaction: rapid click/double-click (Craft block vs text modes, #182), drag-and-drop to every position including into itself/its children, multi-select + move/delete, undo/redo storms (⌘Z/⌘⇧Z 500x), paste of hostile HTML/Markdown/RTF/images/huge text, IME composition (Japanese, Korean), RTL/bidi, emoji ZWJ sequences, Unicode normalisation, zero-width chars. - Concurrency: 2-5 collab clients editing the same block, one deleting what another edits, offline edits reconciled later, the sync client rewriting the same .md file on disk while the editor is open, server restart mid-edit (collab epochs). - Features in flight: reminders on blocks (calternal-reminders), → make-note-from-block (atomic, undoable), copy link to block, heading links (#184). Invariants: no crash/exception, no data loss (every byte written by any client is in the final file or a conflict copy), no duplicated or lost blocks, file stays valid Markdown that round-trips byte-for-byte where untouched (#95), ^ids unique, undo restores exactly. Every failure: minimal seeded repro as a regression test, fix, commit atomically. Report seeds run and bugs fixed/filed.
Author
Owner

Starting #186 on branch job/break-editor, based on 6e1e5656036eaeb060df3089043519aab206637 (dev merge-base). Worktree was clean at start.

Starting #186 on branch `job/break-editor`, based on `6e1e5656036eaeb060df3089043519aab206637` (dev merge-base). Worktree was clean at start.
Author
Owner

Finding from the first harness run: ./tests/adversarial/run.sh fails in its cargo build step before starting the local server. The compiler reports crates/plugins/files/src/index.rs:620:19: return Ok(()) returns () where the function expects bool. git blame attributes the line to 70c847ea (perf(files): skip an Index upsert that would change nothing). The function returns Result<bool>, and the parallel Agenda worktree has return Ok(true) at this branch. This file is outside the #186 owned paths, so I have not changed it. I am checking a way to continue the editor probe against the current production UI without changing another job's source.

Finding from the first harness run: `./tests/adversarial/run.sh` fails in its `cargo build` step before starting the local server. The compiler reports `crates/plugins/files/src/index.rs:620:19`: `return Ok(())` returns `()` where the function expects `bool`. `git blame` attributes the line to `70c847ea` (`perf(files): skip an Index upsert that would change nothing`). The function returns `Result<bool>`, and the parallel Agenda worktree has `return Ok(true)` at this branch. This file is outside the #186 owned paths, so I have not changed it. I am checking a way to continue the editor probe against the current production UI without changing another job's source.
Author
Owner

The first seeded editor sweep (seed=0x186c0de) passed the 50-level mixed-Markdown byte-stability case, the 10,000-block room load, and the 1 MiB paragraph case. The browser case found that Copy link reused ^duplicate-id on the second block carrying that ID, violating unique block anchors. In the same run, offline-edit reconciliation timed out; following room cases could not connect. I will isolate the room cases next because the later connection failures may depend on the earlier run state. No product changes have been made yet.

The first seeded editor sweep (`seed=0x186c0de`) passed the 50-level mixed-Markdown byte-stability case, the 10,000-block room load, and the 1 MiB paragraph case. The browser case found that Copy link reused `^duplicate-id` on the second block carrying that ID, violating unique block anchors. In the same run, offline-edit reconciliation timed out; following room cases could not connect. I will isolate the room cases next because the later connection failures may depend on the earlier run state. No product changes have been made yet.
Author
Owner

The duplicate-anchor repro is fixed in 76c9fd6e. ensureAnchorAt now counts physical block-anchor tokens across the Note; it keeps a unique anchor and replaces the selected token when its ID is duplicated. The new apps/web/src/lib/notes/anchors.test.ts regression passes, and bun run --cwd apps/web check reports svelte-check found 0 errors and 0 warnings. I am rerunning the production browser repro now.

The duplicate-anchor repro is fixed in `76c9fd6e`. `ensureAnchorAt` now counts physical block-anchor tokens across the Note; it keeps a unique anchor and replaces the selected token when its ID is duplicated. The new `apps/web/src/lib/notes/anchors.test.ts` regression passes, and `bun run --cwd apps/web check` reports `svelte-check found 0 errors and 0 warnings`. I am rerunning the production browser repro now.
Author
Owner

The production browser rerun no longer reports duplicate anchor reuse after 76c9fd6e. It still fails the browser area because the page emits eight Failed to load resource: 404 console errors. The harness currently omits those response URLs, so I am adding URL-level diagnostics and will isolate the 404 source before deciding whether it is in the application or the local test bridge.

The production browser rerun no longer reports duplicate anchor reuse after `76c9fd6e`. It still fails the browser area because the page emits eight `Failed to load resource: 404` console errors. The harness currently omits those response URLs, so I am adding URL-level diagnostics and will isolate the 404 source before deciding whether it is in the application or the local test bridge.
Author
Owner

The browser response trace identifies the 404s as the test's deliberately hostile paste payload (<img src="x">). The Note image resolver maps that relative path to Notes/x; the Files API returns 404 because that test attachment does not exist. This is expected for the fixture and no script ran. The duplicate block link checks passed after 76c9fd6e. I will exclude only this exact expected missing-image response from browser error reporting; other 4xx/5xx remain reportable.

The browser response trace identifies the 404s as the test's deliberately hostile paste payload (`<img src="x">`). The Note image resolver maps that relative path to `Notes/x`; the Files API returns 404 because that test attachment does not exist. This is expected for the fixture and no script ran. The duplicate block link checks passed after `76c9fd6e`. I will exclude only this exact expected missing-image response from browser error reporting; other 4xx/5xx remain reportable.
Author
Owner

The isolated production browser area now passes on seed=0x186c0de: Copy link creates a unique ID for a duplicate block, malformed/missing anchors are repaired, hostile HTML does not execute, and the 500-step undo/redo storm completes. The only suppressed response is the expected 404 for the deliberate <img src="x"> paste fixture; all other 4xx/5xx responses and runtime console/page errors remain failures. The harness change is committed as 7c9c388d.

The isolated production browser area now passes on `seed=0x186c0de`: Copy link creates a unique ID for a duplicate block, malformed/missing anchors are repaired, hostile HTML does not execute, and the 500-step undo/redo storm completes. The only suppressed response is the expected 404 for the deliberate `<img src="x">` paste fixture; all other 4xx/5xx responses and runtime console/page errors remain failures. The harness change is committed as `7c9c388d`.
Author
Owner

The isolated two-client repro confirms a collab failure independent of other areas: after disconnecting one client and editing locally, it reconnects with the same room epoch and completes the sync handshake. Its document still contains offline-edit, but the peer never receives it; the resumed WebSocket then closes with code 1006. The client sent three SyncStep2 responses during the session and one ordinary update before going offline. I am checking the server's warning output and protocol frame sequence before changing the room or client.

The isolated two-client repro confirms a collab failure independent of other areas: after disconnecting one client and editing locally, it reconnects with the same room epoch and completes the sync handshake. Its document still contains `offline-edit`, but the peer never receives it; the resumed WebSocket then closes with code 1006. The client sent three SyncStep2 responses during the session and one ordinary update before going offline. I am checking the server's warning output and protocol frame sequence before changing the room or client.
Author
Owner

The isolated offline-reconnect case exposed a probe framing defect, not a server failure. WebSocket trace showed the reconnecting Yjs client sent a 35-byte top-level message type 1 after receiving SyncStep1; the server expects Y-sync messages wrapped in top-level type 0. sync.readSyncMessage generated the inner SyncStep2, but the probe omitted the outer type byte. I added the missing wrapper and am rerunning the case. The earlier offline-reconciliation timeout should be treated as a false positive from the probe.

The isolated offline-reconnect case exposed a probe framing defect, not a server failure. WebSocket trace showed the reconnecting Yjs client sent a 35-byte top-level message type `1` after receiving SyncStep1; the server expects Y-sync messages wrapped in top-level type `0`. `sync.readSyncMessage` generated the inner SyncStep2, but the probe omitted the outer type byte. I added the missing wrapper and am rerunning the case. The earlier offline-reconciliation timeout should be treated as a false positive from the probe.
Author
Owner

The framing correction is in place. Trace now shows the offline reconnecting client sending a top-level type 0, SyncStep2 frame (36 bytes), followed by the server forwarding that SyncStep2 to the peer. The remaining isolated failure was the harness reading the saved Note immediately after closing both clients, before the room's debounced save completed. The online peer had already received the offline edit. I added bounded polling for the saved Note body, with 250 ms intervals to keep REST checks light under shared-host load.

The framing correction is in place. Trace now shows the offline reconnecting client sending a top-level type `0`, SyncStep2 frame (`36` bytes), followed by the server forwarding that SyncStep2 to the peer. The remaining isolated failure was the harness reading the saved Note immediately after closing both clients, before the room's debounced save completed. The online peer had already received the offline edit. I added bounded polling for the saved Note body, with 250 ms intervals to keep REST checks light under shared-host load.
Author
Owner

The separated concurrent-write area exposed a second probe readiness race. It asserted that both client documents contained the API-seeded paragraph immediately after each client's SyncStep2 callback; that callback only confirms one direction of the handshake. I changed the probe to wait up to 30 seconds for the seeded block to appear in both documents before mutating either one. This is probe synchronization coverage, not evidence of lost Note data.

The separated concurrent-write area exposed a second probe readiness race. It asserted that both client documents contained the API-seeded paragraph immediately after each client's SyncStep2 callback; that callback only confirms one direction of the handshake. I changed the probe to wait up to 30 seconds for the seeded block to appear in both documents before mutating either one. This is probe synchronization coverage, not evidence of lost Note data.
Author
Owner

The offline reconnect and concurrent-write probe areas now pass after correcting the harness. The Y-sync response wrapper and readiness/save waits are committed at 132fb3ace42c2b2469addb8489be66fc0176c4d6.

Exact area output:

PASS editor concurrent same-block writes seed=25608414 ms=1300
PASS editor all areas seed=25608414
PASS editor same-epoch offline edit reconciliation seed=25608414 ms=1539
PASS editor all areas seed=25608414
The offline reconnect and concurrent-write probe areas now pass after correcting the harness. The Y-sync response wrapper and readiness/save waits are committed at `132fb3ace42c2b2469addb8489be66fc0176c4d6`. Exact area output: ``` PASS editor concurrent same-block writes seed=25608414 ms=1300 PASS editor all areas seed=25608414 PASS editor same-epoch offline edit reconciliation seed=25608414 ms=1539 PASS editor all areas seed=25608414 ```
Author
Owner

The fresh full editor sweep reported two areas that need isolated reruns. In delete/edit, the probe reads the Note body immediately after closing the clients; the offline case showed that this can race the room's debounced save. I will add the same bounded saved-body poll before treating the edit as lost. In the live-editor restart area, the client gives the runner 30 seconds to restart, while the runner's ready loop allows up to 60 seconds; I will align those bounds and rerun the restart case.

Other areas in this sweep passed: depth-50 mixed Markdown, 10,000 blocks, 1 MiB paragraph, browser paste/history, same-block concurrent edits, offline reconciliation, and external Note writes.

The fresh full editor sweep reported two areas that need isolated reruns. In delete/edit, the probe reads the Note body immediately after closing the clients; the offline case showed that this can race the room's debounced save. I will add the same bounded saved-body poll before treating the edit as lost. In the live-editor restart area, the client gives the runner 30 seconds to restart, while the runner's ready loop allows up to 60 seconds; I will align those bounds and rerun the restart case. Other areas in this sweep passed: depth-50 mixed Markdown, 10,000 blocks, 1 MiB paragraph, browser paste/history, same-block concurrent edits, offline reconciliation, and external Note writes.
Author
Owner

Seed 0x186c0de, isolated with EDITOR_AREA=delete-edit against the production web build and a real local server: both Y-sync clients complete their handshakes, then one deletes first-target while the other edits the same block. After closing both sockets, the saved-body poll does not find concurrent-edit-survivor within 30 seconds. This is a possible data-loss finding. I am adding state diagnostics and will determine whether the update reaches the peer and room snapshot before changing product code.

Seed `0x186c0de`, isolated with `EDITOR_AREA=delete-edit` against the production web build and a real local server: both Y-sync clients complete their handshakes, then one deletes `first-target` while the other edits the same block. After closing both sockets, the saved-body poll does not find `concurrent-edit-survivor` within 30 seconds. This is a possible data-loss finding. I am adding state diagnostics and will determine whether the update reaches the peer and room snapshot before changing product code.
Author
Owner

Confirmed with a second isolated run after adding the same seeded-document readiness wait used by the concurrent-write area. The probe waits until both clients have first-target, performs the delete/edit race, then waits until both have received a Y-sync update from the other client. Both clients sent one update; both converged to second-target, and the saved Markdown after 30 seconds was # 186 delete edit race plus second-target. The edited block and concurrent-edit-survivor are absent. This is data loss after both updates reached both peers, not the room's debounced-save delay. I am tracing Yrs update ancestry to preserve the conflicting edit while keeping ordinary deletions clean.

Confirmed with a second isolated run after adding the same seeded-document readiness wait used by the concurrent-write area. The probe waits until both clients have `first-target`, performs the delete/edit race, then waits until both have received a Y-sync update from the other client. Both clients sent one update; both converged to `second-target`, and the saved Markdown after 30 seconds was `# 186 delete edit race` plus `second-target`. The edited block and `concurrent-edit-survivor` are absent. This is data loss after both updates reached both peers, not the room's debounced-save delay. I am tracing Yrs update ancestry to preserve the conflicting edit while keeping ordinary deletions clean.
Author
Owner

Confirmed and fixed the delete/edit data-loss finding. On seed 25608414, both local Yjs clients received each other's updates, and the Note saved the concurrent edit after the server restored it through the existing block merge. The room keeps a pre-delete Yrs mirror only after a root block deletion; the block ID index avoids scanning every block for ordinary text deletes. The focused real-server adversarial run passed.

Confirmed and fixed the delete/edit data-loss finding. On seed 25608414, both local Yjs clients received each other's updates, and the Note saved the concurrent edit after the server restored it through the existing block merge. The room keeps a pre-delete Yrs mirror only after a root block deletion; the block ID index avoids scanning every block for ordinary text deletes. The focused real-server adversarial run passed.
Author
Owner

The full editor sweep found a second data-integrity issue: opening the mixed Markdown Note triggered a save and changed untouched bytes (seed 25608414). The server treated every incoming sync update as a dirty edit, including an empty SyncStep2. The room now compares its serialized Yrs state before and after each accepted update and schedules a save only if the state changes. empty_sync_update_does_not_mark_the_room_document_changed passes; the focused real-server mixed-Markdown probe also passes and preserves the exact body bytes.

The same full sweep timed out waiting for the live-editor restart handshake. A focused restart rerun then passed in 10,048 ms on seed 25608414. This timeout is load-only; it did not reproduce when run alone.

The full editor sweep found a second data-integrity issue: opening the mixed Markdown Note triggered a save and changed untouched bytes (seed 25608414). The server treated every incoming sync update as a dirty edit, including an empty SyncStep2. The room now compares its serialized Yrs state before and after each accepted update and schedules a save only if the state changes. `empty_sync_update_does_not_mark_the_room_document_changed` passes; the focused real-server mixed-Markdown probe also passes and preserves the exact body bytes. The same full sweep timed out waiting for the live-editor restart handshake. A focused restart rerun then passed in 10,048 ms on seed 25608414. This timeout is load-only; it did not reproduce when run alone.
Author
Owner

The full production sweep exposed false findings in the adversarial bridge. editor-proxy.mjs served the web build for every non-API path, so DAV/SPA probes bypassed the server router and response-security middleware; its WebSocket side also returned 101 before the upstream server authorized the request. I changed the bridge to proxy all HTTP routes to the server (which embeds the production web build) and changed the round-2 WebSocket probe to connect directly to the backend port, preserving the public Origin. The runner now starts the backend before checking the proxied root. I am validating these corrections with isolated production probes; no product finding is inferred from the bypassed checks.

The full production sweep exposed false findings in the adversarial bridge. `editor-proxy.mjs` served the web build for every non-API path, so DAV/SPA probes bypassed the server router and response-security middleware; its WebSocket side also returned 101 before the upstream server authorized the request. I changed the bridge to proxy all HTTP routes to the server (which embeds the production web build) and changed the round-2 WebSocket probe to connect directly to the backend port, preserving the public Origin. The runner now starts the backend before checking the proxied root. I am validating these corrections with isolated production probes; no product finding is inferred from the bypassed checks.
Author
Owner

The harness correction is committed at 247ddfebe4c01ff957d3f2cc9d8b71a219e73864. The first filtered attack2 attempt omitted the normal photo fixture and reported an empty shared Photos timeline; that report was a test setup false positive. I updated the helper to run round-one fixture setup before isolation/collab checks and reran it against the production server. The corrected run reports HOSTILE BYTES FINDINGS 0 and ROUND 2 FINDINGS 0; it exercised Photos sharing, unauthorized WebSocket routes, malformed/oversized frames, external edits, block order, and 300-socket limits. The server stayed alive and accepted 59 sockets before the configured cap. Round-one setup printed 46 SLOW timing entries only; per owner rule these are load, not correctness findings.

The harness correction is committed at `247ddfebe4c01ff957d3f2cc9d8b71a219e73864`. The first filtered attack2 attempt omitted the normal photo fixture and reported an empty shared Photos timeline; that report was a test setup false positive. I updated the helper to run round-one fixture setup before isolation/collab checks and reran it against the production server. The corrected run reports `HOSTILE BYTES FINDINGS 0` and `ROUND 2 FINDINGS 0`; it exercised Photos sharing, unauthorized WebSocket routes, malformed/oversized frames, external edits, block order, and 300-socket limits. The server stayed alive and accepted 59 sockets before the configured cap. Round-one setup printed 46 `SLOW` timing entries only; per owner rule these are load, not correctness findings.
Author
Owner

The first full cargo test run failed only in calternal-collab/tests/shared_notes.rs: the Bun probe waited exactly 3 seconds for the atomic-save hook, while the room's MAX_FLUSH_WAIT is also 3 seconds. Every earlier workspace test passed. cargo test -p calternal-collab --test shared_notes passed alone in 5.48 s. I changed the test-only readiness timeout to 10 seconds to allow scheduler and file-write time; the focused rerun passes in 15.72 s.

One browser run also emitted a saved-Markdown duplicate-anchor assertion with 159 ^duplicate-id tokens after the history storm. I could not reproduce it in two instrumented production-browser reruns: both kept four distinct anchor decorations across all interaction stages, 10 paragraphs and 4 list items, and saved Markdown passed the uniqueness assertion (12 ms anchor-save poll on the latest run). The probe now records per-stage anchor state and includes saved Markdown on any recurrence. This intermittent data-integrity report remains tracked here for the owner; no product fix was made without a reproducible case.

The first full `cargo test` run failed only in `calternal-collab/tests/shared_notes.rs`: the Bun probe waited exactly 3 seconds for the atomic-save hook, while the room's `MAX_FLUSH_WAIT` is also 3 seconds. Every earlier workspace test passed. `cargo test -p calternal-collab --test shared_notes` passed alone in 5.48 s. I changed the test-only readiness timeout to 10 seconds to allow scheduler and file-write time; the focused rerun passes in 15.72 s. One browser run also emitted a saved-Markdown duplicate-anchor assertion with 159 `^duplicate-id` tokens after the history storm. I could not reproduce it in two instrumented production-browser reruns: both kept four distinct anchor decorations across all interaction stages, 10 paragraphs and 4 list items, and saved Markdown passed the uniqueness assertion (12 ms anchor-save poll on the latest run). The probe now records per-stage anchor state and includes saved Markdown on any recurrence. This intermittent data-integrity report remains tracked here for the owner; no product fix was made without a reproducible case.
Author
Owner

Resuming Forgejo #186 after the VM restart. Branch: job/break-editor; current merge-base with dev: f6418fc72d750d941f23554ad16381f6dd400fd6. Worktree is clean at checkpoint b8b8ae83c5d5983ee8ac192cf3f1f47384b47aab. I reviewed the prior report comments and am continuing the seeded production-server sweep from the remaining areas.

Resuming Forgejo #186 after the VM restart. Branch: `job/break-editor`; current merge-base with `dev`: `f6418fc72d750d941f23554ad16381f6dd400fd6`. Worktree is clean at checkpoint `b8b8ae83c5d5983ee8ac192cf3f1f47384b47aab`. I reviewed the prior report comments and am continuing the seeded production-server sweep from the remaining areas.
Author
Owner

After merging current dev at bcaa673d, the isolated production browser area passed with seed 25608414. The unresolved duplicate-anchor report did not recur: all four anchors stayed distinct after the 500-step undo/redo storm, and the saved Note passed the uniqueness check. I added checks that copied block and heading URLs use the permanent Note ID and that opening each URL reveals its target.

Exact output:

PASS editor browser editor paste, Unicode, and history storm seed=25608414 ms=32077
PASS editor all areas seed=25608414
After merging current `dev` at `bcaa673d`, the isolated production browser area passed with seed `25608414`. The unresolved duplicate-anchor report did not recur: all four anchors stayed distinct after the 500-step undo/redo storm, and the saved Note passed the uniqueness check. I added checks that copied block and heading URLs use the permanent Note ID and that opening each URL reveals its target. Exact output: ``` PASS editor browser editor paste, Unicode, and history storm seed=25608414 ms=32077 PASS editor all areas seed=25608414 ```
Author
Owner

The full run and a second fixture-complete ROUND2_SECTIONS=isolation run both got HTTP 200 with {"days":[]} for the recipient's opted-in Photos share during the 12-second visibility window. That second run also had an early proxy 502 and several explicitly SLOW results while other jobs were active on the host. I extended this asynchronous visibility window to 60 seconds in f17aa300 so the next isolated pass can distinguish indexing delay from a persistent missing item. I have not treated this as a confirmed Photos defect yet.

The full run and a second fixture-complete `ROUND2_SECTIONS=isolation` run both got HTTP 200 with `{"days":[]}` for the recipient's opted-in Photos share during the 12-second visibility window. That second run also had an early proxy 502 and several explicitly `SLOW` results while other jobs were active on the host. I extended this asynchronous visibility window to 60 seconds in `f17aa300` so the next isolated pass can distinguish indexing delay from a persistent missing item. I have not treated this as a confirmed Photos defect yet.
Author
Owner

The full production sweep also reported a restart handoff timeout: restart-ready-3 was not followed by restart-go-3 within the browser probe's 90-second bound. The later direct epoch probe then reported its initial sync not reached within 20 seconds and several dependent checks failed. Other API probes in that run recorded 7.1-second calendar writes as SLOW, with several unrelated jobs active on the shared host. I am rerunning the browser restart area by itself before treating this as a product failure.

The full production sweep also reported a restart handoff timeout: `restart-ready-3` was not followed by `restart-go-3` within the browser probe's 90-second bound. The later direct epoch probe then reported its initial sync not reached within 20 seconds and several dependent checks failed. Other API probes in that run recorded 7.1-second calendar writes as `SLOW`, with several unrelated jobs active on the shared host. I am rerunning the browser restart area by itself before treating this as a product failure.
Author
Owner

The isolated production browser rerun passed the live-editor restart area on seed 25608414 in 11,615 ms. It confirmed the runner restarted the server and the edited Note was saved exactly once. The earlier browser restart handoff timeout did not reproduce when this area ran alone.

Exact output:

PASS editor server restart with a live editor seed=25608414 ms=11615
PASS editor all areas seed=25608414
The isolated production browser rerun passed the live-editor restart area on seed `25608414` in 11,615 ms. It confirmed the runner restarted the server and the edited Note was saved exactly once. The earlier browser restart handoff timeout did not reproduce when this area ran alone. Exact output: ``` PASS editor server restart with a live editor seed=25608414 ms=11615 PASS editor all areas seed=25608414 ```
Author
Owner

Focused adversarial rerun after the restart-probe fix:

  • ROOM_RESTART_ONLY=1 ADVERSARIAL_SKIP_AUTHZ=1 ... ./tests/adversarial/run.sh passed: restart probe: 0 findings.
  • ADVERSARIAL_ATTACK2_ONLY=1 ROUND2_SECTIONS=isolation,public ... ./tests/adversarial/run.sh completed with the Photos share check producing no finding. ZIP mid-stream reached the 30-second probe limit and was classified SLOW; the server remained alive.
  • The broad API phase in that run recorded 17 saved-search create timeouts and only 23 of 40 expected distinct searches. The server was alive at the end. This is outside the editor's owned behavior and occurred while several other adversarial jobs were active, so I have not attributed it to the editor or treated it as a confirmed product defect.

The direct backend socket change avoids the test proxy's client-side 101 before upstream authorization. Probe isolation commit: 00a022e5.

Focused adversarial rerun after the restart-probe fix: - `ROOM_RESTART_ONLY=1 ADVERSARIAL_SKIP_AUTHZ=1 ... ./tests/adversarial/run.sh` passed: `restart probe: 0 findings`. - `ADVERSARIAL_ATTACK2_ONLY=1 ROUND2_SECTIONS=isolation,public ... ./tests/adversarial/run.sh` completed with the Photos share check producing no finding. ZIP mid-stream reached the 30-second probe limit and was classified `SLOW`; the server remained alive. - The broad API phase in that run recorded 17 saved-search create timeouts and only 23 of 40 expected distinct searches. The server was alive at the end. This is outside the editor's owned behavior and occurred while several other adversarial jobs were active, so I have not attributed it to the editor or treated it as a confirmed product defect. The direct backend socket change avoids the test proxy's client-side 101 before upstream authorization. Probe isolation commit: `00a022e5`.
Author
Owner

Forgejo #186 final report

Head: 578af5fd45c15bca4cf00a9d158ea0e72a607365 (job/break-editor). The worktree was clean after the required merge of the latest dev.

Built

  • Kept collaborative Markdown state consistent through concurrent block deletion/editing and avoided writes for empty sync updates.
  • Regenerated duplicate block anchors and added regression coverage for stable block and heading copy links.
  • Added seeded browser and live-server probes for deep nesting, 10,000 blocks, 1 MiB paragraphs, hostile paste, Unicode, undo/redo storms, concurrent edits, offline/restart flows, external writes, and copied deep links.
  • Isolated the room epoch restart probe from API load and connected its WebSocket clients directly to the backend so the test proxy cannot hide an upstream authorization rejection.
  • Extended the archive timeout handling and Photos share visibility window for shared-host runs.

Files

  • Collaboration: crates/calternal-collab/src/lib.rs, crates/calternal-collab/src/session.rs, crates/calternal-collab/tests/shared_notes.mjs.
  • Note anchors and web tests: apps/web/src/lib/notes/anchors.ts, apps/web/src/lib/notes/anchors.test.ts, apps/web/src/lib/notes/editor-types/anchor.d.ts, apps/web/src/lib/notes/NotesExplorer.svelte, apps/web/src/lib/themes.test.ts.
  • Adversarial harness: tests/adversarial/attack2.py, tests/adversarial/authz_matrix.py, tests/adversarial/bun.lock, tests/adversarial/editor-proxy.mjs, tests/adversarial/editor.mjs, tests/adversarial/package.json, tests/adversarial/restart.mjs, tests/adversarial/run.sh.
  • Other branch files: .forgejo/workflows/ci.yml, apps/web/e2e/a11y.mjs, apps/web/e2e/layout-sweep.mjs, apps/web/e2e/search.mjs, apps/web/package.json, apps/web/src/calternal-app.css, apps/web/src/lib/components/analytics/CalendarHeatmap.svelte, apps/web/src/lib/components/analytics/TimeOfDayHeatmap.svelte, apps/web/src/lib/components/search-dialog.svelte, apps/web/src/lib/files/FilesBrowser.svelte, apps/web/src/lib/files/transfer.ts, apps/web/src/lib/notes/NotesExplorer.svelte, bun.lock, packages/ui/src/components/TabBar.svelte, packages/ui/src/components/TagPill.svelte, packages/ui/src/components/calendar/MiniMonth.svelte, packages/ui/src/components/calendar/MonthGrid.svelte, packages/ui/src/components/calendar/YearHeatmap.svelte.

Adversarial findings and gaps

  • The isolated browser and room restart probes passed. In the focused API rerun, Photos share visibility produced no finding; the ZIP stream exceeded its 30-second cap and was classified SLOW, with the server still alive.
  • The broad API phase recorded 17 saved-search request timeouts and only 23 of 40 expected distinct searches; the server was alive at the end. Several other adversarial jobs were active on the shared host. I recorded this non-SLOW cross-API observation in the issue; saved-search behavior is outside this editor change.
  • The live Note UI still has no Make a note action, block reminder action, or multi-select. The browser run did not claim coverage of those absent controls.

Decisions where the design is silent

  • The restart probe uses direct backend WebSockets and retains the proxy URL as the HTTP Origin. The proxy can send a client-side 101 before upstream authorization, which made the earlier proxied check report a false connection.
  • I set the Photos share visibility wait to 60 seconds for asynchronous indexing on this shared host. ZIP stream completion after 30 seconds is reported as SLOW.

Gates

cargo fmt --check exited 0 with empty output.

cargo clippy --all-targets -- -D warnings output:

    Checking calternal-notes-core v0.1.0 (/home/kayg/Developer/calternal-wt/break-editor/crates/calternal-notes-core)
    Checking calternal-fs v0.1.0 (/home/kayg/Developer/calternal-wt/break-editor/crates/calternal-fs)
   Compiling calternal-server v0.0.1 (/home/kayg/Developer/calternal-wt/break-editor/crates/calternal-server)
    Checking calternal-plugin v0.0.1 (/home/kayg/Developer/calternal-wt/break-editor/crates/calternal-plugin)
    Checking calternal-dav v0.0.1 (/home/kayg/Developer/calternal-wt/break-editor/crates/calternal-dav)
    Checking calternal-embed v0.0.1 (/home/kayg/Developer/calternal-wt/break-editor/crates/calternal-embed)
    Checking calternal-sync v0.0.1 (/home/kayg/Developer/calternal-wt/break-editor/crates/calternal-sync)
    Checking calternal-tags v0.0.1 (/home/kayg/Developer/calternal-wt/break-editor/crates/calternal-tags)
    Checking calternal-plugin-notes v0.0.1 (/home/kayg/Developer/calternal-wt/break-editor/crates/plugins/notes)
    Checking calternal-search v0.0.1 (/home/kayg/Developer/calternal-wt/break-editor/crates/calternal-search)
    Checking calternal-cli v0.0.1 (/home/kayg/Developer/calternal-wt/break-editor/crates/calternal-cli)
    Checking calternal-plugin-files v0.0.1 (/home/kayg/Developer/calternal-wt/break-editor/crates/plugins/files)
    Checking calternal-collab v0.0.1 (/home/kayg/Developer/calternal-wt/break-editor/crates/calternal-collab)
    Checking calternal-plugin-calendar v0.0.1 (/home/kayg/Developer/calternal-wt/break-editor/crates/plugins/calendar)
    Checking calternal-plugin-photos v0.0.1 (/home/kayg/Developer/calternal-wt/break-editor/crates/plugins/photos)
    Checking calternal-plugin-video v0.0.1 (/home/kayg/Developer/calternal-wt/break-editor/crates/plugins/video)
    Checking calternal-plugin-ai v0.0.1 (/home/kayg/Developer/calternal-wt/break-editor/crates/plugins/ai)
    Checking calternal-plugin-notifications v0.0.1 (/home/kayg/Developer/calternal-wt/break-editor/crates/plugins/notifications)
    Checking calternal-plugin-analytics v0.0.1 (/home/kayg/Developer/calternal-wt/break-editor/crates/plugins/analytics)
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 35.51s

cargo test exited 0. Per-harness result lines copied verbatim:

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s
test result: ok. 49 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 30.28s
test result: ok. 10 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.04s
test result: ok. 11 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.43s
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.74s
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 3.14s
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 56.18s
test result: ok. 11 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 7.20s
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 2.92s
test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.37s
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 11.84s
test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 2.50s
test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 39.78s
test result: ok. 15 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.11s
test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 21.60s
test result: ok. 10 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.50s
test result: ok. 9 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out; finished in 1.61s
test result: ok. 17 passed; 0 failed; 4 ignored; 0 measured; 0 filtered out; finished in 0.40s
test result: ok. 33 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 22.10s
test result: ok. 35 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 7.34s
test result: ok. 477 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.36s
test result: ok. 13 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 2.67s
test result: ok. 7 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.59s
test result: ok. 11 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s
test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
test result: ok. 19 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 6.02s
test result: ok. 10 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.28s
test result: ok. 29 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 3.53s
test result: ok. 42 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 2.35s
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.48s
test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.43s
test result: ok. 101 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 36.87s
test result: ok. 90 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 106.15s
test result: ok. 12 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.19s
test result: ok. 38 passed; 0 failed; 2 ignored; 0 measured; 0 filtered out; finished in 5.04s
test result: ok. 10 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.18s
test result: ok. 24 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out; finished in 1.68s
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.33s
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.14s
test result: ok. 14 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 6.15s
test result: ok. 4 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.04s
test result: ok. 1 passed; 0 failed; 2 ignored; 0 measured; 0 filtered out; finished in 6.49s
test result: ok. 4 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
test result: ok. 41 passed; 0 failed; 2 ignored; 0 measured; 0 filtered out; finished in 4.83s
test result: ok. 45 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.16s
test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
test result: ok. 10 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 9.89s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

bun run check output:

$ svelte-kit sync && svelte-check --tsconfig ./tsconfig.json
Loading svelte-check in workspace: /home/kayg/Developer/calternal-wt/break-editor/apps/web
Getting Svelte diagnostics...

svelte-check found 0 errors and 0 warnings

bun run test output:

$ vitest run

 RUN  v5.0.1 /home/kayg/Developer/calternal-wt/break-editor/apps/web

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

 Test Files  72 passed (72)
      Tests  547 passed (547)
   Start at  11:17:26
   Duration  32.96s (transform 65%, environment 14%, import 13%, tests 6%, setup 2%)

  Transform  |component| transforming modules took 49.96s · 58% of tracked time, re-done on every run
             persist transforms across runs with fsModuleCache: true
             learn more: https://vitest.dev/guide/improving-performance#caching-between-reruns

# Forgejo #186 final report Head: `578af5fd45c15bca4cf00a9d158ea0e72a607365` (`job/break-editor`). The worktree was clean after the required merge of the latest `dev`. ## Built - Kept collaborative Markdown state consistent through concurrent block deletion/editing and avoided writes for empty sync updates. - Regenerated duplicate block anchors and added regression coverage for stable block and heading copy links. - Added seeded browser and live-server probes for deep nesting, 10,000 blocks, 1 MiB paragraphs, hostile paste, Unicode, undo/redo storms, concurrent edits, offline/restart flows, external writes, and copied deep links. - Isolated the room epoch restart probe from API load and connected its WebSocket clients directly to the backend so the test proxy cannot hide an upstream authorization rejection. - Extended the archive timeout handling and Photos share visibility window for shared-host runs. ## Files - Collaboration: `crates/calternal-collab/src/lib.rs`, `crates/calternal-collab/src/session.rs`, `crates/calternal-collab/tests/shared_notes.mjs`. - Note anchors and web tests: `apps/web/src/lib/notes/anchors.ts`, `apps/web/src/lib/notes/anchors.test.ts`, `apps/web/src/lib/notes/editor-types/anchor.d.ts`, `apps/web/src/lib/notes/NotesExplorer.svelte`, `apps/web/src/lib/themes.test.ts`. - Adversarial harness: `tests/adversarial/attack2.py`, `tests/adversarial/authz_matrix.py`, `tests/adversarial/bun.lock`, `tests/adversarial/editor-proxy.mjs`, `tests/adversarial/editor.mjs`, `tests/adversarial/package.json`, `tests/adversarial/restart.mjs`, `tests/adversarial/run.sh`. - Other branch files: `.forgejo/workflows/ci.yml`, `apps/web/e2e/a11y.mjs`, `apps/web/e2e/layout-sweep.mjs`, `apps/web/e2e/search.mjs`, `apps/web/package.json`, `apps/web/src/calternal-app.css`, `apps/web/src/lib/components/analytics/CalendarHeatmap.svelte`, `apps/web/src/lib/components/analytics/TimeOfDayHeatmap.svelte`, `apps/web/src/lib/components/search-dialog.svelte`, `apps/web/src/lib/files/FilesBrowser.svelte`, `apps/web/src/lib/files/transfer.ts`, `apps/web/src/lib/notes/NotesExplorer.svelte`, `bun.lock`, `packages/ui/src/components/TabBar.svelte`, `packages/ui/src/components/TagPill.svelte`, `packages/ui/src/components/calendar/MiniMonth.svelte`, `packages/ui/src/components/calendar/MonthGrid.svelte`, `packages/ui/src/components/calendar/YearHeatmap.svelte`. ## Adversarial findings and gaps - The isolated browser and room restart probes passed. In the focused API rerun, Photos share visibility produced no finding; the ZIP stream exceeded its 30-second cap and was classified `SLOW`, with the server still alive. - The broad API phase recorded 17 saved-search request timeouts and only 23 of 40 expected distinct searches; the server was alive at the end. Several other adversarial jobs were active on the shared host. I recorded this non-`SLOW` cross-API observation in the issue; saved-search behavior is outside this editor change. - The live Note UI still has no Make a note action, block reminder action, or multi-select. The browser run did not claim coverage of those absent controls. ## Decisions where the design is silent - The restart probe uses direct backend WebSockets and retains the proxy URL as the HTTP Origin. The proxy can send a client-side 101 before upstream authorization, which made the earlier proxied check report a false connection. - I set the Photos share visibility wait to 60 seconds for asynchronous indexing on this shared host. ZIP stream completion after 30 seconds is reported as `SLOW`. ## Gates `cargo fmt --check` exited 0 with empty output. `cargo clippy --all-targets -- -D warnings` output: ```text Checking calternal-notes-core v0.1.0 (/home/kayg/Developer/calternal-wt/break-editor/crates/calternal-notes-core) Checking calternal-fs v0.1.0 (/home/kayg/Developer/calternal-wt/break-editor/crates/calternal-fs) Compiling calternal-server v0.0.1 (/home/kayg/Developer/calternal-wt/break-editor/crates/calternal-server) Checking calternal-plugin v0.0.1 (/home/kayg/Developer/calternal-wt/break-editor/crates/calternal-plugin) Checking calternal-dav v0.0.1 (/home/kayg/Developer/calternal-wt/break-editor/crates/calternal-dav) Checking calternal-embed v0.0.1 (/home/kayg/Developer/calternal-wt/break-editor/crates/calternal-embed) Checking calternal-sync v0.0.1 (/home/kayg/Developer/calternal-wt/break-editor/crates/calternal-sync) Checking calternal-tags v0.0.1 (/home/kayg/Developer/calternal-wt/break-editor/crates/calternal-tags) Checking calternal-plugin-notes v0.0.1 (/home/kayg/Developer/calternal-wt/break-editor/crates/plugins/notes) Checking calternal-search v0.0.1 (/home/kayg/Developer/calternal-wt/break-editor/crates/calternal-search) Checking calternal-cli v0.0.1 (/home/kayg/Developer/calternal-wt/break-editor/crates/calternal-cli) Checking calternal-plugin-files v0.0.1 (/home/kayg/Developer/calternal-wt/break-editor/crates/plugins/files) Checking calternal-collab v0.0.1 (/home/kayg/Developer/calternal-wt/break-editor/crates/calternal-collab) Checking calternal-plugin-calendar v0.0.1 (/home/kayg/Developer/calternal-wt/break-editor/crates/plugins/calendar) Checking calternal-plugin-photos v0.0.1 (/home/kayg/Developer/calternal-wt/break-editor/crates/plugins/photos) Checking calternal-plugin-video v0.0.1 (/home/kayg/Developer/calternal-wt/break-editor/crates/plugins/video) Checking calternal-plugin-ai v0.0.1 (/home/kayg/Developer/calternal-wt/break-editor/crates/plugins/ai) Checking calternal-plugin-notifications v0.0.1 (/home/kayg/Developer/calternal-wt/break-editor/crates/plugins/notifications) Checking calternal-plugin-analytics v0.0.1 (/home/kayg/Developer/calternal-wt/break-editor/crates/plugins/analytics) Finished `dev` profile [unoptimized + debuginfo] target(s) in 35.51s ``` `cargo test` exited 0. Per-harness result lines copied verbatim: ```text test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s test result: ok. 49 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 30.28s test result: ok. 10 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.04s test result: ok. 11 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.43s test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.74s test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 3.14s test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 56.18s test result: ok. 11 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 7.20s test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 2.92s test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.37s test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 11.84s test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 2.50s test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 39.78s test result: ok. 15 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.11s test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 21.60s test result: ok. 10 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.50s test result: ok. 9 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out; finished in 1.61s test result: ok. 17 passed; 0 failed; 4 ignored; 0 measured; 0 filtered out; finished in 0.40s test result: ok. 33 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 22.10s test result: ok. 35 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 7.34s test result: ok. 477 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.36s test result: ok. 13 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 2.67s test result: ok. 7 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.59s test result: ok. 11 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s test result: ok. 19 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 6.02s test result: ok. 10 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.28s test result: ok. 29 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 3.53s test result: ok. 42 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 2.35s test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.48s test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.43s test result: ok. 101 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 36.87s test result: ok. 90 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 106.15s test result: ok. 12 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.19s test result: ok. 38 passed; 0 failed; 2 ignored; 0 measured; 0 filtered out; finished in 5.04s test result: ok. 10 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.18s test result: ok. 24 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out; finished in 1.68s test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.33s test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.14s test result: ok. 14 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 6.15s test result: ok. 4 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.04s test result: ok. 1 passed; 0 failed; 2 ignored; 0 measured; 0 filtered out; finished in 6.49s test result: ok. 4 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s test result: ok. 41 passed; 0 failed; 2 ignored; 0 measured; 0 filtered out; finished in 4.83s test result: ok. 45 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.16s test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s test result: ok. 10 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 9.89s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s ``` `bun run check` output: ```text $ svelte-kit sync && svelte-check --tsconfig ./tsconfig.json Loading svelte-check in workspace: /home/kayg/Developer/calternal-wt/break-editor/apps/web Getting Svelte diagnostics... svelte-check found 0 errors and 0 warnings ``` `bun run test` output: ```text $ vitest run RUN v5.0.1 /home/kayg/Developer/calternal-wt/break-editor/apps/web Could not parse CSS stylesheet Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Test Files 72 passed (72) Tests 547 passed (547) Start at 11:17:26 Duration 32.96s (transform 65%, environment 14%, import 13%, tests 6%, setup 2%) Transform |component| transforming modules took 49.96s · 58% of tracked time, re-done on every run persist transforms across runs with fsModuleCache: true learn more: https://vitest.dev/guide/improving-performance#caching-between-reruns ```
Author
Owner

Forgejo #186 final report

Head: 67de33ac0eecf4c70e56abbaa942ea685329ba2b (job/break-editor). I merged dev through 65265f87 before the final gates. dev advanced to fbecfbc6 while those gates ran; this tested head is the fixed snapshot from the start of the final gate run.

Built

  • Preserved edits that race with collaborative block deletion and skipped saves for empty sync updates.
  • Regenerated duplicate block anchors and added copy-link deep-link coverage for blocks and headings.
  • Added seeded editor browser and direct-server probes for deep nesting, 10,000 blocks, 1 MiB paragraphs, hostile paste, Unicode, undo/redo storms, concurrent edits, offline/restart flows, external writes, and copied links.
  • Made the room restart probe connect directly to the backend so a proxy-side 101 cannot hide an upstream authorization rejection.
  • Extended the archive timeout handling and Photos share visibility window for shared-host adversarial runs.

Files

  • apps/web/src/lib/notes/anchors.test.ts
  • apps/web/src/lib/notes/anchors.ts
  • apps/web/src/lib/notes/editor-types/anchor.d.ts
  • crates/calternal-collab/src/lib.rs
  • crates/calternal-collab/src/session.rs
  • crates/calternal-collab/tests/shared_notes.mjs
  • tests/adversarial/attack2.py
  • tests/adversarial/authz_matrix.py
  • tests/adversarial/bun.lock
  • tests/adversarial/editor-proxy.mjs
  • tests/adversarial/editor.mjs
  • tests/adversarial/package.json
  • tests/adversarial/restart.mjs
  • tests/adversarial/run.sh

Adversarial findings and gaps

  • The isolated browser and room restart probes passed. The focused Photos share check produced no finding. The ZIP stream exceeded its 30-second cap and was classified SLOW; the server remained alive.
  • The broad API phase recorded 17 saved-search request timeouts and only 23 of 40 expected distinct searches; the server remained alive. Several other adversarial jobs were active on the shared host. I recorded this non-SLOW, cross-API observation on this issue. Saved-search behavior is outside this editor change.
  • The live Note UI still has no Make a note action, block reminder action, or multi-select. The browser run did not claim coverage of those absent controls.

Decisions where the design is silent

  • The restart probe uses direct backend WebSockets and retains the proxy URL as the HTTP Origin. The proxy can send a client-side 101 before upstream authorization.
  • I set the Photos share visibility wait to 60 seconds for asynchronous indexing on this shared host. ZIP stream completion after 30 seconds is reported as SLOW.
  • bun run build was required before the Rust gates because calternal-server embeds apps/web/build. The production build exited 0 and emitted existing bundler notices for vendor use client directives.

Gates

cargo fmt --check exited 0 with empty output.

cargo clippy --all-targets -- -D warnings output:

   Compiling calternal-server v0.0.1 (/home/kayg/Developer/calternal-wt/break-editor/crates/calternal-server)
    Checking calternal-collab v0.0.1 (/home/kayg/Developer/calternal-wt/break-editor/crates/calternal-collab)
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 21.21s

cargo test exited 0. Per-harness result lines copied verbatim:

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
test result: ok. 49 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 43.46s
test result: ok. 10 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.04s
test result: ok. 11 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.87s
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.68s
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 6.17s
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 97.97s
test result: ok. 11 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 4.91s
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.09s
test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.20s
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 11.36s
test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.98s
test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 27.54s
test result: ok. 15 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.13s
test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 46.04s
test result: ok. 10 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.02s
test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.33s
test result: ok. 9 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out; finished in 1.09s
test result: ok. 17 passed; 0 failed; 4 ignored; 0 measured; 0 filtered out; finished in 0.48s
test result: ok. 33 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 12.56s
test result: ok. 35 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 3.20s
test result: ok. 477 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.56s
test result: ok. 13 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 3.94s
test result: ok. 7 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.94s
test result: ok. 11 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.06s
test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
test result: ok. 19 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 7.48s
test result: ok. 10 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.51s
test result: ok. 29 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 6.03s
test result: ok. 42 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 4.34s
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.04s
test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.50s
test result: ok. 101 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 63.66s
test result: ok. 90 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 152.30s
test result: ok. 12 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.27s
test result: ok. 38 passed; 0 failed; 2 ignored; 0 measured; 0 filtered out; finished in 4.67s
test result: ok. 10 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.12s
test result: ok. 24 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out; finished in 2.00s
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 2.48s
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.16s
test result: ok. 14 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 9.61s
test result: ok. 4 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.09s
test result: ok. 1 passed; 0 failed; 2 ignored; 0 measured; 0 filtered out; finished in 7.76s
test result: ok. 4 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s
test result: ok. 41 passed; 0 failed; 2 ignored; 0 measured; 0 filtered out; finished in 9.28s
test result: ok. 45 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.22s
test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
test result: ok. 10 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 5.66s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

bun run check output:

$ svelte-kit sync && svelte-check --tsconfig ./tsconfig.json
Loading svelte-check in workspace: /home/kayg/Developer/calternal-wt/break-editor/apps/web
Getting Svelte diagnostics...

svelte-check found 0 errors and 0 warnings

bun run test output:

$ vitest run

 RUN  v5.0.1 /home/kayg/Developer/calternal-wt/break-editor/apps/web

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

 Test Files  72 passed (72)
      Tests  547 passed (547)
   Start at  11:52:29
   Duration  98.71s (transform 72%, environment 11%, import 8%, tests 6%, setup 2%)

  Transform  |component| transforming modules took 197.04s · 67% of tracked time, re-done on every run
             persist transforms across runs with fsModuleCache: true
             learn more: https://vitest.dev/guide/improving-performance#caching-between-reruns

# Forgejo #186 final report Head: `67de33ac0eecf4c70e56abbaa942ea685329ba2b` (`job/break-editor`). I merged `dev` through `65265f87` before the final gates. `dev` advanced to `fbecfbc6` while those gates ran; this tested head is the fixed snapshot from the start of the final gate run. ## Built - Preserved edits that race with collaborative block deletion and skipped saves for empty sync updates. - Regenerated duplicate block anchors and added copy-link deep-link coverage for blocks and headings. - Added seeded editor browser and direct-server probes for deep nesting, 10,000 blocks, 1 MiB paragraphs, hostile paste, Unicode, undo/redo storms, concurrent edits, offline/restart flows, external writes, and copied links. - Made the room restart probe connect directly to the backend so a proxy-side 101 cannot hide an upstream authorization rejection. - Extended the archive timeout handling and Photos share visibility window for shared-host adversarial runs. ## Files - `apps/web/src/lib/notes/anchors.test.ts` - `apps/web/src/lib/notes/anchors.ts` - `apps/web/src/lib/notes/editor-types/anchor.d.ts` - `crates/calternal-collab/src/lib.rs` - `crates/calternal-collab/src/session.rs` - `crates/calternal-collab/tests/shared_notes.mjs` - `tests/adversarial/attack2.py` - `tests/adversarial/authz_matrix.py` - `tests/adversarial/bun.lock` - `tests/adversarial/editor-proxy.mjs` - `tests/adversarial/editor.mjs` - `tests/adversarial/package.json` - `tests/adversarial/restart.mjs` - `tests/adversarial/run.sh` ## Adversarial findings and gaps - The isolated browser and room restart probes passed. The focused Photos share check produced no finding. The ZIP stream exceeded its 30-second cap and was classified `SLOW`; the server remained alive. - The broad API phase recorded 17 saved-search request timeouts and only 23 of 40 expected distinct searches; the server remained alive. Several other adversarial jobs were active on the shared host. I recorded this non-`SLOW`, cross-API observation on this issue. Saved-search behavior is outside this editor change. - The live Note UI still has no Make a note action, block reminder action, or multi-select. The browser run did not claim coverage of those absent controls. ## Decisions where the design is silent - The restart probe uses direct backend WebSockets and retains the proxy URL as the HTTP Origin. The proxy can send a client-side 101 before upstream authorization. - I set the Photos share visibility wait to 60 seconds for asynchronous indexing on this shared host. ZIP stream completion after 30 seconds is reported as `SLOW`. - `bun run build` was required before the Rust gates because `calternal-server` embeds `apps/web/build`. The production build exited 0 and emitted existing bundler notices for vendor `use client` directives. ## Gates `cargo fmt --check` exited 0 with empty output. `cargo clippy --all-targets -- -D warnings` output: ```text Compiling calternal-server v0.0.1 (/home/kayg/Developer/calternal-wt/break-editor/crates/calternal-server) Checking calternal-collab v0.0.1 (/home/kayg/Developer/calternal-wt/break-editor/crates/calternal-collab) Finished `dev` profile [unoptimized + debuginfo] target(s) in 21.21s ``` `cargo test` exited 0. Per-harness result lines copied verbatim: ```text test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s test result: ok. 49 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 43.46s test result: ok. 10 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.04s test result: ok. 11 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.87s test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.68s test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 6.17s test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 97.97s test result: ok. 11 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 4.91s test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.09s test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.20s test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 11.36s test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.98s test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 27.54s test result: ok. 15 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.13s test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 46.04s test result: ok. 10 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.02s test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.33s test result: ok. 9 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out; finished in 1.09s test result: ok. 17 passed; 0 failed; 4 ignored; 0 measured; 0 filtered out; finished in 0.48s test result: ok. 33 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 12.56s test result: ok. 35 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 3.20s test result: ok. 477 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.56s test result: ok. 13 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 3.94s test result: ok. 7 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.94s test result: ok. 11 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.06s test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s test result: ok. 19 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 7.48s test result: ok. 10 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.51s test result: ok. 29 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 6.03s test result: ok. 42 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 4.34s test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.04s test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.50s test result: ok. 101 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 63.66s test result: ok. 90 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 152.30s test result: ok. 12 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.27s test result: ok. 38 passed; 0 failed; 2 ignored; 0 measured; 0 filtered out; finished in 4.67s test result: ok. 10 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.12s test result: ok. 24 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out; finished in 2.00s test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 2.48s test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.16s test result: ok. 14 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 9.61s test result: ok. 4 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.09s test result: ok. 1 passed; 0 failed; 2 ignored; 0 measured; 0 filtered out; finished in 7.76s test result: ok. 4 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s test result: ok. 41 passed; 0 failed; 2 ignored; 0 measured; 0 filtered out; finished in 9.28s test result: ok. 45 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.22s test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s test result: ok. 10 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 5.66s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s ``` `bun run check` output: ```text $ svelte-kit sync && svelte-check --tsconfig ./tsconfig.json Loading svelte-check in workspace: /home/kayg/Developer/calternal-wt/break-editor/apps/web Getting Svelte diagnostics... svelte-check found 0 errors and 0 warnings ``` `bun run test` output: ```text $ vitest run RUN v5.0.1 /home/kayg/Developer/calternal-wt/break-editor/apps/web Could not parse CSS stylesheet Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Test Files 72 passed (72) Tests 547 passed (547) Start at 11:52:29 Duration 98.71s (transform 72%, environment 11%, import 8%, tests 6%, setup 2%) Transform |component| transforming modules took 197.04s · 67% of tracked time, re-done on every run persist transforms across runs with fsModuleCache: true learn more: https://vitest.dev/guide/improving-performance#caching-between-reruns ```
Author
Owner

Merged into dev at dfa8e85f (concurrent edit preserved during block deletion, no saves for empty sync updates, no duplicate anchors; seeded editor and restart probes). Deploy status on #203.

Merged into dev at dfa8e85f (concurrent edit preserved during block deletion, no saves for empty sync updates, no duplicate anchors; seeded editor and restart probes). Deploy status on #203.
kayg referenced this issue from a commit 2026-09-27 09:59:24 +00:00
kayg closed this issue 2026-09-27 09:59:25 +00:00
Author
Owner

Adversarial regression from the post-merge editor run: I filed #225. On seed 25608414, Copy link initially repaired the duplicate anchor, but after hostile paste/IME and 500 undo plus 500 redo steps the saved Note contained dozens of repeated ^duplicate-id anchors and was missing expected repaired anchors. The browser probe timed out after 30 s waiting for persistence. The same run's concurrent, offline, delete/edit and external-write probes passed. Full evidence is in target/tmp/menu-icons-adversarial-latest.log in the menu-icons worktree.

Adversarial regression from the post-merge editor run: I filed #225. On seed `25608414`, Copy link initially repaired the duplicate anchor, but after hostile paste/IME and 500 undo plus 500 redo steps the saved Note contained dozens of repeated `^duplicate-id` anchors and was missing expected repaired anchors. The browser probe timed out after 30 s waiting for persistence. The same run's concurrent, offline, delete/edit and external-write probes passed. Full evidence is in `target/tmp/menu-icons-adversarial-latest.log` in the menu-icons worktree.
Author
Owner

The same post-merge run also exposed a harness gap: issue #226 records that the live-editor restart probe's synchronous runner waits only 60 seconds for restart-ready-3, while the browser reaches that case after earlier editor attacks. In this run the ready marker appeared after the runner had returned, restart-go-3 was absent, and the browser reported a restart finding even though it did not request a restart. No product restart failure was established.

The same post-merge run also exposed a harness gap: issue #226 records that the live-editor restart probe's synchronous runner waits only 60 seconds for `restart-ready-3`, while the browser reaches that case after earlier editor attacks. In this run the ready marker appeared after the runner had returned, `restart-go-3` was absent, and the browser reported a restart finding even though it did not request a restart. No product restart failure was established.
Author
Owner

Post-merge replay on job/fonts at ffcc5d2a117ebafd4d32df9968230b3803f25a32, seed 25608414: the 10,000 top-level block case reached 10,002 room nodes, preserved all 130,027 Markdown bytes, and passed in 5.7 s. The timeout from the earlier run did not reproduce under the later host load.

Post-merge replay on `job/fonts` at `ffcc5d2a117ebafd4d32df9968230b3803f25a32`, seed `25608414`: the 10,000 top-level block case reached 10,002 room nodes, preserved all 130,027 Markdown bytes, and passed in 5.7 s. The timeout from the earlier run did not reproduce under the later host load.
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#186
No description provided.