Notes: the blank line after frontmatter is dropped on the first live save #95

Closed
opened 2026-09-25 15:23:48 +00:00 by kayg · 1 comment
Owner

Found by the editor-parity job (#87). The notes plugin hands the Markdown converter a body that starts with the blank line after the frontmatter; the converter drops leading blank lines (keeping them would render an empty line above every note title), so the first live save removes that one byte from any Note that has it. Stable afterwards, no content lost, but it rewrites bytes the user did not touch. Fix in the notes plugin: move the blank line after the closing '---' into the frontmatter prefix so the body never starts with it, and add a round-trip test: open + save an untouched Note leaves its bytes identical.

Found by the editor-parity job (#87). The notes plugin hands the Markdown converter a body that starts with the blank line after the frontmatter; the converter drops leading blank lines (keeping them would render an empty line above every note title), so the first live save removes that one byte from any Note that has it. Stable afterwards, no content lost, but it rewrites bytes the user did not touch. Fix in the notes plugin: move the blank line after the closing '---' into the frontmatter prefix so the body never starts with it, and add a round-trip test: open + save an untouched Note leaves its bytes identical.
Author
Owner

Fixed on branch job/frontmatter-blank (not merged).

  • b5318e9 test(collab): crates/calternal-collab/tests/untouched_bytes.rs. It opens a Note in a real Hub room and saves it with no change, restarts the Hub, applies an external edit to an open room, and runs a seeded property test (200 random frontmatter, blank-line and body combinations, with every JavaScript \s character, LF, CRLF and lone CR). Before the fix, all 3 tests failed. Example: ---\ntitle: Trip\n---\n\n# Restart target… was saved as …---\n# Restart target….
  • a0ba563 fix(notes): collab_split in crates/plugins/notes/src/lib.rs. The preserved prefix is now the frontmatter plus every leading blank line (it uses the same line and blank rules as the converter). A Note without frontmatter that starts with blank lines keeps them too. collab_read gives the room only the body after the prefix, and collab_write puts the prefix back without change. The converters, the parity vectors and the HTTP body view are not changed. DESIGN.md §9 records the rule.

Gates: cargo fmt --check passes. cargo clippy --workspace --all-targets -- -D warnings passes. cargo test --workspace passes (1056 passed, 0 failed). bash tests/adversarial/run.sh reports restart probe: 0 findings and ROUND 2 FINDINGS 0. It also reports 13 SLOW-only findings on appearance concurrent PUT (5 to 7 s, status 200). The load average was about 20 to 30 during the run.

Fixed on branch `job/frontmatter-blank` (not merged). - `b5318e9` test(collab): `crates/calternal-collab/tests/untouched_bytes.rs`. It opens a Note in a real Hub room and saves it with no change, restarts the Hub, applies an external edit to an open room, and runs a seeded property test (200 random frontmatter, blank-line and body combinations, with every JavaScript `\s` character, LF, CRLF and lone CR). Before the fix, all 3 tests failed. Example: `---\ntitle: Trip\n---\n\n# Restart target…` was saved as `…---\n# Restart target…`. - `a0ba563` fix(notes): `collab_split` in `crates/plugins/notes/src/lib.rs`. The preserved prefix is now the frontmatter plus every leading blank line (it uses the same line and blank rules as the converter). A Note without frontmatter that starts with blank lines keeps them too. `collab_read` gives the room only the body after the prefix, and `collab_write` puts the prefix back without change. The converters, the parity vectors and the HTTP body view are not changed. DESIGN.md §9 records the rule. Gates: `cargo fmt --check` passes. `cargo clippy --workspace --all-targets -- -D warnings` passes. `cargo test --workspace` passes (1056 passed, 0 failed). `bash tests/adversarial/run.sh` reports `restart probe: 0 findings` and `ROUND 2 FINDINGS 0`. It also reports 13 SLOW-only findings on `appearance concurrent PUT` (5 to 7 s, status 200). The load average was about 20 to 30 during the run.
kayg closed this issue 2026-09-25 18:47:23 +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#95
No description provided.